diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2021-06-27 14:54:27 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-28 14:09:03 -0700 |
commit | 7e8c18586daf7c1653c4b43a8119bc9662ed8fa6 (patch) | |
tree | 09dd4c834f33db188e6a39842e2b3093dcd66318 /net/bridge/br_vlan.c | |
parent | bdf123b455ce596aec6e410ec36fe3687b6a2140 (diff) |
net: bridge: allow the switchdev replay functions to be called for deletion
When a switchdev port leaves a LAG that is a bridge port, the switchdev
objects and port attributes offloaded to that port are not removed:
ip link add br0 type bridge
ip link add bond0 type bond mode 802.3ad
ip link set swp0 master bond0
ip link set bond0 master br0
bridge vlan add dev bond0 vid 100
ip link set swp0 nomaster
VLAN 100 will remain installed on swp0 despite it going into standalone
mode, because as far as the bridge is concerned, nothing ever happened
to its bridge port.
Let's extend the bridge vlan, fdb and mdb replay functions to take a
'bool adding' argument, and make DSA and ocelot call the replay
functions with 'adding' as false from the switchdev unsync path, for the
switch port that leaves the bridge.
Note that this patch in itself does not salvage anything, because in the
current pull mode of operation, DSA still needs to call the replay
helpers with adding=false. This will be done in another patch.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_vlan.c')
-rw-r--r-- | net/bridge/br_vlan.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 2bfa2a00e193..a08e9f193009 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -1807,7 +1807,8 @@ out_kfree: static int br_vlan_replay_one(struct notifier_block *nb, struct net_device *dev, struct switchdev_obj_port_vlan *vlan, - const void *ctx, struct netlink_ext_ack *extack) + const void *ctx, unsigned long action, + struct netlink_ext_ack *extack) { struct switchdev_notifier_port_obj_info obj_info = { .info = { @@ -1819,18 +1820,19 @@ static int br_vlan_replay_one(struct notifier_block *nb, }; int err; - err = nb->notifier_call(nb, SWITCHDEV_PORT_OBJ_ADD, &obj_info); + err = nb->notifier_call(nb, action, &obj_info); return notifier_to_errno(err); } int br_vlan_replay(struct net_device *br_dev, struct net_device *dev, - const void *ctx, struct notifier_block *nb, + const void *ctx, bool adding, struct notifier_block *nb, struct netlink_ext_ack *extack) { struct net_bridge_vlan_group *vg; struct net_bridge_vlan *v; struct net_bridge_port *p; struct net_bridge *br; + unsigned long action; int err = 0; u16 pvid; @@ -1857,6 +1859,11 @@ int br_vlan_replay(struct net_device *br_dev, struct net_device *dev, if (!vg) return 0; + if (adding) + action = SWITCHDEV_PORT_OBJ_ADD; + else + action = SWITCHDEV_PORT_OBJ_DEL; + pvid = br_get_pvid(vg); list_for_each_entry(v, &vg->vlan_list, vlist) { @@ -1870,7 +1877,7 @@ int br_vlan_replay(struct net_device *br_dev, struct net_device *dev, if (!br_vlan_should_use(v)) continue; - err = br_vlan_replay_one(nb, dev, &vlan, ctx, extack); + err = br_vlan_replay_one(nb, dev, &vlan, ctx, action, extack); if (err) return err; } |