mirror of https://gitee.com/openkylin/linux.git
bridge: Use the correct bit length for bitmap functions in the VLAN code
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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5c751c9344
commit
ef40b7ef18
|
@ -161,7 +161,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
|
||||||
if (!pv)
|
if (!pv)
|
||||||
return;
|
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);
|
f = __br_fdb_get(br, br->dev->dev_addr, vid);
|
||||||
if (f && f->is_local && !f->dst)
|
if (f && f->is_local && !f->dst)
|
||||||
fdb_delete(br, f);
|
fdb_delete(br, f);
|
||||||
|
@ -730,7 +730,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
|
||||||
/* VID was specified, so use it. */
|
/* VID was specified, so use it. */
|
||||||
err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
|
err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
|
||||||
} else {
|
} 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);
|
err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
|
||||||
goto out;
|
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
|
* specify a VLAN. To be nice, add/update entry for every
|
||||||
* vlan on this port.
|
* 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);
|
err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -817,7 +817,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
|
||||||
|
|
||||||
err = __br_fdb_delete(p, addr, vid);
|
err = __br_fdb_delete(p, addr, vid);
|
||||||
} else {
|
} 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);
|
err = __br_fdb_delete(p, addr, 0);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -827,7 +827,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
|
||||||
* vlan on this port.
|
* vlan on this port.
|
||||||
*/
|
*/
|
||||||
err = -ENOENT;
|
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);
|
err &= __br_fdb_delete(p, addr, vid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
|
||||||
else
|
else
|
||||||
pv = br_get_vlan_info(br);
|
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;
|
goto done;
|
||||||
|
|
||||||
af = nla_nest_start(skb, IFLA_AF_SPEC);
|
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;
|
goto nla_put_failure;
|
||||||
|
|
||||||
pvid = br_get_pvid(pv);
|
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.vid = vid;
|
||||||
vinfo.flags = 0;
|
vinfo.flags = 0;
|
||||||
if (vid == pvid)
|
if (vid == pvid)
|
||||||
|
|
|
@ -108,7 +108,7 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid)
|
||||||
|
|
||||||
clear_bit(vid, v->vlan_bitmap);
|
clear_bit(vid, v->vlan_bitmap);
|
||||||
v->num_vlans--;
|
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)
|
if (v->port_idx)
|
||||||
rcu_assign_pointer(v->parent.port->vlan_info, NULL);
|
rcu_assign_pointer(v->parent.port->vlan_info, NULL);
|
||||||
else
|
else
|
||||||
|
@ -122,7 +122,7 @@ static void __vlan_flush(struct net_port_vlans *v)
|
||||||
{
|
{
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
v->pvid = 0;
|
v->pvid = 0;
|
||||||
bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
|
bitmap_zero(v->vlan_bitmap, VLAN_N_VID);
|
||||||
if (v->port_idx)
|
if (v->port_idx)
|
||||||
rcu_assign_pointer(v->parent.port->vlan_info, NULL);
|
rcu_assign_pointer(v->parent.port->vlan_info, NULL);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue