diff options
author | Nikolay Aleksandrov <nikolay@cumulusnetworks.com> | 2015-06-09 06:34:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-06-11 00:58:13 -0400 |
commit | 8c86f967dd24a79ef202fd6f479ca9988ea31f3b (patch) | |
tree | 7c6ddbdce8e74661e0448b24024b4b23fb0aad50 /net/bridge/br_fdb.c | |
parent | 43559893be501d41d7833a1a0229c0bbd22b9c5c (diff) |
bridge: make br_fdb_delete also check if the port matches
Before this patch the user-specified bridge port was ignored when
deleting an fdb entry and thus one could delete an entry that belonged
to any port.
Example (eth0 and eth1 are br0 ports):
bridge fdb add 00:11:22:33:44:55 dev eth0 master
bridge fdb del 00:11:22:33:44:55 dev eth1 master
(succeeds)
after the patch:
bridge fdb add 00:11:22:33:44:55 dev eth0 master
bridge fdb del 00:11:22:33:44:55 dev eth1 master
RTNETLINK answers: No such file or directory
Based on a patch by Wilson Kok.
Reported-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_fdb.c')
-rw-r--r-- | net/bridge/br_fdb.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index cecb482ed919..13949a71591d 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -873,13 +873,15 @@ out: | |||
873 | return err; | 873 | return err; |
874 | } | 874 | } |
875 | 875 | ||
876 | static int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vlan) | 876 | static int fdb_delete_by_addr_and_port(struct net_bridge_port *p, |
877 | const u8 *addr, u16 vlan) | ||
877 | { | 878 | { |
879 | struct net_bridge *br = p->br; | ||
878 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)]; | 880 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vlan)]; |
879 | struct net_bridge_fdb_entry *fdb; | 881 | struct net_bridge_fdb_entry *fdb; |
880 | 882 | ||
881 | fdb = fdb_find(head, addr, vlan); | 883 | fdb = fdb_find(head, addr, vlan); |
882 | if (!fdb) | 884 | if (!fdb || fdb->dst != p) |
883 | return -ENOENT; | 885 | return -ENOENT; |
884 | 886 | ||
885 | fdb_delete(br, fdb); | 887 | fdb_delete(br, fdb); |
@@ -892,7 +894,7 @@ static int __br_fdb_delete(struct net_bridge_port *p, | |||
892 | int err; | 894 | int err; |
893 | 895 | ||
894 | spin_lock_bh(&p->br->hash_lock); | 896 | spin_lock_bh(&p->br->hash_lock); |
895 | err = fdb_delete_by_addr(p->br, addr, vid); | 897 | err = fdb_delete_by_addr_and_port(p, addr, vid); |
896 | spin_unlock_bh(&p->br->hash_lock); | 898 | spin_unlock_bh(&p->br->hash_lock); |
897 | 899 | ||
898 | return err; | 900 | return err; |