summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/dsa/dsa_priv.h13
-rw-r--r--net/dsa/slave.c8
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)