* [BUG] v3.12-rc5-139-gbdeeab6 assertion failed at drivers/net/bonding/bond_main.c (3398)
From: Thomas Glanzmann @ 2013-10-19 20:27 UTC (permalink / raw)
To: netdev
Cc: Jay Vosburgh, Andy Gospodarek, Nikolay Aleksandrov,
Veaceslav Falico, David S. Miller
Hello,
I'm referring to commit 7864a1adf7291993d74923fdd0a45459ce9da27e. I just
checked out the tip from Linus tree compiled it and run it on Debian Wheezy
with 4 1 GBIT NICs, two connected to one switch and two to another. I
configured bonding to use tlb. On the ports is one untagged and one
tagged VLAN. When I boot the kernel even if only one NIC is attached I
get multiple failed assertions:
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Initializing cgroup subsys cpuacct
[ 0.000000] Linux version 3.12.0-rc5+ (sithglan@infra) (gcc version 4.7.2 (Debian 4.7.2-5) ) #1 SMP Sat Oct 19 20:15:20 CEST 2013
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.12.0-rc5+ root=UUID=80f5fc61-60ba-4e3d-8d3a-2a51e4e4a5bc ro
[ 0.000000] e820: BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009abff] usable
[ 0.000000] BIOS-e820: [mem 0x000000000009ac00-0x000000000009ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000000e0000-0x00000000000fffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000007dfe9fff] usable
[ 0.000000] BIOS-e820: [mem 0x000000007dfea000-0x000000007e026fff] reserved
[ 0.000000] BIOS-e820: [mem 0x000000007e027000-0x000000007e2c2fff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x000000007e2c3000-0x000000007f36bfff] reserved
[ 0.000000] BIOS-e820: [mem 0x000000007f36c000-0x000000007f7fffff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x0000000080000000-0x000000008fffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fed1c000-0x00000000fed3ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000ff000000-0x00000000ffffffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000107fffffff] usable
[ 0.000000] NX (Execute Disable) protection: active
[ 0.000000] SMBIOS 2.7 present.
[ 0.000000] DMI: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 0.000000] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[ 0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable
[ 0.000000] No AGP bridge found
[ 0.000000] e820: last_pfn = 0x1080000 max_arch_pfn = 0x400000000
[ 0.000000] MTRR default type: uncachable
[ 0.000000] MTRR fixed ranges enabled:
[ 0.000000] 00000-9FFFF write-back
[ 0.000000] A0000-BFFFF uncachable
[ 0.000000] C0000-FFFFF write-protect
[ 0.000000] MTRR variable ranges enabled:
[ 0.000000] 0 base 000000000000 mask 3FF000000000 write-back
[ 0.000000] 1 base 001000000000 mask 3FFF80000000 write-back
[ 0.000000] 2 base 000080000000 mask 3FFF80000000 uncachable
[ 0.000000] 3 disabled
[ 0.000000] 4 disabled
[ 0.000000] 5 disabled
[ 0.000000] 6 disabled
[ 0.000000] 7 disabled
[ 0.000000] 8 disabled
[ 0.000000] 9 disabled
[ 0.000000] x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106
[ 0.000000] e820: update [mem 0x80000000-0xffffffff] usable ==> reserved
[ 0.000000] e820: last_pfn = 0x7dfea max_arch_pfn = 0x400000000
[ 0.000000] found SMP MP-table at [mem 0x000fd840-0x000fd84f] mapped at [ffff8800000fd840]
[ 0.000000] Base memory trampoline at [ffff880000094000] 94000 size 24576
[ 0.000000] Using GB pages for direct mapping
[ 0.000000] init_memory_mapping: [mem 0x00000000-0x000fffff]
[ 0.000000] [mem 0x00000000-0x000fffff] page 4k
[ 0.000000] BRK [0x01853000, 0x01853fff] PGTABLE
[ 0.000000] BRK [0x01854000, 0x01854fff] PGTABLE
[ 0.000000] BRK [0x01855000, 0x01855fff] PGTABLE
[ 0.000000] init_memory_mapping: [mem 0x107fe00000-0x107fffffff]
[ 0.000000] [mem 0x107fe00000-0x107fffffff] page 1G
[ 0.000000] init_memory_mapping: [mem 0x107c000000-0x107fdfffff]
[ 0.000000] [mem 0x107c000000-0x107fdfffff] page 1G
[ 0.000000] init_memory_mapping: [mem 0x1000000000-0x107bffffff]
[ 0.000000] [mem 0x1000000000-0x107bffffff] page 1G
[ 0.000000] init_memory_mapping: [mem 0x00100000-0x7dfe9fff]
[ 0.000000] [mem 0x00100000-0x001fffff] page 4k
[ 0.000000] [mem 0x00200000-0x7ddfffff] page 2M
[ 0.000000] [mem 0x7de00000-0x7dfe9fff] page 4k
[ 0.000000] init_memory_mapping: [mem 0x100000000-0xfffffffff]
[ 0.000000] [mem 0x100000000-0xfffffffff] page 1G
[ 0.000000] RAMDISK: [mem 0x36938000-0x37493fff]
[ 0.000000] ACPI: RSDP 00000000000f0490 00024 (v02 SUPERM)
[ 0.000000] ACPI: XSDT 000000007e245088 0008C (v01 \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff 00000001 AMI 00010013)
[ 0.000000] ACPI: FACP 000000007e24e7d8 000F4 (v04 \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff 00000001 AMI 00010013)
[ 0.000000] ACPI: DSDT 000000007e2451a8 09629 (v02 \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff 00000000 INTL 20091112)
[ 0.000000] ACPI: FACS 000000007e2c0f80 00040
[ 0.000000] ACPI: APIC 000000007e24e8d0 00100 (v03 00000001 AMI 00010013)
[ 0.000000] ACPI: FPDT 000000007e24e9d0 00044 (v01 00000001 AMI 00010013)
[ 0.000000] ACPI: HPET 000000007e24ea18 00038 (v01 SUPERM SMCI--MB 00000001 AMI. 00000005)
[ 0.000000] ACPI: PRAD 000000007e24ea50 000BE (v02 PRADID PRADTID 00000001 MSFT 04000000)
[ 0.000000] ACPI: SPMI 000000007e24eb10 00040 (v05 A M I OEMSPMI 00000000 AMI. 00000000)
[ 0.000000] ACPI: SSDT 000000007e24eb50 6B344 (v02 INTEL CpuPm 00004000 INTL 20091112)
[ 0.000000] ACPI: EINJ 000000007e2b9e98 00130 (v01 AMI AMI EINJ 00000000 00000000)
[ 0.000000] ACPI: ERST 000000007e2b9fc8 00230 (v01 AMIER AMI ERST 00000000 00000000)
[ 0.000000] ACPI: HEST 000000007e2ba1f8 000A8 (v01 AMI AMI HEST 00000000 00000000)
[ 0.000000] ACPI: BERT 000000007e2ba2a0 00030 (v01 AMI AMI BERT 00000000 00000000)
[ 0.000000] ACPI: DMAR 000000007e2ba2d0 000CC (v01 A M I OEMDMAR 00000001 INTL 00000001)
[ 0.000000] ACPI: MCFG 000000007e2ba3a0 0003C (v01 SUPERM SMCI--MB 00000001 MSFT 00000097)
[ 0.000000] ACPI: Local APIC address 0xfee00000
[ 0.000000] No NUMA configuration found
[ 0.000000] Faking a node at [mem 0x0000000000000000-0x000000107fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x00000000-0x107fffffff]
[ 0.000000] NODE_DATA [mem 0x107fffa000-0x107fffdfff]
[ 0.000000] [ffffea0000000000-ffffea0039bfffff] PMD -> [ffff88103f600000-ffff8810775fffff] on node 0
[ 0.000000] Zone ranges:
[ 0.000000] DMA [mem 0x00001000-0x00ffffff]
[ 0.000000] DMA32 [mem 0x01000000-0xffffffff]
[ 0.000000] Normal [mem 0x100000000-0x107fffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x00001000-0x00099fff]
[ 0.000000] node 0: [mem 0x00100000-0x7dfe9fff]
[ 0.000000] node 0: [mem 0x100000000-0x107fffffff]
[ 0.000000] On node 0 totalpages: 16768899
[ 0.000000] DMA zone: 56 pages used for memmap
[ 0.000000] DMA zone: 21 pages reserved
[ 0.000000] DMA zone: 3993 pages, LIFO batch:0
[ 0.000000] DMA32 zone: 7000 pages used for memmap
[ 0.000000] DMA32 zone: 511978 pages, LIFO batch:31
[ 0.000000] Normal zone: 222208 pages used for memmap
[ 0.000000] Normal zone: 16252928 pages, LIFO batch:31
[ 0.000000] ACPI: PM-Timer IO Port: 0x408
[ 0.000000] ACPI: Local APIC address 0xfee00000
[ 0.000000] ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x02] lapic_id[0x02] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x04] lapic_id[0x04] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x06] lapic_id[0x06] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x08] lapic_id[0x08] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x0a] lapic_id[0x0a] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x03] lapic_id[0x03] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x05] lapic_id[0x05] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x07] lapic_id[0x07] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x09] lapic_id[0x09] enabled)
[ 0.000000] ACPI: LAPIC (acpi_id[0x0b] lapic_id[0x0b] enabled)
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x02] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x04] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x06] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x08] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x0a] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x03] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x05] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x07] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x09] high edge lint[0x1])
[ 0.000000] ACPI: LAPIC_NMI (acpi_id[0x0b] high edge lint[0x1])
[ 0.000000] ACPI: IOAPIC (id[0x00] address[0xfec00000] gsi_base[0])
[ 0.000000] IOAPIC[0]: apic_id 0, version 32, address 0xfec00000, GSI 0-23
[ 0.000000] ACPI: IOAPIC (id[0x02] address[0xfec01000] gsi_base[24])
[ 0.000000] IOAPIC[1]: apic_id 2, version 32, address 0xfec01000, GSI 24-47
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[ 0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[ 0.000000] ACPI: IRQ0 used by override.
[ 0.000000] ACPI: IRQ2 used by override.
[ 0.000000] ACPI: IRQ9 used by override.
[ 0.000000] Using ACPI (MADT) for SMP configuration information
[ 0.000000] ACPI: HPET id: 0x8086a701 base: 0xfed00000
[ 0.000000] smpboot: Allowing 12 CPUs, 0 hotplug CPUs
[ 0.000000] nr_irqs_gsi: 64
[ 0.000000] PM: Registered nosave memory: [mem 0x0009a000-0x0009afff]
[ 0.000000] PM: Registered nosave memory: [mem 0x0009b000-0x0009ffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x000a0000-0x000dffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x000e0000-0x000fffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x7dfea000-0x7e026fff]
[ 0.000000] PM: Registered nosave memory: [mem 0x7e027000-0x7e2c2fff]
[ 0.000000] PM: Registered nosave memory: [mem 0x7e2c3000-0x7f36bfff]
[ 0.000000] PM: Registered nosave memory: [mem 0x7f36c000-0x7f7fffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x7f800000-0x7fffffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x80000000-0x8fffffff]
[ 0.000000] PM: Registered nosave memory: [mem 0x90000000-0xfed1bfff]
[ 0.000000] PM: Registered nosave memory: [mem 0xfed1c000-0xfed3ffff]
[ 0.000000] PM: Registered nosave memory: [mem 0xfed40000-0xfeffffff]
[ 0.000000] PM: Registered nosave memory: [mem 0xff000000-0xffffffff]
[ 0.000000] e820: [mem 0x90000000-0xfed1bfff] available for PCI devices
[ 0.000000] setup_percpu: NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:12 nr_node_ids:1
[ 0.000000] PERCPU: Embedded 27 pages/cpu @ffff88107fc00000 s80704 r8192 d21696 u131072
[ 0.000000] pcpu-alloc: s80704 r8192 d21696 u131072 alloc=1*2097152
[ 0.000000] pcpu-alloc: [0] 00 01 02 03 04 05 06 07 08 09 10 11 -- -- -- --
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16539614
[ 0.000000] Policy zone: Normal
[ 0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-3.12.0-rc5+ root=UUID=80f5fc61-60ba-4e3d-8d3a-2a51e4e4a5bc ro
[ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.000000] xsave: enabled xstate_bv 0x7, cntxt size 0x340
[ 0.000000] Checking aperture...
[ 0.000000] No AGP bridge found
[ 0.000000] Calgary: detecting Calgary via BIOS EBDA area
[ 0.000000] Calgary: Unable to locate Rio Grande table in EBDA - bailing!
[ 0.000000] Memory: 66070184K/67075596K available (3584K kernel code, 607K rwdata, 1512K rodata, 872K init, 876K bss, 1005412K reserved)
[ 0.000000] Hierarchical RCU implementation.
[ 0.000000] RCU dyntick-idle grace-period acceleration is enabled.
[ 0.000000] RCU restricting CPUs from NR_CPUS=512 to nr_cpu_ids=12.
[ 0.000000] NR_IRQS:33024 nr_irqs:1184 16
[ 0.000000] Console: colour VGA+ 80x25
[ 0.000000] console [tty0] enabled
[ 0.000000] hpet clockevent registered
[ 0.000000] tsc: Fast TSC calibration using PIT
[ 0.004000] tsc: Detected 1999.978 MHz processor
[ 0.000004] Calibrating delay loop (skipped), value calculated using timer frequency.. 3999.95 BogoMIPS (lpj=7999912)
[ 0.000145] pid_max: default: 32768 minimum: 301
[ 0.000250] Security Framework initialized
[ 0.000321] AppArmor: AppArmor disabled by boot time parameter
[ 0.005209] Dentry cache hash table entries: 8388608 (order: 14, 67108864 bytes)
[ 0.020973] Inode-cache hash table entries: 4194304 (order: 13, 33554432 bytes)
[ 0.027672] Mount-cache hash table entries: 256
[ 0.027980] Initializing cgroup subsys devices
[ 0.028052] Initializing cgroup subsys freezer
[ 0.028122] Initializing cgroup subsys net_cls
[ 0.028192] Initializing cgroup subsys blkio
[ 0.028261] Initializing cgroup subsys perf_event
[ 0.028357] CPU: Physical Processor ID: 0
[ 0.028425] CPU: Processor Core ID: 0
[ 0.028519] mce: CPU supports 18 MCE banks
[ 0.028618] CPU0: Thermal monitoring enabled (TM1)
[ 0.028708] Last level iTLB entries: 4KB 512, 2MB 0, 4MB 0
[ 0.028708] Last level dTLB entries: 4KB 512, 2MB 32, 4MB 32
[ 0.028708] tlb_flushall_shift: 5
[ 0.028929] Freeing SMP alternatives memory: 12K (ffffffff81773000 - ffffffff81776000)
[ 0.029019] ACPI: Core revision 20130725
[ 0.053605] ACPI: All ACPI Tables successfully acquired
[ 0.054045] dmar: Host address width 46
[ 0.054114] dmar: DRHD base: 0x000000fbffc000 flags: 0x1
[ 0.054191] dmar: IOMMU 0: reg_base_addr fbffc000 ver 1:0 cap d2078c106f0462 ecap f020fe
[ 0.054280] dmar: RMRR base: 0x0000007dffd000 end: 0x0000007e009fff
[ 0.054352] dmar: ATSR flags: 0x0
[ 0.054419] dmar: RHSA base: 0x000000fbffc000 proximity domain: 0x0
[ 0.054586] IOAPIC id 0 under DRHD base 0xfbffc000 IOMMU 0
[ 0.054658] IOAPIC id 2 under DRHD base 0xfbffc000 IOMMU 0
[ 0.054729] HPET id 0 under DRHD base 0xfbffc000
[ 0.054927] Enabled IRQ remapping in x2apic mode
[ 0.054996] Enabling x2apic
[ 0.055061] Enabled x2apic
[ 0.055131] Switched APIC routing to cluster x2apic.
[ 0.055744] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[ 0.095498] smpboot: CPU0: Intel(R) Xeon(R) CPU E5-2630L 0 @ 2.00GHz (fam: 06, model: 2d, stepping: 07)
[ 0.095735] TSC deadline timer enabled
[ 0.095744] Performance Events: PEBS fmt1+, 16-deep LBR, SandyBridge events, full-width counters, Intel PMU driver.
[ 0.096078] ... version: 3
[ 0.096145] ... bit width: 48
[ 0.101511] ... generic registers: 4
[ 0.101579] ... value mask: 0000ffffffffffff
[ 0.101649] ... max period: 0000ffffffffffff
[ 0.101718] ... fixed-purpose events: 3
[ 0.101786] ... event mask: 000000070000000f
[ 0.116326] NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter.
[ 0.102246] smpboot: Booting Node 0, Processors # 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 OK
[ 0.248878] Brought up 12 CPUs
[ 0.248949] smpboot: Total of 12 processors activated (47999.47 BogoMIPS)
[ 0.267646] devtmpfs: initialized
[ 0.281269] PM: Registering ACPI NVS region [mem 0x7e027000-0x7e2c2fff] (2736128 bytes)
[ 0.281497] PM: Registering ACPI NVS region [mem 0x7f36c000-0x7f7fffff] (4800512 bytes)
[ 0.282080] regulator-dummy: no parameters
[ 0.282240] NET: Registered protocol family 16
[ 0.282421] cpuidle: using governor ladder
[ 0.282489] cpuidle: using governor menu
[ 0.282577] ACPI FADT declares the system doesn't support PCIe ASPM, so disable it
[ 0.282666] ACPI: bus type PCI registered
[ 0.282734] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[ 0.282882] PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0x80000000-0x8fffffff] (base 0x80000000)
[ 0.282975] PCI: MMCONFIG at [mem 0x80000000-0x8fffffff] reserved in E820
[ 0.292053] PCI: Using configuration type 1 for base access
[ 0.294195] bio: create slab <bio-0> at 0
[ 0.294500] ACPI: Added _OSI(Module Device)
[ 0.294569] ACPI: Added _OSI(Processor Device)
[ 0.294637] ACPI: Added _OSI(3.0 _SCP Extensions)
[ 0.294707] ACPI: Added _OSI(Processor Aggregator Device)
[ 0.299686] ACPI: EC: Look up EC in DSDT
[ 0.304858] ACPI: Executed 1 blocks of module-level executable AML code
[ 0.585219] ACPI: Interpreter enabled
[ 0.585299] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S2_] (20130725/hwxface-571)
[ 0.585485] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S3_] (20130725/hwxface-571)
[ 0.585676] ACPI: (supports S0 S1 S4 S5)
[ 0.585744] ACPI: Using IOAPIC for interrupt routing
[ 0.585883] HEST: Table parsing has been initialized.
[ 0.585955] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[ 0.586280] ACPI: No dock devices found.
[ 0.588734] [Firmware Bug]: ACPI: BIOS _OSI(Linux) query ignored
[ 0.597833] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-fe])
[ 0.598131] acpi PNP0A08:00: Requesting ACPI _OSC control (0x1d)
[ 0.598525] acpi PNP0A08:00: ACPI _OSC control (0x11) granted
[ 0.598924] ACPI: \_SB_.PCI0.IOH_: can't evaluate _ADR (0x5)
[ 0.598996] ACPI: \_SB_.PCI0.VTDR: can't evaluate _ADR (0x5)
[ 0.599079] ACPI: \_SB_.PCI0.PCH_: can't evaluate _ADR (0x5)
[ 0.599151] ACPI: \_SB_.PCI0.CWDT: can't evaluate _ADR (0x5)
[ 0.599368] ACPI: \_SB_.PCI0.HPET: can't evaluate _ADR (0x5)
[ 0.599440] ACPI: \_SB_.PCI0.ITPM: can't evaluate _ADR (0x5)
[ 0.599511] PCI host bridge to bus 0000:00
[ 0.599580] pci_bus 0000:00: root bus resource [bus 00-fe]
[ 0.599652] pci_bus 0000:00: root bus resource [io 0x0000-0x03af]
[ 0.599725] pci_bus 0000:00: root bus resource [io 0x03e0-0x0cf7]
[ 0.599797] pci_bus 0000:00: root bus resource [io 0x03b0-0x03df]
[ 0.599869] pci_bus 0000:00: root bus resource [io 0x0d00-0xffff]
[ 0.599942] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff]
[ 0.600015] pci_bus 0000:00: root bus resource [mem 0x000c0000-0x000dffff]
[ 0.600089] pci_bus 0000:00: root bus resource [mem 0xfed0e000-0xfed0ffff]
[ 0.600162] pci_bus 0000:00: root bus resource [mem 0x80000000-0xfbffffff]
[ 0.600247] pci 0000:00:00.0: [8086:3c00] type 00 class 0x060000
[ 0.600307] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[ 0.600420] pci 0000:00:01.0: [8086:3c02] type 01 class 0x060400
[ 0.600489] pci 0000:00:01.0: PME# supported from D0 D3hot D3cold
[ 0.600562] pci 0000:00:01.0: System wakeup disabled by ACPI
[ 0.600679] pci 0000:00:01.1: [8086:3c03] type 01 class 0x060400
[ 0.600747] pci 0000:00:01.1: PME# supported from D0 D3hot D3cold
[ 0.600818] pci 0000:00:01.1: System wakeup disabled by ACPI
[ 0.600940] pci 0000:00:02.0: [8086:3c04] type 01 class 0x060400
[ 0.601007] pci 0000:00:02.0: PME# supported from D0 D3hot D3cold
[ 0.601080] pci 0000:00:02.0: System wakeup disabled by ACPI
[ 0.601194] pci 0000:00:02.2: [8086:3c06] type 01 class 0x060400
[ 0.601261] pci 0000:00:02.2: PME# supported from D0 D3hot D3cold
[ 0.601332] pci 0000:00:02.2: System wakeup disabled by ACPI
[ 0.601449] pci 0000:00:03.0: [8086:3c08] type 01 class 0x060400
[ 0.601516] pci 0000:00:03.0: PME# supported from D0 D3hot D3cold
[ 0.601589] pci 0000:00:03.0: System wakeup disabled by ACPI
[ 0.601703] pci 0000:00:03.2: [8086:3c0a] type 01 class 0x060400
[ 0.601770] pci 0000:00:03.2: PME# supported from D0 D3hot D3cold
[ 0.601841] pci 0000:00:03.2: System wakeup disabled by ACPI
[ 0.601960] pci 0000:00:04.0: [8086:3c20] type 00 class 0x088000
[ 0.601976] pci 0000:00:04.0: reg 0x10: [mem 0xfb81c000-0xfb81ffff 64bit]
[ 0.602134] pci 0000:00:04.1: [8086:3c21] type 00 class 0x088000
[ 0.602148] pci 0000:00:04.1: reg 0x10: [mem 0xfb818000-0xfb81bfff 64bit]
[ 0.602305] pci 0000:00:04.2: [8086:3c22] type 00 class 0x088000
[ 0.602320] pci 0000:00:04.2: reg 0x10: [mem 0xfb814000-0xfb817fff 64bit]
[ 0.602483] pci 0000:00:04.3: [8086:3c23] type 00 class 0x088000
[ 0.602498] pci 0000:00:04.3: reg 0x10: [mem 0xfb810000-0xfb813fff 64bit]
[ 0.602655] pci 0000:00:04.4: [8086:3c24] type 00 class 0x088000
[ 0.602670] pci 0000:00:04.4: reg 0x10: [mem 0xfb80c000-0xfb80ffff 64bit]
[ 0.602831] pci 0000:00:04.5: [8086:3c25] type 00 class 0x088000
[ 0.602845] pci 0000:00:04.5: reg 0x10: [mem 0xfb808000-0xfb80bfff 64bit]
[ 0.603000] pci 0000:00:04.6: [8086:3c26] type 00 class 0x088000
[ 0.603015] pci 0000:00:04.6: reg 0x10: [mem 0xfb804000-0xfb807fff 64bit]
[ 0.603169] pci 0000:00:04.7: [8086:3c27] type 00 class 0x088000
[ 0.603184] pci 0000:00:04.7: reg 0x10: [mem 0xfb800000-0xfb803fff 64bit]
[ 0.603337] pci 0000:00:05.0: [8086:3c28] type 00 class 0x088000
[ 0.603479] pci 0000:00:05.2: [8086:3c2a] type 00 class 0x088000
[ 0.603620] pci 0000:00:05.4: [8086:3c2c] type 00 class 0x080020
[ 0.603633] pci 0000:00:05.4: reg 0x10: [mem 0xfb825000-0xfb825fff]
[ 0.603789] pci 0000:00:11.0: [8086:1d3e] type 01 class 0x060400
[ 0.603881] pci 0000:00:11.0: PME# supported from D0 D3hot D3cold
[ 0.603997] pci 0000:00:16.0: [8086:1d3a] type 00 class 0x078000
[ 0.604020] pci 0000:00:16.0: reg 0x10: [mem 0xfed0e000-0xfed0e00f 64bit]
[ 0.604095] pci 0000:00:16.0: PME# supported from D0 D3hot D3cold
[ 0.604199] pci 0000:00:16.1: [8086:1d3b] type 00 class 0x078000
[ 0.604222] pci 0000:00:16.1: reg 0x10: [mem 0xfed0f000-0xfed0f00f 64bit]
[ 0.604297] pci 0000:00:16.1: PME# supported from D0 D3hot D3cold
[ 0.604415] pci 0000:00:1a.0: [8086:1d2d] type 00 class 0x0c0320
[ 0.604437] pci 0000:00:1a.0: reg 0x10: [mem 0xfb823000-0xfb8233ff]
[ 0.604531] pci 0000:00:1a.0: PME# supported from D0 D3hot D3cold
[ 0.604600] pci 0000:00:1a.0: System wakeup disabled by ACPI
[ 0.604719] pci 0000:00:1d.0: [8086:1d26] type 00 class 0x0c0320
[ 0.604741] pci 0000:00:1d.0: reg 0x10: [mem 0xfb822000-0xfb8223ff]
[ 0.604835] pci 0000:00:1d.0: PME# supported from D0 D3hot D3cold
[ 0.604905] pci 0000:00:1d.0: System wakeup disabled by ACPI
[ 0.605015] pci 0000:00:1e.0: [8086:244e] type 01 class 0x060401
[ 0.605125] pci 0000:00:1e.0: System wakeup disabled by ACPI
[ 0.605238] pci 0000:00:1f.0: [8086:1d41] type 00 class 0x060100
[ 0.605442] pci 0000:00:1f.2: [8086:1d02] type 00 class 0x010601
[ 0.605462] pci 0000:00:1f.2: reg 0x10: [io 0xf050-0xf057]
[ 0.605470] pci 0000:00:1f.2: reg 0x14: [io 0xf040-0xf043]
[ 0.605478] pci 0000:00:1f.2: reg 0x18: [io 0xf030-0xf037]
[ 0.605487] pci 0000:00:1f.2: reg 0x1c: [io 0xf020-0xf023]
[ 0.605495] pci 0000:00:1f.2: reg 0x20: [io 0xf000-0xf01f]
[ 0.605503] pci 0000:00:1f.2: reg 0x24: [mem 0xfb821000-0xfb8217ff]
[ 0.605551] pci 0000:00:1f.2: PME# supported from D3hot
[ 0.605650] pci 0000:00:1f.3: [8086:1d22] type 00 class 0x0c0500
[ 0.605666] pci 0000:00:1f.3: reg 0x10: [mem 0xfb820000-0xfb8200ff 64bit]
[ 0.605688] pci 0000:00:1f.3: reg 0x20: [io 0x1180-0x119f]
[ 0.605799] pci 0000:00:1f.6: [8086:1d24] type 00 class 0x118000
[ 0.605820] pci 0000:00:1f.6: reg 0x10: [mem 0x90000000-0x90000fff 64bit]
[ 0.606027] pci 0000:00:01.0: PCI bridge to [bus 01]
[ 0.606161] pci 0000:00:01.1: PCI bridge to [bus 02]
[ 0.606308] pci 0000:03:00.0: [8086:1521] type 00 class 0x020000
[ 0.606319] pci 0000:03:00.0: reg 0x10: [mem 0xfb580000-0xfb5fffff]
[ 0.606333] pci 0000:03:00.0: reg 0x18: [io 0xe020-0xe03f]
[ 0.606341] pci 0000:03:00.0: reg 0x1c: [mem 0xfb704000-0xfb707fff]
[ 0.606362] pci 0000:03:00.0: reg 0x30: [mem 0xfb640000-0xfb67ffff pref]
[ 0.606401] pci 0000:03:00.0: PME# supported from D0 D3hot D3cold
[ 0.606430] pci 0000:03:00.0: reg 0x184: [mem 0xfb6e0000-0xfb6e3fff]
[ 0.606447] pci 0000:03:00.0: reg 0x190: [mem 0xfb6c0000-0xfb6c3fff]
[ 0.606516] pci 0000:03:00.1: [8086:1521] type 00 class 0x020000
[ 0.606527] pci 0000:03:00.1: reg 0x10: [mem 0xfb500000-0xfb57ffff]
[ 0.606541] pci 0000:03:00.1: reg 0x18: [io 0xe000-0xe01f]
[ 0.606549] pci 0000:03:00.1: reg 0x1c: [mem 0xfb700000-0xfb703fff]
[ 0.606569] pci 0000:03:00.1: reg 0x30: [mem 0xfb600000-0xfb63ffff pref]
[ 0.606608] pci 0000:03:00.1: PME# supported from D0 D3hot D3cold
[ 0.606632] pci 0000:03:00.1: reg 0x184: [mem 0xfb6a0000-0xfb6a3fff]
[ 0.606649] pci 0000:03:00.1: reg 0x190: [mem 0xfb680000-0xfb683fff]
[ 0.614483] pci 0000:00:02.0: PCI bridge to [bus 03-04]
[ 0.614569] pci 0000:00:02.0: bridge window [io 0xe000-0xefff]
[ 0.614573] pci 0000:00:02.0: bridge window [mem 0xfb500000-0xfb7fffff]
[ 0.614650] pci 0000:05:00.0: [8086:1521] type 00 class 0x020000
[ 0.614660] pci 0000:05:00.0: reg 0x10: [mem 0xfb200000-0xfb2fffff]
[ 0.614680] pci 0000:05:00.0: reg 0x1c: [mem 0xfb404000-0xfb407fff]
[ 0.614701] pci 0000:05:00.0: reg 0x30: [mem 0xfb300000-0xfb37ffff pref]
[ 0.614739] pci 0000:05:00.0: PME# supported from D0 D3hot D3cold
[ 0.614768] pci 0000:05:00.0: reg 0x184: [mem 0xfb3e0000-0xfb3e3fff]
[ 0.614784] pci 0000:05:00.0: reg 0x190: [mem 0xfb3c0000-0xfb3c3fff]
[ 0.614846] pci 0000:05:00.1: [8086:1521] type 00 class 0x020000
[ 0.614857] pci 0000:05:00.1: reg 0x10: [mem 0xfb100000-0xfb1fffff]
[ 0.614877] pci 0000:05:00.1: reg 0x1c: [mem 0xfb400000-0xfb403fff]
[ 0.614933] pci 0000:05:00.1: PME# supported from D0 D3hot D3cold
[ 0.614957] pci 0000:05:00.1: reg 0x184: [mem 0xfb3a0000-0xfb3a3fff]
[ 0.614974] pci 0000:05:00.1: reg 0x190: [mem 0xfb380000-0xfb383fff]
[ 0.622495] pci 0000:00:02.2: PCI bridge to [bus 05-06]
[ 0.622570] pci 0000:00:02.2: bridge window [mem 0xfb100000-0xfb4fffff]
[ 0.622636] pci 0000:00:03.0: PCI bridge to [bus 07]
[ 0.622774] pci 0000:00:03.2: PCI bridge to [bus 08]
[ 0.622919] pci 0000:00:11.0: PCI bridge to [bus 09]
[ 0.623049] pci 0000:0a:01.0: [102b:0532] type 00 class 0x030000
[ 0.623067] pci 0000:0a:01.0: reg 0x10: [mem 0xf9000000-0xf9ffffff pref]
[ 0.623077] pci 0000:0a:01.0: reg 0x14: [mem 0xfb000000-0xfb003fff]
[ 0.623087] pci 0000:0a:01.0: reg 0x18: [mem 0xfa800000-0xfaffffff]
[ 0.623222] pci 0000:00:1e.0: PCI bridge to [bus 0a] (subtractive decode)
[ 0.623299] pci 0000:00:1e.0: bridge window [mem 0xfa800000-0xfb0fffff]
[ 0.623305] pci 0000:00:1e.0: bridge window [mem 0xf9000000-0xf9ffffff 64bit pref]
[ 0.623307] pci 0000:00:1e.0: bridge window [io 0x0000-0x03af] (subtractive decode)
[ 0.623310] pci 0000:00:1e.0: bridge window [io 0x03e0-0x0cf7] (subtractive decode)
[ 0.623312] pci 0000:00:1e.0: bridge window [io 0x03b0-0x03df] (subtractive decode)
[ 0.623315] pci 0000:00:1e.0: bridge window [io 0x0d00-0xffff] (subtractive decode)
[ 0.623317] pci 0000:00:1e.0: bridge window [mem 0x000a0000-0x000bffff] (subtractive decode)
[ 0.623320] pci 0000:00:1e.0: bridge window [mem 0x000c0000-0x000dffff] (subtractive decode)
[ 0.623322] pci 0000:00:1e.0: bridge window [mem 0xfed0e000-0xfed0ffff] (subtractive decode)
[ 0.623325] pci 0000:00:1e.0: bridge window [mem 0x80000000-0xfbffffff] (subtractive decode)
[ 0.623366] pci_bus 0000:00: on NUMA node 0 (pxm 0)
[ 0.623368] acpi PNP0A08:00: Disabling ASPM (FADT indicates it is unsupported)
[ 0.624144] ACPI: PCI Root Bridge [UNC0] (domain 0000 [bus ff])
[ 0.624219] acpi PNP0A03:00: ACPI _OSC support notification failed, disabling PCIe ASPM
[ 0.624308] acpi PNP0A03:00: Unable to request _OSC control (_OSC support mask: 0x08)
[ 0.624464] PCI host bridge to bus 0000:ff
[ 0.624533] pci_bus 0000:ff: root bus resource [bus ff]
[ 0.624612] pci 0000:ff:08.0: [8086:3c80] type 00 class 0x088000
[ 0.624676] pci 0000:ff:08.3: [8086:3c83] type 00 class 0x088000
[ 0.624747] pci 0000:ff:08.4: [8086:3c84] type 00 class 0x088000
[ 0.624822] pci 0000:ff:09.0: [8086:3c90] type 00 class 0x088000
[ 0.624882] pci 0000:ff:09.3: [8086:3c93] type 00 class 0x088000
[ 0.624951] pci 0000:ff:09.4: [8086:3c94] type 00 class 0x088000
[ 0.625023] pci 0000:ff:0a.0: [8086:3cc0] type 00 class 0x088000
[ 0.625074] pci 0000:ff:0a.1: [8086:3cc1] type 00 class 0x088000
[ 0.625124] pci 0000:ff:0a.2: [8086:3cc2] type 00 class 0x088000
[ 0.625174] pci 0000:ff:0a.3: [8086:3cd0] type 00 class 0x088000
[ 0.625227] pci 0000:ff:0b.0: [8086:3ce0] type 00 class 0x088000
[ 0.625278] pci 0000:ff:0b.3: [8086:3ce3] type 00 class 0x088000
[ 0.625329] pci 0000:ff:0c.0: [8086:3ce8] type 00 class 0x088000
[ 0.625380] pci 0000:ff:0c.1: [8086:3ce8] type 00 class 0x088000
[ 0.625430] pci 0000:ff:0c.2: [8086:3ce8] type 00 class 0x088000
[ 0.625482] pci 0000:ff:0c.6: [8086:3cf4] type 00 class 0x088000
[ 0.625532] pci 0000:ff:0c.7: [8086:3cf6] type 00 class 0x088000
[ 0.625582] pci 0000:ff:0d.0: [8086:3ce8] type 00 class 0x088000
[ 0.625632] pci 0000:ff:0d.1: [8086:3ce8] type 00 class 0x088000
[ 0.625682] pci 0000:ff:0d.2: [8086:3ce8] type 00 class 0x088000
[ 0.625733] pci 0000:ff:0d.6: [8086:3cf5] type 00 class 0x088000
[ 0.625784] pci 0000:ff:0e.0: [8086:3ca0] type 00 class 0x088000
[ 0.625838] pci 0000:ff:0e.1: [8086:3c46] type 00 class 0x110100
[ 0.625898] pci 0000:ff:0f.0: [8086:3ca8] type 00 class 0x088000
[ 0.625963] pci 0000:ff:0f.1: [8086:3c71] type 00 class 0x088000
[ 0.626031] pci 0000:ff:0f.2: [8086:3caa] type 00 class 0x088000
[ 0.626097] pci 0000:ff:0f.3: [8086:3cab] type 00 class 0x088000
[ 0.626162] pci 0000:ff:0f.4: [8086:3cac] type 00 class 0x088000
[ 0.626231] pci 0000:ff:0f.5: [8086:3cad] type 00 class 0x088000
[ 0.626294] pci 0000:ff:0f.6: [8086:3cae] type 00 class 0x088000
[ 0.626352] pci 0000:ff:10.0: [8086:3cb0] type 00 class 0x088000
[ 0.626419] pci 0000:ff:10.1: [8086:3cb1] type 00 class 0x088000
[ 0.626493] pci 0000:ff:10.2: [8086:3cb2] type 00 class 0x088000
[ 0.626560] pci 0000:ff:10.3: [8086:3cb3] type 00 class 0x088000
[ 0.626628] pci 0000:ff:10.4: [8086:3cb4] type 00 class 0x088000
[ 0.626696] pci 0000:ff:10.5: [8086:3cb5] type 00 class 0x088000
[ 0.626763] pci 0000:ff:10.6: [8086:3cb6] type 00 class 0x088000
[ 0.626830] pci 0000:ff:10.7: [8086:3cb7] type 00 class 0x088000
[ 0.626894] pci 0000:ff:11.0: [8086:3cb8] type 00 class 0x088000
[ 0.626959] pci 0000:ff:13.0: [8086:3ce4] type 00 class 0x088000
[ 0.627012] pci 0000:ff:13.1: [8086:3c43] type 00 class 0x110100
[ 0.627066] pci 0000:ff:13.4: [8086:3ce6] type 00 class 0x110100
[ 0.627118] pci 0000:ff:13.5: [8086:3c44] type 00 class 0x110100
[ 0.627170] pci 0000:ff:13.6: [8086:3c45] type 00 class 0x088000
[ 0.627326] ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 7 10 *11 12 14 15)
[ 0.628013] ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 6 7 *10 11 12 14 15)
[ 0.628699] ACPI: PCI Interrupt Link [LNKC] (IRQs 3 4 *5 6 10 11 12 14 15)
[ 0.629337] ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 10 *11 12 14 15)
[ 0.629977] ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 5 6 7 10 11 12 14 15) *0
[ 0.630729] ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 6 7 10 11 12 14 15) *0
[ 0.631473] ACPI: PCI Interrupt Link [LNKG] (IRQs 3 4 5 6 7 *10 11 12 14 15)
[ 0.632158] ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 6 *7 10 11 12 14 15)
[ 0.634271] ACPI: Enabled 2 GPEs in block 00 to 3F
[ 0.634461] ACPI: \_SB_.PCI0: notify handler is installed
[ 0.634636] ACPI: \_SB_.UNC0: notify handler is installed
[ 0.634711] Found 2 acpi root devices
[ 0.634819] vgaarb: device added: PCI:0000:0a:01.0,decodes=io+mem,owns=io+mem,locks=none
[ 0.634919] vgaarb: loaded
[ 0.634984] vgaarb: bridge control possible 0000:0a:01.0
[ 0.635123] PCI: Using ACPI for IRQ routing
[ 0.641814] PCI: pci_cache_line_size set to 64 bytes
[ 0.641943] e820: reserve RAM buffer [mem 0x0009ac00-0x0009ffff]
[ 0.641946] e820: reserve RAM buffer [mem 0x7dfea000-0x7fffffff]
[ 0.642092] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0, 0, 0, 0, 0
[ 0.642586] hpet0: 8 comparators, 64-bit 14.318180 MHz counter
[ 0.644700] Switched to clocksource hpet
[ 0.646733] pnp: PnP ACPI init
[ 0.646817] ACPI: bus type PNP registered
[ 0.646980] system 00:00: [mem 0xfc000000-0xfcffffff] has been reserved
[ 0.647057] system 00:00: [mem 0xfd000000-0xfdffffff] has been reserved
[ 0.647130] system 00:00: [mem 0xfe000000-0xfeafffff] has been reserved
[ 0.647204] system 00:00: [mem 0xfeb00000-0xfebfffff] has been reserved
[ 0.647277] system 00:00: [mem 0xfed00400-0xfed3ffff] could not be reserved
[ 0.647351] system 00:00: [mem 0xfed45000-0xfedfffff] has been reserved
[ 0.647426] system 00:00: Plug and Play ACPI device, IDs PNP0c01 (active)
[ 0.647530] system 00:01: [mem 0xfbffc000-0xfbffdfff] could not be reserved
[ 0.647605] system 00:01: Plug and Play ACPI device, IDs PNP0c02 (active)
[ 0.647621] pnp 00:02: [dma 4]
[ 0.647644] pnp 00:02: Plug and Play ACPI device, IDs PNP0200 (active)
[ 0.647684] pnp 00:03: Plug and Play ACPI device, IDs PNP0b00 (active)
[ 0.647713] pnp 00:04: Plug and Play ACPI device, IDs PNP0800 (active)
[ 0.647794] system 00:05: [io 0x04d0-0x04d1] has been reserved
[ 0.647867] system 00:05: [mem 0x00000400-0x000004ff] could not be reserved
[ 0.647941] system 00:05: Plug and Play ACPI device, IDs PNP0c02 (active)
[ 0.647977] pnp 00:06: Plug and Play ACPI device, IDs PNP0c04 (active)
[ 0.648132] system 00:07: [io 0x0a00-0x0a1f] has been reserved
[ 0.648205] system 00:07: [io 0x0a30-0x0a3f] has been reserved
[ 0.648277] system 00:07: Plug and Play ACPI device, IDs PNP0c02 (active)
[ 0.648549] pnp 00:08: [dma 0 disabled]
[ 0.648611] pnp 00:08: Plug and Play ACPI device, IDs PNP0501 (active)
[ 0.648777] system 00:09: [io 0x0b00-0x0b7f] has been reserved
[ 0.648851] system 00:09: Plug and Play ACPI device, IDs PNP0c02 (active)
[ 0.649064] pnp 00:0a: [dma 0 disabled]
[ 0.649123] pnp 00:0a: Plug and Play ACPI device, IDs PNP0501 (active)
[ 0.649296] pnp 00:0b: Plug and Play ACPI device, IDs IPI0001 (active)
[ 0.649544] system 00:0c: [io 0x0400-0x0453] could not be reserved
[ 0.649618] system 00:0c: [io 0x0458-0x047f] has been reserved
[ 0.649690] system 00:0c: [io 0x1180-0x119f] has been reserved
[ 0.649762] system 00:0c: [io 0x0500-0x057f] has been reserved
[ 0.649835] system 00:0c: [mem 0xfed1c000-0xfed1ffff] has been reserved
[ 0.649909] system 00:0c: [mem 0xfec00000-0xfecfffff] could not be reserved
[ 0.649983] system 00:0c: [mem 0xfed08000-0xfed08fff] has been reserved
[ 0.650056] system 00:0c: [mem 0xff000000-0xffffffff] has been reserved
[ 0.650129] system 00:0c: Plug and Play ACPI device, IDs PNP0c01 (active)
[ 0.650217] system 00:0d: [io 0x0454-0x0457] has been reserved
[ 0.650290] system 00:0d: Plug and Play ACPI device, IDs INT3f0d PNP0c02 (active)
[ 0.650462] pnp 00:0e: Plug and Play ACPI device, IDs PNP0103 (active)
[ 0.650693] system 00:0f: [mem 0x00000000-0x0009ffff] could not be reserved
[ 0.650767] system 00:0f: Plug and Play ACPI device, IDs PNP0c01 (active)
[ 0.650986] pnp: PnP ACPI: found 16 devices
[ 0.651054] ACPI: bus type PNP unregistered
[ 0.657936] pci 0000:00:01.0: PCI bridge to [bus 01]
[ 0.658015] pci 0000:00:01.1: PCI bridge to [bus 02]
[ 0.658094] pci 0000:00:02.0: PCI bridge to [bus 03-04]
[ 0.658166] pci 0000:00:02.0: bridge window [io 0xe000-0xefff]
[ 0.658240] pci 0000:00:02.0: bridge window [mem 0xfb500000-0xfb7fffff]
[ 0.658319] pci 0000:00:02.2: PCI bridge to [bus 05-06]
[ 0.658392] pci 0000:00:02.2: bridge window [mem 0xfb100000-0xfb4fffff]
[ 0.658470] pci 0000:00:03.0: PCI bridge to [bus 07]
[ 0.658548] pci 0000:00:03.2: PCI bridge to [bus 08]
[ 0.658626] pci 0000:00:11.0: PCI bridge to [bus 09]
[ 0.658708] pci 0000:00:1e.0: PCI bridge to [bus 0a]
[ 0.658781] pci 0000:00:1e.0: bridge window [mem 0xfa800000-0xfb0fffff]
[ 0.658856] pci 0000:00:1e.0: bridge window [mem 0xf9000000-0xf9ffffff 64bit pref]
[ 0.658949] pci_bus 0000:00: resource 4 [io 0x0000-0x03af]
[ 0.658951] pci_bus 0000:00: resource 5 [io 0x03e0-0x0cf7]
[ 0.658954] pci_bus 0000:00: resource 6 [io 0x03b0-0x03df]
[ 0.658956] pci_bus 0000:00: resource 7 [io 0x0d00-0xffff]
[ 0.658958] pci_bus 0000:00: resource 8 [mem 0x000a0000-0x000bffff]
[ 0.658960] pci_bus 0000:00: resource 9 [mem 0x000c0000-0x000dffff]
[ 0.658963] pci_bus 0000:00: resource 10 [mem 0xfed0e000-0xfed0ffff]
[ 0.658965] pci_bus 0000:00: resource 11 [mem 0x80000000-0xfbffffff]
[ 0.658967] pci_bus 0000:03: resource 0 [io 0xe000-0xefff]
[ 0.658969] pci_bus 0000:03: resource 1 [mem 0xfb500000-0xfb7fffff]
[ 0.658972] pci_bus 0000:05: resource 1 [mem 0xfb100000-0xfb4fffff]
[ 0.658974] pci_bus 0000:0a: resource 1 [mem 0xfa800000-0xfb0fffff]
[ 0.658976] pci_bus 0000:0a: resource 2 [mem 0xf9000000-0xf9ffffff 64bit pref]
[ 0.658979] pci_bus 0000:0a: resource 4 [io 0x0000-0x03af]
[ 0.658981] pci_bus 0000:0a: resource 5 [io 0x03e0-0x0cf7]
[ 0.658983] pci_bus 0000:0a: resource 6 [io 0x03b0-0x03df]
[ 0.658985] pci_bus 0000:0a: resource 7 [io 0x0d00-0xffff]
[ 0.658987] pci_bus 0000:0a: resource 8 [mem 0x000a0000-0x000bffff]
[ 0.658989] pci_bus 0000:0a: resource 9 [mem 0x000c0000-0x000dffff]
[ 0.658991] pci_bus 0000:0a: resource 10 [mem 0xfed0e000-0xfed0ffff]
[ 0.658993] pci_bus 0000:0a: resource 11 [mem 0x80000000-0xfbffffff]
[ 0.659129] NET: Registered protocol family 2
[ 0.660115] TCP established hash table entries: 524288 (order: 11, 8388608 bytes)
[ 0.661610] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
[ 0.661822] TCP: Hash tables configured (established 524288 bind 65536)
[ 0.661918] TCP: reno registered
[ 0.662066] UDP hash table entries: 32768 (order: 8, 1048576 bytes)
[ 0.662408] UDP-Lite hash table entries: 32768 (order: 8, 1048576 bytes)
[ 0.662816] NET: Registered protocol family 1
[ 0.700841] pci 0000:0a:01.0: Boot video device
[ 0.700902] PCI: CLS 64 bytes, default 64
[ 0.700950] Unpacking initramfs...
[ 0.973164] Freeing initrd memory: 11632K (ffff880036938000 - ffff880037494000)
[ 0.973267] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
[ 0.973341] software IO TLB [mem 0x79fea000-0x7dfea000] (64MB) mapped at [ffff880079fea000-ffff88007dfe9fff]
[ 0.974695] audit: initializing netlink socket (disabled)
[ 0.974787] type=2000 audit(1382206912.796:1): initialized
[ 0.999115] bounce pool size: 64 pages
[ 0.999187] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[ 1.003098] VFS: Disk quotas dquot_6.5.2
[ 1.003206] Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 1.003398] msgmni has been set to 32768
[ 1.003811] alg: No test for stdrng (krng)
[ 1.003916] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[ 1.004006] io scheduler noop registered
[ 1.004074] io scheduler deadline registered
[ 1.004180] io scheduler cfq registered (default)
[ 1.005428] ioapic: probe of 0000:00:05.4 failed with error -22
[ 1.005512] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[ 1.005598] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
[ 1.011015] intel_idle: MWAIT substates: 0x21120
[ 1.011017] intel_idle: v0.4 model 0x2D
[ 1.011018] intel_idle: lapic_timer_reliable_states 0xffffffff
[ 1.011477] ERST: Error Record Serialization Table (ERST) support is initialized.
[ 1.011571] pstore: Registered erst as persistent store backend
[ 1.011788] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
[ 1.011930] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 1.032503] 00:08: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[ 1.053054] 00:0a: ttyS2 at I/O 0x3e8 (irq = 3, base_baud = 115200) is a 16550A
[ 1.053637] Linux agpgart interface v0.103
[ 1.053940] i8042: PNP: No PS/2 controller found. Probing ports directly.
[ 1.056544] serio: i8042 KBD port at 0x60,0x64 irq 1
[ 1.056620] serio: i8042 AUX port at 0x60,0x64 irq 12
[ 1.056831] mousedev: PS/2 mouse device common for all mice
[ 1.056943] rtc_cmos 00:03: RTC can wake from S4
[ 1.057149] rtc_cmos 00:03: rtc core: registered rtc_cmos as rtc0
[ 1.057251] rtc_cmos 00:03: alarms up to one month, y3k, 114 bytes nvram, hpet irqs
[ 1.057400] drop_monitor: Initializing network drop monitor service
[ 1.057563] TCP: cubic registered
[ 1.057815] NET: Registered protocol family 10
[ 1.058187] mip6: Mobile IPv6
[ 1.058255] NET: Registered protocol family 17
[ 1.058336] Key type dns_resolver registered
[ 1.058903] PM: Hibernation image not present or could not be loaded.
[ 1.058914] registered taskstats version 1
[ 1.063057] rtc_cmos 00:03: setting system clock to 2013-10-19 18:21:53 UTC (1382206913)
[ 1.064477] Freeing unused kernel memory: 872K (ffffffff81699000 - ffffffff81773000)
[ 1.064565] Write protecting the kernel read-only data: 6144k
[ 1.066220] Freeing unused kernel memory: 504K (ffff880001382000 - ffff880001400000)
[ 1.067735] Freeing unused kernel memory: 536K (ffff88000157a000 - ffff880001600000)
[ 1.079405] udevd[106]: starting version 175
[ 1.113716] pps_core: LinuxPPS API ver. 1 registered
[ 1.113794] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 1.114175] PTP clock support registered
[ 1.114498] dca service started, version 1.12.1
[ 1.115895] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.0.5-k
[ 1.115975] igb: Copyright (c) 2007-2013 Intel Corporation.
[ 1.116084] pcieport 0000:00:02.0: driver skip pci_set_master, fix it!
[ 1.116509] igb 0000:03:00.0: irq 65 for MSI/MSI-X
[ 1.116524] igb 0000:03:00.0: irq 66 for MSI/MSI-X
[ 1.116538] igb 0000:03:00.0: irq 67 for MSI/MSI-X
[ 1.116551] igb 0000:03:00.0: irq 68 for MSI/MSI-X
[ 1.116562] igb 0000:03:00.0: irq 69 for MSI/MSI-X
[ 1.116573] igb 0000:03:00.0: irq 70 for MSI/MSI-X
[ 1.116585] igb 0000:03:00.0: irq 71 for MSI/MSI-X
[ 1.116596] igb 0000:03:00.0: irq 72 for MSI/MSI-X
[ 1.116609] igb 0000:03:00.0: irq 73 for MSI/MSI-X
[ 1.118537] SCSI subsystem initialized
[ 1.120087] libata version 3.00 loaded.
[ 1.122387] ahci 0000:00:1f.2: version 3.0
[ 1.122533] ahci 0000:00:1f.2: irq 74 for MSI/MSI-X
[ 1.128664] microcode: CPU0 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.128824] microcode: CPU0 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.129973] microcode: CPU0 updated to revision 0x710, date = 2013-06-17
[ 1.130062] microcode: CPU1 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.130174] microcode: CPU1 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.130917] microcode: CPU1 updated to revision 0x710, date = 2013-06-17
[ 1.131002] microcode: CPU2 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.131118] microcode: CPU2 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.131846] microcode: CPU2 updated to revision 0x710, date = 2013-06-17
[ 1.131936] microcode: CPU3 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.132038] microcode: CPU3 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.132765] microcode: CPU3 updated to revision 0x710, date = 2013-06-17
[ 1.132861] microcode: CPU4 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.132977] microcode: CPU4 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.133706] microcode: CPU4 updated to revision 0x710, date = 2013-06-17
[ 1.133797] microcode: CPU5 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.133895] microcode: CPU5 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.134624] microcode: CPU5 updated to revision 0x710, date = 2013-06-17
[ 1.134705] microcode: CPU6 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.134802] microcode: CPU6 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.135522] microcode: CPU6 updated to revision 0x710, date = 2013-06-17
[ 1.135613] microcode: CPU7 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.135716] microcode: CPU7 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.136442] microcode: CPU7 updated to revision 0x710, date = 2013-06-17
[ 1.136531] microcode: CPU8 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.136631] microcode: CPU8 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.136760] ahci 0000:00:1f.2: AHCI 0001.0300 32 slots 6 ports 6 Gbps 0x3f impl SATA mode
[ 1.136856] ahci 0000:00:1f.2: flags: 64bit ncq sntf pm led clo pio slum part ems apst
[ 1.136951] ahci 0000:00:1f.2: setting latency timer to 64
[ 1.137373] microcode: CPU8 updated to revision 0x710, date = 2013-06-17
[ 1.137489] microcode: CPU9 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.137606] microcode: CPU9 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.138334] microcode: CPU9 updated to revision 0x710, date = 2013-06-17
[ 1.138425] microcode: CPU10 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.138538] microcode: CPU10 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.139268] microcode: CPU10 updated to revision 0x710, date = 2013-06-17
[ 1.139354] microcode: CPU11 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.139466] microcode: CPU11 sig=0x206d7, pf=0x1, revision=0x70d
[ 1.140196] microcode: CPU11 updated to revision 0x710, date = 2013-06-17
[ 1.140356] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
[ 1.177366] scsi0 : ahci
[ 1.177655] scsi1 : ahci
[ 1.177869] scsi2 : ahci
[ 1.178142] scsi3 : ahci
[ 1.178360] scsi4 : ahci
[ 1.178578] scsi5 : ahci
[ 1.178726] ata1: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821100 irq 74
[ 1.178817] ata2: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821180 irq 74
[ 1.178905] ata3: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821200 irq 74
[ 1.178993] ata4: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821280 irq 74
[ 1.179081] ata5: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821300 irq 74
[ 1.179170] ata6: SATA max UDMA/133 abar m2048@0xfb821000 port 0xfb821380 irq 74
[ 1.193441] igb 0000:03:00.0: added PHC on eth0
[ 1.193514] igb 0000:03:00.0: Intel(R) Gigabit Ethernet Network Connection
[ 1.193590] igb 0000:03:00.0: eth0: (PCIe:5.0Gb/s:Width x4) 00:25:90:97:dc:1e
[ 1.193735] igb 0000:03:00.0: eth0: PBA No: 104900-000
[ 1.193806] igb 0000:03:00.0: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)
[ 1.194283] igb 0000:03:00.1: irq 75 for MSI/MSI-X
[ 1.194293] igb 0000:03:00.1: irq 76 for MSI/MSI-X
[ 1.194301] igb 0000:03:00.1: irq 77 for MSI/MSI-X
[ 1.194309] igb 0000:03:00.1: irq 78 for MSI/MSI-X
[ 1.194316] igb 0000:03:00.1: irq 79 for MSI/MSI-X
[ 1.194324] igb 0000:03:00.1: irq 80 for MSI/MSI-X
[ 1.194331] igb 0000:03:00.1: irq 81 for MSI/MSI-X
[ 1.194339] igb 0000:03:00.1: irq 82 for MSI/MSI-X
[ 1.194346] igb 0000:03:00.1: irq 83 for MSI/MSI-X
[ 1.273269] igb 0000:03:00.1: added PHC on eth1
[ 1.273342] igb 0000:03:00.1: Intel(R) Gigabit Ethernet Network Connection
[ 1.273417] igb 0000:03:00.1: eth1: (PCIe:5.0Gb/s:Width x4) 00:25:90:97:dc:1f
[ 1.273562] igb 0000:03:00.1: eth1: PBA No: 104900-000
[ 1.273633] igb 0000:03:00.1: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)
[ 1.273802] pcieport 0000:00:02.2: driver skip pci_set_master, fix it!
[ 1.274177] igb 0000:05:00.0: irq 84 for MSI/MSI-X
[ 1.274187] igb 0000:05:00.0: irq 85 for MSI/MSI-X
[ 1.274195] igb 0000:05:00.0: irq 86 for MSI/MSI-X
[ 1.274204] igb 0000:05:00.0: irq 87 for MSI/MSI-X
[ 1.274211] igb 0000:05:00.0: irq 88 for MSI/MSI-X
[ 1.274219] igb 0000:05:00.0: irq 89 for MSI/MSI-X
[ 1.274226] igb 0000:05:00.0: irq 90 for MSI/MSI-X
[ 1.274234] igb 0000:05:00.0: irq 91 for MSI/MSI-X
[ 1.274241] igb 0000:05:00.0: irq 92 for MSI/MSI-X
[ 1.353398] igb 0000:05:00.0: added PHC on eth2
[ 1.353472] igb 0000:05:00.0: Intel(R) Gigabit Ethernet Network Connection
[ 1.353547] igb 0000:05:00.0: eth2: (PCIe:5.0Gb/s:Width x4) a0:36:9f:18:17:c2
[ 1.353904] igb 0000:05:00.0: eth2: PBA No: G15138-001
[ 1.353982] igb 0000:05:00.0: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)
[ 1.354453] igb 0000:05:00.1: irq 93 for MSI/MSI-X
[ 1.354463] igb 0000:05:00.1: irq 94 for MSI/MSI-X
[ 1.354471] igb 0000:05:00.1: irq 95 for MSI/MSI-X
[ 1.354479] igb 0000:05:00.1: irq 96 for MSI/MSI-X
[ 1.354486] igb 0000:05:00.1: irq 97 for MSI/MSI-X
[ 1.354494] igb 0000:05:00.1: irq 98 for MSI/MSI-X
[ 1.354501] igb 0000:05:00.1: irq 99 for MSI/MSI-X
[ 1.354509] igb 0000:05:00.1: irq 100 for MSI/MSI-X
[ 1.354517] igb 0000:05:00.1: irq 101 for MSI/MSI-X
[ 1.433311] igb 0000:05:00.1: added PHC on eth3
[ 1.433384] igb 0000:05:00.1: Intel(R) Gigabit Ethernet Network Connection
[ 1.433458] igb 0000:05:00.1: eth3: (PCIe:5.0Gb/s:Width x4) a0:36:9f:18:17:c3
[ 1.433815] igb 0000:05:00.1: eth3: PBA No: G15138-001
[ 1.433886] igb 0000:05:00.1: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)
[ 1.450598] e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
[ 1.450690] e100: Copyright(c) 1999-2006 Intel Corporation
[ 1.455050] e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI
[ 1.455129] e1000: Copyright (c) 1999-2006 Intel Corporation.
[ 1.467666] via_rhine: v1.10-LK1.5.1 2010-10-09 Written by Donald Becker
[ 1.493763] md: raid1 personality registered for level 1
[ 1.495476] 3ware Storage Controller device driver for Linux v1.26.02.003.
[ 1.496738] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[ 1.496836] ata3: SATA link down (SStatus 0 SControl 300)
[ 1.496933] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[ 1.497026] ata5: SATA link down (SStatus 0 SControl 300)
[ 1.498941] ata1.00: ATA-8: WDC WD20EADS-00S2B0, 04.05G04, max UDMA/133
[ 1.499030] ata1.00: 3907029168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[ 1.500742] ata6: SATA link down (SStatus 0 SControl 300)
[ 1.500780] ata4: SATA link down (SStatus 0 SControl 300)
[ 1.501594] ata1.00: configured for UDMA/133
[ 1.501851] scsi 0:0:0:0: Direct-Access ATA WDC WD20EADS-00S 04.0 PQ: 0 ANSI: 5
[ 1.502103] sd 0:0:0:0: [sda] 3907029168 512-byte logical blocks: (2.00 TB/1.81 TiB)
[ 1.502397] sd 0:0:0:0: [sda] Write Protect is off
[ 1.502469] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[ 1.502549] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 1.503063] ata2.00: ATA-8: WDC WD20EADS-00R6B0, 01.00A01, max UDMA/133
[ 1.503143] ata2.00: 3907029168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[ 1.505050] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 1.509072] ata2.00: configured for UDMA/133
[ 1.509306] scsi 1:0:0:0: Direct-Access ATA WDC WD20EADS-00R 01.0 PQ: 0 ANSI: 5
[ 1.509584] sd 1:0:0:0: [sdb] 3907029168 512-byte logical blocks: (2.00 TB/1.81 TiB)
[ 1.509597] sd 1:0:0:0: Attached scsi generic sg1 type 0
[ 1.510000] sd 1:0:0:0: [sdb] Write Protect is off
[ 1.510075] sd 1:0:0:0: [sdb] Mode Sense: 00 3a 00 00
[ 1.510195] sd 1:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 1.510731] sda: sda1 sda2 sda3
[ 1.516692] sd 0:0:0:0: [sda] Attached SCSI disk
[ 1.527180] sdb: sdb1 sdb2 sdb3
[ 1.528266] sd 1:0:0:0: [sdb] Attached SCSI disk
[ 1.617985] md: md1 stopped.
[ 1.618646] md: bind<sda2>
[ 1.620069] md/raid1:md1: active with 1 out of 2 mirrors
[ 1.620176] md1: detected capacity change from 0 to 17178746880
[ 1.620295] RAID1 conf printout:
[ 1.620297] --- wd:1 rd:2
[ 1.620298] disk 0, wo:0, o:1, dev:sda2
[ 1.626874] md1: unknown partition table
[ 1.835982] md: md2 stopped.
[ 1.836659] md: bind<sdb3>
[ 1.836870] md: bind<sda3>
[ 1.838743] md/raid1:md2: active with 2 out of 2 mirrors
[ 1.838839] md2: detected capacity change from 0 to 1983007113216
[ 1.838932] RAID1 conf printout:
[ 1.838935] --- wd:2 rd:2
[ 1.838938] disk 0, wo:0, o:1, dev:sda3
[ 1.838939] disk 1, wo:0, o:1, dev:sdb3
[ 1.848710] md2: unknown partition table
[ 1.972804] tsc: Refined TSC clocksource calibration: 1999.999 MHz
[ 2.042479] md: md0 stopped.
[ 2.043221] md: bind<sdb1>
[ 2.043430] md: bind<sda1>
[ 2.044925] md/raid1:md0: active with 2 out of 2 mirrors
[ 2.045020] md0: detected capacity change from 0 to 209702912
[ 2.045139] RAID1 conf printout:
[ 2.045140] --- wd:2 rd:2
[ 2.045143] disk 0, wo:0, o:1, dev:sda1
[ 2.045145] disk 1, wo:0, o:1, dev:sdb1
[ 2.046421] md0: unknown partition table
[ 2.294075] kjournald starting. Commit interval 5 seconds
[ 2.294597] EXT3-fs (md2): mounted filesystem with ordered data mode
[ 2.972995] Switched to clocksource tsc
[ 4.864390] udevd[572]: starting version 175
[ 5.144965] input: Power Button as /devices/LNXSYSTM:00/device:00/PNP0C0C:00/input/input0
[ 5.145066] ACPI: Power Button [PWRB]
[ 5.145204] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input1
[ 5.145296] ACPI: Power Button [PWRF]
[ 5.190660] wmi: Mapper loaded
[ 5.310723] ipmi message handler version 39.2
[ 5.346745] EDAC MC: Ver: 3.0.0
[ 5.349291] ACPI: Requesting acpi_cpufreq
[ 5.354218] IPMI System Interface driver.
[ 5.354322] ipmi_si: probing via ACPI
[ 5.355634] ipmi_si 00:0b: [io 0x0ca2] regsize 1 spacing 1 irq 0
[ 5.355705] ipmi_si: Adding ACPI-specified kcs state machine
[ 5.355838] ipmi_si: probing via SMBIOS
[ 5.355906] ipmi_si: SMBIOS: io 0xca2 regsize 1 spacing 1 irq 0
[ 5.355977] ipmi_si: Adding SMBIOS-specified kcs state machine duplicate interface
[ 5.356112] ipmi_si: probing via SPMI
[ 5.356180] ipmi_si: SPMI: io 0xca2 regsize 1 spacing 1 irq 0
[ 5.356250] ipmi_si: Adding SPMI-specified kcs state machine duplicate interface
[ 5.356384] ipmi_si: Trying ACPI-specified kcs state machine at i/o address 0xca2, slave address 0x0, irq 0
[ 5.489492] ipmi_si 00:0b: Found new BMC (man_id: 0x002a7c, prod_id: 0x0668, dev_id: 0x20)
[ 5.489599] ipmi_si 00:0b: IPMI kcs interface initialized
[ 5.521856] EDAC sbridge: Seeking for: dev 0e.0 PCI ID 8086:3ca0
[ 5.521938] EDAC sbridge: Seeking for: dev 0e.0 PCI ID 8086:3ca0
[ 5.522011] EDAC sbridge: Seeking for: dev 0f.0 PCI ID 8086:3ca8
[ 5.522086] EDAC sbridge: Seeking for: dev 0f.0 PCI ID 8086:3ca8
[ 5.522158] EDAC sbridge: Seeking for: dev 0f.1 PCI ID 8086:3c71
[ 5.522233] EDAC sbridge: Seeking for: dev 0f.1 PCI ID 8086:3c71
[ 5.522306] EDAC sbridge: Seeking for: dev 0f.2 PCI ID 8086:3caa
[ 5.522381] EDAC sbridge: Seeking for: dev 0f.2 PCI ID 8086:3caa
[ 5.522453] EDAC sbridge: Seeking for: dev 0f.3 PCI ID 8086:3cab
[ 5.522528] EDAC sbridge: Seeking for: dev 0f.3 PCI ID 8086:3cab
[ 5.522600] EDAC sbridge: Seeking for: dev 0f.4 PCI ID 8086:3cac
[ 5.522675] EDAC sbridge: Seeking for: dev 0f.4 PCI ID 8086:3cac
[ 5.522748] EDAC sbridge: Seeking for: dev 0f.5 PCI ID 8086:3cad
[ 5.522823] EDAC sbridge: Seeking for: dev 0f.5 PCI ID 8086:3cad
[ 5.522895] EDAC sbridge: Seeking for: dev 11.0 PCI ID 8086:3cb8
[ 5.522971] EDAC sbridge: Seeking for: dev 11.0 PCI ID 8086:3cb8
[ 5.523043] EDAC sbridge: Seeking for: dev 0c.6 PCI ID 8086:3cf4
[ 5.523117] EDAC sbridge: Seeking for: dev 0c.6 PCI ID 8086:3cf4
[ 5.523190] EDAC sbridge: Seeking for: dev 0c.7 PCI ID 8086:3cf6
[ 5.523265] EDAC sbridge: Seeking for: dev 0c.7 PCI ID 8086:3cf6
[ 5.523337] EDAC sbridge: Seeking for: dev 0d.6 PCI ID 8086:3cf5
[ 5.523412] EDAC sbridge: Seeking for: dev 0d.6 PCI ID 8086:3cf5
[ 5.523655] EDAC MC0: Giving out device to 'sbridge_edac.c' 'Sandy Bridge Socket#0': DEV 0000:ff:0e.0
[ 5.523746] EDAC sbridge: Driver loaded.
[ 5.656444] input: PC Speaker as /devices/platform/pcspkr/input/input2
[ 5.700367] ACPI Warning: 0x0000000000000428-0x000000000000042f SystemIO conflicts with Region \PMIO 1 (20130725/utaddress-251)
[ 5.700569] ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver
[ 5.700664] ACPI Warning: 0x0000000000000500-0x000000000000052f SystemIO conflicts with Region \GINV 1 (20130725/utaddress-251)
[ 5.700859] ACPI Warning: 0x0000000000000500-0x000000000000052f SystemIO conflicts with Region \GPIO 2 (20130725/utaddress-251)
[ 5.701048] ACPI Warning: 0x0000000000000500-0x000000000000052f SystemIO conflicts with Region \_SB_.PCI0.HEC2.GPO2 3 (20130725/utaddress-251)
[ 5.701239] ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver
[ 5.701357] lpc_ich: Resource conflict(s) found affecting gpio_ich
[ 5.851000] ACPI: bus type USB registered
[ 5.851099] usbcore: registered new interface driver usbfs
[ 5.851180] usbcore: registered new interface driver hub
[ 5.851348] usbcore: registered new device driver usb
[ 5.863037] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 5.868291] iTCO_vendor_support: vendor-support=0
[ 5.870399] ehci-pci: EHCI PCI platform driver
[ 5.870619] ehci-pci 0000:00:1a.0: setting latency timer to 64
[ 5.870641] ehci-pci 0000:00:1a.0: EHCI Host Controller
[ 5.870717] ehci-pci 0000:00:1a.0: new USB bus registered, assigned bus number 1
[ 5.870816] ehci-pci 0000:00:1a.0: debug port 2
[ 5.874793] ehci-pci 0000:00:1a.0: cache line size of 64 is not supported
[ 5.874827] ehci-pci 0000:00:1a.0: irq 16, io mem 0xfb823000
[ 5.884721] ehci-pci 0000:00:1a.0: USB 2.0 started, EHCI 1.00
[ 5.884839] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 5.884913] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 5.885001] usb usb1: Product: EHCI Host Controller
[ 5.885071] usb usb1: Manufacturer: Linux 3.12.0-rc5+ ehci_hcd
[ 5.885142] usb usb1: SerialNumber: 0000:00:1a.0
[ 5.885345] hub 1-0:1.0: USB hub found
[ 5.885420] hub 1-0:1.0: 2 ports detected
[ 5.885744] ehci-pci 0000:00:1d.0: setting latency timer to 64
[ 5.885761] ehci-pci 0000:00:1d.0: EHCI Host Controller
[ 5.885836] ehci-pci 0000:00:1d.0: new USB bus registered, assigned bus number 2
[ 5.885935] ehci-pci 0000:00:1d.0: debug port 2
[ 5.889887] ehci-pci 0000:00:1d.0: cache line size of 64 is not supported
[ 5.889923] ehci-pci 0000:00:1d.0: irq 23, io mem 0xfb822000
[ 5.900708] ehci-pci 0000:00:1d.0: USB 2.0 started, EHCI 1.00
[ 5.900817] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[ 5.900890] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 5.900978] usb usb2: Product: EHCI Host Controller
[ 5.901048] usb usb2: Manufacturer: Linux 3.12.0-rc5+ ehci_hcd
[ 5.901119] usb usb2: SerialNumber: 0000:00:1d.0
[ 5.901300] hub 2-0:1.0: USB hub found
[ 5.901374] hub 2-0:1.0: 2 ports detected
[ 5.926812] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.10
[ 5.926906] iTCO_wdt: Found a Patsburg TCO device (Version=2, TCOBASE=0x0460)
[ 5.927076] iTCO_wdt: initialized. heartbeat=30 sec (nowayout=0)
[ 6.059469] alg: No test for __gcm-aes-aesni (__driver-gcm-aes-aesni)
[ 6.097328] ioatdma: Intel(R) QuickData Technology Driver 4.00
[ 6.097651] ioatdma 0000:00:04.0: irq 102 for MSI/MSI-X
[ 6.097898] igb 0000:03:00.0: DCA enabled
[ 6.097992] igb 0000:03:00.1: DCA enabled
[ 6.098261] ioatdma 0000:00:04.1: irq 103 for MSI/MSI-X
[ 6.098463] igb 0000:05:00.0: DCA enabled
[ 6.098554] igb 0000:05:00.1: DCA enabled
[ 6.098870] ioatdma 0000:00:04.2: irq 104 for MSI/MSI-X
[ 6.099648] ioatdma 0000:00:04.3: irq 105 for MSI/MSI-X
[ 6.100145] ioatdma 0000:00:04.4: irq 106 for MSI/MSI-X
[ 6.100523] ioatdma 0000:00:04.5: irq 107 for MSI/MSI-X
[ 6.100873] ioatdma 0000:00:04.6: irq 108 for MSI/MSI-X
[ 6.101196] ioatdma 0000:00:04.7: irq 109 for MSI/MSI-X
[ 6.117243] Error: Driver 'pcspkr' is already registered, aborting...
[ 6.147760] i801_smbus 0000:00:1f.3: SMBus using PCI Interrupt
[ 6.196732] usb 1-1: new high-speed USB device number 2 using ehci-pci
[ 6.329119] usb 1-1: New USB device found, idVendor=8087, idProduct=0024
[ 6.329205] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 6.329680] hub 1-1:1.0: USB hub found
[ 6.329865] hub 1-1:1.0: 6 ports detected
[ 6.440832] usb 2-1: new high-speed USB device number 2 using ehci-pci
[ 6.573115] usb 2-1: New USB device found, idVendor=8087, idProduct=0024
[ 6.573195] usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 6.573708] hub 2-1:1.0: USB hub found
[ 6.574023] hub 2-1:1.0: 8 ports detected
[ 6.644898] usb 1-1.2: new full-speed USB device number 3 using ehci-pci
[ 6.738838] usb 1-1.2: New USB device found, idVendor=0557, idProduct=2221
[ 6.738915] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6.739003] usb 1-1.2: Product: Hermon USB hidmouse Device
[ 6.739074] usb 1-1.2: Manufacturer: Winbond Electronics Corp
[ 6.780045] hidraw: raw HID events driver (C) Jiri Kosina
[ 6.783057] usbcore: registered new interface driver usbhid
[ 6.783129] usbhid: USB HID core driver
[ 6.797615] input: Winbond Electronics Corp Hermon USB hidmouse Device as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input3
[ 6.797932] hid-generic 0003:0557:2221.0001: input,hidraw0: USB HID v1.00 Mouse [Winbond Electronics Corp Hermon USB hidmouse Device] on usb-0000:00:1a.0-1.2/input0
[ 6.798302] input: Winbond Electronics Corp Hermon USB hidmouse Device as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.1/input/input4
[ 6.804236] hid-generic 0003:0557:2221.0002: input,hidraw1: USB HID v1.00 Keyboard [Winbond Electronics Corp Hermon USB hidmouse Device] on usb-0000:00:1a.0-1.2/input1
[ 7.173766] Adding 16776116k swap on /dev/md1. Priority:-1 extents:1 across:16776116k
[ 7.245067] EXT3-fs (md2): using internal journal
[ 7.645797] loop: module loaded
[ 7.866279] Fusion MPT base driver 3.04.20
[ 7.866353] Copyright (c) 1999-2008 LSI Corporation
[ 7.876599] Fusion MPT SPI Host driver 3.04.20
[ 7.934363] nf_conntrack version 0.5.0 (16384 buckets, 65536 max)
[ 11.286713] kjournald starting. Commit interval 5 seconds
[ 11.297889] EXT3-fs (md0): using internal journal
[ 11.297979] EXT3-fs (md0): mounted filesystem with ordered data mode
[ 11.741785] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 11.856191] ISO 9660 Extensions: RRIP_1991A
[ 11.943248] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 11.960889] ISO 9660 Extensions: RRIP_1991A
[ 12.230732] UDF-fs: warning (device loop5): udf_load_vrs: No anchor found
[ 12.230809] UDF-fs: Rescanning with blocksize 2048
[ 12.231938] UDF-fs: INFO Mounting volume 'UDF Volume', timestamp 2012/07/26 11:16 (1078)
[ 12.232888] UDF-fs: warning (device loop6): udf_load_vrs: No anchor found
[ 12.232963] UDF-fs: Rescanning with blocksize 2048
[ 12.233264] UDF-fs: INFO Mounting volume 'UDF Volume', timestamp 2012/07/26 11:16 (1078)
[ 12.312402] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.338617] ISO 9660 Extensions: RRIP_1991A
[ 12.417054] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.435496] ISO 9660 Extensions: RRIP_1991A
[ 12.479945] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.552621] ISO 9660 Extensions: RRIP_1991A
[ 12.584928] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.600544] ISO 9660 Extensions: RRIP_1991A
[ 12.646825] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.695972] ISO 9660 Extensions: RRIP_1991A
[ 12.742522] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.817960] ISO 9660 Extensions: RRIP_1991A
[ 12.897240] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 12.906041] ISO 9660 Extensions: RRIP_1991A
[ 14.643674] bonding: Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
[ 14.653771] bonding: bond0: Setting MII monitoring interval to 100.
[ 14.657585] bonding: bond0: setting mode to balance-tlb (5).
[ 14.660936] bonding: bond0: Adding slave eth0.
[ 14.757431] bonding: bond0: enslaving eth0 as an active interface with a down link.
[ 14.770985] bonding: bond0: Adding slave eth1.
[ 14.865464] bonding: bond0: enslaving eth1 as an active interface with a down link.
[ 14.869976] bonding: bond0: Adding slave eth2.
[ 14.965313] bonding: bond0: enslaving eth2 as an active interface with a down link.
[ 14.969795] bonding: bond0: Adding slave eth3.
[ 15.065456] bonding: bond0: enslaving eth3 as an active interface with a down link.
[ 15.073178] IPv6: ADDRCONF(NETDEV_UP): bond0: link is not ready
[ 17.698053] igb: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[ 17.772814] bonding: bond0: link status definitely up for interface eth0, 1000 Mbps full duplex.
[ 17.772915] bonding: bond0: making interface eth0 the new active one.
[ 17.773076] bonding: bond0: first active interface up!
[ 17.773159] IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
[ 17.814093] igb: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[ 17.872810] bonding: bond0: link status definitely up for interface eth1, 1000 Mbps full duplex.
[ 17.902092] igb: eth2 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[ 17.972849] bonding: bond0: link status definitely up for interface eth2, 1000 Mbps full duplex.
[ 18.082067] igb: eth3 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[ 18.172815] bonding: bond0: link status definitely up for interface eth3, 1000 Mbps full duplex.
[ 19.080783] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 19.080868] CPU: 4 PID: 0 Comm: swapper/4 Not tainted 3.12.0-rc5+ #1
[ 19.080944] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 19.081022] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 19.081316] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0000
[ 19.081607] ffffffff812c54f5 00000000ffffffff ffff88107fc83c90 ffff88107f000480
[ 19.081912] Call Trace:
[ 19.081982] <IRQ> [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 19.082176] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 19.082258] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 19.082337] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 19.082418] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 19.082497] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 19.082578] [<ffffffff81339f70>] ? addrconf_join_solict+0x2e/0x33
[ 19.082656] [<ffffffff81332e22>] ? ipv6_dev_ac_inc+0x131/0x16f
[ 19.082735] [<ffffffff81336f67>] ? addrconf_join_anycast+0x38/0x3e
[ 19.082814] [<ffffffff8133a0b1>] ? __ipv6_ifa_notify+0x106/0x234
[ 19.082893] [<ffffffff8133a20d>] ? ipv6_ifa_notify+0x2e/0x37
[ 19.082971] [<ffffffff8133a660>] ? addrconf_dad_completed+0x32/0x185
[ 19.083050] [<ffffffff8133a874>] ? addrconf_dad_timer+0xc1/0x13c
[ 19.083129] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 19.083210] [<ffffffff81040613>] ? call_timer_fn+0x4b/0xf6
[ 19.083288] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 19.083367] [<ffffffff81040c04>] ? run_timer_softirq+0x189/0x1ce
[ 19.083448] [<ffffffff8107c7dd>] ? tick_sched_do_timer+0x25/0x25
[ 19.083527] [<ffffffff8103ad68>] ? __do_softirq+0xe8/0x201
[ 19.083606] [<ffffffff81075d98>] ? ktime_get+0x5f/0x6b
[ 19.083682] [<ffffffff8107afca>] ? clockevents_program_event+0x9a/0xb6
[ 19.083761] [<ffffffff8137df5c>] ? call_softirq+0x1c/0x30
[ 19.083839] [<ffffffff81003b7c>] ? do_softirq+0x2c/0x60
[ 19.083916] [<ffffffff8103af46>] ? irq_exit+0x3b/0x7f
[ 19.083994] [<ffffffff81023b19>] ? smp_apic_timer_interrupt+0x2c/0x37
[ 19.084074] [<ffffffff8137d48a>] ? apic_timer_interrupt+0x6a/0x70
[ 19.084149] <EOI> [<ffffffff8129a6b1>] ? cpuidle_enter_state+0x43/0xa6
[ 19.084330] [<ffffffff8129a6aa>] ? cpuidle_enter_state+0x3c/0xa6
[ 19.084408] [<ffffffff8129a7e6>] ? cpuidle_idle_call+0xd2/0x142
[ 19.084486] [<ffffffff81008ff9>] ? arch_cpu_idle+0x6/0x17
[ 19.084563] [<ffffffff8106f7e9>] ? cpu_startup_entry+0x10d/0x180
[ 19.084641] [<ffffffff8137780c>] ? _raw_spin_unlock_irqrestore+0x6/0x7
[ 19.084726] [<ffffffff810226dd>] ? start_secondary+0x1df/0x1e5
[ 288.351173] 8021q: 802.1Q VLAN Support v1.8
[ 288.351258] 8021q: adding VLAN 0 to HW filter on device eth0
[ 288.351382] 8021q: adding VLAN 0 to HW filter on device eth1
[ 288.351506] 8021q: adding VLAN 0 to HW filter on device eth2
[ 288.351628] 8021q: adding VLAN 0 to HW filter on device eth3
[ 288.351751] 8021q: adding VLAN 0 to HW filter on device bond0
[ 290.160653] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 290.160740] CPU: 7 PID: 0 Comm: swapper/7 Not tainted 3.12.0-rc5+ #1
[ 290.160816] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 290.160894] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 290.161186] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 290.161477] ffffffff812c5c61 ffff88103e087000 ffff88103e087000 0000000000000000
[ 290.161769] Call Trace:
[ 290.161845] <IRQ> [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 290.162038] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 290.162122] [<ffffffff812c5c61>] ? dev_mc_sync+0x58/0x6a
[ 290.162200] [<ffffffffa0429e67>] ? vlan_dev_set_rx_mode+0x13/0x23 [8021q]
[ 290.162280] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 290.162360] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 290.162441] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 290.162519] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 290.162599] [<ffffffff81339f70>] ? addrconf_join_solict+0x2e/0x33
[ 290.162678] [<ffffffff81332e22>] ? ipv6_dev_ac_inc+0x131/0x16f
[ 290.162756] [<ffffffff81336f67>] ? addrconf_join_anycast+0x38/0x3e
[ 290.162835] [<ffffffff8133a0b1>] ? __ipv6_ifa_notify+0x106/0x234
[ 290.162913] [<ffffffff8133a20d>] ? ipv6_ifa_notify+0x2e/0x37
[ 290.162991] [<ffffffff8133a660>] ? addrconf_dad_completed+0x32/0x185
[ 290.163070] [<ffffffff8133a874>] ? addrconf_dad_timer+0xc1/0x13c
[ 290.163148] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 290.163228] [<ffffffff81040613>] ? call_timer_fn+0x4b/0xf6
[ 290.163305] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 290.163384] [<ffffffff81040c04>] ? run_timer_softirq+0x189/0x1ce
[ 290.163464] [<ffffffff8107c7dd>] ? tick_sched_do_timer+0x25/0x25
[ 290.163543] [<ffffffff8103ad68>] ? __do_softirq+0xe8/0x201
[ 290.163621] [<ffffffff81075d98>] ? ktime_get+0x5f/0x6b
[ 290.163697] [<ffffffff8107afca>] ? clockevents_program_event+0x9a/0xb6
[ 290.163776] [<ffffffff8137df5c>] ? call_softirq+0x1c/0x30
[ 290.163854] [<ffffffff81003b7c>] ? do_softirq+0x2c/0x60
[ 290.163931] [<ffffffff8103af46>] ? irq_exit+0x3b/0x7f
[ 290.164009] [<ffffffff81023b19>] ? smp_apic_timer_interrupt+0x2c/0x37
[ 290.164089] [<ffffffff8137d48a>] ? apic_timer_interrupt+0x6a/0x70
[ 290.164164] <EOI> [<ffffffff8129a6b1>] ? cpuidle_enter_state+0x43/0xa6
[ 290.164345] [<ffffffff8129a6aa>] ? cpuidle_enter_state+0x3c/0xa6
[ 290.164422] [<ffffffff8129a7e6>] ? cpuidle_idle_call+0xd2/0x142
[ 290.164500] [<ffffffff81008ff9>] ? arch_cpu_idle+0x6/0x17
[ 290.170083] [<ffffffff8106f7e9>] ? cpu_startup_entry+0x10d/0x180
[ 290.170161] [<ffffffff8137780c>] ? _raw_spin_unlock_irqrestore+0x6/0x7
[ 290.170240] [<ffffffff810226dd>] ? start_secondary+0x1df/0x1e5
[ 290.170377] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 290.170455] CPU: 7 PID: 0 Comm: swapper/7 Not tainted 3.12.0-rc5+ #1
[ 290.170531] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 290.170607] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 290.170897] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 290.171186] ffffffff812c5cca 0000000000000000 ffff88103e087000 0000000000000000
[ 290.171484] Call Trace:
[ 290.171554] <IRQ> [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 290.171734] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 290.171818] [<ffffffff812c5cca>] ? dev_uc_sync+0x57/0x6a
[ 290.171896] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 290.171974] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 290.172052] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 290.172132] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 290.172210] [<ffffffff81339f70>] ? addrconf_join_solict+0x2e/0x33
[ 290.172288] [<ffffffff81332e22>] ? ipv6_dev_ac_inc+0x131/0x16f
[ 290.172366] [<ffffffff81336f67>] ? addrconf_join_anycast+0x38/0x3e
[ 290.172446] [<ffffffff8133a0b1>] ? __ipv6_ifa_notify+0x106/0x234
[ 290.172524] [<ffffffff8133a20d>] ? ipv6_ifa_notify+0x2e/0x37
[ 290.172604] [<ffffffff8133a660>] ? addrconf_dad_completed+0x32/0x185
[ 290.172683] [<ffffffff8133a874>] ? addrconf_dad_timer+0xc1/0x13c
[ 290.172762] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 290.172840] [<ffffffff81040613>] ? call_timer_fn+0x4b/0xf6
[ 290.172918] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
[ 290.172997] [<ffffffff81040c04>] ? run_timer_softirq+0x189/0x1ce
[ 290.173074] [<ffffffff8107c7dd>] ? tick_sched_do_timer+0x25/0x25
[ 290.173153] [<ffffffff8103ad68>] ? __do_softirq+0xe8/0x201
[ 290.173229] [<ffffffff81075d98>] ? ktime_get+0x5f/0x6b
[ 290.173305] [<ffffffff8107afca>] ? clockevents_program_event+0x9a/0xb6
[ 290.173383] [<ffffffff8137df5c>] ? call_softirq+0x1c/0x30
[ 290.173459] [<ffffffff81003b7c>] ? do_softirq+0x2c/0x60
[ 290.173536] [<ffffffff8103af46>] ? irq_exit+0x3b/0x7f
[ 290.173612] [<ffffffff81023b19>] ? smp_apic_timer_interrupt+0x2c/0x37
[ 290.173690] [<ffffffff8137d48a>] ? apic_timer_interrupt+0x6a/0x70
[ 290.173765] <EOI> [<ffffffff8129a6b1>] ? cpuidle_enter_state+0x43/0xa6
[ 290.173944] [<ffffffff8129a6aa>] ? cpuidle_enter_state+0x3c/0xa6
[ 290.174021] [<ffffffff8129a7e6>] ? cpuidle_idle_call+0xd2/0x142
[ 290.174098] [<ffffffff81008ff9>] ? arch_cpu_idle+0x6/0x17
[ 290.174175] [<ffffffff8106f7e9>] ? cpu_startup_entry+0x10d/0x180
[ 290.174252] [<ffffffff8137780c>] ? _raw_spin_unlock_irqrestore+0x6/0x7
[ 290.174331] [<ffffffff810226dd>] ? start_secondary+0x1df/0x1e5
[ 298.920399] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 298.920499] CPU: 7 PID: 4596 Comm: rpcbind Not tainted 3.12.0-rc5+ #1
[ 298.920587] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 298.920676] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 298.920949] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0000
[ 298.921220] ffffffff812c54f5 00000000000000d0 ffff88103ca31c48 ffff88107f000480
[ 298.921492] Call Trace:
[ 298.921564] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 298.921639] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 298.921715] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 298.921789] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 298.921864] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 298.921937] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 298.922010] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 298.922084] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 298.922159] [<ffffffff8110dd62>] ? full_name_hash+0x13/0x50
[ 298.922232] [<ffffffff812bd5f9>] ? dev_name_hash.isra.57+0x20/0x35
[ 298.922305] [<ffffffff812bd6fb>] ? dev_get_by_name_rcu+0x31/0x52
[ 298.922378] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.922453] [<ffffffff81124f93>] ? __inode_wait_for_writeback+0x67/0xae
[ 298.922527] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.922602] [<ffffffff81117164>] ? dentry_kill+0x13d/0x149
[ 298.922674] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 298.922752] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 298.922828] [<ffffffff81059540>] ? should_resched+0x5/0x23
[ 298.922900] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 298.922973] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 298.923117] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 298.923191] CPU: 7 PID: 4596 Comm: rpcbind Not tainted 3.12.0-rc5+ #1
[ 298.923263] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 298.923336] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 298.923623] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 298.923924] ffffffff812c5c61 ffff88103e087000 ffff88103e087000 0000000000000000
[ 298.924225] Call Trace:
[ 298.924300] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 298.924380] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 298.924460] [<ffffffff812c5c61>] ? dev_mc_sync+0x58/0x6a
[ 298.924539] [<ffffffffa0429e67>] ? vlan_dev_set_rx_mode+0x13/0x23 [8021q]
[ 298.924628] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 298.924716] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 298.924806] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 298.924885] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 298.924962] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 298.925045] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 298.925131] [<ffffffff8110dd62>] ? full_name_hash+0x13/0x50
[ 298.925214] [<ffffffff812bd5f9>] ? dev_name_hash.isra.57+0x20/0x35
[ 298.925296] [<ffffffff812bd6fb>] ? dev_get_by_name_rcu+0x31/0x52
[ 298.925375] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.925455] [<ffffffff81124f93>] ? __inode_wait_for_writeback+0x67/0xae
[ 298.925534] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.925613] [<ffffffff81117164>] ? dentry_kill+0x13d/0x149
[ 298.925691] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 298.925771] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 298.925849] [<ffffffff81059540>] ? should_resched+0x5/0x23
[ 298.925927] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 298.926005] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 298.926143] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 298.926222] CPU: 7 PID: 4596 Comm: rpcbind Not tainted 3.12.0-rc5+ #1
[ 298.926298] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 298.926374] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 298.926678] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 298.926967] ffffffff812c5cca 0000000000000000 ffff88103e087000 0000000000000000
[ 298.927256] Call Trace:
[ 298.927330] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 298.927409] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 298.927489] [<ffffffff812c5cca>] ? dev_uc_sync+0x57/0x6a
[ 298.927566] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 298.927643] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 298.927726] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 298.927812] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 298.927893] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 298.927972] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 298.928050] [<ffffffff8110dd62>] ? full_name_hash+0x13/0x50
[ 298.928127] [<ffffffff812bd5f9>] ? dev_name_hash.isra.57+0x20/0x35
[ 298.928205] [<ffffffff812bd6fb>] ? dev_get_by_name_rcu+0x31/0x52
[ 298.928283] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.928362] [<ffffffff81124f93>] ? __inode_wait_for_writeback+0x67/0xae
[ 298.928441] [<ffffffff810fac27>] ? __cache_free.isra.46+0x178/0x187
[ 298.928521] [<ffffffff81117164>] ? dentry_kill+0x13d/0x149
[ 298.928608] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 298.928699] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 298.928790] [<ffffffff81059540>] ? should_resched+0x5/0x23
[ 298.928867] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 298.928945] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 299.185287] RPC: Registered named UNIX socket transport module.
[ 299.185374] RPC: Registered udp transport module.
[ 299.185443] RPC: Registered tcp transport module.
[ 299.185511] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 299.235908] FS-Cache: Loaded
[ 299.264498] FS-Cache: Netfs 'nfs' registered for caching
[ 299.298592] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[ 304.218323] Netfilter messages via NETLINK v0.30.
[ 313.028841] tun: Universal TUN/TAP device driver, 1.6
[ 313.028931] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 313.409097] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 314.231257] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 314.231336] CPU: 0 PID: 6146 Comm: avahi-daemon Not tainted 3.12.0-rc5+ #1
[ 314.231410] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 314.231484] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 314.231758] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 314.232035] ffffffff812c5c61 ffff88103e087000 ffff88103e087000 0000000000000000
[ 314.232317] Call Trace:
[ 314.232397] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 314.232475] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 314.232552] [<ffffffff812c5c61>] ? dev_mc_sync+0x58/0x6a
[ 314.232624] [<ffffffffa0429e67>] ? vlan_dev_set_rx_mode+0x13/0x23 [8021q]
[ 314.232699] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 314.232779] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 314.232856] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 314.232929] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 314.233001] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 314.233076] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 314.233151] [<ffffffff812aeac3>] ? sock_sendmsg+0x49/0x64
[ 314.233225] [<ffffffff8111b33d>] ? fget_light+0x2e/0x7c
[ 314.233297] [<ffffffff812acbdc>] ? sockfd_lookup_light+0x17/0x4b
[ 314.233369] [<ffffffff812af517>] ? SYSC_sendto+0xec/0x101
[ 314.233441] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 314.233517] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 314.233591] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 314.233665] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 314.233794] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 314.233868] CPU: 0 PID: 6146 Comm: avahi-daemon Not tainted 3.12.0-rc5+ #1
[ 314.233940] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 314.234013] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 314.234285] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0204
[ 314.234558] ffffffff812c5cca 0000000000000000 ffff88103e087000 0000000000000000
[ 314.234831] Call Trace:
[ 314.234897] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 314.234970] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 314.235044] [<ffffffff812c5cca>] ? dev_uc_sync+0x57/0x6a
[ 314.235123] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 314.235194] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 314.235274] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 314.235347] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 314.235420] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 314.235493] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 314.235566] [<ffffffff812aeac3>] ? sock_sendmsg+0x49/0x64
[ 314.235639] [<ffffffff8111b33d>] ? fget_light+0x2e/0x7c
[ 314.235710] [<ffffffff812acbdc>] ? sockfd_lookup_light+0x17/0x4b
[ 314.235782] [<ffffffff812af517>] ? SYSC_sendto+0xec/0x101
[ 314.235854] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 314.235928] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 314.236002] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 314.236075] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 314.236393] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
[ 314.236467] CPU: 0 PID: 6146 Comm: avahi-daemon Not tainted 3.12.0-rc5+ #1
[ 314.236540] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
[ 314.236613] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
[ 314.236889] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0000
[ 314.237162] ffffffff812c54f5 00000000000000d0 ffff88102f5c5c48 ffff88107f000480
[ 314.237434] Call Trace:
[ 314.237501] [<ffffffff81373aba>] ? dump_stack+0x41/0x51
[ 314.237575] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
[ 314.237649] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
[ 314.237720] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
[ 314.237794] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
[ 314.237866] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
[ 314.237939] [<ffffffff8134e91b>] ? ipv6_sock_mc_join+0x116/0x171
[ 314.238018] [<ffffffff813442c4>] ? do_ipv6_setsockopt.isra.6+0x8e4/0xc57
[ 314.238093] [<ffffffff812aeac3>] ? sock_sendmsg+0x49/0x64
[ 314.238166] [<ffffffff810dfc2a>] ? handle_mm_fault+0x22c/0x8aa
[ 314.238239] [<ffffffff8111b33d>] ? fget_light+0x2e/0x7c
[ 314.238310] [<ffffffff812acbdc>] ? sockfd_lookup_light+0x17/0x4b
[ 314.238382] [<ffffffff812af517>] ? SYSC_sendto+0xec/0x101
[ 314.238454] [<ffffffff813446ad>] ? compat_ipv6_setsockopt+0x76/0xc4
[ 314.238528] [<ffffffff81058942>] ? mmdrop+0xd/0x1c
[ 314.238599] [<ffffffff812d7b61>] ? compat_sys_setsockopt+0x1df/0x203
[ 314.238674] [<ffffffff81075fa6>] ? getnstimeofday+0x7/0x20
[ 314.238746] [<ffffffff812d7f3b>] ? compat_sys_socketcall+0x126/0x19f
[ 314.238818] [<ffffffff8137dff5>] ? sysenter_dispatch+0x7/0x1a
[ 314.508396] NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
[ 314.528759] NFSD: starting 90-second grace period (net ffffffff81678200)
[ 320.219271] postgres (6634): /proc/6634/oom_adj is deprecated, please use /proc/6634/oom_score_adj instead.
Howto reproduce:
- Build the kernel from Torvalds tip
- Configure bonding with tlb with one NIC.
auto bond0
iface bond0 inet static
address ...
netmask ...
network ...
broadcast ...
gateway ...
bond-mode balance-tlb
bond-miimon 100
slaves eth0
# eth1 eth2 eth3
Cheers,
Thomas
^ permalink raw reply
* Re: [patch net v2 1/3] udp6: respect IPV6_DONTFRAG sockopt in case there are pending frames
From: Hannes Frederic Sowa @ 2013-10-19 20:45 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, eric.dumazet, jdmason, yoshfuji, kuznet, jmorris,
kaber, herbert
In-Reply-To: <1382178557-14737-2-git-send-email-jiri@resnulli.us>
On Sat, Oct 19, 2013 at 12:29:15PM +0200, Jiri Pirko wrote:
> if up->pending != 0 dontfrag is left with default value -1. That
> causes that application that do:
> sendto len>mtu flag MSG_MORE
> sendto len>mtu flag 0
> will receive EMSGSIZE errno as the result of the second sendto.
>
> This patch fixes it by respecting IPV6_DONTFRAG socket option.
>
> introduced by:
> commit 4b340ae20d0e2366792abe70f46629e576adaf5e "IPv6: Complete IPV6_DONTFRAG support"
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
^ permalink raw reply
* Re: [BUG] v3.12-rc5-139-gbdeeab6 assertion failed at drivers/net/bonding/bond_main.c (3398)
From: Veaceslav Falico @ 2013-10-19 20:52 UTC (permalink / raw)
To: Thomas Glanzmann
Cc: netdev, Jay Vosburgh, Andy Gospodarek, Nikolay Aleksandrov,
David S. Miller
In-Reply-To: <20131019202702.GA8354@glanzmann.de>
On Sat, Oct 19, 2013 at 10:27:02PM +0200, Thomas Glanzmann wrote:
>Hello,
>I'm referring to commit 7864a1adf7291993d74923fdd0a45459ce9da27e. I just
>checked out the tip from Linus tree compiled it and run it on Debian Wheezy
>with 4 1 GBIT NICs, two connected to one switch and two to another. I
>configured bonding to use tlb. On the ports is one untagged and one
>tagged VLAN. When I boot the kernel even if only one NIC is attached I
>get multiple failed assertions:
>
...snip...
>[ 19.080783] RTNL: assertion failed at drivers/net/bonding/bond_main.c (3398)
>[ 19.080868] CPU: 4 PID: 0 Comm: swapper/4 Not tainted 3.12.0-rc5+ #1
>[ 19.080944] Hardware name: Supermicro X9SRD-F/X9SRD-F, BIOS 1.0a 10/15/2012
>[ 19.081022] 0000000000000000 0000000000000000 ffffffff81373aba ffff88103e1a0000
>[ 19.081316] ffffffffa040aea2 ffff88103e1a0000 0000000000000000 ffff88103e1a0000
>[ 19.081607] ffffffff812c54f5 00000000ffffffff ffff88107fc83c90 ffff88107f000480
>[ 19.081912] Call Trace:
>[ 19.081982] <IRQ> [<ffffffff81373aba>] ? dump_stack+0x41/0x51
>[ 19.082176] [<ffffffffa040aea2>] ? bond_set_rx_mode+0x2d/0xa7 [bonding]
>[ 19.082258] [<ffffffff812c54f5>] ? __dev_mc_add+0x48/0x59
>[ 19.082337] [<ffffffff8134d4ee>] ? igmp6_group_added+0x65/0x17d
>[ 19.082418] [<ffffffff810fc836>] ? kmem_cache_alloc_trace+0xbb/0xcb
>[ 19.082497] [<ffffffff8134e7dd>] ? ipv6_dev_mc_inc+0x20e/0x236
>[ 19.082578] [<ffffffff81339f70>] ? addrconf_join_solict+0x2e/0x33
>[ 19.082656] [<ffffffff81332e22>] ? ipv6_dev_ac_inc+0x131/0x16f
>[ 19.082735] [<ffffffff81336f67>] ? addrconf_join_anycast+0x38/0x3e
>[ 19.082814] [<ffffffff8133a0b1>] ? __ipv6_ifa_notify+0x106/0x234
>[ 19.082893] [<ffffffff8133a20d>] ? ipv6_ifa_notify+0x2e/0x37
>[ 19.082971] [<ffffffff8133a660>] ? addrconf_dad_completed+0x32/0x185
>[ 19.083050] [<ffffffff8133a874>] ? addrconf_dad_timer+0xc1/0x13c
>[ 19.083129] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
>[ 19.083210] [<ffffffff81040613>] ? call_timer_fn+0x4b/0xf6
>[ 19.083288] [<ffffffff8133a7b3>] ? addrconf_dad_completed+0x185/0x185
>[ 19.083367] [<ffffffff81040c04>] ? run_timer_softirq+0x189/0x1ce
>[ 19.083448] [<ffffffff8107c7dd>] ? tick_sched_do_timer+0x25/0x25
>[ 19.083527] [<ffffffff8103ad68>] ? __do_softirq+0xe8/0x201
>[ 19.083606] [<ffffffff81075d98>] ? ktime_get+0x5f/0x6b
>[ 19.083682] [<ffffffff8107afca>] ? clockevents_program_event+0x9a/0xb6
>[ 19.083761] [<ffffffff8137df5c>] ? call_softirq+0x1c/0x30
>[ 19.083839] [<ffffffff81003b7c>] ? do_softirq+0x2c/0x60
>[ 19.083916] [<ffffffff8103af46>] ? irq_exit+0x3b/0x7f
>[ 19.083994] [<ffffffff81023b19>] ? smp_apic_timer_interrupt+0x2c/0x37
>[ 19.084074] [<ffffffff8137d48a>] ? apic_timer_interrupt+0x6a/0x70
>[ 19.084149] <EOI> [<ffffffff8129a6b1>] ? cpuidle_enter_state+0x43/0xa6
>[ 19.084330] [<ffffffff8129a6aa>] ? cpuidle_enter_state+0x3c/0xa6
>[ 19.084408] [<ffffffff8129a7e6>] ? cpuidle_idle_call+0xd2/0x142
>[ 19.084486] [<ffffffff81008ff9>] ? arch_cpu_idle+0x6/0x17
>[ 19.084563] [<ffffffff8106f7e9>] ? cpu_startup_entry+0x10d/0x180
>[ 19.084641] [<ffffffff8137780c>] ? _raw_spin_unlock_irqrestore+0x6/0x7
>[ 19.084726] [<ffffffff810226dd>] ? start_secondary+0x1df/0x1e5
Fixed in commit b32418705107265dfca5edfe2b547643e53a732e ("bonding: RCUify
bond_set_rx_mode()") net-next. It should get into mainline soon.
...snip...
>Howto reproduce:
>
> - Build the kernel from Torvalds tip
> - Configure bonding with tlb with one NIC.
>
>auto bond0
>iface bond0 inet static
> address ...
> netmask ...
> network ...
> broadcast ...
> gateway ...
> bond-mode balance-tlb
> bond-miimon 100
> slaves eth0
> # eth1 eth2 eth3
>
>Cheers,
> Thomas
^ permalink raw reply
* Re: [PATCH net-next 5/6] ipip: add GSO/TSO support
From: Dmitry Kravkov @ 2013-10-19 21:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, netdev@vger.kernel.org, Jerry Chu, Tom Herbert
In-Reply-To: <1382208178-22347-6-git-send-email-edumazet@google.com>
> diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
> index 55e6bfb..e5d4361 100644
> --- a/net/ipv4/gre_offload.c
> +++ b/net/ipv4/gre_offload.c
> @@ -39,7 +39,8 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
> SKB_GSO_UDP |
> SKB_GSO_DODGY |
> SKB_GSO_TCP_ECN |
> - SKB_GSO_GRE)))
> + SKB_GSO_GRE |
> + SKB_GSO_IPIP)))
> goto out;
Why GRE needs this bit?
^ permalink raw reply
* Re: [patch net v2 2/3] ip6_output: do skb ufo init for peeked non ufo skb as well
From: Hannes Frederic Sowa @ 2013-10-19 21:06 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, eric.dumazet, jdmason, yoshfuji, kuznet, jmorris,
kaber, herbert
In-Reply-To: <1382178557-14737-3-git-send-email-jiri@resnulli.us>
On Sat, Oct 19, 2013 at 12:29:16PM +0200, Jiri Pirko wrote:
> Now, if user application does:
> sendto len<mtu flag MSG_MORE
> sendto len>mtu flag 0
> The skb is not treated as fragmented one because it is not initialized
> that way. So move the initialization to fix this.
>
> introduced by:
> commit e89e9cf539a28df7d0eb1d0a545368e9920b34ac "[IPv4/IPv6]: UFO Scatter-gather approach"
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
^ permalink raw reply
* Re: [patch net v2 3/3] ip_output: do skb ufo init for peeked non ufo skb as well
From: Hannes Frederic Sowa @ 2013-10-19 21:10 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, eric.dumazet, jdmason, yoshfuji, kuznet, jmorris,
kaber, herbert
In-Reply-To: <1382178557-14737-4-git-send-email-jiri@resnulli.us>
On Sat, Oct 19, 2013 at 12:29:17PM +0200, Jiri Pirko wrote:
> Now, if user application does:
> sendto len<mtu flag MSG_MORE
> sendto len>mtu flag 0
> The skb is not treated as fragmented one because it is not initialized
> that way. So move the initialization to fix this.
>
> introduced by:
> commit e89e9cf539a28df7d0eb1d0a545368e9920b34ac "[IPv4/IPv6]: UFO Scatter-gather approach"
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Thanks Jiri!
^ permalink raw reply
* Re: [PATCH iproute2] ss: make socket statistic parseable
From: Eric Dumazet @ 2013-10-19 21:56 UTC (permalink / raw)
To: Hagen Paul Pfeifer; +Cc: netdev, shemminger, Eric Dumazet
In-Reply-To: <1382205252-14988-1-git-send-email-hagen@jauu.net>
On Sat, 2013-10-19 at 19:54 +0200, Hagen Paul Pfeifer wrote:
> Currently "ss -emoi" output is nearly perfect: key value(s) tuples are
> delimited by colon. Except three groups: socket options, congestion
> control algorithm and send data. Especially the first two groups prevent
> automated parsing: what if a future congestion control algorithm is
> named "faster" - is this a TCP flag or a congestion control algorithm?
> The current syntax allow no parsing.
>
> This patch harmonize the syntax for the last three remaining groups.
>
> Signed-off-by: Hagen Paul Pfeifer <hagen@jauu.net>
> ---
Seems fine to me, maybe we want to support json for better parsing
capabilities ?
^ permalink raw reply
* (unknown),
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n
Hello David,
this is another batch intended for net-next/linux-3.13.
This pull request is a bit bigger than usual, but 6 patches are very small
(three of them are about email updates)..
Patch 1 is fixing a previous merge conflict resolution that went wrong
(I realised that only now while checking other patches..).
Patches from 2 to 4 that are updating our emails in all the proper files
(Documentation/, headers and MAINTAINERS).
Patches 5, 6 and 7 are bringing a big improvement to the TranslationTable
component: it is now able to group non-mesh clients based on the VLAN they
belong to. In this way a lot a new enhancements are now possible thanks to the
fact that each batman-adv behaviour can be applied on a per VLAN basis.
And, of course, in patches from 8 to 12 you have some of the enhancements I was
talking about:
- make the batman-Gateway selection VLAN dependent
- make DAT (Distributed ARP Table) group ARP entries on a VLAN basis (this
allows DAT to work even when the admin decided to use the same IP subnet on
different VLANs)
- make the AP-Isolation behaviour switchable on each VLAN independently
- export VLAN specific attributes via sysfs. Switches like the AP-Isolation are
now exported once per VLAN (backward compatibility of the sysfs interface has
been preserved)
Patches 13 and 14 are small code cleanups.
Patch 15 is a minor improvement in the TT locking mechanism.
Patches 16 and 17 are other enhancements to the TT component. Those allow a
node to parse a "non-mesh client announcement message" and accept only those
TT entries belonging to certain VLANs.
Patch 18 exploits this parse&accept mechanism to make the Bridge Loop Avoidance
component reject only TT entries connected to the VLAN where it is operating.
Previous to this change, BLA was rejecting all the entries coming from any other
Backbone node, regardless of the VLAN (for more details about how the Bridge
Loop Avoidance works please check [1]).
Please pull or let me know of any problem.
Thanks a lot,
Antonio
[1] http://www.open-mesh.org/projects/batman-adv/wiki/Bridge-loop-avoidance-II
The following changes since commit b1eda2ac3fa6bf23b27c7c70eda6885124c79ed3:
em_ipset: use dev_net() accessor (2013-10-18 16:23:06 -0400)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem
for you to fetch changes up to cfd4f75701b6b13b1ec74e6f65ad0d1969c19247:
batman-adv: make the backbone gw check VLAN specific (2013-10-19 23:25:38 +0200)
----------------------------------------------------------------
Included changed:
- email addresses update in documentation, source files and MAINTAINERS
- make the TT component distinguish non-mesh clients based on the VLAN they
belong to
- improve all the internal components to properly work on a per-VLAN basis
(enabled by the new TT-VLAN feature)
- enhance the sysfs interface in order to provide behaviour switches on a
per-VLAN basis (enabled by the new TT-VLAN feature)
- improve TT lock mechanism
- improve unicast transmission APIs
----------------------------------------------------------------
Antonio Quartulli (15):
batman-adv: check skb preparation return value
batman-adv: update email address for Antonio Quartulli
batman-adv: add the VLAN ID attribute to the TT entry
batman-adv: use vid when computing local and global TT CRC
batman-adv: print the VID together with the TT entries
batman-adv: make the GW module correctly talk to the new VLAN-TT
batman-adv: make the Distributed ARP Table vlan aware
batman-adv: add per VLAN interface attribute framework
batman-adv: add sysfs framework for VLAN
batman-adv: make the AP isolation attribute VLAN specific
batman-adv: remove bogus comment
batman-adv: lock around TT operations to avoid sending inconsistent data
batman-adv: make the TT CRC logic VLAN specific
batman-adv: make the TT global purge routine VLAN specific
batman-adv: make the backbone gw check VLAN specific
Linus Lüssing (1):
batman-adv: refine API calls for unicast transmissions of SKBs
Marek Lindner (1):
batman-adv: update email address for Marek Lindner
Simon Wunderlich (1):
batman-adv: update email address for Simon Wunderlich
.../ABI/testing/sysfs-class-net-batman-adv | 4 +-
Documentation/ABI/testing/sysfs-class-net-mesh | 23 +-
Documentation/networking/batman-adv.txt | 4 +-
MAINTAINERS | 2 +-
net/batman-adv/bridge_loop_avoidance.c | 58 +-
net/batman-adv/bridge_loop_avoidance.h | 10 +-
net/batman-adv/distributed-arp-table.c | 160 ++-
net/batman-adv/gateway_client.c | 25 +-
net/batman-adv/hard-interface.c | 2 +
net/batman-adv/main.c | 33 +-
net/batman-adv/main.h | 15 +-
net/batman-adv/originator.c | 104 +-
net/batman-adv/originator.h | 7 +
net/batman-adv/packet.h | 32 +-
net/batman-adv/routing.c | 28 +-
net/batman-adv/send.c | 98 +-
net/batman-adv/send.h | 51 +-
net/batman-adv/soft-interface.c | 227 +++-
net/batman-adv/soft-interface.h | 4 +
net/batman-adv/sysfs.c | 178 ++-
net/batman-adv/sysfs.h | 10 +
net/batman-adv/translation-table.c | 1157 +++++++++++++++-----
net/batman-adv/translation-table.h | 23 +-
net/batman-adv/types.h | 83 +-
24 files changed, 1851 insertions(+), 487 deletions(-)
^ permalink raw reply
* [PATCH 01/18] batman-adv: check skb preparation return value
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
Fix bogus merge conflict resolution by checking the return
values of the skb preparation routines.
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
net/batman-adv/send.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 82588e4..d765d53 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -267,11 +267,14 @@ int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
switch (packet_type) {
case BATADV_UNICAST:
- batadv_send_skb_prepare_unicast(skb, orig_node);
+ if (!batadv_send_skb_prepare_unicast(skb, orig_node))
+ goto out;
break;
case BATADV_UNICAST_4ADDR:
- batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, orig_node,
- packet_subtype);
+ if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb,
+ orig_node,
+ packet_subtype))
+ goto out;
break;
default:
/* this function supports UNICAST and UNICAST_4ADDR only. It
--
1.8.4
^ permalink raw reply related
* [PATCH 02/18] batman-adv: update email address for Simon Wunderlich
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Simon Wunderlich, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Simon Wunderlich <sw@simonwunderlich.de>
My university will stop email service for alumni in january 2014, please
use my new e-mail address instead.
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
Documentation/ABI/testing/sysfs-class-net-mesh | 4 ++--
Documentation/networking/batman-adv.txt | 2 +-
MAINTAINERS | 2 +-
net/batman-adv/main.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index f00a69b..96ae0a4 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -16,7 +16,7 @@ Description:
What: /sys/class/net/<mesh_iface>/mesh/bonding
Date: June 2010
-Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Contact: Simon Wunderlich <sw@simonwunderlich.de>
Description:
Indicates whether the data traffic going through the
mesh will be sent using multiple interfaces at the
@@ -24,7 +24,7 @@ Description:
What: /sys/class/net/<mesh_iface>/mesh/bridge_loop_avoidance
Date: November 2011
-Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Contact: Simon Wunderlich <sw@simonwunderlich.de>
Description:
Indicates whether the bridge loop avoidance feature
is enabled. This feature detects and avoids loops
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index 897d1f4..89ace66 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -200,4 +200,4 @@ Mailing-list: b.a.t.m.a.n@open-mesh.org (optional subscription
You can also contact the Authors:
Marek Lindner <lindner_marek@yahoo.de>
-Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Simon Wunderlich <sw@simonwunderlich.de>
diff --git a/MAINTAINERS b/MAINTAINERS
index a46bcf81..f169259 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1653,7 +1653,7 @@ F: include/linux/backlight.h
BATMAN ADVANCED
M: Marek Lindner <mareklindner@neomailbox.ch>
-M: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+M: Simon Wunderlich <sw@simonwunderlich.de>
M: Antonio Quartulli <antonio@meshcoding.com>
L: b.a.t.m.a.n@lists.open-mesh.org
W: http://www.open-mesh.org/
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 54c13d5..c754f8e 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -21,7 +21,7 @@
#define _NET_BATMAN_ADV_MAIN_H_
#define BATADV_DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \
- "Simon Wunderlich <siwu@hrz.tu-chemnitz.de>"
+ "Simon Wunderlich <sw@simonwunderlich.de>"
#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced"
#define BATADV_DRIVER_DEVICE "batman-adv"
--
1.8.4
^ permalink raw reply related
* [PATCH 03/18] batman-adv: update email address for Antonio Quartulli
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
Documentation/ABI/testing/sysfs-class-net-mesh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index 96ae0a4..a86528c 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -8,7 +8,7 @@ Description:
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
Date: May 2011
-Contact: Antonio Quartulli <ordex@autistici.org>
+Contact: Antonio Quartulli <antonio@meshcoding.com>
Description:
Indicates whether the data traffic going from a
wireless client to another wireless client will be
--
1.8.4
^ permalink raw reply related
* [PATCH 04/18] batman-adv: update email address for Marek Lindner
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Antonio Quartulli
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
---
Documentation/ABI/testing/sysfs-class-net-batman-adv | 4 ++--
Documentation/ABI/testing/sysfs-class-net-mesh | 12 ++++++------
Documentation/networking/batman-adv.txt | 2 +-
net/batman-adv/main.h | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv
index bdc0070..7f34a95 100644
--- a/Documentation/ABI/testing/sysfs-class-net-batman-adv
+++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv
@@ -1,13 +1,13 @@
What: /sys/class/net/<iface>/batman-adv/iface_status
Date: May 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Indicates the status of <iface> as it is seen by batman.
What: /sys/class/net/<iface>/batman-adv/mesh_iface
Date: May 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
The /sys/class/net/<iface>/batman-adv/mesh_iface file
displays the batman mesh interface this <iface>
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index a86528c..dfdea2b 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -1,7 +1,7 @@
What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
Date: May 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Indicates whether the batman protocol messages of the
mesh <mesh_iface> shall be aggregated or not.
@@ -41,21 +41,21 @@ Description:
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
Date: October 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Defines the bandwidth which is propagated by this
node if gw_mode was set to 'server'.
What: /sys/class/net/<mesh_iface>/mesh/gw_mode
Date: October 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Defines the state of the gateway features. Can be
either 'off', 'client' or 'server'.
What: /sys/class/net/<mesh_iface>/mesh/gw_sel_class
Date: October 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Defines the selection criteria this node will use
to choose a gateway if gw_mode was set to 'client'.
@@ -77,14 +77,14 @@ Description:
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
Date: May 2010
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Defines the interval in milliseconds in which batman
sends its protocol messages.
What: /sys/class/net/<mesh_iface>/mesh/routing_algo
Date: Dec 2011
-Contact: Marek Lindner <lindner_marek@yahoo.de>
+Contact: Marek Lindner <mareklindner@neomailbox.ch>
Description:
Defines the routing procotol this mesh instance
uses to find the optimal paths through the mesh.
diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt
index 89ace66..89490beb 100644
--- a/Documentation/networking/batman-adv.txt
+++ b/Documentation/networking/batman-adv.txt
@@ -199,5 +199,5 @@ Mailing-list: b.a.t.m.a.n@open-mesh.org (optional subscription
You can also contact the Authors:
-Marek Lindner <lindner_marek@yahoo.de>
+Marek Lindner <mareklindner@neomailbox.ch>
Simon Wunderlich <sw@simonwunderlich.de>
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index c754f8e..ff55dcc 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -20,7 +20,7 @@
#ifndef _NET_BATMAN_ADV_MAIN_H_
#define _NET_BATMAN_ADV_MAIN_H_
-#define BATADV_DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \
+#define BATADV_DRIVER_AUTHOR "Marek Lindner <mareklindner@neomailbox.ch>, " \
"Simon Wunderlich <sw@simonwunderlich.de>"
#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced"
#define BATADV_DRIVER_DEVICE "batman-adv"
--
1.8.4
^ permalink raw reply related
* [PATCH 05/18] batman-adv: add the VLAN ID attribute to the TT entry
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
To make the translation table code VLAN-aware, each entry
must carry the VLAN ID which it belongs to. This patch adds
such attribute to the related TT structures.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/bridge_loop_avoidance.c | 37 ++---
net/batman-adv/distributed-arp-table.c | 11 +-
net/batman-adv/gateway_client.c | 3 +-
net/batman-adv/main.c | 29 +++-
net/batman-adv/main.h | 9 +-
net/batman-adv/packet.h | 14 +-
net/batman-adv/routing.c | 28 ++--
net/batman-adv/send.c | 8 +-
net/batman-adv/send.h | 16 ++-
net/batman-adv/soft-interface.c | 35 ++---
net/batman-adv/translation-table.c | 240 ++++++++++++++++++++++++++-------
net/batman-adv/translation-table.h | 19 +--
net/batman-adv/types.h | 2 +
13 files changed, 314 insertions(+), 137 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 5bb58d7..e8a6458 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -858,27 +858,25 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
struct batadv_hard_iface *primary_if,
struct sk_buff *skb)
{
- struct ethhdr *ethhdr;
- struct vlan_ethhdr *vhdr;
- struct arphdr *arphdr;
- uint8_t *hw_src, *hw_dst;
struct batadv_bla_claim_dst *bla_dst;
+ uint8_t *hw_src, *hw_dst;
+ struct vlan_ethhdr *vhdr;
+ struct ethhdr *ethhdr;
+ struct arphdr *arphdr;
+ unsigned short vid;
__be16 proto;
int headlen;
- unsigned short vid = BATADV_NO_FLAGS;
int ret;
+ vid = batadv_get_vid(skb, 0);
ethhdr = eth_hdr(skb);
- if (ethhdr->h_proto == htons(ETH_P_8021Q)) {
+ proto = ethhdr->h_proto;
+ headlen = ETH_HLEN;
+ if (vid & BATADV_VLAN_HAS_TAG) {
vhdr = (struct vlan_ethhdr *)ethhdr;
- vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
- vid |= BATADV_VLAN_HAS_TAG;
proto = vhdr->h_vlan_encapsulated_proto;
- headlen = sizeof(*vhdr);
- } else {
- proto = ethhdr->h_proto;
- headlen = ETH_HLEN;
+ headlen += VLAN_HLEN;
}
if (proto != htons(ETH_P_ARP))
@@ -1365,10 +1363,8 @@ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig)
int batadv_bla_is_backbone_gw(struct sk_buff *skb,
struct batadv_orig_node *orig_node, int hdr_size)
{
- struct ethhdr *ethhdr;
- struct vlan_ethhdr *vhdr;
struct batadv_bla_backbone_gw *backbone_gw;
- unsigned short vid = BATADV_NO_FLAGS;
+ unsigned short vid;
if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
return 0;
@@ -1377,16 +1373,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
return 0;
- ethhdr = (struct ethhdr *)(((uint8_t *)skb->data) + hdr_size);
-
- if (ethhdr->h_proto == htons(ETH_P_8021Q)) {
- if (!pskb_may_pull(skb, hdr_size + VLAN_ETH_HLEN))
- return 0;
-
- vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
- vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
- vid |= BATADV_VLAN_HAS_TAG;
- }
+ vid = batadv_get_vid(skb, hdr_size);
/* see if this originator is a backbone gw for this VLAN */
backbone_gw = batadv_backbone_hash_find(orig_node->bat_priv,
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 99da412..1b590f0 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -905,7 +905,8 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
* additional DAT answer may trigger kernel warnings about
* a packet coming from the wrong port.
*/
- if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
+ if (batadv_is_my_client(bat_priv, dat_entry->mac_addr,
+ BATADV_NO_FLAGS)) {
ret = true;
goto out;
}
@@ -990,9 +991,11 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
*/
if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
- BATADV_P_DAT_CACHE_REPLY);
+ BATADV_P_DAT_CACHE_REPLY,
+ BATADV_NO_FLAGS);
else
- err = batadv_send_skb_unicast(bat_priv, skb_new);
+ err = batadv_send_skb_unicast(bat_priv, skb_new,
+ BATADV_NO_FLAGS);
if (!err) {
batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
@@ -1080,7 +1083,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
/* if this REPLY is directed to a client of mine, let's deliver the
* packet to the interface
*/
- ret = !batadv_is_my_client(bat_priv, hw_dst);
+ ret = !batadv_is_my_client(bat_priv, hw_dst, BATADV_NO_FLAGS);
out:
if (ret)
kfree_skb(skb);
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 053bb31..a920946 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -744,7 +744,8 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
ethhdr = (struct ethhdr *)skb->data;
orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
- ethhdr->h_dest);
+ ethhdr->h_dest,
+ BATADV_NO_FLAGS);
if (!orig_dst_node)
goto out;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 7f3a5c4..80f60d1 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -132,7 +132,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
goto err;
batadv_tt_local_add(soft_iface, soft_iface->dev_addr,
- BATADV_NULL_IFINDEX);
+ BATADV_NO_FLAGS, BATADV_NULL_IFINDEX);
ret = batadv_bla_init(bat_priv);
if (ret < 0)
@@ -1144,6 +1144,33 @@ out:
batadv_orig_node_free_ref(orig_node);
}
+/**
+ * batadv_get_vid - extract the VLAN identifier from skb if any
+ * @skb: the buffer containing the packet
+ * @header_len: length of the batman header preceding the ethernet header
+ *
+ * If the packet embedded in the skb is vlan tagged this function returns the
+ * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
+ */
+unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
+{
+ struct ethhdr *ethhdr = (struct ethhdr *)(skb->data + header_len);
+ struct vlan_ethhdr *vhdr;
+ unsigned short vid;
+
+ if (ethhdr->h_proto != htons(ETH_P_8021Q))
+ return BATADV_NO_FLAGS;
+
+ if (!pskb_may_pull(skb, header_len + VLAN_ETH_HLEN))
+ return BATADV_NO_FLAGS;
+
+ vhdr = (struct vlan_ethhdr *)(skb->data + header_len);
+ vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+ vid |= BATADV_VLAN_HAS_TAG;
+
+ return vid;
+}
+
static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
{
struct batadv_algo_ops *bat_algo_ops;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index ff55dcc..2774d7f 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -169,14 +169,6 @@ enum batadv_uev_type {
#include <linux/seq_file.h>
#include "types.h"
-/**
- * batadv_vlan_flags - flags for the four MSB of any vlan ID field
- * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
- */
-enum batadv_vlan_flags {
- BATADV_VLAN_HAS_TAG = BIT(15),
-};
-
#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
(int)(vid & VLAN_VID_MASK) : -1)
@@ -368,5 +360,6 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
uint8_t *dst, uint8_t type, uint8_t version,
void *tvlv_value, uint16_t tvlv_value_len);
+unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len);
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 65e723e..6311642 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -122,6 +122,14 @@ enum batadv_tt_client_flags {
BATADV_TT_CLIENT_TEMP = BIT(11),
};
+/**
+ * batadv_vlan_flags - flags for the four MSB of any vlan ID field
+ * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
+ */
+enum batadv_vlan_flags {
+ BATADV_VLAN_HAS_TAG = BIT(15),
+};
+
/* claim frame types for the bridge loop avoidance */
enum batadv_bla_claimframe {
BATADV_CLAIM_TYPE_CLAIM = 0x00,
@@ -399,21 +407,23 @@ struct batadv_tvlv_tt_data {
* batadv_tt_client_flags)
* @reserved: reserved field
* @addr: mac address of non-mesh client that triggered this tt change
+ * @vid: VLAN identifier
*/
struct batadv_tvlv_tt_change {
uint8_t flags;
uint8_t reserved;
uint8_t addr[ETH_ALEN];
+ __be16 vid;
};
/**
* struct batadv_tvlv_roam_adv - roaming advertisement
* @client: mac address of roaming client
- * @reserved: field reserved for future use
+ * @vid: VLAN identifier
*/
struct batadv_tvlv_roam_adv {
uint8_t client[ETH_ALEN];
- uint16_t reserved;
+ __be16 vid;
};
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 3281a50..149ef57 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -30,6 +30,8 @@
#include "network-coding.h"
#include "fragmentation.h"
+#include <linux/if_vlan.h>
+
static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
@@ -724,6 +726,7 @@ out:
* @bat_priv: the bat priv with all the soft interface information
* @unicast_packet: the unicast header to be updated
* @dst_addr: the payload destination
+ * @vid: VLAN identifier
*
* Search the translation table for dst_addr and update the unicast header with
* the new corresponding information (originator address where the destination
@@ -734,21 +737,22 @@ out:
static bool
batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
struct batadv_unicast_packet *unicast_packet,
- uint8_t *dst_addr)
+ uint8_t *dst_addr, unsigned short vid)
{
struct batadv_orig_node *orig_node = NULL;
struct batadv_hard_iface *primary_if = NULL;
bool ret = false;
uint8_t *orig_addr, orig_ttvn;
- if (batadv_is_my_client(bat_priv, dst_addr)) {
+ if (batadv_is_my_client(bat_priv, dst_addr, vid)) {
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
goto out;
orig_addr = primary_if->net_dev->dev_addr;
orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
} else {
- orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr);
+ orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr,
+ vid);
if (!orig_node)
goto out;
@@ -775,11 +779,12 @@ out:
static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
struct sk_buff *skb, int hdr_len) {
- uint8_t curr_ttvn, old_ttvn;
- struct batadv_orig_node *orig_node;
- struct ethhdr *ethhdr;
+ struct batadv_unicast_packet *unicast_packet;
struct batadv_hard_iface *primary_if;
- struct batadv_unicast_packet *unicast_packet;
+ struct batadv_orig_node *orig_node;
+ uint8_t curr_ttvn, old_ttvn;
+ struct ethhdr *ethhdr;
+ unsigned short vid;
int is_old_ttvn;
/* check if there is enough data before accessing it */
@@ -791,6 +796,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
return 0;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
+ vid = batadv_get_vid(skb, hdr_len);
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
/* check if the destination client was served by this node and it is now
@@ -798,9 +804,9 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
* message and that it knows the new destination in the mesh to re-route
* the packet to
*/
- if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest)) {
+ if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
- ethhdr->h_dest))
+ ethhdr->h_dest, vid))
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
bat_priv,
"Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
@@ -846,7 +852,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
* target host
*/
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
- ethhdr->h_dest)) {
+ ethhdr->h_dest, vid)) {
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
"Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
unicast_packet->dest, ethhdr->h_dest,
@@ -858,7 +864,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
* currently served by this node or there is no destination at all and
* it is possible to drop the packet
*/
- if (!batadv_is_my_client(bat_priv, ethhdr->h_dest))
+ if (!batadv_is_my_client(bat_priv, ethhdr->h_dest, vid))
return 0;
/* update the header in order to let the packet be delivered to this
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index d765d53..acaa7ff 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -240,12 +240,14 @@ out:
* @packet_type: the batman unicast packet type to use
* @packet_subtype: the unicast 4addr packet subtype (only relevant for unicast
* 4addr packets)
+ * @vid: the vid to be used to search the translation table
*
* Returns 1 in case of error or 0 otherwise.
*/
int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
struct sk_buff *skb, int packet_type,
- int packet_subtype)
+ int packet_subtype,
+ unsigned short vid)
{
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct batadv_unicast_packet *unicast_packet;
@@ -260,7 +262,7 @@ int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
* returns NULL in case of AP isolation
*/
orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
- ethhdr->h_dest);
+ ethhdr->h_dest, vid);
if (!orig_node)
goto out;
@@ -290,7 +292,7 @@ int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
* try to reroute it because the ttvn contained in the header is less
* than the current one
*/
- if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
+ if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
unicast_packet->ttvn = unicast_packet->ttvn - 1;
if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index ad63184..c030cb7 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -40,21 +40,23 @@ bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
int packet_subtype);
int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
struct sk_buff *skb, int packet_type,
- int packet_subtype);
-
+ int packet_subtype,
+ unsigned short vid);
/**
* batadv_send_unicast_skb - send the skb encapsulated in a unicast packet
* @bat_priv: the bat priv with all the soft interface information
* @skb: the payload to send
+ * @vid: the vid to be used to search the translation table
*
* Returns 1 in case of error or 0 otherwise.
*/
static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
- struct sk_buff *skb)
+ struct sk_buff *skb,
+ unsigned short vid)
{
return batadv_send_skb_generic_unicast(bat_priv, skb, BATADV_UNICAST,
- 0);
+ 0, vid);
}
/**
@@ -63,16 +65,18 @@ static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
* @bat_priv: the bat priv with all the soft interface information
* @skb: the payload to send
* @packet_subtype: the unicast 4addr packet subtype to use
+ * @vid: the vid to be used to search the translation table
*
* Returns 1 in case of error or 0 otherwise.
*/
static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv,
struct sk_buff *skb,
- int packet_subtype)
+ int packet_subtype,
+ unsigned short vid)
{
return batadv_send_skb_generic_unicast(bat_priv, skb,
BATADV_UNICAST_4ADDR,
- packet_subtype);
+ packet_subtype, vid);
}
#endif /* _NET_BATMAN_ADV_SEND_H_ */
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index e8a2bd6..279e91d 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -118,9 +118,10 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
/* only modify transtable if it has been initialized before */
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
- batadv_tt_local_remove(bat_priv, old_addr,
+ batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS,
"mac address changed", false);
- batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
+ batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS,
+ BATADV_NULL_IFINDEX);
}
return 0;
@@ -152,33 +153,33 @@ static void batadv_interface_set_rx_mode(struct net_device *dev)
static int batadv_interface_tx(struct sk_buff *skb,
struct net_device *soft_iface)
{
- struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+ struct ethhdr *ethhdr;
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
struct batadv_hard_iface *primary_if = NULL;
struct batadv_bcast_packet *bcast_packet;
- struct vlan_ethhdr *vhdr;
__be16 ethertype = htons(ETH_P_BATMAN);
static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
0x00, 0x00};
static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
0x00, 0x00};
+ struct vlan_ethhdr *vhdr;
unsigned int header_len = 0;
int data_len = skb->len, ret;
- unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
+ unsigned long brd_delay = 1;
bool do_bcast = false;
+ unsigned short vid;
uint32_t seqno;
- unsigned long brd_delay = 1;
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
goto dropped;
soft_iface->trans_start = jiffies;
+ vid = batadv_get_vid(skb, 0);
+ ethhdr = (struct ethhdr *)skb->data;
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q:
vhdr = (struct vlan_ethhdr *)skb->data;
- vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
- vid |= BATADV_VLAN_HAS_TAG;
if (vhdr->h_vlan_encapsulated_proto != ethertype)
break;
@@ -196,7 +197,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
/* Register the client MAC in the transtable */
if (!is_multicast_ether_addr(ethhdr->h_source))
- batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
+ batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
+ skb->skb_iif);
/* don't accept stp packets. STP does not help in meshes.
* better use the bridge loop avoidance ...
@@ -296,7 +298,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
- ret = batadv_send_skb_unicast(bat_priv, skb);
+ ret = batadv_send_skb_unicast(bat_priv, skb, vid);
if (ret != 0)
goto dropped_freed;
}
@@ -319,12 +321,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
struct sk_buff *skb, struct batadv_hard_iface *recv_if,
int hdr_size, struct batadv_orig_node *orig_node)
{
- struct batadv_priv *bat_priv = netdev_priv(soft_iface);
- struct ethhdr *ethhdr;
- struct vlan_ethhdr *vhdr;
struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
- unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
+ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
__be16 ethertype = htons(ETH_P_BATMAN);
+ struct vlan_ethhdr *vhdr;
+ struct ethhdr *ethhdr;
+ unsigned short vid;
bool is_bcast;
is_bcast = (batadv_header->packet_type == BATADV_BCAST);
@@ -336,13 +338,12 @@ void batadv_interface_rx(struct net_device *soft_iface,
skb_pull_rcsum(skb, hdr_size);
skb_reset_mac_header(skb);
+ vid = batadv_get_vid(skb, hdr_size);
ethhdr = eth_hdr(skb);
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q:
vhdr = (struct vlan_ethhdr *)skb->data;
- vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
- vid |= BATADV_VLAN_HAS_TAG;
if (vhdr->h_vlan_encapsulated_proto != ethertype)
break;
@@ -378,7 +379,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
if (orig_node)
batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
- ethhdr->h_source);
+ ethhdr->h_source, vid);
if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
goto dropped;
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index b521afb..63adb97 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -34,6 +34,7 @@ static struct lock_class_key batadv_tt_local_hash_lock_class_key;
static struct lock_class_key batadv_tt_global_hash_lock_class_key;
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
+ unsigned short vid,
struct batadv_orig_node *orig_node);
static void batadv_tt_purge(struct work_struct *work);
static void
@@ -41,7 +42,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
static void batadv_tt_global_del(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
const unsigned char *addr,
- const char *message, bool roaming);
+ unsigned short vid, const char *message,
+ bool roaming);
/* returns 1 if they are the same mac addr */
static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
@@ -52,43 +54,93 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
+/**
+ * batadv_choose_tt - return the index of the tt entry in the hash table
+ * @data: pointer to the tt_common_entry object to map
+ * @size: the size of the hash table
+ *
+ * Returns the hash index where the object represented by 'data' should be
+ * stored at.
+ */
+static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
+{
+ struct batadv_tt_common_entry *tt;
+ uint32_t hash = 0;
+
+ tt = (struct batadv_tt_common_entry *)data;
+ hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
+ hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash % size;
+}
+
+/**
+ * batadv_tt_hash_find - look for a client in the given hash table
+ * @hash: the hash table to search
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the tt_common struct belonging to the searched client if
+ * found, NULL otherwise.
+ */
static struct batadv_tt_common_entry *
-batadv_tt_hash_find(struct batadv_hashtable *hash, const void *data)
+batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
+ unsigned short vid)
{
struct hlist_head *head;
- struct batadv_tt_common_entry *tt_common_entry;
- struct batadv_tt_common_entry *tt_common_entry_tmp = NULL;
+ struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
uint32_t index;
if (!hash)
return NULL;
- index = batadv_choose_orig(data, hash->size);
+ memcpy(to_search.addr, addr, ETH_ALEN);
+ to_search.vid = vid;
+
+ index = batadv_choose_tt(&to_search, hash->size);
head = &hash->table[index];
rcu_read_lock();
- hlist_for_each_entry_rcu(tt_common_entry, head, hash_entry) {
- if (!batadv_compare_eth(tt_common_entry, data))
+ hlist_for_each_entry_rcu(tt, head, hash_entry) {
+ if (!batadv_compare_eth(tt, addr))
continue;
- if (!atomic_inc_not_zero(&tt_common_entry->refcount))
+ if (tt->vid != vid)
continue;
- tt_common_entry_tmp = tt_common_entry;
+ if (!atomic_inc_not_zero(&tt->refcount))
+ continue;
+
+ tt_tmp = tt;
break;
}
rcu_read_unlock();
- return tt_common_entry_tmp;
+ return tt_tmp;
}
+/**
+ * batadv_tt_local_hash_find - search the local table for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the corresponding tt_local_entry struct if the client is
+ * found, NULL otherwise.
+ */
static struct batadv_tt_local_entry *
-batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
+batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
+ unsigned short vid)
{
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tt_local_entry *tt_local_entry = NULL;
- tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data);
+ tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
+ vid);
if (tt_common_entry)
tt_local_entry = container_of(tt_common_entry,
struct batadv_tt_local_entry,
@@ -96,13 +148,24 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
return tt_local_entry;
}
+/**
+ * batadv_tt_global_hash_find - search the global table for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to look for
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the corresponding tt_global_entry struct if the client
+ * is found, NULL otherwise.
+ */
static struct batadv_tt_global_entry *
-batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
+batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
+ unsigned short vid)
{
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tt_global_entry *tt_global_entry = NULL;
- tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data);
+ tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
+ vid);
if (tt_common_entry)
tt_global_entry = container_of(tt_common_entry,
struct batadv_tt_global_entry,
@@ -178,6 +241,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
tt_change_node->change.flags = flags;
tt_change_node->change.reserved = 0;
memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
+ tt_change_node->change.vid = htons(common->vid);
del_op_requested = flags & BATADV_TT_CLIENT_DEL;
@@ -268,12 +332,21 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
tt_global->common.addr, message);
batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
- batadv_choose_orig, tt_global->common.addr);
+ batadv_choose_tt, &tt_global->common);
batadv_tt_global_entry_free_ref(tt_global);
}
+/**
+ * batadv_tt_local_add - add a new client to the local table or update an
+ * existing client
+ * @soft_iface: netdev struct of the mesh interface
+ * @addr: the mac address of the client to add
+ * @vid: VLAN identifier
+ * @ifindex: index of the interface where the client is connected to (useful to
+ * identify wireless clients)
+ */
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
- int ifindex)
+ unsigned short vid, int ifindex)
{
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
struct batadv_tt_local_entry *tt_local;
@@ -283,8 +356,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
int hash_added;
bool roamed_back = false;
- tt_local = batadv_tt_local_hash_find(bat_priv, addr);
- tt_global = batadv_tt_global_hash_find(bat_priv, addr);
+ tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
+ tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
if (tt_local) {
tt_local->last_seen = jiffies;
@@ -329,6 +402,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
* (consistency check)
*/
tt_local->common.flags = BATADV_TT_CLIENT_NEW;
+ tt_local->common.vid = vid;
if (batadv_is_wifi_iface(ifindex))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
atomic_set(&tt_local->common.refcount, 2);
@@ -340,7 +414,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
- batadv_choose_orig, &tt_local->common,
+ batadv_choose_tt, &tt_local->common,
&tt_local->common.hash_entry);
if (unlikely(hash_added != 0)) {
@@ -362,6 +436,7 @@ check_roaming:
rcu_read_lock();
hlist_for_each_entry_rcu(orig_entry, head, list) {
batadv_send_roam_adv(bat_priv, tt_global->common.addr,
+ tt_global->common.vid,
orig_entry->orig_node);
}
rcu_read_unlock();
@@ -550,19 +625,20 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
* batadv_tt_local_remove - logically remove an entry from the local table
* @bat_priv: the bat priv with all the soft interface information
* @addr: the MAC address of the client to remove
+ * @vid: VLAN identifier
* @message: message to append to the log on deletion
* @roaming: true if the deletion is due to a roaming event
*
* Returns the flags assigned to the local entry before being deleted
*/
uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
- const uint8_t *addr, const char *message,
- bool roaming)
+ const uint8_t *addr, unsigned short vid,
+ const char *message, bool roaming)
{
struct batadv_tt_local_entry *tt_local_entry;
uint16_t flags, curr_flags = BATADV_NO_FLAGS;
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
if (!tt_local_entry)
goto out;
@@ -798,6 +874,7 @@ out:
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: the originator announcing the client
* @tt_addr: the mac address of the non-mesh client
+ * @vid: VLAN identifier
* @flags: TT flags that have to be set for this non-mesh client
* @ttvn: the tt version number ever announcing this non-mesh client
*
@@ -813,7 +890,8 @@ out:
*/
static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *tt_addr, uint16_t flags,
+ const unsigned char *tt_addr,
+ unsigned short vid, uint16_t flags,
uint8_t ttvn)
{
struct batadv_tt_global_entry *tt_global_entry;
@@ -823,8 +901,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_tt_common_entry *common;
uint16_t local_flags;
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
/* if the node already has a local client for this entry, it has to wait
* for a roaming advertisement instead of manually messing up the global
@@ -841,6 +919,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
common = &tt_global_entry->common;
memcpy(common->addr, tt_addr, ETH_ALEN);
+ common->vid = vid;
common->flags = flags;
tt_global_entry->roam_at = 0;
@@ -858,7 +937,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
hash_added = batadv_hash_add(bat_priv->tt.global_hash,
batadv_compare_tt,
- batadv_choose_orig, common,
+ batadv_choose_tt, common,
&common->hash_entry);
if (unlikely(hash_added != 0)) {
@@ -924,7 +1003,7 @@ add_orig_entry:
out_remove:
/* remove address from local hash if present */
- local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
+ local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
"global tt received",
flags & BATADV_TT_CLIENT_ROAM);
tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
@@ -1147,17 +1226,25 @@ batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
orig_node, message);
}
-
-
+/**
+ * batadv_tt_global_del - remove a client from the global table
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: an originator serving this client
+ * @addr: the mac address of the client
+ * @vid: VLAN identifier
+ * @message: a message explaining the reason for deleting the client to print
+ * for debugging purpose
+ * @roaming: true if the deletion has been triggered by a roaming event
+ */
static void batadv_tt_global_del(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *addr,
+ const unsigned char *addr, unsigned short vid,
const char *message, bool roaming)
{
struct batadv_tt_global_entry *tt_global_entry;
struct batadv_tt_local_entry *local_entry = NULL;
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
if (!tt_global_entry)
goto out;
@@ -1186,7 +1273,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
* the global entry, since it is useless now.
*/
local_entry = batadv_tt_local_hash_find(bat_priv,
- tt_global_entry->common.addr);
+ tt_global_entry->common.addr,
+ vid);
if (local_entry) {
/* local entry exists, case 2: client roamed to us. */
batadv_tt_global_del_orig_list(tt_global_entry);
@@ -1354,9 +1442,24 @@ _batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
return ret;
}
+/**
+ * batadv_transtable_search - get the mesh destination for a given client
+ * @bat_priv: the bat priv with all the soft interface information
+ * @src: mac address of the source client
+ * @addr: mac address of the destination client
+ * @vid: VLAN identifier
+ *
+ * Returns a pointer to the originator that was selected as destination in the
+ * mesh for contacting the client 'addr', NULL otherwise.
+ * In case of multiple originators serving the same client, the function returns
+ * the best one (best in terms of metric towards the destination node).
+ *
+ * If the two clients are AP isolated the function returns NULL.
+ */
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
const uint8_t *src,
- const uint8_t *addr)
+ const uint8_t *addr,
+ unsigned short vid)
{
struct batadv_tt_local_entry *tt_local_entry = NULL;
struct batadv_tt_global_entry *tt_global_entry = NULL;
@@ -1364,13 +1467,13 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
struct batadv_tt_orig_list_entry *best_entry;
if (src && atomic_read(&bat_priv->ap_isolation)) {
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
if (!tt_local_entry ||
(tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
goto out;
}
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
if (!tt_global_entry)
goto out;
@@ -1649,6 +1752,7 @@ batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
memcpy(tt_change->addr, tt_common_entry->addr,
ETH_ALEN);
tt_change->flags = tt_common_entry->flags;
+ tt_change->vid = htons(tt_common_entry->vid);
tt_change->reserved = 0;
tt_num_entries++;
@@ -1979,11 +2083,13 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
batadv_tt_global_del(bat_priv, orig_node,
(tt_change + i)->addr,
+ ntohs((tt_change + i)->vid),
"tt removed by changes",
roams);
} else {
if (!batadv_tt_global_add(bat_priv, orig_node,
(tt_change + i)->addr,
+ ntohs((tt_change + i)->vid),
(tt_change + i)->flags, ttvn))
/* In case of problem while storing a
* global_entry, we stop the updating
@@ -2040,12 +2146,21 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
atomic_set(&orig_node->last_ttvn, ttvn);
}
-bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
+/**
+ * batadv_is_my_client - check if a client is served by the local node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac adress of the client to check
+ * @vid: VLAN identifier
+ *
+ * Returns true if the client is served by this node, false otherwise.
+ */
+bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
+ unsigned short vid)
{
struct batadv_tt_local_entry *tt_local_entry;
bool ret = false;
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
if (!tt_local_entry)
goto out;
/* Check if the client has been logically deleted (but is kept for
@@ -2194,7 +2309,20 @@ unlock:
return ret;
}
+/**
+ * batadv_send_roam_adv - send a roaming advertisement message
+ * @bat_priv: the bat priv with all the soft interface information
+ * @client: mac address of the roaming client
+ * @vid: VLAN identifier
+ * @orig_node: message destination
+ *
+ * Send a ROAMING_ADV message to the node which was previously serving this
+ * client. This is done to inform the node that from now on all traffic destined
+ * for this particular roamed client has to be forwarded to the sender of the
+ * roaming message.
+ */
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
+ unsigned short vid,
struct batadv_orig_node *orig_node)
{
struct batadv_hard_iface *primary_if;
@@ -2217,7 +2345,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
- tvlv_roam.reserved = 0;
+ tvlv_roam.vid = htons(vid);
batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
orig_node->orig, BATADV_TVLV_ROAM, 1,
@@ -2383,11 +2511,13 @@ bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
if (!atomic_read(&bat_priv->ap_isolation))
goto out;
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst,
+ BATADV_NO_FLAGS);
if (!tt_local_entry)
goto out;
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, src);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, src,
+ BATADV_NO_FLAGS);
if (!tt_global_entry)
goto out;
@@ -2482,17 +2612,23 @@ request_table:
}
}
-/* returns true whether we know that the client has moved from its old
- * originator to another one. This entry is kept is still kept for consistency
- * purposes
+/**
+ * batadv_tt_global_client_is_roaming - check if a client is marked as roaming
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the mac address of the client to check
+ * @vid: VLAN identifier
+ *
+ * Returns true if we know that the client has moved from its old originator
+ * to another one. This entry is still kept for consistency purposes and will be
+ * deleted later by a DEL or because of timeout
*/
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
- uint8_t *addr)
+ uint8_t *addr, unsigned short vid)
{
struct batadv_tt_global_entry *tt_global_entry;
bool ret = false;
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
if (!tt_global_entry)
goto out;
@@ -2505,19 +2641,20 @@ out:
/**
* batadv_tt_local_client_is_roaming - tells whether the client is roaming
* @bat_priv: the bat priv with all the soft interface information
- * @addr: the MAC address of the local client to query
+ * @addr: the mac address of the local client to query
+ * @vid: VLAN identifier
*
* Returns true if the local client is known to be roaming (it is not served by
* this node anymore) or not. If yes, the client is still present in the table
* to keep the latter consistent with the node TTVN
*/
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
- uint8_t *addr)
+ uint8_t *addr, unsigned short vid)
{
struct batadv_tt_local_entry *tt_local_entry;
bool ret = false;
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
if (!tt_local_entry)
goto out;
@@ -2529,7 +2666,8 @@ out:
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *addr)
+ const unsigned char *addr,
+ unsigned short vlan)
{
bool ret = false;
@@ -2540,7 +2678,7 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
goto out;
- if (!batadv_tt_global_add(bat_priv, orig_node, addr,
+ if (!batadv_tt_global_add(bat_priv, orig_node, addr, vlan,
BATADV_TT_CLIENT_TEMP,
atomic_read(&orig_node->last_ttvn)))
goto out;
@@ -2706,7 +2844,7 @@ static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
src, roaming_adv->client);
batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
- BATADV_TT_CLIENT_ROAM,
+ ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
atomic_read(&orig_node->last_ttvn) + 1);
out:
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 015d8b9..1d9506d 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -22,10 +22,10 @@
int batadv_tt_init(struct batadv_priv *bat_priv);
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
- int ifindex);
+ unsigned short vid, int ifindex);
uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
- const uint8_t *addr, const char *message,
- bool roaming);
+ const uint8_t *addr, unsigned short vid,
+ const char *message, bool roaming);
int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
@@ -33,18 +33,21 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
const char *message);
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
const uint8_t *src,
- const uint8_t *addr);
+ const uint8_t *addr,
+ unsigned short vid);
void batadv_tt_free(struct batadv_priv *bat_priv);
-bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr);
+bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
+ unsigned short vid);
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
uint8_t *dst);
void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
- uint8_t *addr);
+ uint8_t *addr, unsigned short vid);
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
- uint8_t *addr);
+ uint8_t *addr, unsigned short vid);
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *addr);
+ const unsigned char *addr,
+ unsigned short vid);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 5cbb0d0..99029c5 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -715,6 +715,7 @@ struct batadv_bla_claim {
/**
* struct batadv_tt_common_entry - tt local & tt global common data
* @addr: mac address of non-mesh client
+ * @vid: VLAN identifier
* @hash_entry: hlist node for batadv_priv_tt::local_hash or for
* batadv_priv_tt::global_hash
* @flags: various state handling flags (see batadv_tt_client_flags)
@@ -724,6 +725,7 @@ struct batadv_bla_claim {
*/
struct batadv_tt_common_entry {
uint8_t addr[ETH_ALEN];
+ unsigned short vid;
struct hlist_node hash_entry;
uint16_t flags;
unsigned long added_at;
--
1.8.4
^ permalink raw reply related
* [PATCH 06/18] batman-adv: use vid when computing local and global TT CRC
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
now that each TT entry is characterised by a VLAN ID, the
latter has to be taken into consideration when computing the
local/global table CRC as it would be theoretically possible
to have the same client in two different VLANs
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/translation-table.c | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 63adb97..c8fc303 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1506,6 +1506,24 @@ out:
* batadv_tt_global_crc - calculates the checksum of the local table belonging
* to the given orig_node
* @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: originator for which the CRC should be computed
+ *
+ * This function computes the checksum for the global table corresponding to a
+ * specific originator. In particular, the checksum is computed as follows: For
+ * each client connected to the originator the CRC32C of the MAC address and the
+ * VID is computed and then all the CRC32Cs of the various clients are xor'ed
+ * together.
+ *
+ * The idea behind is that CRC32C should be used as much as possible in order to
+ * produce a unique hash of the table, but since the order which is used to feed
+ * the CRC32C function affects the result and since every node in the network
+ * probably sorts the clients differently, the hash function cannot be directly
+ * computed over the entire table. Hence the CRC32C is used only on
+ * the single client entry, while all the results are then xor'ed together
+ * because the XOR operation can combine them all while trying to reduce the
+ * noise as much as possible.
+ *
+ * Returns the checksum of the global table of a given originator.
*/
static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node)
@@ -1514,7 +1532,7 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
struct batadv_tt_common_entry *tt_common;
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
- uint32_t i, crc = 0;
+ uint32_t i, crc_tmp, crc = 0;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1545,7 +1563,9 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
orig_node))
continue;
- crc ^= crc32c(0, tt_common->addr, ETH_ALEN);
+ crc_tmp = crc32c(0, &tt_common->vid,
+ sizeof(tt_common->vid));
+ crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
}
rcu_read_unlock();
}
@@ -1556,13 +1576,18 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
/**
* batadv_tt_local_crc - calculates the checksum of the local table
* @bat_priv: the bat priv with all the soft interface information
+ *
+ * For details about the computation, please refer to the documentation for
+ * batadv_tt_global_crc().
+ *
+ * Returns the checksum of the local table
*/
static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
{
struct batadv_hashtable *hash = bat_priv->tt.local_hash;
struct batadv_tt_common_entry *tt_common;
struct hlist_head *head;
- uint32_t i, crc = 0;
+ uint32_t i, crc_tmp, crc = 0;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1575,7 +1600,9 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
if (tt_common->flags & BATADV_TT_CLIENT_NEW)
continue;
- crc ^= crc32c(0, tt_common->addr, ETH_ALEN);
+ crc_tmp = crc32c(0, &tt_common->vid,
+ sizeof(tt_common->vid));
+ crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
}
rcu_read_unlock();
}
--
1.8.4
^ permalink raw reply related
* [PATCH 07/18] batman-adv: print the VID together with the TT entries
From: Antonio Quartulli @ 2013-10-19 22:21 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/main.h | 2 +
net/batman-adv/translation-table.c | 82 +++++++++++++++++++++++---------------
2 files changed, 52 insertions(+), 32 deletions(-)
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 2774d7f..d7dfafe 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -167,6 +167,8 @@ enum batadv_uev_type {
#include <net/rtnetlink.h>
#include <linux/jiffies.h>
#include <linux/seq_file.h>
+#include <linux/if_vlan.h>
+
#include "types.h"
#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index c8fc303..9bf928c 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -328,8 +328,9 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
const char *message)
{
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Deleting global tt entry %pM: %s\n",
- tt_global->common.addr, message);
+ "Deleting global tt entry %pM (vid: %d): %s\n",
+ tt_global->common.addr,
+ BATADV_PRINT_VID(tt_global->common.vid), message);
batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
batadv_choose_tt, &tt_global->common);
@@ -363,7 +364,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
tt_local->last_seen = jiffies;
if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Re-adding pending client %pM\n", addr);
+ "Re-adding pending client %pM (vid: %d)\n",
+ addr, BATADV_PRINT_VID(vid));
/* whatever the reason why the PENDING flag was set,
* this is a client which was enqueued to be removed in
* this orig_interval. Since it popped up again, the
@@ -375,8 +377,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Roaming client %pM came back to its original location\n",
- addr);
+ "Roaming client %pM (vid: %d) came back to its original location\n",
+ addr, BATADV_PRINT_VID(vid));
/* the ROAM flag is set because this client roamed away
* and the node got a roaming_advertisement message. Now
* that the client popped up again at its original
@@ -393,7 +395,8 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
goto out;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
+ "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
+ addr, BATADV_PRINT_VID(vid),
(uint8_t)atomic_read(&bat_priv->tt.vn));
memcpy(tt_local->common.addr, addr, ETH_ALEN);
@@ -562,8 +565,8 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.8x):\n",
net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn),
bat_priv->tt.local_crc);
- seq_printf(seq, " %-13s %-7s %-10s\n", "Client", "Flags",
- "Last seen");
+ seq_printf(seq, " %-13s %s %-7s %-10s\n", "Client", "VID",
+ "Flags", "Last seen");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -581,8 +584,9 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
no_purge = tt_common_entry->flags & np_flag;
- seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n",
+ seq_printf(seq, " * %pM %4i [%c%c%c%c%c] %3u.%03u\n",
tt_common_entry->addr,
+ BATADV_PRINT_VID(tt_common_entry->vid),
(tt_common_entry->flags &
BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
no_purge ? 'P' : '.',
@@ -617,8 +621,9 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Local tt entry (%pM) pending to be removed: %s\n",
- tt_local_entry->common.addr, message);
+ "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
+ tt_local_entry->common.addr,
+ BATADV_PRINT_VID(tt_local_entry->common.vid), message);
}
/**
@@ -996,8 +1001,9 @@ add_orig_entry:
batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Creating new global tt entry: %pM (via %pM)\n",
- common->addr, orig_node->orig);
+ "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
+ common->addr, BATADV_PRINT_VID(common->vid),
+ orig_node->orig);
ret = true;
out_remove:
@@ -1077,8 +1083,9 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
if (best_entry) {
last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
seq_printf(seq,
- " %c %pM (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
+ " %c %pM %4i (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
'*', tt_global_entry->common.addr,
+ BATADV_PRINT_VID(tt_global_entry->common.vid),
best_entry->ttvn, best_entry->orig_node->orig,
last_ttvn, best_entry->orig_node->tt_crc,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
@@ -1093,8 +1100,10 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
continue;
last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
- seq_printf(seq, " %c %pM (%3u) via %pM (%3u) [%c%c%c]\n",
+ seq_printf(seq,
+ " %c %pM %4d (%3u) via %pM (%3u) [%c%c%c]\n",
'+', tt_global_entry->common.addr,
+ BATADV_PRINT_VID(tt_global_entry->common.vid),
orig_entry->ttvn, orig_entry->orig_node->orig,
last_ttvn,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
@@ -1121,9 +1130,9 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq,
"Globally announced TT entries received via the mesh %s\n",
net_dev->name);
- seq_printf(seq, " %-13s %s %-15s %s (%-10s) %s\n",
- "Client", "(TTVN)", "Originator", "(Curr TTVN)", "CRC",
- "Flags");
+ seq_printf(seq, " %-13s %s %s %-15s %s (%-10s) %s\n",
+ "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)",
+ "CRC", "Flags");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1170,15 +1179,18 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
struct hlist_head *head;
struct hlist_node *safe;
struct batadv_tt_orig_list_entry *orig_entry;
+ unsigned short vid;
spin_lock_bh(&tt_global_entry->list_lock);
head = &tt_global_entry->orig_list;
hlist_for_each_entry_safe(orig_entry, safe, head, list) {
if (orig_entry->orig_node == orig_node) {
+ vid = tt_global_entry->common.vid;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Deleting %pM from global tt entry %pM: %s\n",
+ "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
orig_node->orig,
- tt_global_entry->common.addr, message);
+ tt_global_entry->common.addr,
+ BATADV_PRINT_VID(vid), message);
hlist_del_rcu(&orig_entry->list);
batadv_tt_orig_list_entry_free_ref(orig_entry);
}
@@ -1303,6 +1315,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
struct hlist_node *safe;
struct hlist_head *head;
spinlock_t *list_lock; /* protects write access to the hash lists */
+ unsigned short vid;
if (!hash)
return;
@@ -1322,9 +1335,11 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
orig_node, message);
if (hlist_empty(&tt_global->orig_list)) {
+ vid = tt_global->common.vid;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Deleting global tt entry %pM: %s\n",
- tt_global->common.addr, message);
+ "Deleting global tt entry %pM (vid: %d): %s\n",
+ tt_global->common.addr,
+ BATADV_PRINT_VID(vid), message);
hlist_del_rcu(&tt_common_entry->hash_entry);
batadv_tt_global_entry_free_ref(tt_global);
}
@@ -1382,8 +1397,10 @@ static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
continue;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Deleting global tt entry (%pM): %s\n",
- tt_global->common.addr, msg);
+ "Deleting global tt entry %pM (vid: %d): %s\n",
+ tt_global->common.addr,
+ BATADV_PRINT_VID(tt_global->common.vid),
+ msg);
hlist_del_rcu(&tt_common->hash_entry);
@@ -2366,8 +2383,8 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
goto out;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Sending ROAMING_ADV to %pM (client %pM)\n",
- orig_node->orig, client);
+ "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
+ orig_node->orig, client, BATADV_PRINT_VID(vid));
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
@@ -2480,8 +2497,9 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
continue;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Deleting local tt entry (%pM): pending\n",
- tt_common->addr);
+ "Deleting local tt entry (%pM, vid: %d): pending\n",
+ tt_common->addr,
+ BATADV_PRINT_VID(tt_common->vid));
atomic_dec(&bat_priv->tt.local_entry_num);
hlist_del_rcu(&tt_common->hash_entry);
@@ -2694,7 +2712,7 @@ out:
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
const unsigned char *addr,
- unsigned short vlan)
+ unsigned short vid)
{
bool ret = false;
@@ -2705,14 +2723,14 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
goto out;
- if (!batadv_tt_global_add(bat_priv, orig_node, addr, vlan,
+ if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
BATADV_TT_CLIENT_TEMP,
atomic_read(&orig_node->last_ttvn)))
goto out;
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "Added temporary global client (addr: %pM orig: %pM)\n",
- addr, orig_node->orig);
+ "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
+ addr, BATADV_PRINT_VID(vid), orig_node->orig);
ret = true;
out:
return ret;
--
1.8.4
^ permalink raw reply related
* [PATCH 08/18] batman-adv: make the GW module correctly talk to the new VLAN-TT
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
The gateway code is now adapted in order to correctly
interact with the Translation Table component by using the
vlan ID
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/gateway_client.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index a920946..4ed410f 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -726,7 +726,20 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
return true;
}
-/* this call might reallocate skb data */
+/**
+ * batadv_gw_out_of_range - check if the dhcp request destination is the best gw
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the outgoing packet
+ *
+ * Check if the skb is a DHCP request and if it is sent to the current best GW
+ * server. Due to topology changes it may be the case that the GW server
+ * previously selected is not the best one anymore.
+ *
+ * Returns true if the packet destination is unicast and it is not the best gw,
+ * false otherwise.
+ *
+ * This call might reallocate skb data.
+ */
bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
struct sk_buff *skb)
{
@@ -737,6 +750,9 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
bool ret, out_of_range = false;
unsigned int header_len = 0;
uint8_t curr_tq_avg;
+ unsigned short vid;
+
+ vid = batadv_get_vid(skb, 0);
ret = batadv_gw_is_dhcp_target(skb, &header_len);
if (!ret)
@@ -744,8 +760,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
ethhdr = (struct ethhdr *)skb->data;
orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
- ethhdr->h_dest,
- BATADV_NO_FLAGS);
+ ethhdr->h_dest, vid);
if (!orig_dst_node)
goto out;
--
1.8.4
^ permalink raw reply related
* [PATCH 09/18] batman-adv: make the Distributed ARP Table vlan aware
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
The same IP subnet can be used on different VLANs, therefore
DAT has to differentiate whether the IP to resolve belongs
to one or the other virtual LAN.
To accomplish this task DAT has to deal with the VLAN tag
and store it together with each ARP entry.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/distributed-arp-table.c | 153 ++++++++++++++++++++++-----------
net/batman-adv/types.h | 2 +
2 files changed, 107 insertions(+), 48 deletions(-)
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 1b590f0..47dbe9a 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -19,6 +19,7 @@
#include <linux/if_ether.h>
#include <linux/if_arp.h>
+#include <linux/if_vlan.h>
#include <net/arp.h>
#include "main.h"
@@ -205,15 +206,11 @@ static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
*/
static uint32_t batadv_hash_dat(const void *data, uint32_t size)
{
- const unsigned char *key = data;
uint32_t hash = 0;
- size_t i;
+ const struct batadv_dat_entry *dat = data;
- for (i = 0; i < 4; i++) {
- hash += key[i];
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
+ hash = batadv_hash_bytes(hash, &dat->ip, sizeof(dat->ip));
+ hash = batadv_hash_bytes(hash, &dat->vid, sizeof(dat->vid));
hash += (hash << 3);
hash ^= (hash >> 11);
@@ -227,21 +224,26 @@ static uint32_t batadv_hash_dat(const void *data, uint32_t size)
* table
* @bat_priv: the bat priv with all the soft interface information
* @ip: search key
+ * @vid: VLAN identifier
*
* Returns the dat_entry if found, NULL otherwise.
*/
static struct batadv_dat_entry *
-batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
+batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,
+ unsigned short vid)
{
struct hlist_head *head;
- struct batadv_dat_entry *dat_entry, *dat_entry_tmp = NULL;
+ struct batadv_dat_entry to_find, *dat_entry, *dat_entry_tmp = NULL;
struct batadv_hashtable *hash = bat_priv->dat.hash;
uint32_t index;
if (!hash)
return NULL;
- index = batadv_hash_dat(&ip, hash->size);
+ to_find.ip = ip;
+ to_find.vid = vid;
+
+ index = batadv_hash_dat(&to_find, hash->size);
head = &hash->table[index];
rcu_read_lock();
@@ -265,22 +267,24 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
* @bat_priv: the bat priv with all the soft interface information
* @ip: ipv4 to add/edit
* @mac_addr: mac address to assign to the given ipv4
+ * @vid: VLAN identifier
*/
static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
- uint8_t *mac_addr)
+ uint8_t *mac_addr, unsigned short vid)
{
struct batadv_dat_entry *dat_entry;
int hash_added;
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid);
/* if this entry is already known, just update it */
if (dat_entry) {
if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr))
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
dat_entry->last_update = jiffies;
batadv_dbg(BATADV_DBG_DAT, bat_priv,
- "Entry updated: %pI4 %pM\n", &dat_entry->ip,
- dat_entry->mac_addr);
+ "Entry updated: %pI4 %pM (vid: %d)\n",
+ &dat_entry->ip, dat_entry->mac_addr,
+ BATADV_PRINT_VID(vid));
goto out;
}
@@ -289,12 +293,13 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
goto out;
dat_entry->ip = ip;
+ dat_entry->vid = vid;
memcpy(dat_entry->mac_addr, mac_addr, ETH_ALEN);
dat_entry->last_update = jiffies;
atomic_set(&dat_entry->refcount, 2);
hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
- batadv_hash_dat, &dat_entry->ip,
+ batadv_hash_dat, dat_entry,
&dat_entry->hash_entry);
if (unlikely(hash_added != 0)) {
@@ -303,8 +308,8 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
goto out;
}
- batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM\n",
- &dat_entry->ip, dat_entry->mac_addr);
+ batadv_dbg(BATADV_DBG_DAT, bat_priv, "New entry added: %pI4 %pM (vid: %d)\n",
+ &dat_entry->ip, dat_entry->mac_addr, BATADV_PRINT_VID(vid));
out:
if (dat_entry)
@@ -756,8 +761,8 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
goto out;
seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
- seq_printf(seq, " %-7s %-13s %5s\n", "IPv4", "MAC",
- "last-seen");
+ seq_printf(seq, " %-7s %-9s %4s %11s\n", "IPv4",
+ "MAC", "VID", "last-seen");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -770,8 +775,9 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
last_seen_msecs = last_seen_msecs % 60000;
last_seen_secs = last_seen_msecs / 1000;
- seq_printf(seq, " * %15pI4 %14pM %6i:%02i\n",
+ seq_printf(seq, " * %15pI4 %14pM %4i %6i:%02i\n",
&dat_entry->ip, dat_entry->mac_addr,
+ BATADV_PRINT_VID(dat_entry->vid),
last_seen_mins, last_seen_secs);
}
rcu_read_unlock();
@@ -858,6 +864,31 @@ out:
}
/**
+ * batadv_dat_get_vid - extract the VLAN identifier from skb if any
+ * @skb: the buffer containing the packet to extract the VID from
+ * @hdr_size: the size of the batman-adv header encapsulating the packet
+ *
+ * If the packet embedded in the skb is vlan tagged this function returns the
+ * VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS is returned.
+ */
+static unsigned short batadv_dat_get_vid(struct sk_buff *skb, int *hdr_size)
+{
+ unsigned short vid;
+
+ vid = batadv_get_vid(skb, *hdr_size);
+
+ /* ARP parsing functions jump forward of hdr_size + ETH_HLEN.
+ * If the header contained in the packet is a VLAN one (which is longer)
+ * hdr_size is updated so that the functions will still skip the
+ * correct amount of bytes.
+ */
+ if (vid & BATADV_VLAN_HAS_TAG)
+ *hdr_size += VLAN_HLEN;
+
+ return vid;
+}
+
+/**
* batadv_dat_snoop_outgoing_arp_request - snoop the ARP request and try to
* answer using DAT
* @bat_priv: the bat priv with all the soft interface information
@@ -876,26 +907,31 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
bool ret = false;
struct batadv_dat_entry *dat_entry = NULL;
struct sk_buff *skb_new;
+ int hdr_size = 0;
+ unsigned short vid;
if (!atomic_read(&bat_priv->distributed_arp_table))
goto out;
- type = batadv_arp_get_type(bat_priv, skb, 0);
+ vid = batadv_dat_get_vid(skb, &hdr_size);
+
+ type = batadv_arp_get_type(bat_priv, skb, hdr_size);
/* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast
* message to the selected DHT candidates
*/
if (type != ARPOP_REQUEST)
goto out;
- batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REQUEST");
+ batadv_dbg_arp(bat_priv, skb, type, hdr_size,
+ "Parsing outgoing ARP REQUEST");
- ip_src = batadv_arp_ip_src(skb, 0);
- hw_src = batadv_arp_hw_src(skb, 0);
- ip_dst = batadv_arp_ip_dst(skb, 0);
+ ip_src = batadv_arp_ip_src(skb, hdr_size);
+ hw_src = batadv_arp_hw_src(skb, hdr_size);
+ ip_dst = batadv_arp_ip_dst(skb, hdr_size);
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
+ batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
if (dat_entry) {
/* If the ARP request is destined for a local client the local
* client will answer itself. DAT would only generate a
@@ -917,11 +953,15 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
if (!skb_new)
goto out;
+ if (vid & BATADV_VLAN_HAS_TAG)
+ skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
+ vid & VLAN_VID_MASK);
+
skb_reset_mac_header(skb_new);
skb_new->protocol = eth_type_trans(skb_new,
bat_priv->soft_iface);
bat_priv->stats.rx_packets++;
- bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
+ bat_priv->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size;
bat_priv->soft_iface->last_rx = jiffies;
netif_rx(skb_new);
@@ -956,11 +996,14 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
struct sk_buff *skb_new;
struct batadv_dat_entry *dat_entry = NULL;
bool ret = false;
+ unsigned short vid;
int err;
if (!atomic_read(&bat_priv->distributed_arp_table))
goto out;
+ vid = batadv_dat_get_vid(skb, &hdr_size);
+
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
if (type != ARPOP_REQUEST)
goto out;
@@ -972,9 +1015,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
batadv_dbg_arp(bat_priv, skb, type, hdr_size,
"Parsing incoming ARP REQUEST");
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
+ batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
if (!dat_entry)
goto out;
@@ -985,6 +1028,10 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
if (!skb_new)
goto out;
+ if (vid & BATADV_VLAN_HAS_TAG)
+ skb_new = vlan_insert_tag(skb_new, htons(ETH_P_8021Q),
+ vid & VLAN_VID_MASK);
+
/* To preserve backwards compatibility, the node has choose the outgoing
* format based on the incoming request packet type. The assumption is
* that a node not using the 4addr packet format doesn't support it.
@@ -992,10 +1039,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
BATADV_P_DAT_CACHE_REPLY,
- BATADV_NO_FLAGS);
+ vid);
else
- err = batadv_send_skb_unicast(bat_priv, skb_new,
- BATADV_NO_FLAGS);
+ err = batadv_send_skb_unicast(bat_priv, skb_new, vid);
if (!err) {
batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
@@ -1020,23 +1066,28 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
uint16_t type;
__be32 ip_src, ip_dst;
uint8_t *hw_src, *hw_dst;
+ int hdr_size = 0;
+ unsigned short vid;
if (!atomic_read(&bat_priv->distributed_arp_table))
return;
- type = batadv_arp_get_type(bat_priv, skb, 0);
+ vid = batadv_dat_get_vid(skb, &hdr_size);
+
+ type = batadv_arp_get_type(bat_priv, skb, hdr_size);
if (type != ARPOP_REPLY)
return;
- batadv_dbg_arp(bat_priv, skb, type, 0, "Parsing outgoing ARP REPLY");
+ batadv_dbg_arp(bat_priv, skb, type, hdr_size,
+ "Parsing outgoing ARP REPLY");
- hw_src = batadv_arp_hw_src(skb, 0);
- ip_src = batadv_arp_ip_src(skb, 0);
- hw_dst = batadv_arp_hw_dst(skb, 0);
- ip_dst = batadv_arp_ip_dst(skb, 0);
+ hw_src = batadv_arp_hw_src(skb, hdr_size);
+ ip_src = batadv_arp_ip_src(skb, hdr_size);
+ hw_dst = batadv_arp_hw_dst(skb, hdr_size);
+ ip_dst = batadv_arp_ip_dst(skb, hdr_size);
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
- batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
+ batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
+ batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
/* Send the ARP reply to the candidates for both the IP addresses that
* the node obtained from the ARP reply
@@ -1058,10 +1109,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
__be32 ip_src, ip_dst;
uint8_t *hw_src, *hw_dst;
bool ret = false;
+ unsigned short vid;
if (!atomic_read(&bat_priv->distributed_arp_table))
goto out;
+ vid = batadv_dat_get_vid(skb, &hdr_size);
+
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
if (type != ARPOP_REPLY)
goto out;
@@ -1077,13 +1131,13 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
/* Update our internal cache with both the IP addresses the node got
* within the ARP reply
*/
- batadv_dat_entry_add(bat_priv, ip_src, hw_src);
- batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
+ batadv_dat_entry_add(bat_priv, ip_src, hw_src, vid);
+ batadv_dat_entry_add(bat_priv, ip_dst, hw_dst, vid);
/* if this REPLY is directed to a client of mine, let's deliver the
* packet to the interface
*/
- ret = !batadv_is_my_client(bat_priv, hw_dst, BATADV_NO_FLAGS);
+ ret = !batadv_is_my_client(bat_priv, hw_dst, vid);
out:
if (ret)
kfree_skb(skb);
@@ -1106,7 +1160,8 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
__be32 ip_dst;
struct batadv_dat_entry *dat_entry = NULL;
bool ret = false;
- const size_t bcast_len = sizeof(struct batadv_bcast_packet);
+ int hdr_size = sizeof(struct batadv_bcast_packet);
+ unsigned short vid;
if (!atomic_read(&bat_priv->distributed_arp_table))
goto out;
@@ -1117,12 +1172,14 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
if (forw_packet->num_packets)
goto out;
- type = batadv_arp_get_type(bat_priv, forw_packet->skb, bcast_len);
+ vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size);
+
+ type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size);
if (type != ARPOP_REQUEST)
goto out;
- ip_dst = batadv_arp_ip_dst(forw_packet->skb, bcast_len);
- dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
+ ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size);
+ dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst, vid);
/* check if the node already got this entry */
if (!dat_entry) {
batadv_dbg(BATADV_DBG_DAT, bat_priv,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 99029c5..6954a5d 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -933,6 +933,7 @@ struct batadv_algo_ops {
* is used to stored ARP entries needed for the global DAT cache
* @ip: the IPv4 corresponding to this DAT/ARP entry
* @mac_addr: the MAC address associated to the stored IPv4
+ * @vid: the vlan ID associated to this entry
* @last_update: time in jiffies when this entry was refreshed last time
* @hash_entry: hlist node for batadv_priv_dat::hash
* @refcount: number of contexts the object is used
@@ -941,6 +942,7 @@ struct batadv_algo_ops {
struct batadv_dat_entry {
__be32 ip;
uint8_t mac_addr[ETH_ALEN];
+ unsigned short vid;
unsigned long last_update;
struct hlist_node hash_entry;
atomic_t refcount;
--
1.8.4
^ permalink raw reply related
* Re: [RFC net-next] ipv6: Use destination address determined by IPVS
From: Hannes Frederic Sowa @ 2013-10-19 22:36 UTC (permalink / raw)
To: Julian Anastasov, Simon Horman,
YOSHIFUJI Hideaki / 吉藤英明, lvs-devel,
netdev, Mark Brooks, Phil Oester
In-Reply-To: <20131019183433.GC31333@order.stressinduktion.org>
On Sat, Oct 19, 2013 at 08:34:33PM +0200, Hannes Frederic Sowa wrote:
> On Sat, Oct 19, 2013 at 07:37:10PM +0300, Julian Anastasov wrote:
> >
> > Hello,
> >
> > On Fri, 18 Oct 2013, Hannes Frederic Sowa wrote:
> >
> > > I played around with your patch and tested xt_TEE. I added a TEE rule to
> > > mangle/OUTPUT and pinged. This happend, I have not yet analyzed it:
> > >
> > > [ 101.126649] ------------[ cut here ]------------
> > > [ 101.128436] BUG: unable to handle kernel paging request at fffffffb8a2fda88
> > > [ 101.129421] IP: [<ffffffff810c9737>] cpuacct_charge+0x97/0x200
> > > [ 101.129421] PGD 1c0f067 PUD 0
> > > [ 101.129421] Thread overran stack, or stack corrupted
> >
> > Problem with process stack? May be some packet loop
> > happens? Because I can not reproduce such problem in my
> > virtual setup, I tested TEE too, with careful packet
> > matching and 1 CPU. Should I assume that you don't have such
> > oops when the patch is not applied, with the same TEE rule?
>
> Oh, sorry, you are right. It happens with an unpatched net-next kernel, too.
>
> I inserted the TEE rule in mangel/OUTGOING and had only one route, ip -6 r a
> default via fe80::1 dev eth0 which at the time of the panic was actually not
> reachable.
>
> > > [ 101.129421] Oops: 0000 [#1] SMP
> >
> > You don't appear to have PREEMPT in above line.
> > I'm not sure when preemption is enabled if tee_tg6() does
> > not have a problem with its anti-loop measures (tee_active).
> > Is preemption possible in OUTPUT hook, i.e. can we change
> > the CPU while playing with tee_active and as result change
> > different flag?
>
> Hm, maybe. I don't have too much insight into netfilter stack and
> what are the differences between OUTPUT and FORWARD path but plan to
> investigate. ;)
It seems tables are processed with bh disabled, so no preemption while
recursing. So I guess the use of tee_active is safe for breaking the
tie here.
The reason I exhaust stack space is that we can actually send out packets
while looking up routes (rt6_probe). The nonreachability of the default
gateway and the to-teed-to box does the rest.
We need to change the route lookup of the duplicated packet in xt_tee to not
cause ndisc probes to be generated.
The more I review the patch the more I think it is ok. But we could actually
try to just always return rt6i_gateway, as we should always be handed a cloned
rt6_info where the gateway is already filled in, no?
Greetings,
Hannes
^ permalink raw reply
* Re: [RFC net-next] ipv6: Use destination address determined by IPVS
From: Hannes Frederic Sowa @ 2013-10-19 22:39 UTC (permalink / raw)
To: Julian Anastasov, Simon Horman,
YOSHIFUJI Hideaki / 吉藤英明, lvs-devel,
netdev, Mark Brooks, Phil Oester
In-Reply-To: <20131019223657.GH31333@order.stressinduktion.org>
On Sun, Oct 20, 2013 at 12:36:57AM +0200, Hannes Frederic Sowa wrote:
> The more I review the patch the more I think it is ok. But we could actually
> try to just always return rt6i_gateway, as we should always be handed a cloned
> rt6_info where the gateway is already filled in, no?
Ergh, this seems to break loopback then.
^ permalink raw reply
* [PATCH 17/18] batman-adv: make the TT global purge routine VLAN specific
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem
Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Simon Wunderlich,
Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
Instead of unconditionally removing all the TT entries
served by a given originator, make tt_global_orig_del()
remove only entries matching a given VLAN identifier
provided as argument.
If such argument is negative all the global entries
served by the originator are removed.
This change is used into the BLA code to purge entries
served by a newly discovered Backbone node, but limiting
the operation only to those connected to the VLAN where the
backbone has been discovered.
Cc: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/bridge_loop_avoidance.c | 4 ++--
net/batman-adv/originator.c | 2 +-
net/batman-adv/routing.c | 2 +-
net/batman-adv/translation-table.c | 17 ++++++++++++++++-
net/batman-adv/translation-table.h | 2 +-
5 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index e8a6458..3b3867db 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -411,10 +411,10 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
return NULL;
}
- /* this is a gateway now, remove any tt entries */
+ /* this is a gateway now, remove any TT entry on this VLAN */
orig_node = batadv_orig_hash_find(bat_priv, orig);
if (orig_node) {
- batadv_tt_global_del_orig(bat_priv, orig_node,
+ batadv_tt_global_del_orig(bat_priv, orig_node, vid,
"became a backbone gateway");
batadv_orig_node_free_ref(orig_node);
}
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 7a499da..ee1d847 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -230,7 +230,7 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
batadv_frag_purge_orig(orig_node, NULL);
- batadv_tt_global_del_orig(orig_node->bat_priv, orig_node,
+ batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
"originator timed out");
kfree(orig_node->tt_buff);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 149ef57..4bcf221 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -47,7 +47,7 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
if ((curr_router) && (!neigh_node)) {
batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
"Deleting route towards: %pM\n", orig_node->orig);
- batadv_tt_global_del_orig(bat_priv, orig_node,
+ batadv_tt_global_del_orig(bat_priv, orig_node, -1,
"Deleted route towards originator");
/* route added */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 41a8387..4c313ff 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1581,8 +1581,18 @@ out:
batadv_tt_local_entry_free_ref(local_entry);
}
+/**
+ * batadv_tt_global_del_orig - remove all the TT global entries belonging to the
+ * given originator matching the provided vid
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: the originator owning the entries to remove
+ * @match_vid: the VLAN identifier to match. If negative all the entries will be
+ * removed
+ * @message: debug message to print as "reason"
+ */
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
+ int32_t match_vid,
const char *message)
{
struct batadv_tt_global_entry *tt_global;
@@ -1604,6 +1614,10 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
spin_lock_bh(list_lock);
hlist_for_each_entry_safe(tt_common_entry, safe,
head, hash_entry) {
+ /* remove only matching entries */
+ if (match_vid >= 0 && tt_common_entry->vid != match_vid)
+ continue;
+
tt_global = container_of(tt_common_entry,
struct batadv_tt_global_entry,
common);
@@ -2570,7 +2584,8 @@ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
goto out;
/* Purge the old table first.. */
- batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table");
+ batadv_tt_global_del_orig(bat_priv, orig_node, -1,
+ "Received full table");
_batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
ttvn);
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index c6bf33c..dc6db4e 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -30,7 +30,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const char *message);
+ int32_t match_vid, const char *message);
struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
const uint8_t *src,
const uint8_t *addr,
--
1.8.4
^ permalink raw reply related
* [PATCH 16/18] batman-adv: make the TT CRC logic VLAN specific
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
This change allows nodes to handle the TT table on a
per-VLAN basis. This is needed because nodes may have to
store only some of the global entries advertised by another
node.
In this scenario such nodes would re-create only a partial
global table and would not be able to compute a correct CRC
anymore.
This patch splits the logic and introduces one CRC per VLAN.
In this way a node fetching only some entries belonging to
some VLANs is still able to compute the needed CRCs and
still check the table correctness.
With this patch the shape of the TVLV-TT is changed too
because now a node needs to advertise all the CRCs of all
the VLANs that it is wired to.
The debug output of the local Translation Table now shows
the CRC along with each entry since there is not a common
value for the entire table anymore.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/originator.c | 101 +++++-
net/batman-adv/originator.h | 7 +
net/batman-adv/packet.h | 18 +-
net/batman-adv/translation-table.c | 720 +++++++++++++++++++++++++++++--------
net/batman-adv/types.h | 41 ++-
5 files changed, 730 insertions(+), 157 deletions(-)
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 867778e..7a499da 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -44,6 +44,88 @@ static int batadv_compare_orig(const struct hlist_node *node, const void *data2)
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
}
+/**
+ * batadv_orig_node_vlan_get - get an orig_node_vlan object
+ * @orig_node: the originator serving the VLAN
+ * @vid: the VLAN identifier
+ *
+ * Returns the vlan object identified by vid and belonging to orig_node or NULL
+ * if it does not exist.
+ */
+struct batadv_orig_node_vlan *
+batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
+ unsigned short vid)
+{
+ struct batadv_orig_node_vlan *vlan = NULL, *tmp;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
+ if (tmp->vid != vid)
+ continue;
+
+ if (!atomic_inc_not_zero(&tmp->refcount))
+ continue;
+
+ vlan = tmp;
+
+ break;
+ }
+ rcu_read_unlock();
+
+ return vlan;
+}
+
+/**
+ * batadv_orig_node_vlan_new - search and possibly create an orig_node_vlan
+ * object
+ * @orig_node: the originator serving the VLAN
+ * @vid: the VLAN identifier
+ *
+ * Returns NULL in case of failure or the vlan object identified by vid and
+ * belonging to orig_node otherwise. The object is created and added to the list
+ * if it does not exist.
+ *
+ * The object is returned with refcounter increased by 1.
+ */
+struct batadv_orig_node_vlan *
+batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
+ unsigned short vid)
+{
+ struct batadv_orig_node_vlan *vlan;
+
+ spin_lock_bh(&orig_node->vlan_list_lock);
+
+ /* first look if an object for this vid already exists */
+ vlan = batadv_orig_node_vlan_get(orig_node, vid);
+ if (vlan)
+ goto out;
+
+ vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
+ if (!vlan)
+ goto out;
+
+ atomic_set(&vlan->refcount, 2);
+ vlan->vid = vid;
+
+ list_add_rcu(&vlan->list, &orig_node->vlan_list);
+
+out:
+ spin_unlock_bh(&orig_node->vlan_list_lock);
+
+ return vlan;
+}
+
+/**
+ * batadv_orig_node_vlan_free_ref - decrement the refcounter and possibly free
+ * the originator-vlan object
+ * @orig_vlan: the originator-vlan object to release
+ */
+void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan)
+{
+ if (atomic_dec_and_test(&orig_vlan->refcount))
+ kfree_rcu(orig_vlan, rcu);
+}
+
int batadv_originator_init(struct batadv_priv *bat_priv)
{
if (bat_priv->orig_hash)
@@ -218,6 +300,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
const uint8_t *addr)
{
struct batadv_orig_node *orig_node;
+ struct batadv_orig_node_vlan *vlan;
int size, i;
int hash_added;
unsigned long reset_time;
@@ -235,11 +318,13 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
INIT_HLIST_HEAD(&orig_node->neigh_list);
INIT_LIST_HEAD(&orig_node->bond_list);
+ INIT_LIST_HEAD(&orig_node->vlan_list);
spin_lock_init(&orig_node->ogm_cnt_lock);
spin_lock_init(&orig_node->bcast_seqno_lock);
spin_lock_init(&orig_node->neigh_list_lock);
spin_lock_init(&orig_node->tt_buff_lock);
spin_lock_init(&orig_node->tt_lock);
+ spin_lock_init(&orig_node->vlan_list_lock);
batadv_nc_init_orig(orig_node);
@@ -251,22 +336,30 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
memcpy(orig_node->orig, addr, ETH_ALEN);
batadv_dat_init_orig_node_addr(orig_node);
orig_node->router = NULL;
- orig_node->tt_crc = 0;
atomic_set(&orig_node->last_ttvn, 0);
orig_node->tt_buff = NULL;
orig_node->tt_buff_len = 0;
- atomic_set(&orig_node->tt_size, 0);
reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
orig_node->bcast_seqno_reset = reset_time;
orig_node->batman_seqno_reset = reset_time;
atomic_set(&orig_node->bond_candidates, 0);
+ /* create a vlan object for the "untagged" LAN */
+ vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
+ if (!vlan)
+ goto free_orig_node;
+ /* batadv_orig_node_vlan_new() increases the refcounter.
+ * Immediately release vlan since it is not needed anymore in this
+ * context
+ */
+ batadv_orig_node_vlan_free_ref(vlan);
+
size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
if (!orig_node->bcast_own)
- goto free_orig_node;
+ goto free_vlan;
size = bat_priv->num_ifaces * sizeof(uint8_t);
orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
@@ -291,6 +384,8 @@ free_bcast_own_sum:
kfree(orig_node->bcast_own_sum);
free_bcast_own:
kfree(orig_node->bcast_own);
+free_vlan:
+ batadv_orig_node_vlan_free_ref(vlan);
free_orig_node:
kfree(orig_node);
return NULL;
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 7887b84..cc6d686 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -40,6 +40,13 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
int max_if_num);
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
int max_if_num);
+struct batadv_orig_node_vlan *
+batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
+ unsigned short vid);
+struct batadv_orig_node_vlan *
+batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
+ unsigned short vid);
+void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan);
/* hashfunction to choose an entry in a hash table of given size
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 6311642..9fbcaac 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -391,14 +391,26 @@ struct batadv_tvlv_gateway_data {
* struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container
* @flags: translation table flags (see batadv_tt_data_flags)
* @ttvn: translation table version number
- * @reserved: field reserved for future use
- * @crc: crc32 checksum of the local translation table
+ * @vlan_num: number of announced VLANs. In the TVLV this struct is followed by
+ * one batadv_tvlv_tt_vlan_data object per announced vlan
*/
struct batadv_tvlv_tt_data {
uint8_t flags;
uint8_t ttvn;
+ __be16 num_vlan;
+};
+
+/**
+ * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through
+ * the tt tvlv container
+ * @crc: crc32 checksum of the entries belonging to this vlan
+ * @vid: vlan identifier
+ * @reserved: unused, useful for alignment purposes
+ */
+struct batadv_tvlv_tt_vlan_data {
+ __be32 crc;
+ __be16 vid;
uint16_t reserved;
- __be32 crc;
};
/**
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 00f4faa..41a8387 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -208,13 +208,107 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
kfree(orig_entry);
}
+/**
+ * batadv_tt_local_size_mod - change the size by v of the local table identified
+ * by vid
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the VLAN identifier of the sub-table to change
+ * @v: the amount to sum to the local table size
+ */
+static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
+ unsigned short vid, int v)
+{
+ struct batadv_softif_vlan *vlan;
+
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+ if (!vlan)
+ return;
+
+ atomic_add(v, &vlan->tt.num_entries);
+
+ batadv_softif_vlan_free_ref(vlan);
+}
+
+/**
+ * batadv_tt_local_size_inc - increase by one the local table size for the given
+ * vid
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the VLAN identifier
+ */
+static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
+ unsigned short vid)
+{
+ batadv_tt_local_size_mod(bat_priv, vid, 1);
+}
+
+/**
+ * batadv_tt_local_size_dec - decrease by one the local table size for the given
+ * vid
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the VLAN identifier
+ */
+static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
+ unsigned short vid)
+{
+ batadv_tt_local_size_mod(bat_priv, vid, -1);
+}
+
+/**
+ * batadv_tt_global_size_mod - change the size by v of the local table
+ * identified by vid
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the VLAN identifier
+ * @v: the amount to sum to the global table size
+ */
+static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
+ unsigned short vid, int v)
+{
+ struct batadv_orig_node_vlan *vlan;
+
+ vlan = batadv_orig_node_vlan_new(orig_node, vid);
+ if (!vlan)
+ return;
+
+ if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
+ spin_lock_bh(&orig_node->vlan_list_lock);
+ list_del_rcu(&vlan->list);
+ spin_unlock_bh(&orig_node->vlan_list_lock);
+ batadv_orig_node_vlan_free_ref(vlan);
+ }
+
+ batadv_orig_node_vlan_free_ref(vlan);
+}
+
+/**
+ * batadv_tt_global_size_inc - increase by one the global table size for the
+ * given vid
+ * @orig_node: the originator which global table size has to be decreased
+ * @vid: the vlan identifier
+ */
+static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
+ unsigned short vid)
+{
+ batadv_tt_global_size_mod(orig_node, vid, 1);
+}
+
+/**
+ * batadv_tt_global_size_dec - decrease by one the global table size for the
+ * given vid
+ * @orig_node: the originator which global table size has to be decreased
+ * @vid: the vlan identifier
+ */
+static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
+ unsigned short vid)
+{
+ batadv_tt_global_size_mod(orig_node, vid, -1);
+}
+
static void
batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
{
if (!atomic_dec_and_test(&orig_entry->refcount))
return;
- /* to avoid race conditions, immediately decrease the tt counter */
- atomic_dec(&orig_entry->orig_node->tt_size);
+
call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
}
@@ -464,6 +558,149 @@ out:
}
/**
+ * batadv_tt_prepare_tvlv_global_data - prepare the TVLV TT header to send
+ * within a TT Response directed to another node
+ * @orig_node: originator for which the TT data has to be prepared
+ * @tt_data: uninitialised pointer to the address of the TVLV buffer
+ * @tt_change: uninitialised pointer to the address of the area where the TT
+ * changed can be stored
+ * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
+ * function reserves the amount of space needed to send the entire global TT
+ * table. In case of success the value is updated with the real amount of
+ * reserved bytes
+
+ * Allocate the needed amount of memory for the entire TT TVLV and write its
+ * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
+ * objects, one per active VLAN served by the originator node.
+ *
+ * Return the size of the allocated buffer or 0 in case of failure.
+ */
+static uint16_t
+batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
+ struct batadv_tvlv_tt_data **tt_data,
+ struct batadv_tvlv_tt_change **tt_change,
+ int32_t *tt_len)
+{
+ uint16_t num_vlan = 0, num_entries = 0, change_offset, tvlv_len;
+ struct batadv_tvlv_tt_vlan_data *tt_vlan;
+ struct batadv_orig_node_vlan *vlan;
+ uint8_t *tt_change_ptr;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
+ num_vlan++;
+ num_entries += atomic_read(&vlan->tt.num_entries);
+ }
+
+ change_offset = sizeof(**tt_data);
+ change_offset += num_vlan * sizeof(*tt_vlan);
+
+ /* if tt_len is negative, allocate the space needed by the full table */
+ if (*tt_len < 0)
+ *tt_len = batadv_tt_len(num_entries);
+
+ tvlv_len = *tt_len;
+ tvlv_len += change_offset;
+
+ *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
+ if (!*tt_data) {
+ *tt_len = 0;
+ goto out;
+ }
+
+ (*tt_data)->flags = BATADV_NO_FLAGS;
+ (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
+ (*tt_data)->num_vlan = htons(num_vlan);
+
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
+ list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
+ tt_vlan->vid = htons(vlan->vid);
+ tt_vlan->crc = htonl(vlan->tt.crc);
+
+ tt_vlan++;
+ }
+
+ tt_change_ptr = (uint8_t *)*tt_data + change_offset;
+ *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
+
+out:
+ rcu_read_unlock();
+ return tvlv_len;
+}
+
+/**
+ * batadv_tt_prepare_tvlv_local_data - allocate and prepare the TT TVLV for this
+ * node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @tt_data: uninitialised pointer to the address of the TVLV buffer
+ * @tt_change: uninitialised pointer to the address of the area where the TT
+ * changes can be stored
+ * @tt_len: pointer to the length to reserve to the tt_change. if -1 this
+ * function reserves the amount of space needed to send the entire local TT
+ * table. In case of success the value is updated with the real amount of
+ * reserved bytes
+ *
+ * Allocate the needed amount of memory for the entire TT TVLV and write its
+ * header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data
+ * objects, one per active VLAN.
+ *
+ * Return the size of the allocated buffer or 0 in case of failure.
+ */
+static uint16_t
+batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
+ struct batadv_tvlv_tt_data **tt_data,
+ struct batadv_tvlv_tt_change **tt_change,
+ int32_t *tt_len)
+{
+ struct batadv_tvlv_tt_vlan_data *tt_vlan;
+ struct batadv_softif_vlan *vlan;
+ uint16_t num_vlan = 0, num_entries = 0, tvlv_len;
+ uint8_t *tt_change_ptr;
+ int change_offset;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ num_vlan++;
+ num_entries += atomic_read(&vlan->tt.num_entries);
+ }
+
+ change_offset = sizeof(**tt_data);
+ change_offset += num_vlan * sizeof(*tt_vlan);
+
+ /* if tt_len is negative, allocate the space needed by the full table */
+ if (*tt_len < 0)
+ *tt_len = batadv_tt_len(num_entries);
+
+ tvlv_len = *tt_len;
+ tvlv_len += change_offset;
+
+ *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
+ if (!*tt_data) {
+ tvlv_len = 0;
+ goto out;
+ }
+
+ (*tt_data)->flags = BATADV_NO_FLAGS;
+ (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
+ (*tt_data)->num_vlan = htons(num_vlan);
+
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
+ hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ tt_vlan->vid = htons(vlan->vid);
+ tt_vlan->crc = htonl(vlan->tt.crc);
+
+ tt_vlan++;
+ }
+
+ tt_change_ptr = (uint8_t *)*tt_data + change_offset;
+ *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
+
+out:
+ rcu_read_unlock();
+ return tvlv_len;
+}
+
+/**
* batadv_tt_tvlv_container_update - update the translation table tvlv container
* after local tt changes have been committed
* @bat_priv: the bat priv with all the soft interface information
@@ -473,10 +710,12 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
struct batadv_tt_change_node *entry, *safe;
struct batadv_tvlv_tt_data *tt_data;
struct batadv_tvlv_tt_change *tt_change;
- int tt_diff_len = 0, tt_change_len = 0;
+ int tt_diff_len, tt_change_len = 0;
int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
+ uint16_t tvlv_len;
- tt_diff_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
+ tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
+ tt_diff_len = batadv_tt_len(tt_diff_entries_num);
/* if we have too many changes for one packet don't send any
* and wait for the tt table request which will be fragmented
@@ -484,24 +723,19 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
if (tt_diff_len > bat_priv->soft_iface->mtu)
tt_diff_len = 0;
- tt_data = kzalloc(sizeof(*tt_data) + tt_diff_len, GFP_ATOMIC);
- if (!tt_data)
+ tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
+ &tt_change, &tt_diff_len);
+ if (!tvlv_len)
return;
tt_data->flags = BATADV_TT_OGM_DIFF;
- tt_data->ttvn = atomic_read(&bat_priv->tt.vn);
- tt_data->crc = htonl(bat_priv->tt.local_crc);
if (tt_diff_len == 0)
goto container_register;
- tt_diff_entries_num = batadv_tt_entries(tt_diff_len);
-
spin_lock_bh(&bat_priv->tt.changes_list_lock);
atomic_set(&bat_priv->tt.local_changes, 0);
- tt_change = (struct batadv_tvlv_tt_change *)(tt_data + 1);
-
list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
list) {
if (tt_diff_entries_count < tt_diff_entries_num) {
@@ -537,7 +771,7 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
container_register:
batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
- sizeof(*tt_data) + tt_change_len);
+ tvlv_len);
kfree(tt_data);
}
@@ -549,7 +783,9 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tt_local_entry *tt_local;
struct batadv_hard_iface *primary_if;
+ struct batadv_softif_vlan *vlan;
struct hlist_head *head;
+ unsigned short vid;
uint32_t i;
int last_seen_secs;
int last_seen_msecs;
@@ -562,11 +798,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
goto out;
seq_printf(seq,
- "Locally retrieved addresses (from %s) announced via TT (TTVN: %u CRC: %#.8x):\n",
- net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn),
- bat_priv->tt.local_crc);
- seq_printf(seq, " %-13s %s %-7s %-10s\n", "Client", "VID",
- "Flags", "Last seen");
+ "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
+ net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
+ seq_printf(seq, " %-13s %s %-7s %-9s (%-10s)\n", "Client", "VID",
+ "Flags", "Last seen", "CRC");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -577,6 +812,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
tt_local = container_of(tt_common_entry,
struct batadv_tt_local_entry,
common);
+ vid = tt_common_entry->vid;
last_seen_jiffies = jiffies - tt_local->last_seen;
last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
last_seen_secs = last_seen_msecs / 1000;
@@ -584,7 +820,15 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
no_purge = tt_common_entry->flags & np_flag;
- seq_printf(seq, " * %pM %4i [%c%c%c%c%c] %3u.%03u\n",
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+ if (!vlan) {
+ seq_printf(seq, "Cannot retrieve VLAN %d\n",
+ BATADV_PRINT_VID(vid));
+ continue;
+ }
+
+ seq_printf(seq,
+ " * %pM %4i [%c%c%c%c%c] %3u.%03u (%#.8x)\n",
tt_common_entry->addr,
BATADV_PRINT_VID(tt_common_entry->vid),
(tt_common_entry->flags &
@@ -597,7 +841,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
(tt_common_entry->flags &
BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
no_purge ? 0 : last_seen_secs,
- no_purge ? 0 : last_seen_msecs);
+ no_purge ? 0 : last_seen_msecs,
+ vlan->tt.crc);
+
+ batadv_softif_vlan_free_ref(vlan);
}
rcu_read_unlock();
}
@@ -860,7 +1107,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
INIT_HLIST_NODE(&orig_entry->list);
atomic_inc(&orig_node->refcount);
- atomic_inc(&orig_node->tt_size);
+ batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
orig_entry->orig_node = orig_node;
orig_entry->ttvn = ttvn;
atomic_set(&orig_entry->refcount, 2);
@@ -1070,45 +1317,71 @@ static void
batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
struct seq_file *seq)
{
- struct hlist_head *head;
struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
struct batadv_tt_common_entry *tt_common_entry;
- uint16_t flags;
+ struct batadv_orig_node_vlan *vlan;
+ struct hlist_head *head;
uint8_t last_ttvn;
+ uint16_t flags;
tt_common_entry = &tt_global_entry->common;
flags = tt_common_entry->flags;
best_entry = batadv_transtable_best_orig(tt_global_entry);
if (best_entry) {
+ vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
+ tt_common_entry->vid);
+ if (!vlan) {
+ seq_printf(seq,
+ " * Cannot retrieve VLAN %d for originator %pM\n",
+ BATADV_PRINT_VID(tt_common_entry->vid),
+ best_entry->orig_node->orig);
+ goto print_list;
+ }
+
last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
seq_printf(seq,
" %c %pM %4i (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
'*', tt_global_entry->common.addr,
BATADV_PRINT_VID(tt_global_entry->common.vid),
best_entry->ttvn, best_entry->orig_node->orig,
- last_ttvn, best_entry->orig_node->tt_crc,
+ last_ttvn, vlan->tt.crc,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
+
+ batadv_orig_node_vlan_free_ref(vlan);
}
+print_list:
head = &tt_global_entry->orig_list;
hlist_for_each_entry_rcu(orig_entry, head, list) {
if (best_entry == orig_entry)
continue;
+ vlan = batadv_orig_node_vlan_get(orig_entry->orig_node,
+ tt_common_entry->vid);
+ if (!vlan) {
+ seq_printf(seq,
+ " + Cannot retrieve VLAN %d for originator %pM\n",
+ BATADV_PRINT_VID(tt_common_entry->vid),
+ orig_entry->orig_node->orig);
+ continue;
+ }
+
last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
seq_printf(seq,
- " %c %pM %4d (%3u) via %pM (%3u) [%c%c%c]\n",
+ " %c %pM %4d (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
'+', tt_global_entry->common.addr,
BATADV_PRINT_VID(tt_global_entry->common.vid),
orig_entry->ttvn, orig_entry->orig_node->orig,
- last_ttvn,
+ last_ttvn, vlan->tt.crc,
(flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
(flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
(flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
+
+ batadv_orig_node_vlan_free_ref(vlan);
}
}
@@ -1165,6 +1438,8 @@ batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
head = &tt_global_entry->orig_list;
hlist_for_each_entry_safe(orig_entry, safe, head, list) {
hlist_del_rcu(&orig_entry->list);
+ batadv_tt_global_size_dec(orig_entry->orig_node,
+ tt_global_entry->common.vid);
batadv_tt_orig_list_entry_free_ref(orig_entry);
}
spin_unlock_bh(&tt_global_entry->list_lock);
@@ -1192,6 +1467,8 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
tt_global_entry->common.addr,
BATADV_PRINT_VID(vid), message);
hlist_del_rcu(&orig_entry->list);
+ batadv_tt_global_size_dec(orig_node,
+ tt_global_entry->common.vid);
batadv_tt_orig_list_entry_free_ref(orig_entry);
}
}
@@ -1535,6 +1812,7 @@ out:
* to the given orig_node
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: originator for which the CRC should be computed
+ * @vid: VLAN identifier for which the CRC32 has to be computed
*
* This function computes the checksum for the global table corresponding to a
* specific originator. In particular, the checksum is computed as follows: For
@@ -1554,7 +1832,8 @@ out:
* Returns the checksum of the global table of a given originator.
*/
static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
- struct batadv_orig_node *orig_node)
+ struct batadv_orig_node *orig_node,
+ unsigned short vid)
{
struct batadv_hashtable *hash = bat_priv->tt.global_hash;
struct batadv_tt_common_entry *tt_common;
@@ -1570,6 +1849,12 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
tt_global = container_of(tt_common,
struct batadv_tt_global_entry,
common);
+ /* compute the CRC only for entries belonging to the
+ * VLAN identified by the vid passed as parameter
+ */
+ if (tt_common->vid != vid)
+ continue;
+
/* Roaming clients are in the global table for
* consistency only. They don't have to be
* taken into account while computing the
@@ -1604,13 +1889,15 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
/**
* batadv_tt_local_crc - calculates the checksum of the local table
* @bat_priv: the bat priv with all the soft interface information
+ * @vid: VLAN identifier for which the CRC32 has to be computed
*
* For details about the computation, please refer to the documentation for
* batadv_tt_global_crc().
*
* Returns the checksum of the local table
*/
-static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
+static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
+ unsigned short vid)
{
struct batadv_hashtable *hash = bat_priv->tt.local_hash;
struct batadv_tt_common_entry *tt_common;
@@ -1622,6 +1909,12 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
rcu_read_lock();
hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
+ /* compute the CRC only for entries belonging to the
+ * VLAN identified by vid
+ */
+ if (tt_common->vid != vid)
+ continue;
+
/* not yet committed clients have not to be taken into
* account while computing the CRC
*/
@@ -1753,44 +2046,29 @@ static int batadv_tt_global_valid(const void *entry_ptr,
}
/**
- * batadv_tt_tvlv_generate - creates tvlv tt data buffer to fill it with the
- * tt entries from the specified tt hash
+ * batadv_tt_tvlv_generate - fill the tvlv buff with the tt entries from the
+ * specified tt hash
* @bat_priv: the bat priv with all the soft interface information
* @hash: hash table containing the tt entries
* @tt_len: expected tvlv tt data buffer length in number of bytes
+ * @tvlv_buff: pointer to the buffer to fill with the TT data
* @valid_cb: function to filter tt change entries
* @cb_data: data passed to the filter function as argument
- *
- * Returns pointer to allocated tvlv tt data buffer if operation was
- * successful or NULL otherwise.
*/
-static struct batadv_tvlv_tt_data *
-batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
- struct batadv_hashtable *hash, uint16_t tt_len,
- int (*valid_cb)(const void *, const void *),
- void *cb_data)
+static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
+ struct batadv_hashtable *hash,
+ void *tvlv_buff, uint16_t tt_len,
+ int (*valid_cb)(const void *, const void *),
+ void *cb_data)
{
struct batadv_tt_common_entry *tt_common_entry;
- struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
struct batadv_tvlv_tt_change *tt_change;
struct hlist_head *head;
uint16_t tt_tot, tt_num_entries = 0;
- ssize_t tvlv_tt_size = sizeof(struct batadv_tvlv_tt_data);
uint32_t i;
- if (tvlv_tt_size + tt_len > bat_priv->soft_iface->mtu) {
- tt_len = bat_priv->soft_iface->mtu - tvlv_tt_size;
- tt_len -= tt_len % sizeof(struct batadv_tvlv_tt_change);
- }
-
tt_tot = batadv_tt_entries(tt_len);
-
- tvlv_tt_data = kzalloc(sizeof(*tvlv_tt_data) + tt_len,
- GFP_ATOMIC);
- if (!tvlv_tt_data)
- goto out;
-
- tt_change = (struct batadv_tvlv_tt_change *)(tvlv_tt_data + 1);
+ tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
rcu_read_lock();
for (i = 0; i < hash->size; i++) {
@@ -1815,9 +2093,89 @@ batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
}
}
rcu_read_unlock();
+}
-out:
- return tvlv_tt_data;
+/**
+ * batadv_tt_global_check_crc - check if all the CRCs are correct
+ * @orig_node: originator for which the CRCs have to be checked
+ * @tt_vlan: pointer to the first tvlv VLAN entry
+ * @num_vlan: number of tvlv VLAN entries
+ * @create: if true, create VLAN objects if not found
+ *
+ * Return true if all the received CRCs match the locally stored ones, false
+ * otherwise
+ */
+static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
+ struct batadv_tvlv_tt_vlan_data *tt_vlan,
+ uint16_t num_vlan)
+{
+ struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
+ struct batadv_orig_node_vlan *vlan;
+ int i;
+
+ /* check if each received CRC matches the locally stored one */
+ for (i = 0; i < num_vlan; i++) {
+ tt_vlan_tmp = tt_vlan + i;
+
+ /* if orig_node is a backbone node for this VLAN, don't check
+ * the CRC as we ignore all the global entries over it
+ */
+ if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
+ orig_node->orig))
+ continue;
+
+ vlan = batadv_orig_node_vlan_get(orig_node,
+ ntohs(tt_vlan_tmp->vid));
+ if (!vlan)
+ return false;
+
+ if (vlan->tt.crc != ntohl(tt_vlan_tmp->crc))
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * batadv_tt_local_update_crc - update all the local CRCs
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
+{
+ struct batadv_softif_vlan *vlan;
+
+ /* recompute the global CRC for each VLAN */
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
+ }
+ rcu_read_unlock();
+}
+
+/**
+ * batadv_tt_global_update_crc - update all the global CRCs for this orig_node
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: the orig_node for which the CRCs have to be updated
+ */
+static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
+ struct batadv_orig_node *orig_node)
+{
+ struct batadv_orig_node_vlan *vlan;
+ uint32_t crc;
+
+ /* recompute the global CRC for each VLAN */
+ rcu_read_lock();
+ list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
+ /* if orig_node is a backbone node for this VLAN, don't compute
+ * the CRC as we ignore all the global entries over it
+ */
+ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
+ continue;
+
+ crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
+ vlan->tt.crc = crc;
+ }
+ rcu_read_unlock();
}
/**
@@ -1825,19 +2183,23 @@ out:
* @bat_priv: the bat priv with all the soft interface information
* @dst_orig_node: the destination of the message
* @ttvn: the version number that the source of the message is looking for
- * @tt_crc: the CRC associated with the version number
+ * @tt_vlan: pointer to the first tvlv VLAN object to request
+ * @num_vlan: number of tvlv VLAN entries
* @full_table: ask for the entire translation table if true, while only for the
* last TT diff otherwise
*/
static int batadv_send_tt_request(struct batadv_priv *bat_priv,
struct batadv_orig_node *dst_orig_node,
- uint8_t ttvn, uint32_t tt_crc,
- bool full_table)
+ uint8_t ttvn,
+ struct batadv_tvlv_tt_vlan_data *tt_vlan,
+ uint16_t num_vlan, bool full_table)
{
struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
- struct batadv_hard_iface *primary_if;
struct batadv_tt_req_node *tt_req_node = NULL;
+ struct batadv_tvlv_tt_vlan_data *tt_vlan_req;
+ struct batadv_hard_iface *primary_if;
bool ret = false;
+ int i, size;
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
@@ -1850,13 +2212,26 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
if (!tt_req_node)
goto out;
- tvlv_tt_data = kzalloc(sizeof(*tvlv_tt_data), GFP_ATOMIC);
+ size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan;
+ tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
if (!tvlv_tt_data)
goto out;
tvlv_tt_data->flags = BATADV_TT_REQUEST;
tvlv_tt_data->ttvn = ttvn;
- tvlv_tt_data->crc = htonl(tt_crc);
+ tvlv_tt_data->num_vlan = htons(num_vlan);
+
+ /* send all the CRCs within the request. This is needed by intermediate
+ * nodes to ensure they have the correct table before replying
+ */
+ tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1);
+ for (i = 0; i < num_vlan; i++) {
+ tt_vlan_req->vid = tt_vlan->vid;
+ tt_vlan_req->crc = tt_vlan->crc;
+
+ tt_vlan_req++;
+ tt_vlan++;
+ }
if (full_table)
tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
@@ -1867,7 +2242,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
dst_orig_node->orig, BATADV_TVLV_TT, 1,
- tvlv_tt_data, sizeof(*tvlv_tt_data));
+ tvlv_tt_data, size);
ret = true;
out:
@@ -1899,10 +2274,13 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
{
struct batadv_orig_node *req_dst_orig_node;
struct batadv_orig_node *res_dst_orig_node = NULL;
+ struct batadv_tvlv_tt_change *tt_change;
struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
- uint8_t orig_ttvn, req_ttvn;
- uint16_t tt_len;
+ struct batadv_tvlv_tt_vlan_data *tt_vlan;
bool ret = false, full_table;
+ uint8_t orig_ttvn, req_ttvn;
+ uint16_t tvlv_len;
+ int32_t tt_len;
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
@@ -1921,9 +2299,11 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
req_ttvn = tt_data->ttvn;
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
/* this node doesn't have the requested data */
if (orig_ttvn != req_ttvn ||
- tt_data->crc != htonl(req_dst_orig_node->tt_crc))
+ !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan,
+ ntohs(tt_data->num_vlan)))
goto out;
/* If the full table has been explicitly requested */
@@ -1940,26 +2320,34 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
tt_len = req_dst_orig_node->tt_buff_len;
- tvlv_tt_data = kzalloc(sizeof(*tvlv_tt_data) + tt_len,
- GFP_ATOMIC);
- if (!tvlv_tt_data)
+ tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
+ &tvlv_tt_data,
+ &tt_change,
+ &tt_len);
+ if (!tt_len)
goto unlock;
/* Copy the last orig_node's OGM buffer */
- memcpy(tvlv_tt_data + 1, req_dst_orig_node->tt_buff,
+ memcpy(tt_change, req_dst_orig_node->tt_buff,
req_dst_orig_node->tt_buff_len);
spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
} else {
- tt_len = (uint16_t)atomic_read(&req_dst_orig_node->tt_size);
- tt_len = batadv_tt_len(tt_len);
-
- tvlv_tt_data = batadv_tt_tvlv_generate(bat_priv,
- bat_priv->tt.global_hash,
- tt_len,
- batadv_tt_global_valid,
- req_dst_orig_node);
- if (!tvlv_tt_data)
+ /* allocate the tvlv, put the tt_data and all the tt_vlan_data
+ * in the initial part
+ */
+ tt_len = -1;
+ tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
+ &tvlv_tt_data,
+ &tt_change,
+ &tt_len);
+ if (!tt_len)
goto out;
+
+ /* fill the rest of the tvlv with the real TT entries */
+ batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
+ tt_change, tt_len,
+ batadv_tt_global_valid,
+ req_dst_orig_node);
}
tvlv_tt_data->flags = BATADV_TT_RESPONSE;
@@ -1976,8 +2364,8 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
- req_src, BATADV_TVLV_TT, 1,
- tvlv_tt_data, sizeof(*tvlv_tt_data) + tt_len);
+ req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
+ tvlv_len);
ret = true;
goto out;
@@ -2008,11 +2396,13 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
uint8_t *req_src)
{
struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
- struct batadv_orig_node *orig_node;
struct batadv_hard_iface *primary_if = NULL;
+ struct batadv_tvlv_tt_change *tt_change;
+ struct batadv_orig_node *orig_node;
uint8_t my_ttvn, req_ttvn;
+ uint16_t tvlv_len;
bool full_table;
- uint16_t tt_len;
+ int32_t tt_len;
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
@@ -2046,29 +2436,37 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
*/
if (!full_table) {
spin_lock_bh(&bat_priv->tt.last_changeset_lock);
+
tt_len = bat_priv->tt.last_changeset_len;
-
- tvlv_tt_data = kzalloc(sizeof(*tvlv_tt_data) + tt_len,
- GFP_ATOMIC);
- if (!tvlv_tt_data)
+ tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
+ &tvlv_tt_data,
+ &tt_change,
+ &tt_len);
+ if (!tt_len)
goto unlock;
/* Copy the last orig_node's OGM buffer */
- memcpy(tvlv_tt_data + 1, bat_priv->tt.last_changeset,
+ memcpy(tt_change, bat_priv->tt.last_changeset,
bat_priv->tt.last_changeset_len);
spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
} else {
- tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num);
- tt_len = batadv_tt_len(tt_len);
req_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
- tvlv_tt_data = batadv_tt_tvlv_generate(bat_priv,
- bat_priv->tt.local_hash,
- tt_len,
- batadv_tt_local_valid,
- NULL);
- if (!tvlv_tt_data)
+ /* allocate the tvlv, put the tt_data and all the tt_vlan_data
+ * in the initial part
+ */
+ tt_len = -1;
+ tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
+ &tvlv_tt_data,
+ &tt_change,
+ &tt_len);
+ if (!tt_len)
goto out;
+
+ /* fill the rest of the tvlv with the real TT entries */
+ batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
+ tt_change, tt_len,
+ batadv_tt_local_valid, NULL);
}
tvlv_tt_data->flags = BATADV_TT_RESPONSE;
@@ -2084,8 +2482,8 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
- req_src, BATADV_TVLV_TT, 1,
- tvlv_tt_data, sizeof(*tvlv_tt_data) + tt_len);
+ req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
+ tvlv_len);
goto out;
@@ -2161,8 +2559,9 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
}
static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
- struct batadv_tvlv_tt_data *tt_data,
- uint8_t *resp_src, uint16_t num_entries)
+ struct batadv_tvlv_tt_change *tt_change,
+ uint8_t ttvn, uint8_t *resp_src,
+ uint16_t num_entries)
{
struct batadv_orig_node *orig_node;
@@ -2173,9 +2572,8 @@ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
/* Purge the old table first.. */
batadv_tt_global_del_orig(bat_priv, orig_node, "Received full table");
- _batadv_tt_update_changes(bat_priv, orig_node,
- (struct batadv_tvlv_tt_change *)(tt_data + 1),
- num_entries, tt_data->ttvn);
+ _batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
+ ttvn);
spin_lock_bh(&orig_node->tt_buff_lock);
kfree(orig_node->tt_buff);
@@ -2183,7 +2581,7 @@ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
orig_node->tt_buff = NULL;
spin_unlock_bh(&orig_node->tt_buff_lock);
- atomic_set(&orig_node->last_ttvn, tt_data->ttvn);
+ atomic_set(&orig_node->last_ttvn, ttvn);
out:
if (orig_node)
@@ -2247,6 +2645,8 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
struct batadv_tt_req_node *node, *safe;
struct batadv_orig_node *orig_node = NULL;
struct batadv_tvlv_tt_change *tt_change;
+ uint8_t *tvlv_ptr = (uint8_t *)tt_data;
+ uint16_t change_offset;
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
@@ -2263,16 +2663,22 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
spin_lock_bh(&orig_node->tt_lock);
+ change_offset = sizeof(struct batadv_tvlv_tt_vlan_data);
+ change_offset *= ntohs(tt_data->num_vlan);
+ change_offset += sizeof(*tt_data);
+ tvlv_ptr += change_offset;
+
+ tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
if (tt_data->flags & BATADV_TT_FULL_TABLE) {
- batadv_tt_fill_gtable(bat_priv, tt_data, resp_src, num_entries);
+ batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
+ resp_src, num_entries);
} else {
- tt_change = (struct batadv_tvlv_tt_change *)(tt_data + 1);
batadv_tt_update_changes(bat_priv, orig_node, num_entries,
tt_data->ttvn, tt_change);
}
/* Recalculate the CRC for this orig_node and store it */
- orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
+ batadv_tt_global_update_crc(bat_priv, orig_node);
spin_unlock_bh(&orig_node->tt_lock);
@@ -2284,6 +2690,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
list_del(&node->list);
kfree(node);
}
+
spin_unlock_bh(&bat_priv->tt.req_list_lock);
out:
if (orig_node)
@@ -2452,19 +2859,25 @@ void batadv_tt_free(struct batadv_priv *bat_priv)
kfree(bat_priv->tt.last_changeset);
}
-/* This function will enable or disable the specified flags for all the entries
- * in the given hash table and returns the number of modified entries
+/**
+ * batadv_tt_local_set_flags - set or unset the specified flags on the local
+ * table and possibly count them in the TT size
+ * @bat_priv: the bat priv with all the soft interface information
+ * @flags: the flag to switch
+ * @enable: whether to set or unset the flag
+ * @count: whether to increase the TT size by the number of changed entries
*/
-static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
- uint16_t flags, bool enable)
+static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv,
+ uint16_t flags, bool enable, bool count)
{
- uint32_t i;
+ struct batadv_hashtable *hash = bat_priv->tt.local_hash;
+ struct batadv_tt_common_entry *tt_common_entry;
uint16_t changed_num = 0;
struct hlist_head *head;
- struct batadv_tt_common_entry *tt_common_entry;
+ uint32_t i;
if (!hash)
- goto out;
+ return;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -2482,11 +2895,15 @@ static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash,
tt_common_entry->flags &= ~flags;
}
changed_num++;
+
+ if (!count)
+ continue;
+
+ batadv_tt_local_size_inc(bat_priv,
+ tt_common_entry->vid);
}
rcu_read_unlock();
}
-out:
- return changed_num;
}
/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
@@ -2518,7 +2935,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
tt_common->addr,
BATADV_PRINT_VID(tt_common->vid));
- atomic_dec(&bat_priv->tt.local_entry_num);
+ batadv_tt_local_size_dec(bat_priv, tt_common->vid);
hlist_del_rcu(&tt_common->hash_entry);
tt_local = container_of(tt_common,
struct batadv_tt_local_entry,
@@ -2536,8 +2953,6 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
*/
void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
{
- uint16_t changed_num = 0;
-
spin_lock_bh(&bat_priv->tt.commit_lock);
if (atomic_read(&bat_priv->tt.local_changes) < 1) {
@@ -2546,13 +2961,10 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
goto out;
}
- changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
- BATADV_TT_CLIENT_NEW, false);
+ batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
- /* all reset entries have to be counted as local entries */
- atomic_add(changed_num, &bat_priv->tt.local_entry_num);
batadv_tt_local_purge_pending_clients(bat_priv);
- bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv);
+ batadv_tt_local_update_crc(bat_priv);
/* Increment the TTVN only once per OGM interval */
atomic_inc(&bat_priv->tt.vn);
@@ -2608,25 +3020,28 @@ out:
* information received via ogms
* @bat_priv: the bat priv with all the soft interface information
* @orig: the orig_node of the ogm
- * @tt_buff: buffer holding the tt information
+ * @tt_vlan: pointer to the first tvlv VLAN entry
+ * @tt_num_vlan: number of tvlv VLAN entries
+ * @tt_change: pointer to the first entry in the TT buffer
* @tt_num_changes: number of tt changes inside the tt buffer
* @ttvn: translation table version number of this changeset
* @tt_crc: crc32 checksum of orig node's translation table
*/
static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
- const unsigned char *tt_buff,
- uint16_t tt_num_changes, uint8_t ttvn,
- uint32_t tt_crc)
+ const void *tt_buff, uint16_t tt_num_vlan,
+ struct batadv_tvlv_tt_change *tt_change,
+ uint16_t tt_num_changes, uint8_t ttvn)
{
uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
+ struct batadv_tvlv_tt_vlan_data *tt_vlan;
bool full_table = true;
- struct batadv_tvlv_tt_change *tt_change;
/* don't care about a backbone gateways updates. */
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
return;
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
/* orig table not initialised AND first diff is in the OGM OR the ttvn
* increased by one -> we can apply the attached changes
*/
@@ -2652,7 +3067,7 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
* prefer to recompute it to spot any possible inconsistency
* in the global table
*/
- orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
+ batadv_tt_global_update_crc(bat_priv, orig_node);
spin_unlock_bh(&orig_node->tt_lock);
@@ -2665,21 +3080,24 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
* checking the CRC value is mandatory to detect the
* inconsistency
*/
- if (orig_node->tt_crc != tt_crc)
+ if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
+ tt_num_vlan))
goto request_table;
} else {
/* if we missed more than one change or our tables are not
* in sync anymore -> request fresh tt data
*/
if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
- orig_node->tt_crc != tt_crc) {
+ !batadv_tt_global_check_crc(orig_node, tt_vlan,
+ tt_num_vlan)) {
request_table:
batadv_dbg(BATADV_DBG_TT, bat_priv,
- "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u crc: %#.8x last_crc: %#.8x num_changes: %u)\n",
- orig_node->orig, ttvn, orig_ttvn, tt_crc,
- orig_node->tt_crc, tt_num_changes);
+ "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
+ orig_node->orig, ttvn, orig_ttvn,
+ tt_num_changes);
batadv_send_tt_request(bat_priv, orig_node, ttvn,
- tt_crc, full_table);
+ tt_vlan, tt_num_vlan,
+ full_table);
return;
}
}
@@ -2774,12 +3192,13 @@ out:
*/
static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig,
- uint8_t flags,
- void *tvlv_value,
+ uint8_t flags, void *tvlv_value,
uint16_t tvlv_value_len)
{
+ struct batadv_tvlv_tt_vlan_data *tt_vlan;
+ struct batadv_tvlv_tt_change *tt_change;
struct batadv_tvlv_tt_data *tt_data;
- uint16_t num_entries;
+ uint16_t num_entries, num_vlan;
if (tvlv_value_len < sizeof(*tt_data))
return;
@@ -2787,11 +3206,19 @@ static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
tvlv_value_len -= sizeof(*tt_data);
+ num_vlan = ntohs(tt_data->num_vlan);
+
+ if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan)
+ return;
+
+ tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
+ tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan);
+ tvlv_value_len -= sizeof(*tt_vlan) * num_vlan;
+
num_entries = batadv_tt_entries(tvlv_value_len);
- batadv_tt_update_orig(bat_priv, orig,
- (unsigned char *)(tt_data + 1),
- num_entries, tt_data->ttvn, ntohl(tt_data->crc));
+ batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change,
+ num_entries, tt_data->ttvn);
}
/**
@@ -2812,7 +3239,7 @@ static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
uint16_t tvlv_value_len)
{
struct batadv_tvlv_tt_data *tt_data;
- uint16_t num_entries;
+ uint16_t tt_vlan_len, tt_num_entries;
char tt_flag;
bool ret;
@@ -2822,7 +3249,14 @@ static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
tvlv_value_len -= sizeof(*tt_data);
- num_entries = batadv_tt_entries(tvlv_value_len);
+ tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data);
+ tt_vlan_len *= ntohs(tt_data->num_vlan);
+
+ if (tvlv_value_len < tt_vlan_len)
+ return NET_RX_SUCCESS;
+
+ tvlv_value_len -= tt_vlan_len;
+ tt_num_entries = batadv_tt_entries(tvlv_value_len);
switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
case BATADV_TT_REQUEST:
@@ -2850,7 +3284,7 @@ static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
if (batadv_is_my_mac(bat_priv, dst)) {
batadv_handle_tt_response(bat_priv, tt_data,
- src, num_entries);
+ src, tt_num_entries);
return NET_RX_SUCCESS;
}
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index bd95d61..ff53933 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -107,6 +107,32 @@ struct batadv_frag_list_entry {
};
/**
+ * struct batadv_vlan_tt - VLAN specific TT attributes
+ * @crc: CRC32 checksum of the entries belonging to this vlan
+ * @num_entries: number of TT entries for this VLAN
+ */
+struct batadv_vlan_tt {
+ uint32_t crc;
+ atomic_t num_entries;
+};
+
+/**
+ * batadv_orig_node_vlan - VLAN specific data per orig_node
+ * @vid: the VLAN identifier
+ * @tt: VLAN specific TT attributes
+ * @list: list node for orig_node::vlan_list
+ * @refcount: number of context where this object is currently in use
+ * @rcu: struct used for freeing in a RCU-safe manner
+ */
+struct batadv_orig_node_vlan {
+ unsigned short vid;
+ struct batadv_vlan_tt tt;
+ struct list_head list;
+ atomic_t refcount;
+ struct rcu_head rcu;
+};
+
+/**
* struct batadv_orig_node - structure for orig_list maintaining nodes of mesh
* @orig: originator ethernet address
* @primary_addr: hosts primary interface address
@@ -120,12 +146,10 @@ struct batadv_frag_list_entry {
* @batman_seqno_reset: time when the batman seqno window was reset
* @capabilities: announced capabilities of this originator
* @last_ttvn: last seen translation table version number
- * @tt_crc: CRC of the translation table
* @tt_buff: last tt changeset this node received from the orig node
* @tt_buff_len: length of the last tt changeset this node received from the
* orig node
* @tt_buff_lock: lock that protects tt_buff and tt_buff_len
- * @tt_size: number of global TT entries announced by the orig node
* @tt_initialised: bool keeping track of whether or not this node have received
* any translation table information from the orig node yet
* @tt_lock: prevents from updating the table while reading it. Table update is
@@ -154,6 +178,9 @@ struct batadv_frag_list_entry {
* @in_coding_list_lock: protects in_coding_list
* @out_coding_list_lock: protects out_coding_list
* @fragments: array with heads for fragment chains
+ * @vlan_list: a list of orig_node_vlan structs, one per VLAN served by the
+ * originator represented by this object
+ * @vlan_list_lock: lock protecting vlan_list
*/
struct batadv_orig_node {
uint8_t orig[ETH_ALEN];
@@ -169,11 +196,9 @@ struct batadv_orig_node {
unsigned long batman_seqno_reset;
uint8_t capabilities;
atomic_t last_ttvn;
- uint32_t tt_crc;
unsigned char *tt_buff;
int16_t tt_buff_len;
spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */
- atomic_t tt_size;
bool tt_initialised;
/* prevents from changing the table while reading it */
spinlock_t tt_lock;
@@ -203,6 +228,8 @@ struct batadv_orig_node {
spinlock_t out_coding_list_lock; /* Protects out_coding_list */
#endif
struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT];
+ struct list_head vlan_list;
+ spinlock_t vlan_list_lock; /* protects vlan_list */
};
/**
@@ -389,8 +416,6 @@ enum batadv_counters {
* @changes_list_lock: lock protecting changes_list
* @req_list_lock: lock protecting req_list
* @roam_list_lock: lock protecting roam_list
- * @local_entry_num: number of entries in the local hash table
- * @local_crc: Checksum of the local table, recomputed before sending a new OGM
* @last_changeset: last tt changeset this host has generated
* @last_changeset_len: length of last tt changeset this host has generated
* @last_changeset_lock: lock protecting last_changeset & last_changeset_len
@@ -413,8 +438,6 @@ struct batadv_priv_tt {
spinlock_t changes_list_lock; /* protects changes */
spinlock_t req_list_lock; /* protects req_list */
spinlock_t roam_list_lock; /* protects roam_list */
- atomic_t local_entry_num;
- uint32_t local_crc;
unsigned char *last_changeset;
int16_t last_changeset_len;
/* protects last_changeset & last_changeset_len */
@@ -548,6 +571,7 @@ struct batadv_priv_nc {
* @vid: VLAN identifier
* @kobj: kobject for sysfs vlan subdirectory
* @ap_isolation: AP isolation state
+ * @tt: TT private attributes (VLAN specific)
* @list: list node for bat_priv::softif_vlan_list
* @refcount: number of context where this object is currently in use
* @rcu: struct used for freeing in a RCU-safe manner
@@ -556,6 +580,7 @@ struct batadv_softif_vlan {
unsigned short vid;
struct kobject *kobj;
atomic_t ap_isolation; /* boolean */
+ struct batadv_vlan_tt tt;
struct hlist_node list;
atomic_t refcount;
struct rcu_head rcu;
--
1.8.4
^ permalink raw reply related
* [PATCH 15/18] batman-adv: lock around TT operations to avoid sending inconsistent data
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
A TT response may be prepared and sent while the local or
global translation table is getting updated.
The worst case is when one of the tables is accessed after
its content has been recently updated but the metadata
(TTVN/CRC) has not yet. In this case the reader will get a
table content which does not match the TTVN/CRC.
This will lead to an inconsistent state and so to a TT
recovery.
To avoid entering this situation, put a lock around those TT
operations recomputing the metadata and around the TT
Response creation (the latter is the only reader that
accesses the metadata together with the table).
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/main.c | 1 +
net/batman-adv/originator.c | 1 +
net/batman-adv/translation-table.c | 37 ++++++++++++++++++++++++++-----------
net/batman-adv/types.h | 13 +++++++++++++
4 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 2207551..3159a14 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -110,6 +110,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->tt.req_list_lock);
spin_lock_init(&bat_priv->tt.roam_list_lock);
spin_lock_init(&bat_priv->tt.last_changeset_lock);
+ spin_lock_init(&bat_priv->tt.commit_lock);
spin_lock_init(&bat_priv->gw.list_lock);
spin_lock_init(&bat_priv->tvlv.container_list_lock);
spin_lock_init(&bat_priv->tvlv.handler_list_lock);
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index a591dc5..867778e 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -239,6 +239,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
spin_lock_init(&orig_node->bcast_seqno_lock);
spin_lock_init(&orig_node->neigh_list_lock);
spin_lock_init(&orig_node->tt_buff_lock);
+ spin_lock_init(&orig_node->tt_lock);
batadv_nc_init_orig(orig_node);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 58794c4..00f4faa 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -2019,6 +2019,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
req_src, tt_data->ttvn,
(tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
+ spin_lock_bh(&bat_priv->tt.commit_lock);
my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
req_ttvn = tt_data->ttvn;
@@ -2091,6 +2092,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
unlock:
spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
out:
+ spin_unlock_bh(&bat_priv->tt.commit_lock);
if (orig_node)
batadv_orig_node_free_ref(orig_node);
if (primary_if)
@@ -2259,6 +2261,8 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
if (!orig_node)
goto out;
+ spin_lock_bh(&orig_node->tt_lock);
+
if (tt_data->flags & BATADV_TT_FULL_TABLE) {
batadv_tt_fill_gtable(bat_priv, tt_data, resp_src, num_entries);
} else {
@@ -2267,18 +2271,20 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
tt_data->ttvn, tt_change);
}
- /* Delete the tt_req_node from pending tt_requests list */
- spin_lock_bh(&bat_priv->tt.req_list_lock);
- list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
- if (!batadv_compare_eth(node->addr, resp_src))
- continue;
- list_del(&node->list);
- kfree(node);
- }
- spin_unlock_bh(&bat_priv->tt.req_list_lock);
-
/* Recalculate the CRC for this orig_node and store it */
orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
+
+ spin_unlock_bh(&orig_node->tt_lock);
+
+ /* Delete the tt_req_node from pending tt_requests list */
+ spin_lock_bh(&bat_priv->tt.req_list_lock);
+ list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
+ if (!batadv_compare_eth(node->addr, resp_src))
+ continue;
+ list_del(&node->list);
+ kfree(node);
+ }
+ spin_unlock_bh(&bat_priv->tt.req_list_lock);
out:
if (orig_node)
batadv_orig_node_free_ref(orig_node);
@@ -2532,10 +2538,12 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
{
uint16_t changed_num = 0;
+ spin_lock_bh(&bat_priv->tt.commit_lock);
+
if (atomic_read(&bat_priv->tt.local_changes) < 1) {
if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
batadv_tt_tvlv_container_update(bat_priv);
- return;
+ goto out;
}
changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
@@ -2555,6 +2563,9 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
/* reset the sending counter */
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
batadv_tt_tvlv_container_update(bat_priv);
+
+out:
+ spin_unlock_bh(&bat_priv->tt.commit_lock);
}
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
@@ -2631,6 +2642,8 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
goto request_table;
}
+ spin_lock_bh(&orig_node->tt_lock);
+
tt_change = (struct batadv_tvlv_tt_change *)tt_buff;
batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
ttvn, tt_change);
@@ -2641,6 +2654,8 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
*/
orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
+ spin_unlock_bh(&orig_node->tt_lock);
+
/* The ttvn alone is not enough to guarantee consistency
* because a single value could represent different states
* (due to the wrap around). Thus a node has to check whether
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 04a0da6..bd95d61 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -128,6 +128,10 @@ struct batadv_frag_list_entry {
* @tt_size: number of global TT entries announced by the orig node
* @tt_initialised: bool keeping track of whether or not this node have received
* any translation table information from the orig node yet
+ * @tt_lock: prevents from updating the table while reading it. Table update is
+ * made up by two operations (data structure update and metdata -CRC/TTVN-
+ * recalculation) and they have to be executed atomically in order to avoid
+ * another thread to read the table/metadata between those.
* @last_real_seqno: last and best known sequence number
* @last_ttl: ttl of last received packet
* @bcast_bits: bitfield containing the info which payload broadcast originated
@@ -171,6 +175,8 @@ struct batadv_orig_node {
spinlock_t tt_buff_lock; /* protects tt_buff & tt_buff_len */
atomic_t tt_size;
bool tt_initialised;
+ /* prevents from changing the table while reading it */
+ spinlock_t tt_lock;
uint32_t last_real_seqno;
uint8_t last_ttl;
DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
@@ -388,6 +394,11 @@ enum batadv_counters {
* @last_changeset: last tt changeset this host has generated
* @last_changeset_len: length of last tt changeset this host has generated
* @last_changeset_lock: lock protecting last_changeset & last_changeset_len
+ * @commit_lock: prevents from executing a local TT commit while reading the
+ * local table. The local TT commit is made up by two operations (data
+ * structure update and metdata -CRC/TTVN- recalculation) and they have to be
+ * executed atomically in order to avoid another thread to read the
+ * table/metadata between those.
* @work: work queue callback item for translation table purging
*/
struct batadv_priv_tt {
@@ -408,6 +419,8 @@ struct batadv_priv_tt {
int16_t last_changeset_len;
/* protects last_changeset & last_changeset_len */
spinlock_t last_changeset_lock;
+ /* prevents from executing a commit while reading the table */
+ spinlock_t commit_lock;
struct delayed_work work;
};
--
1.8.4
^ permalink raw reply related
* [PATCH 14/18] batman-adv: remove bogus comment
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
this comment refers to the old batmand codebase and does
not make sense anymore. Remove it
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/gateway_client.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 4ed410f..20fa053 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -221,11 +221,6 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
struct batadv_neigh_node *router = NULL;
char gw_addr[18] = { '\0' };
- /* The batman daemon checks here if we already passed a full originator
- * cycle in order to make sure we don't choose the first gateway we
- * hear about. This check is based on the daemon's uptime which we
- * don't have.
- */
if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
goto out;
--
1.8.4
^ permalink raw reply related
* [PATCH 11/18] batman-adv: add sysfs framework for VLAN
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
Each VLAN can now have its own set of attributes which are
exported through a new subfolder in the sysfs tree.
Each VLAN created on top of a soft_iface will have its own
subfolder.
The subfolder is named "vlan%VID" and it is created inside
the "mesh" sysfs folder belonging to batman-adv.
Attributes corresponding to the untagged LAN are stored in
the root sysfs folder as before.
This patch also creates all the needed macros and data
structures to easily handle new VLAN spacific attributes.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
net/batman-adv/soft-interface.c | 15 +++-
net/batman-adv/soft-interface.h | 3 +
net/batman-adv/sysfs.c | 173 ++++++++++++++++++++++++++++++++++++++++
net/batman-adv/sysfs.h | 10 +++
4 files changed, 198 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 936b83b..f74200c 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -398,7 +398,7 @@ out:
* possibly free it
* @softif_vlan: the vlan object to release
*/
-static void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
+void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
{
if (atomic_dec_and_test(&softif_vlan->refcount))
kfree_rcu(softif_vlan, rcu);
@@ -412,8 +412,8 @@ static void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
* Returns the private data of the vlan matching the vid passed as argument or
* NULL otherwise. The refcounter of the returned object is incremented by 1.
*/
-static struct batadv_softif_vlan *
-batadv_softif_vlan_get(struct batadv_priv *bat_priv, unsigned short vid)
+struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
+ unsigned short vid)
{
struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
@@ -443,6 +443,7 @@ batadv_softif_vlan_get(struct batadv_priv *bat_priv, unsigned short vid)
int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
{
struct batadv_softif_vlan *vlan;
+ int err;
vlan = batadv_softif_vlan_get(bat_priv, vid);
if (vlan) {
@@ -457,6 +458,12 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
vlan->vid = vid;
atomic_set(&vlan->refcount, 1);
+ err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
+ if (err) {
+ kfree(vlan);
+ return err;
+ }
+
/* add a new TT local entry. This one will be marked with the NOPURGE
* flag
*/
@@ -483,6 +490,8 @@ static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
hlist_del_rcu(&vlan->list);
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+ batadv_sysfs_del_vlan(bat_priv, vlan);
+
/* explicitly remove the associated TT local entry because it is marked
* with the NOPURGE flag
*/
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index 16d9be6..06fc91f 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -29,5 +29,8 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface);
int batadv_softif_is_valid(const struct net_device *net_dev);
extern struct rtnl_link_ops batadv_link_ops;
int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
+void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan);
+struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
+ unsigned short vid);
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 869eb46..f419d21 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -24,6 +24,7 @@
#include "network-coding.h"
#include "originator.h"
#include "hard-interface.h"
+#include "soft-interface.h"
#include "gateway_common.h"
#include "gateway_client.h"
@@ -39,6 +40,53 @@ static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
return netdev_priv(net_dev);
}
+/**
+ * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
+ * @obj: kobject to covert
+ *
+ * Returns the associated batadv_priv struct.
+ */
+static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
+{
+ /* VLAN specific attributes are located in the root sysfs folder if they
+ * refer to the untagged VLAN..
+ */
+ if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
+ return batadv_kobj_to_batpriv(obj);
+
+ /* ..while the attributes for the tagged vlans are located in
+ * the in the corresponding "vlan%VID" subfolder
+ */
+ return batadv_kobj_to_batpriv(obj->parent);
+}
+
+/**
+ * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct
+ * @obj: kobject to covert
+ *
+ * Returns the associated softif_vlan struct if found, NULL otherwise.
+ */
+static struct batadv_softif_vlan *
+batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
+{
+ struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
+ if (vlan_tmp->kobj != obj)
+ continue;
+
+ if (!atomic_inc_not_zero(&vlan_tmp->refcount))
+ continue;
+
+ vlan = vlan_tmp;
+ break;
+ }
+ rcu_read_unlock();
+
+ return vlan;
+}
+
#define BATADV_UEV_TYPE_VAR "BATTYPE="
#define BATADV_UEV_ACTION_VAR "BATACTION="
#define BATADV_UEV_DATA_VAR "BATDATA="
@@ -53,6 +101,15 @@ static char *batadv_uev_type_str[] = {
"gw"
};
+/* Use this, if you have customized show and store functions for vlan attrs */
+#define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \
+struct batadv_attribute batadv_attr_vlan_##_name = { \
+ .attr = {.name = __stringify(_name), \
+ .mode = _mode }, \
+ .show = _show, \
+ .store = _store, \
+};
+
/* Use this, if you have customized show and store functions */
#define BATADV_ATTR(_name, _mode, _show, _store) \
struct batadv_attribute batadv_attr_##_name = { \
@@ -122,6 +179,41 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
batadv_store_##_name)
+#define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
+ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
+ struct attribute *attr, char *buff, \
+ size_t count) \
+{ \
+ struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
+ struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
+ kobj); \
+ size_t res = __batadv_store_bool_attr(buff, count, _post_func, \
+ attr, &vlan->_name, \
+ bat_priv->soft_iface); \
+ batadv_softif_vlan_free_ref(vlan); \
+ return res; \
+}
+
+#define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
+ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
+ struct attribute *attr, char *buff) \
+{ \
+ struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
+ struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
+ kobj); \
+ size_t res = sprintf(buff, "%s\n", \
+ atomic_read(&vlan->_name) == 0 ? \
+ "disabled" : "enabled"); \
+ batadv_softif_vlan_free_ref(vlan); \
+ return res; \
+}
+
+/* Use this, if you are going to turn a [name] in the vlan struct on or off */
+#define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \
+ static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
+ static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
+ static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
+ batadv_store_vlan_##_name)
static int batadv_store_bool_attr(char *buff, size_t count,
struct net_device *net_dev,
@@ -407,6 +499,13 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
NULL,
};
+/**
+ * batadv_vlan_attrs - array of vlan specific sysfs attributes
+ */
+static struct batadv_attribute *batadv_vlan_attrs[] = {
+ NULL,
+};
+
int batadv_sysfs_add_meshif(struct net_device *dev)
{
struct kobject *batif_kobject = &dev->dev.kobj;
@@ -457,6 +556,80 @@ void batadv_sysfs_del_meshif(struct net_device *dev)
bat_priv->mesh_obj = NULL;
}
+/**
+ * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
+ * @dev: netdev of the mesh interface
+ * @vlan: private data of the newly added VLAN interface
+ *
+ * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
+ */
+int batadv_sysfs_add_vlan(struct net_device *dev,
+ struct batadv_softif_vlan *vlan)
+{
+ char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
+ struct batadv_priv *bat_priv = netdev_priv(dev);
+ struct batadv_attribute **bat_attr;
+ int err;
+
+ if (vlan->vid & BATADV_VLAN_HAS_TAG) {
+ sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
+ vlan->vid & VLAN_VID_MASK);
+
+ vlan->kobj = kobject_create_and_add(vlan_subdir,
+ bat_priv->mesh_obj);
+ if (!vlan->kobj) {
+ batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
+ dev->name, vlan_subdir);
+ goto out;
+ }
+ } else {
+ /* the untagged LAN uses the root folder to store its "VLAN
+ * specific attributes"
+ */
+ vlan->kobj = bat_priv->mesh_obj;
+ kobject_get(bat_priv->mesh_obj);
+ }
+
+ for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
+ err = sysfs_create_file(vlan->kobj,
+ &((*bat_attr)->attr));
+ if (err) {
+ batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
+ dev->name, vlan_subdir,
+ ((*bat_attr)->attr).name);
+ goto rem_attr;
+ }
+ }
+
+ return 0;
+
+rem_attr:
+ for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
+ sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
+
+ kobject_put(vlan->kobj);
+ vlan->kobj = NULL;
+out:
+ return -ENOMEM;
+}
+
+/**
+ * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vlan: the private data of the VLAN to destroy
+ */
+void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
+ struct batadv_softif_vlan *vlan)
+{
+ struct batadv_attribute **bat_attr;
+
+ for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
+ sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
+
+ kobject_put(vlan->kobj);
+ vlan->kobj = NULL;
+}
+
static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
struct attribute *attr, char *buff)
{
diff --git a/net/batman-adv/sysfs.h b/net/batman-adv/sysfs.h
index 479acf4..c7d725d 100644
--- a/net/batman-adv/sysfs.h
+++ b/net/batman-adv/sysfs.h
@@ -22,6 +22,12 @@
#define BATADV_SYSFS_IF_MESH_SUBDIR "mesh"
#define BATADV_SYSFS_IF_BAT_SUBDIR "batman_adv"
+/**
+ * BATADV_SYSFS_VLAN_SUBDIR_PREFIX - prefix of the subfolder that will be
+ * created in the sysfs hierarchy for each VLAN interface. The subfolder will
+ * be named "BATADV_SYSFS_VLAN_SUBDIR_PREFIX%vid".
+ */
+#define BATADV_SYSFS_VLAN_SUBDIR_PREFIX "vlan"
struct batadv_attribute {
struct attribute attr;
@@ -36,6 +42,10 @@ void batadv_sysfs_del_meshif(struct net_device *dev);
int batadv_sysfs_add_hardif(struct kobject **hardif_obj,
struct net_device *dev);
void batadv_sysfs_del_hardif(struct kobject **hardif_obj);
+int batadv_sysfs_add_vlan(struct net_device *dev,
+ struct batadv_softif_vlan *vlan);
+void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
+ struct batadv_softif_vlan *vlan);
int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
enum batadv_uev_action action, const char *data);
--
1.8.4
^ permalink raw reply related
* [PATCH 12/18] batman-adv: make the AP isolation attribute VLAN specific
From: Antonio Quartulli @ 2013-10-19 22:22 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
In-Reply-To: <1382221330-3769-1-git-send-email-antonio@meshcoding.com>
From: Antonio Quartulli <antonio@open-mesh.com>
AP isolation has to be enabled on one VLAN interface only.
This patch moves the AP isolation attribute to the per-vlan
interface attribute set, enabling it to have a different
value depending on the selected vlan.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
Documentation/ABI/testing/sysfs-class-net-mesh | 5 +++--
net/batman-adv/soft-interface.c | 6 ++++--
net/batman-adv/sysfs.c | 5 +++--
net/batman-adv/translation-table.c | 27 +++++++++++++++++++-------
net/batman-adv/translation-table.h | 2 +-
net/batman-adv/types.h | 4 ++--
6 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index dfdea2b..0baa657 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -6,13 +6,14 @@ Description:
Indicates whether the batman protocol messages of the
mesh <mesh_iface> shall be aggregated or not.
-What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
+What: /sys/class/net/<mesh_iface>/mesh/<vlan_subdir>/ap_isolation
Date: May 2011
Contact: Antonio Quartulli <antonio@meshcoding.com>
Description:
Indicates whether the data traffic going from a
wireless client to another wireless client will be
- silently dropped.
+ silently dropped. <vlan_subdir> is empty when referring
+ to the untagged lan.
What: /sys/class/net/<mesh_iface>/mesh/bonding
Date: June 2010
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index f74200c..baa74b9 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -381,7 +381,8 @@ void batadv_interface_rx(struct net_device *soft_iface,
batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
ethhdr->h_source, vid);
- if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
+ if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest,
+ vid))
goto dropped;
netif_rx(skb);
@@ -458,6 +459,8 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
vlan->vid = vid;
atomic_set(&vlan->refcount, 1);
+ atomic_set(&vlan->ap_isolation, 0);
+
err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
if (err) {
kfree(vlan);
@@ -657,7 +660,6 @@ static int batadv_softif_init_late(struct net_device *dev)
#ifdef CONFIG_BATMAN_ADV_DAT
atomic_set(&bat_priv->distributed_arp_table, 1);
#endif
- atomic_set(&bat_priv->ap_isolation, 0);
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
atomic_set(&bat_priv->gw_sel_class, 20);
atomic_set(&bat_priv->gw.bandwidth_down, 100);
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index f419d21..6335433 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -453,7 +453,6 @@ BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
batadv_dat_status_update);
#endif
BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
-BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
batadv_store_gw_mode);
@@ -483,7 +482,6 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
&batadv_attr_distributed_arp_table,
#endif
&batadv_attr_fragmentation,
- &batadv_attr_ap_isolation,
&batadv_attr_routing_algo,
&batadv_attr_gw_mode,
&batadv_attr_orig_interval,
@@ -499,10 +497,13 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
NULL,
};
+BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
+
/**
* batadv_vlan_attrs - array of vlan specific sysfs attributes
*/
static struct batadv_attribute *batadv_vlan_attrs[] = {
+ &batadv_attr_vlan_ap_isolation,
NULL,
};
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 9bf928c..58794c4 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1482,8 +1482,19 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
struct batadv_tt_global_entry *tt_global_entry = NULL;
struct batadv_orig_node *orig_node = NULL;
struct batadv_tt_orig_list_entry *best_entry;
+ bool ap_isolation_enabled = false;
+ struct batadv_softif_vlan *vlan;
- if (src && atomic_read(&bat_priv->ap_isolation)) {
+ /* if the AP isolation is requested on a VLAN, then check for its
+ * setting in the proper VLAN private data structure
+ */
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+ if (vlan) {
+ ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
+ batadv_softif_vlan_free_ref(vlan);
+ }
+
+ if (src && ap_isolation_enabled) {
tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
if (!tt_local_entry ||
(tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
@@ -2547,22 +2558,22 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
}
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
- uint8_t *dst)
+ uint8_t *dst, unsigned short vid)
{
struct batadv_tt_local_entry *tt_local_entry = NULL;
struct batadv_tt_global_entry *tt_global_entry = NULL;
+ struct batadv_softif_vlan *vlan;
bool ret = false;
- if (!atomic_read(&bat_priv->ap_isolation))
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+ if (!vlan || !atomic_read(&vlan->ap_isolation))
goto out;
- tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst,
- BATADV_NO_FLAGS);
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
if (!tt_local_entry)
goto out;
- tt_global_entry = batadv_tt_global_hash_find(bat_priv, src,
- BATADV_NO_FLAGS);
+ tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
if (!tt_global_entry)
goto out;
@@ -2572,6 +2583,8 @@ bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
ret = true;
out:
+ if (vlan)
+ batadv_softif_vlan_free_ref(vlan);
if (tt_global_entry)
batadv_tt_global_entry_free_ref(tt_global_entry);
if (tt_local_entry)
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 1d9506d..c6bf33c 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -39,7 +39,7 @@ void batadv_tt_free(struct batadv_priv *bat_priv);
bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
unsigned short vid);
bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
- uint8_t *dst);
+ uint8_t *dst, unsigned short vid);
void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv);
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
uint8_t *addr, unsigned short vid);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index e5fecd4..04a0da6 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -534,6 +534,7 @@ struct batadv_priv_nc {
* struct batadv_softif_vlan - per VLAN attributes set
* @vid: VLAN identifier
* @kobj: kobject for sysfs vlan subdirectory
+ * @ap_isolation: AP isolation state
* @list: list node for bat_priv::softif_vlan_list
* @refcount: number of context where this object is currently in use
* @rcu: struct used for freeing in a RCU-safe manner
@@ -541,6 +542,7 @@ struct batadv_priv_nc {
struct batadv_softif_vlan {
unsigned short vid;
struct kobject *kobj;
+ atomic_t ap_isolation; /* boolean */
struct hlist_node list;
atomic_t refcount;
struct rcu_head rcu;
@@ -556,7 +558,6 @@ struct batadv_softif_vlan {
* @bonding: bool indicating whether traffic bonding is enabled
* @fragmentation: bool indicating whether traffic fragmentation is enabled
* @frag_seqno: incremental counter to identify chains of egress fragments
- * @ap_isolation: bool indicating whether ap isolation is enabled
* @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is
* enabled
* @distributed_arp_table: bool indicating whether distributed ARP table is
@@ -603,7 +604,6 @@ struct batadv_priv {
atomic_t bonding;
atomic_t fragmentation;
atomic_t frag_seqno;
- atomic_t ap_isolation;
#ifdef CONFIG_BATMAN_ADV_BLA
atomic_t bridge_loop_avoidance;
#endif
--
1.8.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox