Files
openwrt-R7800-nss/target/linux/ipq806x/patches-6.6/990-0208-bridge-Extend-struct-br_fdb_event.patch
SqTER-PL 5536c2039e Updated and refreshed patches.
Renamed patches to keep their original numbering from codelinaro.org
Fixed minor bugs and added support for the qca-nss-drv-l2tpv2 module
2025-08-04 18:52:30 +02:00

102 lines
3.4 KiB
Diff

From 44dd3e7f5c8a6adddce555e12c98c912a96e33c2 Mon Sep 17 00:00:00 2001
From: Murat Sezgin <msezgin@codeaurora.org>
Date: Thu, 12 Mar 2020 17:25:42 -0700
Subject: [PATCH 222/500] bridge: Extend struct br_fdb_event
Send an FDB update event with device information
Change-Id: I67df950c35af944543e31eef2f447494cea8bde1
Signed-off-by: Casey Chen <kexinc@codeaurora.org>
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
---
include/linux/if_bridge.h | 7 +++++--
net/bridge/br_fdb.c | 22 ++++++++++++++++++----
2 files changed, 23 insertions(+), 6 deletions(-)
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -243,13 +243,16 @@ extern br_multicast_handle_hook_t __rcu
#define BR_FDB_EVENT_DEL 0x02
struct br_fdb_event {
+ unsigned char addr[6];
+ unsigned char is_local;
struct net_device *dev;
- unsigned char addr[6];
- unsigned char is_local;
+ struct net_bridge *br;
+ struct net_device *orig_dev;
};
extern void br_fdb_register_notify(struct notifier_block *nb);
extern void br_fdb_unregister_notify(struct notifier_block *nb);
+extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br);
typedef struct net_bridge_port *br_get_dst_hook_t(
const struct net_bridge_port *src,
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -574,7 +574,7 @@ void br_fdb_cleanup(struct work_struct *
unsigned long delay = hold_time(br);
unsigned long work_delay = delay;
unsigned long now = jiffies;
- u8 mac_addr[6];
+ struct br_fdb_event fdb_event;
/* this part is tricky, in order to avoid blocking learning and
* consequently forwarding, we rely on rcu to delete objects with
@@ -602,10 +602,11 @@ void br_fdb_cleanup(struct work_struct *
} else {
spin_lock_bh(&br->hash_lock);
if (!hlist_unhashed(&f->fdb_node)) {
- ether_addr_copy(mac_addr, f->key.addr.addr);
+ memset(&fdb_event, 0, sizeof(fdb_event));
+ ether_addr_copy(fdb_event.addr, f->key.addr.addr);
fdb_delete(br, f, true);
atomic_notifier_call_chain(&br_fdb_update_notifier_list, 0,
- (void *)mac_addr);
+ (void *)&fdb_event);
}
spin_unlock_bh(&br->hash_lock);
}
@@ -902,10 +903,19 @@ static bool __fdb_mark_active(struct net
test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags));
}
+/* Get the bridge device */
+struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br)
+{
+ dev_hold(br->dev);
+ return br->dev;
+}
+EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold);
+
void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
const unsigned char *addr, u16 vid, unsigned long flags)
{
struct net_bridge_fdb_entry *fdb;
+ struct br_fdb_event fdb_event;
/* some users want to always flood. */
if (hold_time(br) == 0)
@@ -931,6 +941,10 @@ void br_fdb_update(struct net_bridge *br
if (unlikely(source != READ_ONCE(fdb->dst) &&
!test_bit(BR_FDB_STICKY, &fdb->flags))) {
br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH);
+ ether_addr_copy(fdb_event.addr, addr);
+ fdb_event.br = br;
+ fdb_event.orig_dev = fdb->dst->dev;
+ fdb_event.dev = source->dev;
WRITE_ONCE(fdb->dst, source);
fdb_modified = true;
@@ -947,7 +961,7 @@ void br_fdb_update(struct net_bridge *br
atomic_notifier_call_chain(
&br_fdb_update_notifier_list,
- 0, (void *)addr);
+ 0, (void *)&fdb_event);
}
if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags)))