From: Nikolay Aleksandrov nikolay@cumulusnetworks.com
stable inclusion from stable-v4.19.322 commit d3bc290bdd518e056f5cfe82accb93d5ad8643c2 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAYZ0U
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit b5cd9f7c42480ede119a390607a9dbe6263f6795 ]
Convert the added_by_external_learn field to a flag and use bitops.
Signed-off-by: Nikolay Aleksandrov nikolay@cumulusnetworks.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: bee2ef946d31 ("net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN") Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Wang Liang wangliang74@huawei.com --- net/bridge/br_fdb.c | 19 +++++++++---------- net/bridge/br_private.h | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 7ae27569ced9..d898e3814f91 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -81,7 +81,7 @@ static inline int has_expired(const struct net_bridge *br, const struct net_bridge_fdb_entry *fdb) { return !test_bit(BR_FDB_STATIC, &fdb->flags) && - !fdb->added_by_external_learn && + !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) && time_before_eq(fdb->updated + hold_time(br), jiffies); }
@@ -357,7 +357,7 @@ void br_fdb_cleanup(struct work_struct *work) unsigned long this_timer;
if (test_bit(BR_FDB_STATIC, &f->flags) || - f->added_by_external_learn) + test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) continue; this_timer = f->updated + delay; if (time_after(this_timer, now)) { @@ -511,7 +511,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, set_bit(BR_FDB_LOCAL, &fdb->flags); if (is_static) set_bit(BR_FDB_STATIC, &fdb->flags); - fdb->added_by_external_learn = 0; fdb->offloaded = 0; fdb->updated = fdb->used = jiffies; if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, @@ -598,8 +597,8 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, fdb->dst = source; fdb_modified = true; /* Take over HW learned entry */ - if (unlikely(fdb->added_by_external_learn)) - fdb->added_by_external_learn = 0; + test_and_clear_bit(BR_FDB_ADDED_BY_EXT_LEARN, + &fdb->flags); } if (now != fdb->updated) fdb->updated = now; @@ -664,7 +663,7 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
if (fdb->offloaded) ndm->ndm_flags |= NTF_OFFLOADED; - if (fdb->added_by_external_learn) + if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) ndm->ndm_flags |= NTF_EXT_LEARNED; if (test_bit(BR_FDB_STICKY, &fdb->flags)) ndm->ndm_flags |= NTF_STICKY; @@ -1107,7 +1106,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, } if (swdev_notify) set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); - fdb->added_by_external_learn = 1; + set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags); fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify); } else { fdb->updated = jiffies; @@ -1117,12 +1116,12 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, modified = true; }
- if (fdb->added_by_external_learn) { + if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) { /* Refresh entry */ fdb->used = jiffies; } else if (!test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags)) { /* Take over SW learned entry */ - fdb->added_by_external_learn = 1; + set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags); modified = true; }
@@ -1149,7 +1148,7 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p, spin_lock_bh(&br->hash_lock);
fdb = br_fdb_find(br, addr, vid); - if (fdb && fdb->added_by_external_learn) + if (fdb && test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) fdb_delete(br, fdb, swdev_notify); else err = -ENOENT; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 100ea7a11e4c..c8513b121e3a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -177,6 +177,7 @@ enum { BR_FDB_STATIC, BR_FDB_STICKY, BR_FDB_ADDED_BY_USER, + BR_FDB_ADDED_BY_EXT_LEARN, };
struct net_bridge_fdb_key { @@ -191,8 +192,7 @@ struct net_bridge_fdb_entry { struct net_bridge_fdb_key key; struct hlist_node fdb_node; unsigned long flags; - unsigned char added_by_external_learn:1, - offloaded:1; + unsigned char offloaded:1;
/* write-heavy members should not affect lookups */ unsigned long updated ____cacheline_aligned_in_smp;