summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2017-07-04 00:14:59 +0200
committerDavid S. Miller <davem@davemloft.net>2017-07-04 10:49:44 +0200
commit7597b266c56feaad7d4e6e65822766e929407da2 (patch)
tree31fd22be84c3ce80d04e452920969f35765a5d70
parentnet: reflect mark on tcp syn ack packets (diff)
downloadlinux-7597b266c56feaad7d4e6e65822766e929407da2.tar.xz
linux-7597b266c56feaad7d4e6e65822766e929407da2.zip
bridge: allow ext learned entries to change ports
current code silently ignores change of port in the request message. This patch makes sure the port is modified and notification is sent to userspace. Fixes: cf6b8e1eedff ("bridge: add API to notify bridge driver of learned FBD on offloaded device") Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/bridge/br_fdb.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index fef7872a320b..a5e4a736a984 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -1079,8 +1079,9 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
const unsigned char *addr, u16 vid)
{
- struct hlist_head *head;
struct net_bridge_fdb_entry *fdb;
+ struct hlist_head *head;
+ bool modified = false;
int err = 0;
spin_lock_bh(&br->hash_lock);
@@ -1095,14 +1096,25 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
}
fdb->added_by_external_learn = 1;
fdb_notify(br, fdb, RTM_NEWNEIGH);
- } else if (fdb->added_by_external_learn) {
- /* Refresh entry */
- fdb->updated = fdb->used = jiffies;
- } else if (!fdb->added_by_user) {
- /* Take over SW learned entry */
- fdb->added_by_external_learn = 1;
+ } else {
fdb->updated = jiffies;
- fdb_notify(br, fdb, RTM_NEWNEIGH);
+
+ if (fdb->dst != p) {
+ fdb->dst = p;
+ modified = true;
+ }
+
+ if (fdb->added_by_external_learn) {
+ /* Refresh entry */
+ fdb->used = jiffies;
+ } else if (!fdb->added_by_user) {
+ /* Take over SW learned entry */
+ fdb->added_by_external_learn = 1;
+ modified = true;
+ }
+
+ if (modified)
+ fdb_notify(br, fdb, RTM_NEWNEIGH);
}
err_unlock: