blob: 8b869dd8f396e8fae6b5c4d355b7086d44e62f71 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 2e50fd9322047253c327550b4485cf8761035a8c Mon Sep 17 00:00:00 2001
2From: Tobias Waldekranz <tobias@waldekranz.com>
3Date: Sat, 16 Jan 2021 02:25:11 +0100
4Subject: [PATCH] net: bridge: switchdev: Send FDB notifications for host
5 addresses
6
7Treat addresses added to the bridge itself in the same way as regular
8ports and send out a notification so that drivers may sync it down to
9the hardware FDB.
10
11Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
12---
13 net/bridge/br_fdb.c | 4 ++--
14 net/bridge/br_private.h | 7 ++++---
15 net/bridge/br_switchdev.c | 11 +++++------
16 3 files changed, 11 insertions(+), 11 deletions(-)
17
18--- a/net/bridge/br_fdb.c
19+++ b/net/bridge/br_fdb.c
20@@ -581,7 +581,7 @@ void br_fdb_update(struct net_bridge *br
21
22 /* fastpath: update of existing entry */
23 if (unlikely(source != fdb->dst && !fdb->is_sticky)) {
24- br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
25+ br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH);
26 fdb->dst = source;
27 fdb_modified = true;
28 /* Take over HW learned entry */
29@@ -697,7 +697,7 @@ static void fdb_notify(struct net_bridge
30 int err = -ENOBUFS;
31
32 if (swdev_notify)
33- br_switchdev_fdb_notify(fdb, type);
34+ br_switchdev_fdb_notify(br, fdb, type);
35
36 skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
37 if (skb == NULL)
38--- a/net/bridge/br_private.h
39+++ b/net/bridge/br_private.h
40@@ -1203,8 +1203,8 @@ bool nbp_switchdev_allowed_egress(const
41 int br_switchdev_set_port_flag(struct net_bridge_port *p,
42 unsigned long flags,
43 unsigned long mask);
44-void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb,
45- int type);
46+void br_switchdev_fdb_notify(struct net_bridge *br,
47+ const struct net_bridge_fdb_entry *fdb, int type);
48 int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
49 struct netlink_ext_ack *extack);
50 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
51@@ -1250,7 +1250,8 @@ static inline int br_switchdev_port_vlan
52 }
53
54 static inline void
55-br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
56+br_switchdev_fdb_notify(struct net_bridge *br,
57+ const struct net_bridge_fdb_entry *fdb, int type)
58 {
59 }
60
61--- a/net/bridge/br_switchdev.c
62+++ b/net/bridge/br_switchdev.c
63@@ -103,7 +103,8 @@ int br_switchdev_set_port_flag(struct ne
64 }
65
66 void
67-br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
68+br_switchdev_fdb_notify(struct net_bridge *br,
69+ const struct net_bridge_fdb_entry *fdb, int type)
70 {
71 struct switchdev_notifier_fdb_info info = {
72 .addr = fdb->key.addr.addr,
73@@ -112,18 +113,16 @@ br_switchdev_fdb_notify(const struct net
74 .local = fdb->is_local,
75 .offloaded = fdb->offloaded,
76 };
77-
78- if (!fdb->dst)
79- return;
80+ struct net_device *dev = fdb->dst ? fdb->dst->dev : br->dev;
81
82 switch (type) {
83 case RTM_DELNEIGH:
84 call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_DEVICE,
85- fdb->dst->dev, &info.info, NULL);
86+ dev, &info.info, NULL);
87 break;
88 case RTM_NEWNEIGH:
89 call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_DEVICE,
90- fdb->dst->dev, &info.info, NULL);
91+ dev, &info.info, NULL);
92 break;
93 }
94 }