|
@@ -305,8 +305,21 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
|
|
|
return num;
|
|
|
}
|
|
|
|
|
|
-static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
|
|
|
- const unsigned char *addr)
|
|
|
+static struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head,
|
|
|
+ const unsigned char *addr)
|
|
|
+{
|
|
|
+ struct hlist_node *h;
|
|
|
+ struct net_bridge_fdb_entry *fdb;
|
|
|
+
|
|
|
+ hlist_for_each_entry(fdb, h, head, hlist) {
|
|
|
+ if (!compare_ether_addr(fdb->addr.addr, addr))
|
|
|
+ return fdb;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static struct net_bridge_fdb_entry *fdb_find_rcu(struct hlist_head *head,
|
|
|
+ const unsigned char *addr)
|
|
|
{
|
|
|
struct hlist_node *h;
|
|
|
struct net_bridge_fdb_entry *fdb;
|
|
@@ -393,7 +406,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
|
|
|
source->state == BR_STATE_FORWARDING))
|
|
|
return;
|
|
|
|
|
|
- fdb = fdb_find(head, addr);
|
|
|
+ fdb = fdb_find_rcu(head, addr);
|
|
|
if (likely(fdb)) {
|
|
|
/* attempt to update an entry for a local interface */
|
|
|
if (unlikely(fdb->is_local)) {
|