Message ID | 20210318231829.3892920-2-olteanv@gmail.com |
---|---|
State | New |
Headers | show |
Series | Better support for sandwiched LAGs with bridge and DSA | expand |
On Fri, Mar 19, 2021 at 01:18, Vladimir Oltean <olteanv@gmail.com> wrote: > From: Vladimir Oltean <vladimir.oltean@nxp.com> > > DSA can properly detect and offload this sequence of operations: > > ip link add br0 type bridge > ip link add bond0 type bond > ip link set swp0 master bond0 > ip link set bond0 master br0 > > But not this one: > > ip link add br0 type bridge > ip link add bond0 type bond > ip link set bond0 master br0 > ip link set swp0 master bond0 > > Actually the second one is more complicated, due to the elapsed time > between the enslavement of bond0 and the offloading of it via swp0, a > lot of things could have happened to the bond0 bridge port in terms of > switchdev objects (host MDBs, VLANs, altered STP state etc). So this is > a bit of a can of worms, and making sure that the DSA port's state is in > sync with this already existing bridge port is handled in the next > patches. > > Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> > --- Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
diff --git a/net/dsa/port.c b/net/dsa/port.c index c9c6d7ab3f47..d39262a9fe0e 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -249,17 +249,31 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag, .lag = lag, .info = uinfo, }; + struct net_device *bridge_dev; int err; dsa_lag_map(dp->ds->dst, lag); dp->lag_dev = lag; err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_JOIN, &info); - if (err) { - dp->lag_dev = NULL; - dsa_lag_unmap(dp->ds->dst, lag); - } + if (err) + goto err_lag_join; + bridge_dev = netdev_master_upper_dev_get(lag); + if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) + return 0; + + err = dsa_port_bridge_join(dp, bridge_dev); + if (err) + goto err_bridge_join; + + return 0; + +err_bridge_join: + dsa_port_notify(dp, DSA_NOTIFIER_LAG_LEAVE, &info); +err_lag_join: + dp->lag_dev = NULL; + dsa_lag_unmap(dp->ds->dst, lag); return err; }