summaryrefslogtreecommitdiff
path: root/net/dsa/slave.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2021-06-29 17:06:51 +0300
committerDavid S. Miller <davem@davemloft.net>2021-06-29 20:46:23 +0300
commit3dc80afc509831ec436e14d8ae74de330b37636d (patch)
treec0d007fdd41bc02533a124e3b649a5ddf6667baf /net/dsa/slave.c
parent161ca59d39e909d37eeeaf14bc1165b114790d00 (diff)
downloadlinux-3dc80afc509831ec436e14d8ae74de330b37636d.tar.xz
net: dsa: introduce a separate cross-chip notifier type for host FDBs
DSA treats some bridge FDB entries by trapping them to the CPU port. Currently, the only class of such entries are FDB addresses learnt by the software bridge on a foreign interface. However there are many more to be added: - FDB entries with the is_local flag (for termination) added by the bridge on the user ports (typically containing the MAC address of the bridge port) - FDB entries pointing towards the bridge net device (for termination). Typically these contain the MAC address of the bridge net device. - Static FDB entries installed on a foreign interface that is in the same bridge with a DSA user port. The reason why a separate cross-chip notifier for host FDBs is justified compared to normal FDBs is the same as in the case of host MDBs: the cross-chip notifier matching function in switch.c should avoid installing these entries on routing ports that route towards the targeted switch, but not towards the CPU. This is required in order to have proper support for H-like multi-chip topologies. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/slave.c')
-rw-r--r--net/dsa/slave.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 4b1d738bc3bc..ac7f4f200ab1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2315,8 +2315,12 @@ static void dsa_slave_switchdev_event_work(struct work_struct *work)
rtnl_lock();
switch (switchdev_work->event) {
case SWITCHDEV_FDB_ADD_TO_DEVICE:
- err = dsa_port_fdb_add(dp, switchdev_work->addr,
- switchdev_work->vid);
+ if (switchdev_work->host_addr)
+ err = dsa_port_host_fdb_add(dp, switchdev_work->addr,
+ switchdev_work->vid);
+ else
+ err = dsa_port_fdb_add(dp, switchdev_work->addr,
+ switchdev_work->vid);
if (err) {
dev_err(ds->dev,
"port %d failed to add %pM vid %d to fdb: %d\n",
@@ -2328,8 +2332,12 @@ static void dsa_slave_switchdev_event_work(struct work_struct *work)
break;
case SWITCHDEV_FDB_DEL_TO_DEVICE:
- err = dsa_port_fdb_del(dp, switchdev_work->addr,
- switchdev_work->vid);
+ if (switchdev_work->host_addr)
+ err = dsa_port_host_fdb_del(dp, switchdev_work->addr,
+ switchdev_work->vid);
+ else
+ err = dsa_port_fdb_del(dp, switchdev_work->addr,
+ switchdev_work->vid);
if (err) {
dev_err(ds->dev,
"port %d failed to delete %pM vid %d from fdb: %d\n",
@@ -2375,6 +2383,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
const struct switchdev_notifier_fdb_info *fdb_info;
struct dsa_switchdev_event_work *switchdev_work;
+ bool host_addr = false;
struct dsa_port *dp;
int err;
@@ -2412,7 +2421,8 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
if (!p)
return NOTIFY_DONE;
- dp = p->dp->cpu_dp;
+ dp = p->dp;
+ host_addr = true;
if (!dp->ds->assisted_learning_on_cpu_port)
return NOTIFY_DONE;
@@ -2442,6 +2452,7 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
ether_addr_copy(switchdev_work->addr,
fdb_info->addr);
switchdev_work->vid = fdb_info->vid;
+ switchdev_work->host_addr = host_addr;
/* Hold a reference on the slave for dsa_fdb_offload_notify */
if (dsa_is_user_port(dp->ds, dp->index))