netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Bridge vlan malfunctions for vid greater than 63
@ 2013-08-20  8:07 Toshiaki Makita
  2013-08-20  8:10 ` [net PATCH] bridge: Use the correct bit length for bitmap functions in the VLAN code Toshiaki Makita
  0 siblings, 1 reply; 3+ messages in thread
From: Toshiaki Makita @ 2013-08-20  8:07 UTC (permalink / raw)
  To: David S. Miller, Vlad Yasevich, netdev; +Cc: Toshiaki Makita

Hello.

Bridge vlan behaves unexpectedly for certain vids.
These are examples on Fedora 19 x86_64:
- "bridge vlan show" command cannot retrieve vids greater than 63,
  even if patch 3e805ad (using ifinfomsg instead of rtgenmsg) is
  applied.
- When we delete a vid, if no configured vid less than 64 remains,
  vlan_info will be freed prematurely, which could delete other
  configured vids.
- Parmanent fdb entries could not be deleted even if corresponding vid
  is deleted.

I'm afraid that some bitmap functions are given the number of elements
in a bitmap array (BR_VLAN_BITMAP_LEN), which is less than the bit
length.

Example:
static int br_fill_ifinfo(struct sk_buff *skb,
...
		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN))

As BR_VLAN_BITMAP_LEN is "BITS_TO_LONGS(VLAN_N_VID)", I tested after
changing BR_VLAN_BITMAP_LEN to VLAN_N_VID, and confirmed that this
resolves that malfunctions.

The following mail contains the patch described above.
Please comment if I misunderstood something.

Thanks,
Toshiaki Makita

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [net PATCH] bridge: Use the correct bit length for bitmap functions in the VLAN code
  2013-08-20  8:07 Bridge vlan malfunctions for vid greater than 63 Toshiaki Makita
@ 2013-08-20  8:10 ` Toshiaki Makita
  2013-08-21  6:36   ` David Miller
  0 siblings, 1 reply; 3+ messages in thread
From: Toshiaki Makita @ 2013-08-20  8:10 UTC (permalink / raw)
  To: David S. Miller, Vlad Yasevich, netdev; +Cc: Toshiaki Makita

The VLAN code needs to know the length of the per-port VLAN bitmap to
perform its most basic operations (retrieving VLAN informations, removing
VLANs, forwarding database manipulation, etc). Unfortunately, in the
current implementation we are using a macro that indicates the bitmap
size in longs in places where the size in bits is expected, which in
some cases can cause what appear to be random failures.
Use the correct macro.

Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
---
 net/bridge/br_fdb.c     | 10 +++++-----
 net/bridge/br_netlink.c |  4 ++--
 net/bridge/br_vlan.c    |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 60aca91..ffd5874 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -161,7 +161,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
 	if (!pv)
 		return;
 
-	for_each_set_bit_from(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+	for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) {
 		f = __br_fdb_get(br, br->dev->dev_addr, vid);
 		if (f && f->is_local && !f->dst)
 			fdb_delete(br, f);
@@ -730,7 +730,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 		/* VID was specified, so use it. */
 		err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
 	} else {
-		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+		if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
 			err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
 			goto out;
 		}
@@ -739,7 +739,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 		 * specify a VLAN.  To be nice, add/update entry for every
 		 * vlan on this port.
 		 */
-		for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+		for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
 			err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
 			if (err)
 				goto out;
@@ -817,7 +817,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
 
 		err = __br_fdb_delete(p, addr, vid);
 	} else {
-		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+		if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
 			err = __br_fdb_delete(p, addr, 0);
 			goto out;
 		}
@@ -827,7 +827,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
 		 * vlan on this port.
 		 */
 		err = -ENOENT;
-		for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+		for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
 			err &= __br_fdb_delete(p, addr, vid);
 		}
 	}
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 1fc30ab..b9259ef 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -132,7 +132,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
 		else
 			pv = br_get_vlan_info(br);
 
-		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN))
+		if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID))
 			goto done;
 
 		af = nla_nest_start(skb, IFLA_AF_SPEC);
@@ -140,7 +140,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
 			goto nla_put_failure;
 
 		pvid = br_get_pvid(pv);
-		for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+		for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
 			vinfo.vid = vid;
 			vinfo.flags = 0;
 			if (vid == pvid)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index bd58b45..9a9ffe7 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -108,7 +108,7 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid)
 
 	clear_bit(vid, v->vlan_bitmap);
 	v->num_vlans--;
-	if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+	if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) {
 		if (v->port_idx)
 			rcu_assign_pointer(v->parent.port->vlan_info, NULL);
 		else
@@ -122,7 +122,7 @@ static void __vlan_flush(struct net_port_vlans *v)
 {
 	smp_wmb();
 	v->pvid = 0;
-	bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
+	bitmap_zero(v->vlan_bitmap, VLAN_N_VID);
 	if (v->port_idx)
 		rcu_assign_pointer(v->parent.port->vlan_info, NULL);
 	else
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [net PATCH] bridge: Use the correct bit length for bitmap functions in the VLAN code
  2013-08-20  8:10 ` [net PATCH] bridge: Use the correct bit length for bitmap functions in the VLAN code Toshiaki Makita
@ 2013-08-21  6:36   ` David Miller
  0 siblings, 0 replies; 3+ messages in thread
From: David Miller @ 2013-08-21  6:36 UTC (permalink / raw)
  To: makita.toshiaki; +Cc: vyasevic, netdev

From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Date: Tue, 20 Aug 2013 17:10:18 +0900

> The VLAN code needs to know the length of the per-port VLAN bitmap to
> perform its most basic operations (retrieving VLAN informations, removing
> VLANs, forwarding database manipulation, etc). Unfortunately, in the
> current implementation we are using a macro that indicates the bitmap
> size in longs in places where the size in bits is expected, which in
> some cases can cause what appear to be random failures.
> Use the correct macro.
> 
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>

Applied and queued up for -stable, thank you.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-08-21  6:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-20  8:07 Bridge vlan malfunctions for vid greater than 63 Toshiaki Makita
2013-08-20  8:10 ` [net PATCH] bridge: Use the correct bit length for bitmap functions in the VLAN code Toshiaki Makita
2013-08-21  6:36   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).