diff options
author | Mike Manning <mmanning@vyatta.att-mail.com> | 2019-04-18 20:35:33 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-19 23:58:17 +0300 |
commit | 9c0ec2e7182a508335364c752da0883a2a7f3999 (patch) | |
tree | 24450f8c5a0377effa51131ca78c4df51bdbbc82 /net/bridge/br.c | |
parent | 76052d8c4f2dda6f31390521069bc109204e2f28 (diff) | |
download | linux-9c0ec2e7182a508335364c752da0883a2a7f3999.tar.xz |
bridge: support binding vlan dev link state to vlan member bridge ports
In the case of vlan filtering on bridges, the bridge may also have the
corresponding vlan devices as upper devices. A vlan bridge binding mode
is added to allow the link state of the vlan device to track only the
state of the subset of bridge ports that are also members of the vlan,
rather than that of all bridge ports. This mode is set with a vlan flag
rather than a bridge sysfs so that the 8021q module is aware that it
should not set the link state for the vlan device.
If bridge vlan is configured, the bridge device event handling results
in the link state for an upper device being set, if it is a vlan device
with the vlan bridge binding mode enabled. This also sets a
vlan_bridge_binding flag so that subsequent UP/DOWN/CHANGE events for
the ports in that bridge result in a link state update of the vlan
device if required.
The link state of the vlan device is up if there is at least one bridge
port that is a vlan member that is admin & oper up, otherwise its oper
state is IF_OPER_LOWERLAYERDOWN.
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>
Diffstat (limited to 'net/bridge/br.c')
-rw-r--r-- | net/bridge/br.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c index a5174e5001d8..e69fc87a13e0 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -40,10 +40,13 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v bool changed_addr; int err; - /* register of bridge completed, add sysfs entries */ - if ((dev->priv_flags & IFF_EBRIDGE) && event == NETDEV_REGISTER) { - br_sysfs_addbr(dev); - return NOTIFY_DONE; + if (dev->priv_flags & IFF_EBRIDGE) { + if (event == NETDEV_REGISTER) { + /* register of bridge completed, add sysfs entries */ + br_sysfs_addbr(dev); + return NOTIFY_DONE; + } + br_vlan_bridge_event(dev, event, ptr); } /* not a port of a bridge */ @@ -126,6 +129,8 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v break; } + br_vlan_port_event(p, event); + /* Events that may cause spanning tree to refresh */ if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP || event == NETDEV_CHANGE || event == NETDEV_DOWN)) |