summaryrefslogtreecommitdiff
path: root/net/dsa/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dsa/port.c')
-rw-r--r--net/dsa/port.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 46089dd2b2ec..28b45b7e66df 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -199,11 +199,17 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp,
if (err && err != -EOPNOTSUPP)
return err;
+ /* Forwarding and termination FDB entries on the port */
err = br_fdb_replay(br, brport_dev, dp, true,
&dsa_slave_switchdev_notifier);
if (err && err != -EOPNOTSUPP)
return err;
+ /* Termination FDB entries on the bridge itself */
+ err = br_fdb_replay(br, br, dp, true, &dsa_slave_switchdev_notifier);
+ if (err && err != -EOPNOTSUPP)
+ return err;
+
err = br_vlan_replay(br, brport_dev, dp, true,
&dsa_slave_switchdev_blocking_notifier, extack);
if (err && err != -EOPNOTSUPP)
@@ -225,11 +231,17 @@ static int dsa_port_switchdev_unsync_objs(struct dsa_port *dp,
if (err && err != -EOPNOTSUPP)
return err;
+ /* Forwarding and termination FDB entries on the port */
err = br_fdb_replay(br, brport_dev, dp, false,
&dsa_slave_switchdev_notifier);
if (err && err != -EOPNOTSUPP)
return err;
+ /* Termination FDB entries on the bridge itself */
+ err = br_fdb_replay(br, br, dp, false, &dsa_slave_switchdev_notifier);
+ if (err && err != -EOPNOTSUPP)
+ return err;
+
err = br_vlan_replay(br, brport_dev, dp, false,
&dsa_slave_switchdev_blocking_notifier, extack);
if (err && err != -EOPNOTSUPP)
@@ -646,6 +658,44 @@ int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
}
+int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr,
+ u16 vid)
+{
+ struct dsa_notifier_fdb_info info = {
+ .sw_index = dp->ds->index,
+ .port = dp->index,
+ .addr = addr,
+ .vid = vid,
+ };
+ struct dsa_port *cpu_dp = dp->cpu_dp;
+ int err;
+
+ err = dev_uc_add(cpu_dp->master, addr);
+ if (err)
+ return err;
+
+ return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
+}
+
+int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr,
+ u16 vid)
+{
+ struct dsa_notifier_fdb_info info = {
+ .sw_index = dp->ds->index,
+ .port = dp->index,
+ .addr = addr,
+ .vid = vid,
+ };
+ struct dsa_port *cpu_dp = dp->cpu_dp;
+ int err;
+
+ err = dev_uc_del(cpu_dp->master, addr);
+ if (err)
+ return err;
+
+ return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_DEL, &info);
+}
+
int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data)
{
struct dsa_switch *ds = dp->ds;
@@ -681,6 +731,42 @@ int dsa_port_mdb_del(const struct dsa_port *dp,
return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
}
+int dsa_port_host_mdb_add(const struct dsa_port *dp,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct dsa_notifier_mdb_info info = {
+ .sw_index = dp->ds->index,
+ .port = dp->index,
+ .mdb = mdb,
+ };
+ struct dsa_port *cpu_dp = dp->cpu_dp;
+ int err;
+
+ err = dev_mc_add(cpu_dp->master, mdb->addr);
+ if (err)
+ return err;
+
+ return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info);
+}
+
+int dsa_port_host_mdb_del(const struct dsa_port *dp,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct dsa_notifier_mdb_info info = {
+ .sw_index = dp->ds->index,
+ .port = dp->index,
+ .mdb = mdb,
+ };
+ struct dsa_port *cpu_dp = dp->cpu_dp;
+ int err;
+
+ err = dev_mc_del(cpu_dp->master, mdb->addr);
+ if (err)
+ return err;
+
+ return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_DEL, &info);
+}
+
int dsa_port_vlan_add(struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan,
struct netlink_ext_ack *extack)