Message ID | 20210625185321.626325-8-olteanv@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Cleanup for the bridge replay helpers | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | success | CCed 7 of 7 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 39 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
On 6/25/2021 11:53 AM, Vladimir Oltean wrote: > From: Vladimir Oltean <vladimir.oltean@nxp.com> > > When a DSA switch port leaves a bonding interface that is under a > bridge, there might be dangling switchdev objects on that port left > behind, because the bridge is not aware that its lower interface (the > bond) changed state in any way. > > Call the bridge replay helpers with adding=false before changing > dp->bridge_dev to NULL, because we need to simulate to > dsa_slave_port_obj_del() that these notifications were emitted by the > bridge. > > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
diff --git a/net/dsa/port.c b/net/dsa/port.c index 4e58d07ececd..787c0454f9bd 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -212,7 +212,22 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, return 0; } -static void dsa_port_switchdev_unsync(struct dsa_port *dp) +static void dsa_port_switchdev_unsync_objs(struct dsa_port *dp) +{ + struct net_device *brport_dev = dsa_port_to_bridge_port(dp); + struct net_device *br = dp->bridge_dev; + + /* Delete the switchdev objects left on this port */ + br_mdb_replay(br, brport_dev, dp, false, + &dsa_slave_switchdev_blocking_notifier, NULL); + + br_fdb_replay(br, brport_dev, dp, false, &dsa_slave_switchdev_notifier); + + br_vlan_replay(br, brport_dev, dp, false, + &dsa_slave_switchdev_blocking_notifier, NULL); +} + +static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp) { /* Configure the port for standalone mode (no address learning, * flood everything). @@ -288,6 +303,8 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) }; int err; + dsa_port_switchdev_unsync_objs(dp); + /* Here the port is already unbridged. Reflect the current configuration * so that drivers can program their chips accordingly. */ @@ -297,7 +314,7 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) if (err) pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); - dsa_port_switchdev_unsync(dp); + dsa_port_switchdev_unsync_attrs(dp); } int dsa_port_lag_change(struct dsa_port *dp,