Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] bgmac: omit the fcs
From: Hauke Mehrtens @ 2013-02-28 18:13 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: davem, netdev
In-Reply-To: <CACna6rw6MR3agrDvz0+X7ne6uSNQN0tpZupeM5c-6xy5-pvv2Q@mail.gmail.com>

On 02/28/2013 06:57 PM, Rafał Miłecki wrote:
> 2013/2/28 Hauke Mehrtens <hauke@hauke-m.de>:
>> Do not include the frame check sequence when adding the skb to
>> netif_receive_skb(). This causes problems when this interface was
>> bridged to a wifi ap and a big package should be forwarded from this
>> Ethernet driver through a bride to the wifi client.
> 
> Is this a real fix?
> 
> Don't get me wrong, but it sounds a little like a workaround for some
> issue in another network layer ;)
> 
Many drivers are doing similar things, b44 is one of them. Hopefully
someone more familiar with the network stack could say if this is the
right way to do this.

On a wireless client I saw that all packages directly from my router did
not had a FCS, but all the packages send from an other LAN client which
went through this driver had a FCS and where 4 bytes bigger and this FCS
was wrong.

Hauke

^ permalink raw reply

* Re: [PATCH v6 04/46] percpu_rwlock: Implement the core design of Per-CPU Reader-Writer Locks
From: Oleg Nesterov @ 2013-02-28 18:20 UTC (permalink / raw)
  To: Michel Lespinasse
  Cc: Srivatsa S. Bhat, Lai Jiangshan, linux-doc, peterz, fweisbec,
	linux-kernel, namhyung, mingo, linux-arch, linux, xiaoguangrong,
	wangyun, paulmck, nikunj, linux-pm, rusty, rostedt, rjw,
	vincent.guittot, tglx, linux-arm-kernel, netdev, sbw, tj, akpm,
	linuxppc-dev
In-Reply-To: <20130228180007.GA3537@redhat.com>

On 02/28, Oleg Nesterov wrote:
> On 02/28, Michel Lespinasse wrote:
> >
> > On Thu, Feb 28, 2013 at 3:25 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> > > On 02/27, Michel Lespinasse wrote:
> > >>
> > >> +void lg_rwlock_local_read_lock(struct lgrwlock *lgrw)
> > >> +{
> > >> +       preempt_disable();
> > >> +
> > >> +       if (__this_cpu_read(*lgrw->local_refcnt) ||
> > >> +           arch_spin_trylock(this_cpu_ptr(lgrw->lglock->lock))) {
> > >> +               __this_cpu_inc(*lgrw->local_refcnt);
> > >
> > > Please look at __this_cpu_generic_to_op(). You need this_cpu_inc()
> > > to avoid the race with irs. The same for _read_unlock.
> >
> > Hmmm, I was thinking that this was safe because while interrupts might
> > modify local_refcnt to acquire a nested read lock, they are expected
> > to release that lock as well which would set local_refcnt back to its
> > original value ???
>
> Yes, yes, this is correct.
>
> I meant that (in general, x86 is fine) __this_cpu_inc() itself is not
> irq-safe. It simply does "pcp += 1".
>
> this_cpu_inc() is fine, _this_cpu_generic_to_op() does cli/sti around.

Just in case, it is not that I really understand why __this_cpu_inc() can
race with irq in this particular case (given that irq handler should
restore the counter).

So perhaps I am wrong again. The comments in include/linux/percpu.h look
confusing to me, and I simply know nothing about !x86 architectures. But
since, say, preempt_disable() doesn't do anything special then probably
__this_cpu_inc() is fine too.

In short: please ignore me ;)

Oleg.

^ permalink raw reply

* RE: hv_netvsc: WARNING in softirq.c
From: Haiyang Zhang @ 2013-02-28 18:33 UTC (permalink / raw)
  To: Richard GENOUD, KY Srinivasan
  Cc: devel@linuxdriverproject.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20130228083437.GA28143@lnx-rg>



> -----Original Message-----
> From: Richard GENOUD [mailto:richard.genoud@gmail.com]
> Sent: Thursday, February 28, 2013 3:35 AM
> To: KY Srinivasan
> Cc: Haiyang Zhang; devel@linuxdriverproject.org; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: hv_netvsc: WARNING in softirq.c
> 
> Hi,
> 
> Here is the kernel trace I got this morning (kern.log):
> Feb 27 22:32:59 devlabo kernel: [10688.187062] hv_vmbus: child device
> vmbus_0_8 unregistered
> Feb 27 22:34:37 devlabo kernel: [10688.187196] ------------[ cut here ]-----------
> -
> Feb 27 22:34:37 devlabo kernel: [10688.187203] WARNING: at /build/buildd-
> linux_3.2.35-2-amd64-v9djlH/linux-3.2.35/kernel/softirq.c:159
> _local_bh_enable_ip.isra.11+0x3d/0x88()
> Feb 27 22:34:37 devlabo kernel: [10688.187206] Hardware name: Virtual
> Machine
> Feb 27 22:34:37 devlabo kernel: [10688.187208] Modules linked in:
> des_generic ecb md4 hmac nls_utf8 cifs nfsd nfs nfs_acl auth_rpcgss fscache
> lockd sunrpc loop snd_pcm snd_page_alloc snd_timer snd joydev processor
> hid_hyperv crc32c_intel hid thermal_sys i2c_piix4 evdev button soundcore
> hv_utils i2c_core psmouse serio_raw pcspkr ext4 crc16 jbd2 mbcache
> sd_mod crc_t10dif hv_netvsc hv_storvsc sg sr_mod cdrom ata_generic
> floppy hv_vmbus ata_piix libata scsi_mod [last unloaded: scsi_wait_scan]
> Feb 27 22:34:37 devlabo kernel: [10688.187244] Pid: 0, comm: swapper/0 Not
> tainted 3.2.0-4-amd64 #1 Debian 3.2.35-2
> Feb 27 22:34:37 devlabo kernel: [10688.187246] Call Trace:
> Feb 27 22:34:37 devlabo kernel: [10688.187248]  <IRQ>  [<ffffffff81046a75>] ?
> warn_slowpath_common+0x78/0x8c
> Feb 27 22:34:37 devlabo kernel: [10688.187257]  [<ffffffff8104bf76>] ?
> _local_bh_enable_ip.isra.11+0x3d/0x88
> Feb 27 22:34:37 devlabo kernel: [10688.187262]  [<ffffffffa00a59b5>] ?
> rndis_filter_receive+0x236/0x259 [hv_netvsc]
> Feb 27 22:34:37 devlabo kernel: [10688.187267]  [<ffffffffa00a4e5f>] ?
> netvsc_channel_cb+0x37a/0x449 [hv_netvsc]
> Feb 27 22:34:37 devlabo kernel: [10688.187273]  [<ffffffffa006211b>] ?
> vmbus_on_event+0x91/0xdd [hv_vmbus]
> Feb 27 22:34:37 devlabo kernel: [10688.187277]  [<ffffffff812432d5>] ?
> add_interrupt_randomness+0x38/0x155
> Feb 27 22:34:37 devlabo kernel: [10688.187283]  [<ffffffff8104b89a>] ?
> tasklet_action+0x73/0xc2
> Feb 27 22:34:37 devlabo kernel: [10688.187287]  [<ffffffff8104c084>] ?
> __do_softirq+0xb9/0x177
> Feb 27 22:34:37 devlabo kernel: [10688.187292]  [<ffffffff8135426c>] ?
> call_softirq+0x1c/0x30
> Feb 27 22:34:37 devlabo kernel: [10688.187297]  [<ffffffff8100f8dd>] ?
> do_softirq+0x3c/0x7b
> Feb 27 22:34:37 devlabo kernel: [10688.187300]  [<ffffffff8104c2ec>] ?
> irq_exit+0x3c/0x9a
> Feb 27 22:34:37 devlabo kernel: [10688.187303]  [<ffffffff8100f60d>] ?
> do_IRQ+0x82/0x98
> Feb 27 22:34:37 devlabo kernel: [10688.187307]  [<ffffffff8134d32e>] ?
> common_interrupt+0x6e/0x6e
> Feb 27 22:34:37 devlabo kernel: [10688.187309]  <EOI>  [<ffffffff81065dbd>] ?
> timekeeping_get_ns+0xd/0x2a
> Feb 27 22:34:37 devlabo kernel: [10688.187317]  [<ffffffff8106bc20>] ?
> arch_local_irq_enable+0x4/0x8
> Feb 27 22:34:37 devlabo kernel: [10688.187321]  [<ffffffff8100d286>] ?
> cpu_idle+0xe8/0xf2
> Feb 27 22:34:37 devlabo kernel: [10688.187324]  [<ffffffff816abb33>] ?
> start_kernel+0x3b3/0x3be
> Feb 27 22:34:37 devlabo kernel: [10688.187328]  [<ffffffff816ab140>] ?
> early_idt_handlers+0x140/0x140
> Feb 27 22:34:37 devlabo kernel: [10688.187331]  [<ffffffff816ab3c4>] ?
> x86_64_start_kernel+0x104/0x111
> Feb 27 22:34:37 devlabo kernel: [10688.187333] ---[ end trace
> 39158641c6e4b495 ]---
> 
> and there was a lot of them :
> Feb 26 22:35:14 devlabo kernel: [37398.788119] ------------[ cut here ]-----------
> -
> Feb 26 22:35:14 devlabo kernel: [37398.788129] WARNING: at /build/buildd-
> linux_3.2.35-2-amd64-v9djlH/linux-3.2.35/kernel/softirq.c:159
> _local_bh_enable_ip.isra.11+0x3d/0x88()
> Feb 26 22:35:14 devlabo kernel: [37398.788132] Hardware name: Virtual
> Machine
> Feb 26 22:35:14 devlabo kernel: [37398.788133] Modules linked in: nfsd nfs
> nfs_acl auth_rpcgss lockd sunrpc des_generic ecb md4 hmac nls_utf8 cifs
> fscache loop snd_pcm snd_page_alloc snd_timer joydev crc32c_intel
> i2c_piix4 snd processor hid_hyperv hid hv_utils soundcore button
> thermal_sys pcspkr i2c_core psmouse evdev serio_raw ext4 crc16 jbd2
> mbcache sd_mod crc_t10dif hv_netvsc hv_storvsc sg sr_mod cdrom
> ata_generic ata_piix libata scsi_mod floppy hv_vmbus [last unloaded:
> scsi_wait_scan]
> Feb 26 22:35:14 devlabo kernel: [37398.788169] Pid: 0, comm: swapper/0 Not
> tainted 3.2.0-4-amd64 #1 Debian 3.2.35-2
> Feb 26 22:35:14 devlabo kernel: [37398.788171] Call Trace:
> Feb 26 22:35:14 devlabo kernel: [37398.788172]  <IRQ>  [<ffffffff81046a75>] ?
> warn_slowpath_common+0x78/0x8c
> Feb 26 22:35:14 devlabo kernel: [37398.788181]  [<ffffffff8104bf76>] ?
> _local_bh_enable_ip.isra.11+0x3d/0x88
> Feb 26 22:35:14 devlabo kernel: [37398.788186]  [<ffffffffa009e9b5>] ?
> rndis_filter_receive+0x236/0x259 [hv_netvsc]
> Feb 26 22:35:14 devlabo kernel: [37398.788190]  [<ffffffffa009de5f>] ?
> netvsc_channel_cb+0x37a/0x449 [hv_netvsc]
> Feb 26 22:35:14 devlabo kernel: [37398.788196]  [<ffffffffa000111b>] ?
> vmbus_on_event+0x91/0xdd [hv_vmbus]
> Feb 26 22:35:14 devlabo kernel: [37398.788200]  [<ffffffff8104b89a>] ?
> tasklet_action+0x73/0xc2
> Feb 26 22:35:14 devlabo kernel: [37398.788203]  [<ffffffff8104c084>] ?
> __do_softirq+0xb9/0x177
> Feb 26 22:35:14 devlabo kernel: [37398.788207]  [<ffffffff81061755>] ?
> run_posix_cpu_timers+0x23/0x346
> Feb 26 22:35:14 devlabo kernel: [37398.788211]  [<ffffffff8135426c>] ?
> call_softirq+0x1c/0x30
> Feb 26 22:35:14 devlabo kernel: [37398.788216]  [<ffffffff8100f8dd>] ?
> do_softirq+0x3c/0x7b
> Feb 26 22:35:14 devlabo kernel: [37398.788218]  [<ffffffff8104c2ec>] ?
> irq_exit+0x3c/0x9a
> Feb 26 22:35:14 devlabo kernel: [37398.788222]  [<ffffffff810241c8>] ?
> smp_apic_timer_interrupt+0x74/0x82
> Feb 26 22:35:14 devlabo kernel: [37398.788225]  [<ffffffff81352ade>] ?
> apic_timer_interrupt+0x6e/0x80
> Feb 26 22:35:14 devlabo kernel: [37398.788227]  <EOI>  [<ffffffff81013a17>] ?
> native_sched_clock+0x27/0x2f
> Feb 26 22:35:14 devlabo kernel: [37398.788233]  [<ffffffff8102b360>] ?
> native_safe_halt+0x2/0x3
> Feb 26 22:35:14 devlabo kernel: [37398.788236]  [<ffffffff81014508>] ?
> default_idle+0x47/0x7f
> Feb 26 22:35:14 devlabo kernel: [37398.788238]  [<ffffffff8100d24d>] ?
> cpu_idle+0xaf/0xf2
> Feb 26 22:35:14 devlabo kernel: [37398.788241]  [<ffffffff816abb33>] ?
> start_kernel+0x3b3/0x3be
> Feb 26 22:35:14 devlabo kernel: [37398.788244]  [<ffffffff816ab140>] ?
> early_idt_handlers+0x140/0x140
> Feb 26 22:35:14 devlabo kernel: [37398.788247]  [<ffffffff816ab3c4>] ?
> x86_64_start_kernel+0x104/0x111
> Feb 26 22:35:14 devlabo kernel: [37398.788249] ---[ end trace
> 8f3991272dc0c5cc ]---
> Feb 26 22:35:14 devlabo kernel: [37398.789256] hv_vmbus: child device
> vmbus_0_8 unregistered
> 
> Feb  3 22:31:55 devlabo kernel: [37819.617243] ------------[ cut here ]-----------
> -
> Feb  3 22:31:55 devlabo kernel: [37819.617253] WARNING: at /build/buildd-
> linux_3.2.35-2-amd64-v9djlH/linux-3.2.35/kernel/softirq.c:159
> _local_bh_enable_ip.isra.11+0x3d/0x88()
> Feb  3 22:31:55 devlabo kernel: [37819.617257] Hardware name: Virtual
> Machine
> Feb  3 22:31:55 devlabo kernel: [37819.617259] Modules linked in: nfsd nfs
> nfs_acl auth_rpcgss lockd sunrpc des_generic ecb md4 hmac nls_utf8 cifs
> fscache loop joydev snd_pcm hid_hyperv hid snd_page_alloc snd_timer snd
> hv_utils i2c_piix4 i2c_core soundcore processor psmouse crc32c_intel
> thermal_sys button pcspkr evdev serio_raw ext4 crc16 jbd2 mbcache
> sd_mod crc_t10dif hv_netvsc hv_storvsc sg sr_mod cdrom ata_generic
> hv_vmbus ata_piix floppy libata scsi_mod [last unloaded: scsi_wait_scan]
> Feb  3 22:31:55 devlabo kernel: [37819.617308] Pid: 0, comm: swapper/0 Not
> tainted 3.2.0-4-amd64 #1 Debian 3.2.35-2
> Feb  3 22:31:55 devlabo kernel: [37819.617311] Call Trace:
> Feb  3 22:31:55 devlabo kernel: [37819.617313]  <IRQ>  [<ffffffff81046a75>] ?
> warn_slowpath_common+0x78/0x8c
> Feb  3 22:31:55 devlabo kernel: [37819.617324]  [<ffffffff8104bf76>] ?
> _local_bh_enable_ip.isra.11+0x3d/0x88
> Feb  3 22:31:55 devlabo kernel: [37819.617331]  [<ffffffffa00a09b5>] ?
> rndis_filter_receive+0x236/0x259 [hv_netvsc]
> Feb  3 22:31:55 devlabo kernel: [37819.617339]  [<ffffffffa009fe5f>] ?
> netvsc_channel_cb+0x37a/0x449 [hv_netvsc]
> Feb  3 22:31:55 devlabo kernel: [37819.617347]  [<ffffffffa006211b>] ?
> vmbus_on_event+0x91/0xdd [hv_vmbus]
> Feb  3 22:31:55 devlabo kernel: [37819.617353]  [<ffffffff8104b89a>] ?
> tasklet_action+0x73/0xc2
> Feb  3 22:31:55 devlabo kernel: [37819.617357]  [<ffffffff8104c084>] ?
> __do_softirq+0xb9/0x177
> Feb  3 22:31:55 devlabo kernel: [37819.617362]  [<ffffffff81061755>] ?
> run_posix_cpu_timers+0x23/0x346
> Feb  3 22:31:55 devlabo kernel: [37819.617366]  [<ffffffff8104c350>] ?
> raise_softirq_irqoff+0x6/0x25
> Feb  3 22:31:55 devlabo kernel: [37819.617372]  [<ffffffff8135426c>] ?
> call_softirq+0x1c/0x30
> Feb  3 22:31:55 devlabo kernel: [37819.617378]  [<ffffffff8100f8dd>] ?
> do_softirq+0x3c/0x7b
> Feb  3 22:31:55 devlabo kernel: [37819.617382]  [<ffffffff8104c2ec>] ?
> irq_exit+0x3c/0x9a
> Feb  3 22:31:55 devlabo kernel: [37819.617387]  [<ffffffff810241c8>] ?
> smp_apic_timer_interrupt+0x74/0x82
> Feb  3 22:31:55 devlabo kernel: [37819.617391]  [<ffffffff81352ade>] ?
> apic_timer_interrupt+0x6e/0x80
> Feb  3 22:31:55 devlabo kernel: [37819.617394]  <EOI>  [<ffffffff81013a17>] ?
> native_sched_clock+0x27/0x2f
> Feb  3 22:31:55 devlabo kernel: [37819.617402]  [<ffffffff8102b360>] ?
> native_safe_halt+0x2/0x3
> Feb  3 22:31:55 devlabo kernel: [37819.617407]  [<ffffffff81014508>] ?
> default_idle+0x47/0x7f
> Feb  3 22:31:55 devlabo kernel: [37819.617411]  [<ffffffff8100d24d>] ?
> cpu_idle+0xaf/0xf2
> Feb  3 22:31:55 devlabo kernel: [37819.617415]  [<ffffffff816abb33>] ?
> start_kernel+0x3b3/0x3be
> Feb  3 22:31:55 devlabo kernel: [37819.617420]  [<ffffffff816ab140>] ?
> early_idt_handlers+0x140/0x140
> Feb  3 22:31:55 devlabo kernel: [37819.617424]  [<ffffffff816ab3c4>] ?
> x86_64_start_kernel+0x104/0x111
> Feb  3 22:31:55 devlabo kernel: [37819.617427] ---[ end trace
> a20acc0adc92e993 ]---
> Feb  3 22:31:55 devlabo kernel: [37819.618127] hv_vmbus: child device
> vmbus_0_8 unregistered
> 
> It does not happen every day, but quite often : 4 times in February
> I'll ask my sysadm if there's something special at 22h30 in the host,
> because it's always happening around this time.
> 
> Machine is debian wheezy (7) under windows server 2008 R2

We will look into this. And further info around the time will also be helpful.

Thanks,
- Haiyang

^ permalink raw reply

* [PATCH 1/1] net/phy: micrel: Disable asymmetric pause for KSZ9021
From: Vlastimil Kosar @ 2013-02-28 18:45 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Vlastimil Kosar

Phyter KSZ9021 has hardware bug. If asymmetric pause is enabled,
then it is necessary to disconnect and then reconnect the ethernet
cable to get the phyter working. The solution is to disable the
asymmetric pause.

Signed-off-by: Vlastimil Kosar <ikosar@fit.vutbr.cz>
---
 drivers/net/phy/micrel.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 2993444..abf7b61 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -257,8 +257,7 @@ static struct phy_driver ksphy_driver[] = {
 	.phy_id		= PHY_ID_KSZ9021,
 	.phy_id_mask	= 0x000ffffe,
 	.name		= "Micrel KSZ9021 Gigabit PHY",
-	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause),
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= kszphy_config_init,
 	.config_aneg	= genphy_config_aneg,
-- 
1.7.2.5

^ permalink raw reply related

* Re: [PATCH] bgmac: omit the fcs
From: David Miller @ 2013-02-28 19:21 UTC (permalink / raw)
  To: zajec5; +Cc: hauke, netdev
In-Reply-To: <CACna6rw6MR3agrDvz0+X7ne6uSNQN0tpZupeM5c-6xy5-pvv2Q@mail.gmail.com>

From: Rafał Miłecki <zajec5@gmail.com>
Date: Thu, 28 Feb 2013 18:57:03 +0100

> 2013/2/28 Hauke Mehrtens <hauke@hauke-m.de>:
>> Do not include the frame check sequence when adding the skb to
>> netif_receive_skb(). This causes problems when this interface was
>> bridged to a wifi ap and a big package should be forwarded from this
>> Ethernet driver through a bride to the wifi client.
> 
> Is this a real fix?
> 
> Don't get me wrong, but it sounds a little like a workaround for some
> issue in another network layer ;)

FCS should never be included in the SKB unless a specific debugging
configuration knob has enabled it.

Having the FCS there will screw up things like device provided partial
checksums (CHECKSUM_PARTIAL), which operate over the entire contents
of the packet starting at a particular offset, so if the FCS is there
we'll include it.

This change is therefore about as correct as can possibly be.

^ permalink raw reply

* Re: [PATCH net] tcp: Don't collapse if resulting skb could overflow skb->csum_start
From: Thomas Graf @ 2013-02-28 19:23 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, netdev, foraker1
In-Reply-To: <1362073254.15793.43.camel@edumazet-glaptop>

On 02/28/13 at 09:40am, Eric Dumazet wrote:
> On Thu, 2013-02-28 at 09:35 -0800, Eric Dumazet wrote:
> > This had a followup with 22b4a4f22da4
> > (tcp: fix retransmit of partially acked frames)
> > 
> > I also wonder if there is not another similar potential problem in
> > __tcp_retransmit_skb) after call to 
> > 
> > tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq)
> > 
> > csum_start can overflow again because of MAX_TCP_HEADER headroom
> > reserve.
> > 
> > So maybe we should limit TCP MTU to (64K - MAX_TCP_HEADER)
> > 
> 
> Or adapt the test at line 2390 in net/ipv4/tcp_output.c
> 
> to force in the case there could be an overflow a :
> 
> struct sk_buff *nskb = __pskb_copy()
> 
> So that we have a new skb with minimal headroom.

I would favour the __pskb_copy() variant as that would be more
generic. I'll redo the patch.

^ permalink raw reply

* Re: [PATCH] bgmac: omit the fcs
From: Rafał Miłecki @ 2013-02-28 19:25 UTC (permalink / raw)
  To: David Miller; +Cc: hauke, netdev
In-Reply-To: <20130228.142142.242861205295035084.davem@davemloft.net>

2013/2/28 David Miller <davem@davemloft.net>:
> From: Rafał Miłecki <zajec5@gmail.com>
> Date: Thu, 28 Feb 2013 18:57:03 +0100
>
>> 2013/2/28 Hauke Mehrtens <hauke@hauke-m.de>:
>>> Do not include the frame check sequence when adding the skb to
>>> netif_receive_skb(). This causes problems when this interface was
>>> bridged to a wifi ap and a big package should be forwarded from this
>>> Ethernet driver through a bride to the wifi client.
>>
>> Is this a real fix?
>>
>> Don't get me wrong, but it sounds a little like a workaround for some
>> issue in another network layer ;)
>
> FCS should never be included in the SKB unless a specific debugging
> configuration knob has enabled it.
>
> Having the FCS there will screw up things like device provided partial
> checksums (CHECKSUM_PARTIAL), which operate over the entire contents
> of the packet starting at a particular offset, so if the FCS is there
> we'll include it.
>
> This change is therefore about as correct as can possibly be.

OK, thanks! :)

-- 
Rafał

^ permalink raw reply

* [PATCH net-next] generalize VXLAN forwarding tables
From: David L Stevens @ 2013-02-28 19:23 UTC (permalink / raw)
  To: David Miller, Stephen Hemminger; +Cc: netdev


This patch generalizes VXLAN forwarding table entries allowing an administrator
to:
	1) specify multiple destinations for a given MAC
	2) specify alternate vni's in the VXLAN header
	3) specify alternate destination UDP ports
	4) use multicast MAC addresses as fdb lookup keys
	5) specify multicast destinations
	6) specify the outgoing interface for forwarded packets

The combination allows configuration of more complex topologies using VXLAN
encapsulation.

Signed-Off-By: David L Stevens <dlstevens@us.ibm.com>

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 9d70421..bfcdac3 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -80,13 +80,22 @@ struct vxlan_net {
 	struct hlist_head vni_list[VNI_HASH_SIZE];
 };
 
+struct vxlan_rdst {
+	struct rcu_head		 rcu;
+	__be32			 remote_ip;
+	__be16			 remote_port;
+	u32			 remote_vni;
+	u32			 remote_ifindex;
+	struct vxlan_rdst	*remote_next;
+};
+
 /* Forwarding table entry */
 struct vxlan_fdb {
 	struct hlist_node hlist;	/* linked list of entries */
 	struct rcu_head	  rcu;
 	unsigned long	  updated;	/* jiffies */
 	unsigned long	  used;
-	__be32		  remote_ip;
+	struct vxlan_rdst remote;
 	u16		  state;	/* see ndm_state */
 	u8		  eth_addr[ETH_ALEN];
 };
@@ -157,7 +166,8 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id)
 /* Fill in neighbour message in skbuff. */
 static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 			   const struct vxlan_fdb *fdb,
-			   u32 portid, u32 seq, int type, unsigned int flags)
+			   u32 portid, u32 seq, int type, unsigned int flags,
+			   const struct vxlan_rdst *rdst)
 {
 	unsigned long now = jiffies;
 	struct nda_cacheinfo ci;
@@ -176,7 +186,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 
 	if (type == RTM_GETNEIGH) {
 		ndm->ndm_family	= AF_INET;
-		send_ip = fdb->remote_ip != 0;
+		send_ip = rdst->remote_ip != 0;
 		send_eth = !is_zero_ether_addr(fdb->eth_addr);
 	} else
 		ndm->ndm_family	= AF_BRIDGE;
@@ -188,7 +198,17 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 	if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
 		goto nla_put_failure;
 
-	if (send_ip && nla_put_be32(skb, NDA_DST, fdb->remote_ip))
+	if (send_ip && nla_put_be32(skb, NDA_DST, rdst->remote_ip))
+		goto nla_put_failure;
+
+	if (rdst->remote_port && rdst->remote_port != vxlan_port &&
+	    nla_put_be16(skb, NDA_PORT, rdst->remote_port))
+		goto nla_put_failure;
+	if (rdst->remote_vni != vxlan->vni &&
+	    nla_put_be32(skb, NDA_VNI, rdst->remote_vni))
+		goto nla_put_failure;
+	if (rdst->remote_ifindex &&
+	    nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex))
 		goto nla_put_failure;
 
 	ci.ndm_used	 = jiffies_to_clock_t(now - fdb->used);
@@ -211,6 +231,9 @@ static inline size_t vxlan_nlmsg_size(void)
 	return NLMSG_ALIGN(sizeof(struct ndmsg))
 		+ nla_total_size(ETH_ALEN) /* NDA_LLADDR */
 		+ nla_total_size(sizeof(__be32)) /* NDA_DST */
+		+ nla_total_size(sizeof(__be32)) /* NDA_PORT */
+		+ nla_total_size(sizeof(__be32)) /* NDA_VNI */
+		+ nla_total_size(sizeof(__u32)) /* NDA_IFINDEX */
 		+ nla_total_size(sizeof(struct nda_cacheinfo));
 }
 
@@ -225,7 +248,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
 	if (skb == NULL)
 		goto errout;
 
-	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0);
+	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, &fdb->remote);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -247,7 +270,8 @@ static void vxlan_ip_miss(struct net_device *dev, __be32 ipa)
 
 	memset(&f, 0, sizeof f);
 	f.state = NUD_STALE;
-	f.remote_ip = ipa; /* goes to NDA_DST */
+	f.remote.remote_ip = ipa; /* goes to NDA_DST */
+	f.remote.remote_vni = VXLAN_N_VID;
 
 	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
 }
@@ -301,10 +325,38 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
 	return NULL;
 }
 
+/* Add/update destinations for multicast */
+static int vxlan_fdb_append(struct vxlan_fdb *f,
+			    __be32 ip, __u32 port, __u32 vni, __u32 ifindex)
+{
+	struct vxlan_rdst *rd_prev, *rd;
+
+	rd_prev = NULL;
+	for (rd = &f->remote; rd; rd = rd->remote_next) {
+		if (rd->remote_ip == ip &&
+		    rd->remote_port == port &&
+		    rd->remote_vni == vni &&
+		    rd->remote_ifindex == ifindex)
+			return 0;
+		rd_prev = rd;
+	}
+	rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
+	if (rd == NULL)
+		return -ENOBUFS;
+	rd->remote_ip = ip;
+	rd->remote_port = port;
+	rd->remote_vni = vni;
+	rd->remote_ifindex = ifindex;
+	rd->remote_next = NULL;
+	rd_prev->remote_next = rd;
+	return 1;
+}
+
 /* Add new entry to forwarding table -- assumes lock held */
 static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			    const u8 *mac, __be32 ip,
-			    __u16 state, __u16 flags)
+			    __u16 state, __u16 flags,
+			    __u32 port, __u32 vni, __u32 ifindex)
 {
 	struct vxlan_fdb *f;
 	int notify = 0;
@@ -321,6 +373,14 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			f->updated = jiffies;
 			notify = 1;
 		}
+		if ((flags & NLM_F_APPEND) &&
+		    is_multicast_ether_addr(f->eth_addr)) {
+			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex);
+
+			if (rc < 0)
+				return rc;
+			notify |= rc;
+		}
 	} else {
 		if (!(flags & NLM_F_CREATE))
 			return -ENOENT;
@@ -334,7 +394,11 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			return -ENOMEM;
 
 		notify = 1;
-		f->remote_ip = ip;
+		f->remote.remote_ip = ip;
+		f->remote.remote_port = port;
+		f->remote.remote_vni = vni;
+		f->remote.remote_ifindex = ifindex;
+		f->remote.remote_next = NULL;
 		f->state = state;
 		f->updated = f->used = jiffies;
 		memcpy(f->eth_addr, mac, ETH_ALEN);
@@ -350,6 +414,19 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 	return 0;
 }
 
+void vxlan_fdb_free(struct rcu_head *head)
+{
+	struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
+
+	while (f->remote.remote_next) {
+		struct vxlan_rdst *rd = f->remote.remote_next;
+
+		f->remote.remote_next = rd->remote_next;
+		kfree(rd);
+	}
+	kfree(f);
+}
+
 static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
 {
 	netdev_dbg(vxlan->dev,
@@ -359,7 +436,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
 	vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH);
 
 	hlist_del_rcu(&f->hlist);
-	kfree_rcu(f, rcu);
+	call_rcu(&f->rcu, vxlan_fdb_free);
 }
 
 /* Add static entry (via netlink) */
@@ -368,7 +445,9 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 			 const unsigned char *addr, u16 flags)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct net *net = dev_net(vxlan->dev);
 	__be32 ip;
+	u32 port, vni, ifindex;
 	int err;
 
 	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
@@ -385,8 +464,36 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 
 	ip = nla_get_be32(tb[NDA_DST]);
 
+	if (tb[NDA_PORT]) {
+		if (nla_len(tb[NDA_PORT]) != sizeof(u32))
+			return -EINVAL;
+		port = nla_get_u32(tb[NDA_PORT]);
+	} else
+		port = vxlan_port;
+
+	if (tb[NDA_VNI]) {
+		if (nla_len(tb[NDA_VNI]) != sizeof(u32))
+			return -EINVAL;
+		vni = nla_get_u32(tb[NDA_VNI]);
+	} else
+		vni = vxlan->vni;
+
+	if (tb[NDA_IFINDEX]) {
+		struct net_device *dev;
+
+		if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
+			return -EINVAL;
+		ifindex = nla_get_u32(tb[NDA_IFINDEX]);
+		dev = dev_get_by_index(net, ifindex);
+		if (!dev)
+			return -EADDRNOTAVAIL;
+		dev_put(dev);
+	} else
+		ifindex = 0;
+
 	spin_lock_bh(&vxlan->hash_lock);
-	err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags);
+	err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags, port,
+		vni, ifindex);
 	spin_unlock_bh(&vxlan->hash_lock);
 
 	return err;
@@ -425,18 +532,21 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
 		int err;
 
 		hlist_for_each_entry_rcu(f, n, &vxlan->fdb_head[h], hlist) {
-			if (idx < cb->args[0])
-				goto skip;
-
-			err = vxlan_fdb_info(skb, vxlan, f,
-					     NETLINK_CB(cb->skb).portid,
-					     cb->nlh->nlmsg_seq,
-					     RTM_NEWNEIGH,
-					     NLM_F_MULTI);
-			if (err < 0)
-				break;
+			struct vxlan_rdst *rd;
+			for (rd = &f->remote; rd; rd = rd->remote_next) {
+				if (idx < cb->args[0])
+					goto skip;
+
+				err = vxlan_fdb_info(skb, vxlan, f,
+						     NETLINK_CB(cb->skb).portid,
+						     cb->nlh->nlmsg_seq,
+						     RTM_NEWNEIGH,
+						     NLM_F_MULTI, rd);
+				if (err < 0)
+					break;
 skip:
-			++idx;
+				++idx;
+			}
 		}
 	}
 
@@ -456,22 +566,23 @@ static void vxlan_snoop(struct net_device *dev,
 	f = vxlan_find_mac(vxlan, src_mac);
 	if (likely(f)) {
 		f->used = jiffies;
-		if (likely(f->remote_ip == src_ip))
+		if (likely(f->remote.remote_ip == src_ip))
 			return;
 
 		if (net_ratelimit())
 			netdev_info(dev,
 				    "%pM migrated from %pI4 to %pI4\n",
-				    src_mac, &f->remote_ip, &src_ip);
+				    src_mac, &f->remote.remote_ip, &src_ip);
 
-		f->remote_ip = src_ip;
+		f->remote.remote_ip = src_ip;
 		f->updated = jiffies;
 	} else {
 		/* learned new entry */
 		spin_lock(&vxlan->hash_lock);
 		err = vxlan_fdb_create(vxlan, src_mac, src_ip,
 				       NUD_REACHABLE,
-				       NLM_F_EXCL|NLM_F_CREATE);
+				       NLM_F_EXCL|NLM_F_CREATE,
+				       vxlan_port, vxlan->vni, 0);
 		spin_unlock(&vxlan->hash_lock);
 	}
 }
@@ -704,7 +815,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
 		}
 
 		f = vxlan_find_mac(vxlan, n->ha);
-		if (f && f->remote_ip == 0) {
+		if (f && f->remote.remote_ip == 0) {
 			/* bridge-local neighbor */
 			neigh_release(n);
 			goto out;
@@ -823,48 +934,27 @@ static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
 	return (((u64) hash * range) >> 32) + vxlan->port_min;
 }
 
-/* Transmit local packets over Vxlan
- *
- * Outer IP header inherits ECN and DF from inner header.
- * Outer UDP destination is the VXLAN assigned port.
- *           source port is based on hash of flow
- */
-static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+				  struct vxlan_rdst *rdst, bool did_rsc)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct rtable *rt;
 	const struct iphdr *old_iph;
-	struct ethhdr *eth;
 	struct iphdr *iph;
 	struct vxlanhdr *vxh;
 	struct udphdr *uh;
 	struct flowi4 fl4;
 	unsigned int pkt_len = skb->len;
 	__be32 dst;
-	__u16 src_port;
+	__u16 src_port, dst_port;
+	u32 vni;
 	__be16 df = 0;
 	__u8 tos, ttl;
 	int err;
-	bool did_rsc = false;
-	const struct vxlan_fdb *f;
-
-	skb_reset_mac_header(skb);
-	eth = eth_hdr(skb);
-
-	if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP)
-		return arp_reduce(dev, skb);
-	else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP)
-		did_rsc = route_shortcircuit(dev, skb);
 
-	f = vxlan_find_mac(vxlan, eth->h_dest);
-	if (f == NULL) {
-		did_rsc = false;
-		dst = vxlan->gaddr;
-		if (!dst && (vxlan->flags & VXLAN_F_L2MISS) &&
-		    !is_multicast_ether_addr(eth->h_dest))
-			vxlan_fdb_miss(vxlan, eth->h_dest);
-	} else
-		dst = f->remote_ip;
+	dst_port = rdst->remote_port ? rdst->remote_port : vxlan_port;
+	vni = rdst->remote_vni;
+	dst = rdst->remote_ip;
 
 	if (!dst) {
 		if (did_rsc) {
@@ -912,7 +1002,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 	src_port = vxlan_src_port(vxlan, skb);
 
 	memset(&fl4, 0, sizeof(fl4));
-	fl4.flowi4_oif = vxlan->link;
+	fl4.flowi4_oif = rdst->remote_ifindex;
 	fl4.flowi4_tos = RT_TOS(tos);
 	fl4.daddr = dst;
 	fl4.saddr = vxlan->saddr;
@@ -939,13 +1029,13 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
 	vxh->vx_flags = htonl(VXLAN_FLAGS);
-	vxh->vx_vni = htonl(vxlan->vni << 8);
+	vxh->vx_vni = htonl(vni << 8);
 
 	__skb_push(skb, sizeof(*uh));
 	skb_reset_transport_header(skb);
 	uh = udp_hdr(skb);
 
-	uh->dest = htons(vxlan_port);
+	uh->dest = htons(dst_port);
 	uh->source = htons(src_port);
 
 	uh->len = htons(skb->len);
@@ -995,6 +1085,64 @@ tx_free:
 	return NETDEV_TX_OK;
 }
 
+/* Transmit local packets over Vxlan
+ *
+ * Outer IP header inherits ECN and DF from inner header.
+ * Outer UDP destination is the VXLAN assigned port.
+ *           source port is based on hash of flow
+ */
+static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct ethhdr *eth;
+	bool did_rsc = false;
+	struct vxlan_rdst group, *rdst0, *rdst;
+	struct vxlan_fdb *f;
+	int rc1, rc;
+
+	skb_reset_mac_header(skb);
+	eth = eth_hdr(skb);
+
+	if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP)
+		return arp_reduce(dev, skb);
+	else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP)
+		did_rsc = route_shortcircuit(dev, skb);
+
+	f = vxlan_find_mac(vxlan, eth->h_dest);
+	if (f == NULL) {
+		did_rsc = false;
+		group.remote_port = vxlan_port;
+		group.remote_vni = vxlan->vni;
+		group.remote_ip = vxlan->gaddr;
+		group.remote_ifindex = vxlan->link;
+		group.remote_next = 0;
+		rdst0 = &group;
+
+		if (group.remote_ip == htonl(INADDR_ANY) &&
+		    (vxlan->flags & VXLAN_F_L2MISS) &&
+		    !is_multicast_ether_addr(eth->h_dest))
+			vxlan_fdb_miss(vxlan, eth->h_dest);
+	} else
+		rdst0 = &f->remote;
+
+	rc = NETDEV_TX_OK;
+
+	/* if there are multiple destinations, send copies */
+	for (rdst = rdst0->remote_next; rdst; rdst = rdst->remote_next) {
+		struct sk_buff *skb1;
+
+		skb1 = skb_clone(skb, GFP_ATOMIC);
+		rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
+		if (rc == NETDEV_TX_OK)
+			rc = rc1;
+	}
+
+	rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);
+	if (rc == NETDEV_TX_OK)
+		rc = rc1;
+	return rc;
+}
+
 /* Walk the forwarding table and purge stale entries */
 static void vxlan_cleanup(unsigned long arg)
 {
@@ -1548,6 +1696,7 @@ static void __exit vxlan_cleanup_module(void)
 {
 	rtnl_link_unregister(&vxlan_link_ops);
 	unregister_pernet_device(&vxlan_net_ops);
+	rcu_barrier();
 }
 module_exit(vxlan_cleanup_module);
 
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index adb068c..f175212 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -21,6 +21,9 @@ enum {
 	NDA_CACHEINFO,
 	NDA_PROBES,
 	NDA_VLAN,
+	NDA_PORT,
+	NDA_VNI,
+	NDA_IFINDEX,
 	__NDA_MAX
 };
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d8aa20f..75bc33c 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2080,7 +2080,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 	}
 
 	addr = nla_data(tb[NDA_LLADDR]);
-	if (!is_valid_ether_addr(addr)) {
+	if (is_zero_ether_addr(addr)) {
 		pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n");
 		return -EINVAL;
 	}

^ permalink raw reply related

* [PATCH iproute2] generalize VXLAN forwarding tables
From: David L Stevens @ 2013-02-28 19:26 UTC (permalink / raw)
  To: David Miller, Stephen Hemminger; +Cc: netdev


This is the iproute2 support allowing an administrator to specify alternate
ports, vnis and outgoing interfaces for VXLAN device forwarding tables.

Signed-Off-By: David L Stevens <dlstevens@us.ibm.com>

diff --git a/bridge/fdb.c b/bridge/fdb.c
index 4ca4861..ba4660b 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -9,6 +9,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <netdb.h>
 #include <time.h>
 #include <fcntl.h>
 #include <sys/socket.h>
@@ -29,7 +30,7 @@ int filter_index;
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: bridge fdb { add | del } ADDR dev DEV {self|master} [ temp ] [ dst IPADDR]\n");
+	fprintf(stderr, "Usage: bridge fdb { add | del } ADDR dev DEV {self|master} [ temp ] [ dst IPADDR] [port PORT] [vni VNI] [via DEV]\n");
 	fprintf(stderr, "       bridge fdb {show} [ dev DEV ]\n");
 	exit(-1);
 }
@@ -107,6 +108,23 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 				    abuf, sizeof(abuf)));
 	}
 
+	if (tb[NDA_PORT])
+		fprintf(fp, "port %d ", rta_getattr_u32(tb[NDA_PORT]));
+	if (tb[NDA_VNI])
+		fprintf(fp, "vni %d ", rta_getattr_u32(tb[NDA_VNI]));
+	if (tb[NDA_IFINDEX]) {
+		unsigned int ifindex = rta_getattr_u32(tb[NDA_IFINDEX]);
+
+		if (ifindex) {
+			char ifname[IF_NAMESIZE];
+
+			if (if_indextoname(ifindex, ifname))
+				fprintf(fp, "via %s ", ifname);
+			else
+				fprintf(fp, "via ifindex %u ", ifindex);
+		}
+	}
+
 	if (show_stats && tb[NDA_CACHEINFO]) {
 		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
 		int hz = get_user_hz();
@@ -171,6 +189,10 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 	char abuf[ETH_ALEN];
 	int dst_ok = 0;
 	inet_prefix dst;
+	unsigned long port = 0;
+	unsigned long vni = ~0;
+	unsigned int via = 0;
+	char *endptr;
 
 	memset(&req, 0, sizeof(req));
 
@@ -190,6 +212,29 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 				duparg2("dst", *argv);
 			get_addr(&dst, *argv, preferred_family);
 			dst_ok = 1;
+		} else if (strcmp(*argv, "port") == 0) {
+
+			NEXT_ARG();
+			port = strtoul(*argv, &endptr, 0);
+			if (endptr && *endptr) {
+				struct servent *pse;
+
+				pse = getservbyname(*argv, "udp");
+				if (!pse)
+					invarg("invalid port\n", *argv);
+			} else if (port > 0xffff)
+				invarg("invalid port\n", *argv);
+		} else if (strcmp(*argv, "vni") == 0) {
+			NEXT_ARG();
+			vni = strtoul(*argv, &endptr, 0);
+			if ((endptr && *endptr) ||
+			    (vni >> 24) || vni == ULONG_MAX)
+				invarg("invalid VNI\n", *argv);
+		} else if (strcmp(*argv, "via") == 0) {
+			NEXT_ARG();
+			via = if_nametoindex(*argv);
+			if (via == 0)
+				invarg("invalid device\n", *argv);
 		} else if (strcmp(*argv, "self") == 0) {
 			req.ndm.ndm_flags |= NTF_SELF;
 		} else if (matches(*argv, "master") == 0) {
@@ -236,6 +281,13 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 	if (dst_ok)
 		addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen);
 
+	if (port)
+		addattr32(&req.n, sizeof(req), NDA_PORT, port);
+	if (vni != ~0)
+		addattr32(&req.n, sizeof(req), NDA_VNI, vni);
+	if (via)
+		addattr32(&req.n, sizeof(req), NDA_IFINDEX, via);
+
 	req.ndm.ndm_ifindex = ll_name_to_index(d);
 	if (req.ndm.ndm_ifindex == 0) {
 		fprintf(stderr, "Cannot find device \"%s\"\n", d);
@@ -255,6 +307,8 @@ int do_fdb(int argc, char **argv)
 	if (argc > 0) {
 		if (matches(*argv, "add") == 0)
 			return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
+		if (matches(*argv, "append") == 0)
+			return fdb_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_APPEND, argc-1, argv+1);
 		if (matches(*argv, "delete") == 0)
 			return fdb_modify(RTM_DELNEIGH, 0, argc-1, argv+1);
 		if (matches(*argv, "show") == 0 ||
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h
index 275e5d6..f175212 100644
--- a/include/linux/neighbour.h
+++ b/include/linux/neighbour.h
@@ -20,6 +20,10 @@ enum {
 	NDA_LLADDR,
 	NDA_CACHEINFO,
 	NDA_PROBES,
+	NDA_VLAN,
+	NDA_PORT,
+	NDA_VNI,
+	NDA_IFINDEX,
 	__NDA_MAX
 };
 

^ permalink raw reply related

* [PATCHv2 iproute2 0/3] Bridge VLAN support
From: Vlad Yasevich @ 2013-02-28 20:04 UTC (permalink / raw)
  To: netdev; +Cc: shemminger

This series adds VLAN configuration to the bridge command.  With this
series, one can specify vlans in FDB entries as well as to configure
VLAN configuration on the bridge ports.

Since v1:
 - Rebased.
 - Call rtnl_wilddump_req_filter from rtnl_wilddump_request.  Preserve always
   setting the RTEXT_FILTER_VF filter.

Vlad Yasevich (3):
  bridge: Add vlan support to fdb entries
  bridge: Add vlan configuration support
  bridge: Update bridge man pages to include vlan command

 bridge/Makefile      |    2 +-
 bridge/br_common.h   |    1 +
 bridge/bridge.c      |    3 +-
 bridge/fdb.c         |   16 ++++-
 bridge/vlan.c        |  220 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/libnetlink.h |    2 +
 lib/libnetlink.c     |    8 ++-
 man/man8/bridge.8    |   73 ++++++++++++++++-
 8 files changed, 320 insertions(+), 5 deletions(-)
 create mode 100644 bridge/vlan.c

-- 
1.7.7.6

^ permalink raw reply

* [PATCHv2 iproute2 1/3] bridge: Add vlan support to fdb entries
From: Vlad Yasevich @ 2013-02-28 20:04 UTC (permalink / raw)
  To: netdev; +Cc: shemminger
In-Reply-To: <1362081846-25268-1-git-send-email-vyasevic@redhat.com>

Provide the ability to set and show vlans on FDB entries.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 bridge/fdb.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/bridge/fdb.c b/bridge/fdb.c
index 4ca4861..447045e 100644
--- a/bridge/fdb.c
+++ b/bridge/fdb.c
@@ -29,7 +29,7 @@ int filter_index;
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: bridge fdb { add | del } ADDR dev DEV {self|master} [ temp ] [ dst IPADDR]\n");
+	fprintf(stderr, "Usage: bridge fdb { add | del } ADDR dev DEV {self|master} [ temp ] [ dst IPADDR] [ vlan VID ]\n");
 	fprintf(stderr, "       bridge fdb {show} [ dev DEV ]\n");
 	exit(-1);
 }
@@ -107,6 +107,11 @@ int print_fdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 				    abuf, sizeof(abuf)));
 	}
 
+	if (tb[NDA_VLAN]) {
+		__u16 vid = rta_getattr_u16(tb[NDA_VLAN]);
+		fprintf(fp, "vlan %hu ", vid);
+	}
+
 	if (show_stats && tb[NDA_CACHEINFO]) {
 		struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
 		int hz = get_user_hz();
@@ -171,6 +176,7 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 	char abuf[ETH_ALEN];
 	int dst_ok = 0;
 	inet_prefix dst;
+	short vid = -1;
 
 	memset(&req, 0, sizeof(req));
 
@@ -199,6 +205,11 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 			req.ndm.ndm_state |= NUD_PERMANENT;
 		} else if (matches(*argv, "temp") == 0) {
 			req.ndm.ndm_state |= NUD_REACHABLE;
+		} else if (matches(*argv, "vlan") == 0) {
+			if (vid >= 0)
+				duparg2("vlan", *argv);
+			NEXT_ARG();
+			vid = atoi(*argv);
 		} else {
 			if (strcmp(*argv, "to") == 0) {
 				NEXT_ARG();
@@ -236,6 +247,9 @@ static int fdb_modify(int cmd, int flags, int argc, char **argv)
 	if (dst_ok)
 		addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen);
 
+	if (vid >= 0)
+		addattr16(&req.n, sizeof(req), NDA_VLAN, vid); 
+
 	req.ndm.ndm_ifindex = ll_name_to_index(d);
 	if (req.ndm.ndm_ifindex == 0) {
 		fprintf(stderr, "Cannot find device \"%s\"\n", d);
-- 
1.7.7.6

^ permalink raw reply related

* [PATCHv2 iproute2 2/3] bridge: Add vlan configuration support
From: Vlad Yasevich @ 2013-02-28 20:04 UTC (permalink / raw)
  To: netdev; +Cc: shemminger
In-Reply-To: <1362081846-25268-1-git-send-email-vyasevic@redhat.com>

Recent kernel patches added support for VLAN filtering on the bridge.
This functionality allows one to turn a basic bridge into a VLAN bridge,
where VLANs dicatate packet forwarding and header transformation.

To configure the VLANs on the bridge and its ports a new command is
added to the 'bridge' utility.

   # bridge vlan add dev eth0 vid 10 pvid untagged brdev
   # bridge vlan add
   # bridge vlan delete dev eth0 vid 10
   # bridge vlan show

This command supports the following flags:
   master - peform the operation on the software bridge device.  This is
	    the default behavior.
   self  -  perform the operation on the hardware associated with the port.
            This flag is required when the device is the bridge device and
	    the configuration is desired on the bridge device itself (not
	    one of the ports).
   pvid  -  Set the PVID (port vlan id) for a given port.  Any untagged
            frames arriving on the port will be assigned to this vlan.
   untagged - Sets the egress policy of for a given vlan.  Default port
            egress policy is tagged.  Set this flag if you wish traffic
            associated with this VLAN to exit the port untagged.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 bridge/Makefile      |    2 +-
 bridge/br_common.h   |    1 +
 bridge/bridge.c      |    3 +-
 bridge/vlan.c        |  220 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/libnetlink.h |    2 +
 lib/libnetlink.c     |    8 ++-
 6 files changed, 233 insertions(+), 3 deletions(-)
 create mode 100644 bridge/vlan.c

diff --git a/bridge/Makefile b/bridge/Makefile
index 67aceb4..1fb8320 100644
--- a/bridge/Makefile
+++ b/bridge/Makefile
@@ -1,4 +1,4 @@
-BROBJ = bridge.o fdb.o monitor.o link.o mdb.o
+BROBJ = bridge.o fdb.o monitor.o link.o mdb.o vlan.o
 
 include ../Config
 
diff --git a/bridge/br_common.h b/bridge/br_common.h
index 10f6ce9..8764563 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -9,6 +9,7 @@ extern int print_mdb(const struct sockaddr_nl *who,
 extern int do_fdb(int argc, char **argv);
 extern int do_mdb(int argc, char **argv);
 extern int do_monitor(int argc, char **argv);
+extern int do_vlan(int argc, char **argv);
 
 extern int preferred_family;
 extern int show_stats;
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 1d59a1e..06b7a54 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -27,7 +27,7 @@ static void usage(void)
 {
 	fprintf(stderr,
 "Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
-"where  OBJECT := { fdb |  mdb | monitor }\n"
+"where  OBJECT := { fdb | mdb | vlan | monitor }\n"
 "       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" );
 	exit(-1);
 }
@@ -44,6 +44,7 @@ static const struct cmd {
 } cmds[] = {
 	{ "fdb", 	do_fdb },
 	{ "mdb", 	do_mdb },
+	{ "vlan",	do_vlan },
 	{ "monitor",	do_monitor },
 	{ "help",	do_help },
 	{ 0 }
diff --git a/bridge/vlan.c b/bridge/vlan.c
new file mode 100644
index 0000000..83c4088
--- /dev/null
+++ b/bridge/vlan.c
@@ -0,0 +1,220 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <linux/if_bridge.h>
+#include <linux/if_ether.h>
+#include <string.h>
+
+#include "libnetlink.h"
+#include "br_common.h"
+#include "utils.h"
+
+int filter_index;
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
+	fprintf(stderr, "                                                     [ self ] [ master ]\n");
+	fprintf(stderr, "       bridge vlan { show } [ dev DEV ]\n");
+	exit(-1);
+}
+
+static int vlan_modify(int cmd, int argc, char **argv)
+{
+	struct {
+		struct nlmsghdr 	n;
+		struct ifinfomsg 	ifm;
+		char   			buf[1024];
+	} req;
+	char *d = NULL;
+	short vid = -1;
+	struct rtattr *afspec;
+	struct bridge_vlan_info vinfo;
+	unsigned short flags = 0;
+
+	memset(&vinfo, 0, sizeof(vinfo));
+	memset(&req, 0, sizeof(req));
+
+	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.n.nlmsg_flags = NLM_F_REQUEST;
+	req.n.nlmsg_type = cmd;
+	req.ifm.ifi_family = PF_BRIDGE;
+
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			d = *argv;
+		} else if (strcmp(*argv, "vid") == 0) {
+			NEXT_ARG();
+			vid = atoi(*argv);
+		} else if (strcmp(*argv, "self") == 0) {
+			flags |= BRIDGE_FLAGS_SELF;
+		} else if (strcmp(*argv, "master") == 0) {
+			flags |= BRIDGE_FLAGS_MASTER;
+		} else if (strcmp(*argv, "pvid") == 0) {
+			vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
+		} else if (strcmp(*argv, "untagged") == 0) {
+			vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
+		} else {
+			if (matches(*argv, "help") == 0) {
+				NEXT_ARG();
+			}
+		}
+		argc--; argv++;
+	}
+
+	if (d == NULL || vid == -1) {
+		fprintf(stderr, "Device and VLAN ID are required arguments.\n");
+		exit(-1);
+	}
+
+	req.ifm.ifi_index = ll_name_to_index(d);
+	if (req.ifm.ifi_index == 0) {
+		fprintf(stderr, "Cannot find bridge device \"%s\"\n", d);
+		return -1;
+	}
+
+	if (vid >= 4096) {
+		fprintf(stderr, "Invalid VLAN ID \"%hu\"\n", vid);
+		return -1;
+	}
+
+	vinfo.vid = vid;
+
+	afspec = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
+
+	if (flags)
+		addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);
+
+	addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
+		  sizeof(vinfo));
+
+	addattr_nest_end(&req.n, afspec);
+
+	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
+		exit(2);
+
+	return 0;
+}
+
+static int print_vlan(const struct sockaddr_nl *who,
+		      struct nlmsghdr *n,
+		      void *arg)
+{
+	FILE *fp = arg;
+	struct ifinfomsg *ifm = NLMSG_DATA(n);
+	int len = n->nlmsg_len;
+	struct rtattr * tb[IFLA_MAX+1];
+
+	if (n->nlmsg_type != RTM_NEWLINK) {
+		fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
+			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+		return 0;
+	}
+
+	len -= NLMSG_LENGTH(sizeof(*ifm));
+	if (len < 0) {
+		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+		return -1;
+	}
+
+	if (ifm->ifi_family != AF_BRIDGE)
+		return 0;
+
+	if (filter_index && filter_index != ifm->ifi_index)
+		return 0;
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len);
+
+	/* if AF_SPEC isn't there, vlan table is not preset for this port */
+	if (!tb[IFLA_AF_SPEC]) {
+		fprintf(fp, "%s\tNone\n", ll_index_to_name(ifm->ifi_index));
+		return 0;
+	} else {
+		struct rtattr *i, *list = tb[IFLA_AF_SPEC];
+		int rem = RTA_PAYLOAD(list);
+
+		fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
+		for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+			struct bridge_vlan_info *vinfo;
+
+			if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
+				continue;
+
+			vinfo = RTA_DATA(i);
+			fprintf(fp, "\t %hu", vinfo->vid);
+			if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
+				fprintf(fp, " PVID");
+			if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+				fprintf(fp, " Egress Untagged");
+			fprintf(fp, "\n");
+		}
+	}
+	fprintf(fp, "\n");
+	fflush(fp);
+	return 0;
+}
+
+static int vlan_show(int argc, char **argv)
+{
+	char *filter_dev = NULL;
+
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			if (filter_dev)
+				duparg("dev", *argv);
+			filter_dev = *argv;
+		}
+		argc--; argv++;
+	}
+
+	if (filter_dev) {
+		if ((filter_index = if_nametoindex(filter_dev)) == 0) {
+			fprintf(stderr, "Cannot find device \"%s\"\n",
+			       filter_dev);
+			return -1;
+		}
+	}
+
+	if (rtnl_wilddump_req_filter(&rth, PF_BRIDGE, RTM_GETLINK,
+				     RTEXT_FILTER_BRVLAN) < 0) {
+		perror("Cannont send dump request");
+		exit(1);
+	}
+
+	printf("port\tvlan ids\n");
+	if (rtnl_dump_filter(&rth, print_vlan, stdout) < 0) {
+		fprintf(stderr, "Dump ternminated\n");
+		exit(1);
+	}
+
+	return 0;
+}
+
+
+int do_vlan(int argc, char **argv)
+{
+	ll_init_map(&rth);
+
+	if (argc > 0) {
+		if (matches(*argv, "add") == 0)
+			return vlan_modify(RTM_SETLINK, argc-1, argv+1);
+		if (matches(*argv, "delete") == 0)
+			return vlan_modify(RTM_DELLINK, argc-1, argv+1);
+		if (matches(*argv, "show") == 0 ||
+		    matches(*argv, "lst") == 0 ||
+		    matches(*argv, "list") == 0)
+			return vlan_show(argc-1, argv+1);
+		if (matches(*argv, "help") == 0)
+			usage();
+	} else
+		return vlan_show(0, NULL);
+
+	fprintf(stderr, "Command \"%s\" is unknown, try \"bridge fdb help\".\n", *argv);
+	exit(-1);
+}
diff --git a/include/libnetlink.h b/include/libnetlink.h
index 41e6ed1..8d15ee5 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -26,6 +26,8 @@ extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
 extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol);
 extern void rtnl_close(struct rtnl_handle *rth);
 extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
+extern int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int fam, int type,
+				    __u32 filt_mask);
 extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
 
 typedef int (*rtnl_filter_t)(const struct sockaddr_nl *,
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 09b4277..67f046f 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -91,6 +91,12 @@ int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
 
 int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
 {
+	return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF);
+}
+
+int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int family, int type,
+			    __u32 filt_mask)
+{
 	struct {
 		struct nlmsghdr nlh;
 		struct rtgenmsg g;
@@ -109,7 +115,7 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
 
 	req.ext_req.rta_type = IFLA_EXT_MASK;
 	req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
-	req.ext_filter_mask = RTEXT_FILTER_VF;
+	req.ext_filter_mask = filt_mask;
 
 	return send(rth->fd, (void*)&req, sizeof(req), 0);
 }
-- 
1.7.7.6

^ permalink raw reply related

* [PATCHv2 iproute2 3/3] bridge: Update bridge man pages to include vlan command
From: Vlad Yasevich @ 2013-02-28 20:04 UTC (permalink / raw)
  To: netdev; +Cc: shemminger
In-Reply-To: <1362081846-25268-1-git-send-email-vyasevic@redhat.com>

Add the vlan command documentation to bridge man page.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 man/man8/bridge.8 |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 72 insertions(+), 1 deletions(-)

diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index fd91618..d34e3cf 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -13,7 +13,7 @@ bridge \- show / manipulate bridge addresses and devices
 
 .ti -8
 .IR OBJECT " := { "
-.BR fdb " | " monitor " }"
+.BR fdb " | " vlan " | " monitor " }"
 .sp
 
 .ti -8
@@ -35,6 +35,20 @@ bridge \- show / manipulate bridge addresses and devices
 .IR DEV " ]"
 
 .ti -8
+.BR "bridge vlan" " { " add " | " del " } "
+.B  dev
+.IR DEV
+.B  vid 
+.IR VID " [ "
+.BR  pvid " ] [ " untagged " ]  [ "
+.BR  self " ]  [ " master " ] "
+
+.ti -8
+.BR "bridge vlan" " [ " show " ] [ "
+.B  dev
+.IR DEV " ]"
+
+.ti -8
 .BR "bridge monitor" " [ " all " | " neigh " | " link " ]"
 
 .SH OPTIONS
@@ -61,6 +75,10 @@ As a rule, the information is statistics or some time values.
 .B fdb 
 - Forwarding Database entry.
 
+.TP
+.B vlan
+- VLAN filter list.
+
 .SS
 .I COMMAND
 
@@ -143,6 +161,59 @@ With the
 option, the command becomes verbose.  It prints out the last updated
 and last used time for each entry.
 
+.SH bridge vlan - VLAN filter list
+
+.B vlan
+objects contain known VLAN IDs for a link.
+
+.P
+The corresponding commands display vlan filter entries, add new entries,
+and delete old ones.
+
+.SS bridge vlan add - add a new vlan filter entry
+
+This command creates a new vlan filter entry.
+
+.TP
+.BI dev " NAME"
+the interface with which this vlan is associated.
+
+.TP
+.BI vid " VID"
+the VLAN ID that identifies the vlan.
+
+.TP
+.BI pvid
+the vlan specified is to be considered a PVID at ingress.
+Any untagged frames will be assigned to this VLAN.
+
+.TP
+.BI untagged
+the vlan specified is to be treated as untagged on egress.
+
+.TP
+.BI self
+the vlan is configured on the specified physical device.  Required if the
+device is the bridge device.
+
+.TP
+.BI master
+the vlan is configured on the sofware bridge (default).
+
+.SS bridge vlan delete - delete a forwarding database entry
+This command removes an existing fdb entry.
+
+.PP
+The arguments are the same as with
+.BR "bridge vlan add".
+The
+.BR "pvid " and " untagged"
+flags are ignored.
+
+.SS bridge vlan show - list vlan configuration.
+
+This command displays the current VLAN filter table.
+
 .SH bridge monitor - state monitoring
 
 The
-- 
1.7.7.6

^ permalink raw reply related

* Re: [PATCH v3 0/4] sctp: fix association hangs due to reassembly/ordering logic
From: David Miller @ 2013-02-28 20:36 UTC (permalink / raw)
  To: lee.roberts; +Cc: netdev, linux-sctp
In-Reply-To: <1362062250-26749-1-git-send-email-lee.roberts@hp.com>

From: "Lee A. Roberts" <lee.roberts@hp.com>
Date: Thu, 28 Feb 2013 07:37:26 -0700

> From: "Lee A. Roberts" <lee.roberts@hp.com>
> 
> This series of patches resolves several SCTP association hangs observed during
> SCTP stress testing.  Observable symptoms include communications hangs with
> data being held in the association reassembly and/or lobby (ordering) queues.
> Close examination of reassembly/ordering queues may show either duplicated
> or missing packets.
> 
> In version #2, corrected build failure in initial version of patch series
> due to wrong calling sequence for sctp_ulpq_partial_delivery() being inserted
> in sctp_ulpq_renege().
> 
> In version #3, adjusted patch documentation to be less repetitive.

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH] tcp: avoid wakeups for pure ACK
From: David Miller @ 2013-02-28 20:38 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, ncardwell, therbert, ycheng, ak
In-Reply-To: <1361984703.11403.43.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 27 Feb 2013 09:05:03 -0800

> TCP prequeue mechanism purpose is to let incoming packets
> being processed by the thread currently blocked in tcp_recvmsg(),
> instead of behalf of the softirq handler, to better adapt flow
> control on receiver host capacity to schedule the consumer.
> 
> But in typical request/answer workloads, we send request, then
> block to receive the answer. And before the actual answer, TCP
> stack receives the ACK packets acknowledging the request.
> 
> Processing pure ACK on behalf of the thread blocked in tcp_recvmsg()
> is a waste of resources, as thread has to immediately sleep again
> because it got no payload.
> 
> This patch avoids the extra context switches and scheduler overhead.
 ...
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied.

^ permalink raw reply

* Re: [PATCH] bgmac: omit the fcs
From: David Miller @ 2013-02-28 20:38 UTC (permalink / raw)
  To: hauke; +Cc: zajec5, netdev
In-Reply-To: <1362071814-12822-1-git-send-email-hauke@hauke-m.de>

From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 28 Feb 2013 18:16:54 +0100

> Do not include the frame check sequence when adding the skb to
> netif_receive_skb(). This causes problems when this interface was
> bridged to a wifi ap and a big package should be forwarded from this
> Ethernet driver through a bride to the wifi client.
> 
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

Applied.

^ permalink raw reply

* Re: [PATCH v2] phy: Fix phy_device_free memory leak
From: David Miller @ 2013-02-28 20:38 UTC (permalink / raw)
  To: oss; +Cc: netdev
In-Reply-To: <20130228110152.GA26262@bordel.klfree.net>

From: Petr Malat <oss@malat.biz>
Date: Thu, 28 Feb 2013 12:01:52 +0100

> 
> From: Petr Malat <oss@malat.biz>
> 
> Fix memory leak in phy_device_free() for the case when phy_device*
> returned by phy_device_create() is not registered in the system.
> 
> Bug description:
> phy_device_create() sets name of kobject using dev_set_name(), which 
> allocates memory using kvasprintf(), but this memory isn't freed if 
> the underlying device isn't registered properly, because kobject_cleanup()
> is not called in that case. This can happen (and actually is happening on 
> our machines) if phy_device_register(), called by mdiobus_scan(), fails. 
> 
> Patch description:
> Embedded struct device is initialized in phy_device_create() and it 
> counterpart phy_device_free() just drops one reference to the device,
> which leads to proper deinitialization including releasing the kobject 
> name memory.
> 
> Signed-off-by: Petr Malat <oss@malat.biz>

This looks great, applied, thanks.

^ permalink raw reply

* Re: [PATCH 1/1 net-next] fec: net: put tx to napi poll function to fix dead lock
From: David Miller @ 2013-02-28 20:39 UTC (permalink / raw)
  To: Frank.Li; +Cc: lznuaa, shawn.guo, B38611, linux-arm-kernel, netdev, s.hauer
In-Reply-To: <1362023060-10277-1-git-send-email-Frank.Li@freescale.com>

From: Frank Li <Frank.Li@freescale.com>
Date: Thu, 28 Feb 2013 11:44:20 +0800

> +	int tx_pkts = fec_enet_tx(ndev);
> +
> +	if (tx_pkts)
> +		return budget;

This isn't right, you don't want to finish the NAPI poll because
TX work was done.

Ignore the TX work for poll completion purposes, see
drivers/net/ethernet/broadcom/tg3.c:tg3_poll_work() for
example.

^ permalink raw reply

* Re: [PATCH net 1/1] r8169: honor jumbo settings when chipset is requested to start.
From: David Miller @ 2013-02-28 20:39 UTC (permalink / raw)
  To: romieu; +Cc: netdev, tomimo, hayeswang
In-Reply-To: <20130227230157.GA30053@electric-eye.fr.zoreil.com>

From: Francois Romieu <romieu@fr.zoreil.com>
Date: Thu, 28 Feb 2013 00:01:57 +0100

> Some hardware start settings implicitely assume an usual 1500 bytes mtu
> that can't be guaranteed because changes of mtu may be requested both
> before and after the hardware is started.
> 
> Reported-by: Tomi Orava <tomimo@ncircle.nullnet.fi>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

Applied.

^ permalink raw reply

* Re: [PATCH 1/1] net/phy: micrel: Disable asymmetric pause for KSZ9021
From: David Miller @ 2013-02-28 20:40 UTC (permalink / raw)
  To: ikosar; +Cc: netdev, linux-kernel
In-Reply-To: <1362077122-4266-1-git-send-email-ikosar@fit.vutbr.cz>

From: Vlastimil Kosar <ikosar@fit.vutbr.cz>
Date: Thu, 28 Feb 2013 19:45:22 +0100

> Phyter KSZ9021 has hardware bug. If asymmetric pause is enabled,
> then it is necessary to disconnect and then reconnect the ethernet
> cable to get the phyter working. The solution is to disable the
> asymmetric pause.
> 
> Signed-off-by: Vlastimil Kosar <ikosar@fit.vutbr.cz>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net 0/3] bnx2x: Link/LED fixes
From: David Miller @ 2013-02-28 20:40 UTC (permalink / raw)
  To: yanivr; +Cc: netdev
In-Reply-To: <1362006406-2489-1-git-send-email-yanivr@broadcom.com>

From: "Yaniv Rosner" <yanivr@broadcom.com>
Date: Thu, 28 Feb 2013 01:06:43 +0200

> The following patch series describe couple of link fixes.
> Please consider applying it to net.

All applied, thanks Yaniv.

^ permalink raw reply

* Re: query: localhost - 794ed393b clips hefty load tbench, does it matter?
From: Mike Galbraith @ 2013-02-28 21:06 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Eric Dumazet
In-Reply-To: <1362068018.15793.31.camel@edumazet-glaptop>

On Thu, 2013-02-28 at 08:13 -0800, Eric Dumazet wrote: 
> On Thu, 2013-02-28 at 13:49 +0100, Mike Galbraith wrote:
> > Greetings network wizards,
> > 
> > I was testing a 64 core box after 3.0-stable update, and noticed
> > $subject.
> > 
> > vogelweide:~/:[0]# numactl --hardware
> > available: 1 nodes (0)
> > node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
> > node 0 size: 8181 MB
> > node 0 free: 7353 MB
> > node distances:
> > node   0 
> >   0:  10
> > 
> > Sob, poor thing.  Anyway, that's the box in case it matters.
> > 
> > Without 94ed393b. 
> > 
> > vogelweide:~/:[0]# for i in 1 2 4 8 16 32 64 128 256 512; do tbench.sh $i 10 2>&1|grep Throughput; done
> > Throughput 288.784 MB/sec 1 procs
> > Throughput 559.937 MB/sec 2 procs
> > Throughput 1068.75 MB/sec 4 procs
> > Throughput 2159.04 MB/sec 8 procs
> > Throughput 4193.75 MB/sec 16 procs
> > Throughput 7662.24 MB/sec 32 procs
> > Throughput 9034.49 MB/sec 64 procs
> > Throughput 9045.9 MB/sec 128 procs
> > Throughput 9077.55 MB/sec 256 procs
> > Throughput 8907.48 MB/sec 512 procs
> > 
> > With.
> > 
> > vogelweide:~/:[0]# for i in 1 2 4 8 16 32 64 128 256 512; do tbench.sh $i 10 2>&1|grep Throughput; done
> > Throughput 288.833 MB/sec 1 procs
> > Throughput 520.87 MB/sec 2 procs
> > Throughput 937.758 MB/sec 4 procs
> > Throughput 1563.3 MB/sec 8 procs
> > Throughput 1775.14 MB/sec 16 procs
> > Throughput 1406.55 MB/sec 32 procs
> > Throughput 1448.77 MB/sec 64 procs
> > Throughput 1468.92 MB/sec 128 procs
> > Throughput 1525.35 MB/sec 256 procs
> > Throughput 1713.54 MB/sec 512 procs
> > 
> > I'm wondering if this could cause problems on a big box doing something
> > like say mysql queries of a local database, blasting retrieved data out
> > over industrial strength copper/glass or such.  My desktop box surely
> > won't notice, but it seems heavy lifters might.  I saw the reason for
> > it, but I was left wondering why we used to care about it, but no more,
> > so here I am to see if I can get my curiosity spot scratched.
> > 
> > I'll sorta miss good ole tbench in scheduler litmus test role.  On the
> > bright side, localhost based scalability reports are history.  Oh wait.
> 
> Sure, this patch re-introduces the dst->__refcnt false sharing for
> loopback.
> 
> Hopefully, with current kernels it's not an issue, because each cpu gets
> a different dst.

But but.. I'm mildly concerned over stable kernel performance where a
serious looking regression appeared out of the blue, not a new kernel
where each cpu getting a percpu dst will hopefully mitigate any of the
potential performance issues.. I may well be imagining.

> (It would be an issue if the connect() calls are all done on a single
> cpu, than traffic handled on other cpus)

(that didn't sink right in, but I may generally get it "very unlikely")

> So please try tbench on linux-3.8 or current git tree ;)

Will do.  Thanks, and glad to see that often annoying but quite useful
indicator isn't dead.

-Mike

^ permalink raw reply

* Re: [RFC Patch net-next] vxlan: add ipv6 support
From: Vlad Yasevich @ 2013-02-28 21:07 UTC (permalink / raw)
  To: Thomas Graf; +Cc: Cong Wang, netdev, David S. Miller, Stephen Hemminger
In-Reply-To: <20130228103311.GC7558@casper.infradead.org>

On 02/28/2013 05:33 AM, Thomas Graf wrote:
> On 02/28/13 at 02:01pm, Cong Wang wrote:
>> WARNING: This is just an RFC patch, it only compiles!!
>>
>> This patch adds IPv6 support to vxlan device, as the new version
>> RFC already mentioned it:
>>
>> 	http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-03
>>
>> I am not sure if the following trick will work:
>>
>> 	+       if (nla_len(nla) == sizeof(__be32)) {
>> 	+               ip->ip4 = nla_get_be32(nla);
>> 	+               ip->proto = htons(ETH_P_IP);
>> 	+       }
>> 	+#if IS_ENABLED(CONFIG_IPV6)
>> 	+       else if (nla_len(nla) == sizeof(struct in6_addr)) {
>> 	+               nla_memcpy(&ip->ip6, nla, sizeof(struct in6_addr));
>> 	+               ip->proto = htons(ETH_P_IPV6);
>> 	+       }
>> 	+#endif
>>
>> otherwise we have to introduce some new netlink attributes for
>> IPv6 addresses? Any comments?
>
> How about setting ndm_family to AF_INET6 and parse NDA_DST based on
> that?
>

Not sure if you can do that without registering your own fdb netlink 
handler.  rtnl_fdb_add is registered for PF_BRIDGE family.

You could do that, or use NDA_DST similar to how neighbor table uses it.
There the data inside of NDA_DST holds an address family and other data.

-vlad

> Assuming that nla_len(NDA_DST) > 4 == ip6 is a bit weak as like with
> any Netlink attribute we only ever enforce a minimum length and never
> a maximum or exact length.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH net 1/1] r8169: honor jumbo settings when chipset is requested to start.
From: Tomi Orava @ 2013-02-28 21:21 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, David Miller, Hayes Wang
In-Reply-To: <20130227230157.GA30053@electric-eye.fr.zoreil.com>

On 02/28/2013 01:01 AM, Francois Romieu wrote:
> Some hardware start settings implicitely assume an usual 1500 bytes mtu
> that can't be guaranteed because changes of mtu may be requested both
> before and after the hardware is started.
> 
> Reported-by: Tomi Orava <tomimo@ncircle.nullnet.fi>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Hayes Wang <hayeswang@realtek.com>
> ---
> 
>  Tomi, can you give this one a try ? It should be the "don't break non
>  jumbo setup and fix similar problem on different chipsets" patch that
>  my previous hack wasn't.

I'll try this one out tomorrow. However, it seems that I was able
to get the same hang even with the previous patch when I turned the
power on ... All the previous testing I've done were just normal
reboot's and the one liner fixed those cases 100%, but once
I turned the power completely off and then back on, the NIC hanged
in the same way as before with the jumbo frames enabled from boot.

In case it matters, this happened with 3.4.33 kernel, as the 3.7.x
still have some unresolved nouveau bugs with my HTPC box graphics card.

Tomi

> 
>  drivers/net/ethernet/realtek/r8169.c | 27 ++++++++++++++++++---------
>  1 file changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index 8900398..28fb50a 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -4765,8 +4765,10 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
>  
>  	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
>  
> -	rtl_tx_performance_tweak(pdev,
> -		(0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
> +	if (tp->dev->mtu <= ETH_DATA_LEN) {
> +		rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) |
> +					 PCI_EXP_DEVCTL_NOSNOOP_EN);
> +	}
>  }
>  
>  static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
> @@ -4789,7 +4791,8 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
>  
>  	RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	rtl_disable_clock_request(pdev);
>  
> @@ -4822,7 +4825,8 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
>  
>  	RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
>  }
> @@ -4841,7 +4845,8 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
>  
>  	RTL_W8(MaxTxPacketSize, TxPacketMax);
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
>  }
> @@ -4901,7 +4906,8 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
>  
>  	RTL_W8(MaxTxPacketSize, TxPacketMax);
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
>  }
> @@ -4913,7 +4919,8 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
>  
>  	rtl_csi_access_enable_1(tp);
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	RTL_W8(MaxTxPacketSize, TxPacketMax);
>  
> @@ -4972,7 +4979,8 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
>  
>  	rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	RTL_W8(MaxTxPacketSize, TxPacketMax);
>  
> @@ -4998,7 +5006,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
>  
>  	rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
>  
> -	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
> +	if (tp->dev->mtu <= ETH_DATA_LEN)
> +		rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
>  
>  	rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
>  	rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
> 

^ permalink raw reply

* Re: [PATCH] bgmac: omit the fcs
From: Eric Dumazet @ 2013-02-28 22:16 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: Hauke Mehrtens, davem, netdev
In-Reply-To: <CACna6rw6MR3agrDvz0+X7ne6uSNQN0tpZupeM5c-6xy5-pvv2Q@mail.gmail.com>

On Thu, 2013-02-28 at 18:57 +0100, Rafał Miłecki wrote:

> Is this a real fix?
> 
> Don't get me wrong, but it sounds a little like a workaround for some
> issue in another network layer ;)

It looks a real fix in a forwarding workload, or else MTU would need 4
extra bytes.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox