diff options
-rw-r--r-- | net/dsa/dsa_priv.h | 13 | ||||
-rw-r--r-- | net/dsa/slave.c | 8 |
2 files changed, 21 insertions, 0 deletions
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 263593ce94a8..8a1bcb2b4208 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -209,6 +209,19 @@ static inline bool dsa_port_offloads_netdev(struct dsa_port *dp, return false; } +/* Returns true if any port of this tree offloads the given net_device */ +static inline bool dsa_tree_offloads_netdev(struct dsa_switch_tree *dst, + struct net_device *dev) +{ + struct dsa_port *dp; + + list_for_each_entry(dp, &dst->ports, list) + if (dsa_port_offloads_netdev(dp, dev)) + return true; + + return false; +} + /* slave.c */ extern const struct dsa_device_ops notag_netdev_ops; void dsa_slave_mii_bus_init(struct dsa_switch *ds); diff --git a/net/dsa/slave.c b/net/dsa/slave.c index f77e9eeb1a62..431bdbdd8473 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -2242,6 +2242,14 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused, if (!dp->ds->assisted_learning_on_cpu_port) return NOTIFY_DONE; + + /* When the bridge learns an address on an offloaded + * LAG we don't want to send traffic to the CPU, the + * other ports bridged with the LAG should be able to + * autonomously forward towards it. + */ + if (dsa_tree_offloads_netdev(dp->ds->dst, dev)) + return NOTIFY_DONE; } if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del) |