aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_vlan.c')
-rw-r--r--net/bridge/br_vlan.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 4ca4d0a0151c..8249ca764c79 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -275,9 +275,7 @@ int br_vlan_delete(struct net_bridge *br, u16 vid)
275 if (!pv) 275 if (!pv)
276 return -EINVAL; 276 return -EINVAL;
277 277
278 spin_lock_bh(&br->hash_lock); 278 br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid);
279 fdb_delete_by_addr(br, br->dev->dev_addr, vid);
280 spin_unlock_bh(&br->hash_lock);
281 279
282 __vlan_del(pv, vid); 280 __vlan_del(pv, vid);
283 return 0; 281 return 0;
@@ -295,6 +293,25 @@ void br_vlan_flush(struct net_bridge *br)
295 __vlan_flush(pv); 293 __vlan_flush(pv);
296} 294}
297 295
296bool br_vlan_find(struct net_bridge *br, u16 vid)
297{
298 struct net_port_vlans *pv;
299 bool found = false;
300
301 rcu_read_lock();
302 pv = rcu_dereference(br->vlan_info);
303
304 if (!pv)
305 goto out;
306
307 if (test_bit(vid, pv->vlan_bitmap))
308 found = true;
309
310out:
311 rcu_read_unlock();
312 return found;
313}
314
298int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) 315int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
299{ 316{
300 if (!rtnl_trylock()) 317 if (!rtnl_trylock())
@@ -359,9 +376,7 @@ int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
359 if (!pv) 376 if (!pv)
360 return -EINVAL; 377 return -EINVAL;
361 378
362 spin_lock_bh(&port->br->hash_lock); 379 br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid);
363 fdb_delete_by_addr(port->br, port->dev->dev_addr, vid);
364 spin_unlock_bh(&port->br->hash_lock);
365 380
366 return __vlan_del(pv, vid); 381 return __vlan_del(pv, vid);
367} 382}