bridge: update vlan dev state when port added to or deleted from vlan
If vlan bridge binding is enabled, then the link state of a vlan device that is an upper device of the bridge should track the state of bridge ports that are members of that vlan. So if a bridge port becomes or stops being a member of a vlan, then update the link state of the vlan device if necessary. Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9c0ec2e718
commit
80900acd3a
|
@ -7,6 +7,8 @@
|
|||
#include "br_private.h"
|
||||
#include "br_private_tunnel.h"
|
||||
|
||||
static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid);
|
||||
|
||||
static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg,
|
||||
const void *ptr)
|
||||
{
|
||||
|
@ -293,6 +295,9 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
|
|||
|
||||
__vlan_add_list(v);
|
||||
__vlan_add_flags(v, flags);
|
||||
|
||||
if (p)
|
||||
nbp_vlan_set_vlan_dev_state(p, v->vid);
|
||||
out:
|
||||
return err;
|
||||
|
||||
|
@ -357,6 +362,7 @@ static int __vlan_del(struct net_bridge_vlan *v)
|
|||
rhashtable_remove_fast(&vg->vlan_hash, &v->vnode,
|
||||
br_vlan_rht_params);
|
||||
__vlan_del_list(v);
|
||||
nbp_vlan_set_vlan_dev_state(p, v->vid);
|
||||
call_rcu(&v->rcu, nbp_vlan_rcu_free);
|
||||
}
|
||||
|
||||
|
@ -1387,6 +1393,19 @@ static void br_vlan_upper_change(struct net_device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
/* Must be protected by RTNL. */
|
||||
static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid)
|
||||
{
|
||||
struct net_device *vlan_dev;
|
||||
|
||||
if (!br_opt_get(p->br, BROPT_VLAN_BRIDGE_BINDING))
|
||||
return;
|
||||
|
||||
vlan_dev = br_vlan_get_upper_bind_vlan_dev(p->br->dev, vid);
|
||||
if (vlan_dev)
|
||||
br_vlan_set_vlan_dev_state(p->br, vlan_dev);
|
||||
}
|
||||
|
||||
/* Must be protected by RTNL. */
|
||||
void br_vlan_bridge_event(struct net_device *dev, unsigned long event,
|
||||
void *ptr)
|
||||
|
|
Loading…
Reference in a new issue