Skip to content

Commit

Permalink
bridge: update vlan dev state when port added to or deleted from vlan
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Nikolay Aleksandrov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
mikebcom authored and davem330 committed Apr 19, 2019
1 parent 9c0ec2e commit 80900ac
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions net/bridge/br_vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 80900ac

Please sign in to comment.