summaryrefslogtreecommitdiff
path: root/net/bridge
diff options
context:
space:
mode:
authorArkadi Sharshevsky <arkadis@mellanox.com>2017-04-28 22:39:07 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-30 22:46:32 -0400
commit58073b32b0f716cbd894d503ab2408db9d48aed6 (patch)
tree3a2d66a2ba93ad6aedde5d8cfabe4fb93e7ef71d /net/bridge
parentba3f571d5dde27fc4ae83aabe2c06ff08087af49 (diff)
net: bridge: Fix improper taking over HW learned FDB
Commit 7e26bf45e4cb ("net: bridge: allow SW learn to take over HW fdb entries") added the ability to "take over an entry which was previously learned via HW when it shows up from a SW port". However, if an entry was learned via HW and then a control packet (e.g., ARP request) was trapped to the CPU, the bridge driver will update the entry and remove the externally learned flag, although the entry is still present in HW. Instead, only clear the externally learned flag in case of roaming. Fixes: 7e26bf45e4cb ("net: bridge: allow SW learn to take over HW fdb entries") Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Arkadi Sharashevsky <arkadis@mellanox.com> Cc: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_fdb.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index de7988b0349e..ab0c7cc8448f 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -589,16 +589,14 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
if (unlikely(source != fdb->dst)) {
fdb->dst = source;
fdb_modified = true;
+ /* Take over HW learned entry */
+ if (unlikely(fdb->added_by_external_learn))
+ fdb->added_by_external_learn = 0;
}
if (now != fdb->updated)
fdb->updated = now;
if (unlikely(added_by_user))
fdb->added_by_user = 1;
- /* Take over HW learned entry */
- if (unlikely(fdb->added_by_external_learn)) {
- fdb->added_by_external_learn = 0;
- fdb_modified = true;
- }
if (unlikely(fdb_modified))
fdb_notify(br, fdb, RTM_NEWNEIGH);
}