net: bridge: flush switchdev port fdb

When a switchdev's port is assinged to a bridge, there is a sysfs file /sys/../<port>/brport/flush
that flushes the fdb entries of that port. The bridge code notifies the switchdev for each
entry individually via SWITCHDEV_FDB_DEL_TO_DEVICE. The flush only affects dynamic fdb entries.
Local and user created entries will remain in the fdb. Most switch hw has special operations
to flush all dynamically learned neighbours.
In contrast its not common that a switch allows for individual dynamic fdb entries to get
flushed and its also prevented by the DSA framework.
This commit introduces a new swichtdev_notifier_type SWITCHDEV_FDB_FLUSH_TO_DEVICE that is
called in br_fdb_delete_by_port

Signed-off-by: Jan Sondhauss <jan.sondhauss@wago.com>
This commit is contained in:
Jan Sondhauss
2024-03-04 07:25:53 +01:00
committed by Oleg Karfich
parent 6727c3d86f
commit dea9b71dad
4 changed files with 21 additions and 0 deletions
+1
View File
@@ -216,6 +216,7 @@ enum switchdev_notifier_type {
SWITCHDEV_FDB_DEL_TO_DEVICE,
SWITCHDEV_FDB_OFFLOADED,
SWITCHDEV_FDB_FLUSH_TO_BRIDGE,
SWITCHDEV_FDB_FLUSH_TO_DEVICE,
SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
+1
View File
@@ -734,6 +734,7 @@ void br_fdb_delete_by_port(struct net_bridge *br,
struct net_bridge_fdb_entry *f;
struct hlist_node *tmp;
br_switchdev_fdb_flush_notify(p->br, p);
spin_lock_bh(&br->hash_lock);
hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
if (f->dst != p)
+2
View File
@@ -2141,6 +2141,8 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
struct netlink_ext_ack *extack);
void br_switchdev_fdb_notify(struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb, int type);
int br_switchdev_fdb_flush_notify(struct net_bridge *br,
const struct net_bridge_port *port);
void br_switchdev_mdb_notify(struct net_device *dev,
struct net_bridge_mdb_entry *mp,
struct net_bridge_port_group *pg,
+17
View File
@@ -173,6 +173,23 @@ br_switchdev_fdb_notify(struct net_bridge *br,
}
}
int br_switchdev_fdb_flush_notify(struct net_bridge *br,
const struct net_bridge_port *port)
{
static const u8 addr[ETH_ALEN] = {0};
struct net_device *ndev = port ? port->dev : br->dev;
struct switchdev_notifier_fdb_info info = {
.vid = 0,
.is_local = 0,
.offloaded = 0,
.addr = &addr[0],
.added_by_user = 0,
};
return call_switchdev_notifiers(SWITCHDEV_FDB_FLUSH_TO_DEVICE, ndev,
&info.info, NULL);
}
int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
bool changed, struct netlink_ext_ack *extack)
{