summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/bridge/br_switchdev.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index 8a45b1cfe06f..2fbe881cdfe2 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -122,28 +122,38 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
return 0;
}
+static void br_switchdev_fdb_populate(struct net_bridge *br,
+ struct switchdev_notifier_fdb_info *item,
+ const struct net_bridge_fdb_entry *fdb,
+ const void *ctx)
+{
+ const struct net_bridge_port *p = READ_ONCE(fdb->dst);
+
+ item->addr = fdb->key.addr.addr;
+ item->vid = fdb->key.vlan_id;
+ item->added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
+ item->offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags);
+ item->is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
+ item->info.dev = (!p || item->is_local) ? br->dev : p->dev;
+ item->info.ctx = ctx;
+}
+
void
br_switchdev_fdb_notify(struct net_bridge *br,
const struct net_bridge_fdb_entry *fdb, int type)
{
- const struct net_bridge_port *dst = READ_ONCE(fdb->dst);
- struct switchdev_notifier_fdb_info info = {
- .addr = fdb->key.addr.addr,
- .vid = fdb->key.vlan_id,
- .added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags),
- .is_local = test_bit(BR_FDB_LOCAL, &fdb->flags),
- .offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags),
- };
- struct net_device *dev = (!dst || info.is_local) ? br->dev : dst->dev;
+ struct switchdev_notifier_fdb_info item;
+
+ br_switchdev_fdb_populate(br, &item, fdb, NULL);
switch (type) {
case RTM_DELNEIGH:
call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_DEVICE,
- dev, &info.info, NULL);
+ item.info.dev, &item.info, NULL);
break;
case RTM_NEWNEIGH:
call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_DEVICE,
- dev, &info.info, NULL);
+ item.info.dev, &item.info, NULL);
break;
}
}
@@ -274,17 +284,10 @@ static int br_fdb_replay_one(struct net_bridge *br, struct notifier_block *nb,
const struct net_bridge_fdb_entry *fdb,
unsigned long action, const void *ctx)
{
- const struct net_bridge_port *p = READ_ONCE(fdb->dst);
struct switchdev_notifier_fdb_info item;
int err;
- item.addr = fdb->key.addr.addr;
- item.vid = fdb->key.vlan_id;
- item.added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
- item.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags);
- item.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
- item.info.dev = (!p || item.is_local) ? br->dev : p->dev;
- item.info.ctx = ctx;
+ br_switchdev_fdb_populate(br, &item, fdb, ctx);
err = nb->notifier_call(nb, action, &item);
return notifier_to_errno(err);