summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@nvidia.com>2020-09-28 18:30:02 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-10-14 11:55:59 +0200
commitd1a1891a586561b3085bf92d6dfbc0698000cb01 (patch)
tree40c2f4f78b5f59ffc7957351cc4b44546a3f5c33
parent54d2034e1d130d90b729ddd75d58bd1ebf8bff81 (diff)
downloadlinux-stable-d1a1891a586561b3085bf92d6dfbc0698000cb01.tar.gz
linux-stable-d1a1891a586561b3085bf92d6dfbc0698000cb01.tar.bz2
linux-stable-d1a1891a586561b3085bf92d6dfbc0698000cb01.zip
net: bridge: fdb: don't flush ext_learn entries
commit f2f3729fb65c5c2e6db234e6316b71a7bdc4b30b upstream. When a user-space software manages fdb entries externally it should set the ext_learn flag which marks the fdb entry as externally managed and avoids expiring it (they're treated as static fdbs). Unfortunately on events where fdb entries are flushed (STP down, netlink fdb flush etc) these fdbs are also deleted automatically by the bridge. That in turn causes trouble for the managing user-space software (e.g. in MLAG setups we lose remote fdb entries on port flaps). These entries are completely externally managed so we should avoid automatically deleting them, the only exception are offloaded entries (i.e. BR_FDB_ADDED_BY_EXT_LEARN + BR_FDB_OFFLOADED). They are flushed as before. Fixes: eb100e0e24a2 ("net: bridge: allow to add externally learned entries from user-space") Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/bridge/br_fdb.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 4877a0db16c6..a8fa622e2d9b 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -404,6 +404,8 @@ void br_fdb_delete_by_port(struct net_bridge *br,
if (!do_all)
if (test_bit(BR_FDB_STATIC, &f->flags) ||
+ (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags) &&
+ !test_bit(BR_FDB_OFFLOADED, &f->flags)) ||
(vid && f->key.vlan_id != vid))
continue;