summaryrefslogtreecommitdiff
path: root/net/bridge/br_private.h
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2015-10-12 21:47:02 +0200
committerDavid S. Miller <davem@davemloft.net>2015-10-13 04:57:52 -0700
commit907b1e6e83ed25d9dece1e55b704581b6c127051 (patch)
treee3262a006fb576e8c4866bd6fc5483bd4734bd66 /net/bridge/br_private.h
parent4b918163aecdec1c5424dcc317907282c58838df (diff)
bridge: vlan: use proper rcu for the vlgrp member
The bridge and port's vlgrp member is already used in RCU way, currently we rely on the fact that it cannot disappear while the port exists but that is error-prone and we might miss places with improper locking (either RCU or RTNL must be held to walk the vlan_list). So make it official and use RCU for vlgrp to catch offenders. Introduce proper vlgrp accessors and use them consistently throughout the code. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_private.h')
-rw-r--r--net/bridge/br_private.h34
1 files changed, 30 insertions, 4 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index ba0c67b2159a..8835642a6326 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -132,6 +132,7 @@ struct net_bridge_vlan_group {
struct list_head vlan_list;
u16 num_vlans;
u16 pvid;
+ struct rcu_head rcu;
};
struct net_bridge_fdb_entry
@@ -229,7 +230,7 @@ struct net_bridge_port
struct netpoll *np;
#endif
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
- struct net_bridge_vlan_group *vlgrp;
+ struct net_bridge_vlan_group __rcu *vlgrp;
#endif
};
@@ -337,7 +338,7 @@ struct net_bridge
struct kobject *ifobj;
u32 auto_cnt;
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
- struct net_bridge_vlan_group *vlgrp;
+ struct net_bridge_vlan_group __rcu *vlgrp;
u8 vlan_enabled;
__be16 vlan_proto;
u16 default_pvid;
@@ -700,13 +701,25 @@ int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
static inline struct net_bridge_vlan_group *br_vlan_group(
const struct net_bridge *br)
{
- return br->vlgrp;
+ return rtnl_dereference(br->vlgrp);
}
static inline struct net_bridge_vlan_group *nbp_vlan_group(
const struct net_bridge_port *p)
{
- return p->vlgrp;
+ return rtnl_dereference(p->vlgrp);
+}
+
+static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
+ const struct net_bridge *br)
+{
+ return rcu_dereference(br->vlgrp);
+}
+
+static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
+ const struct net_bridge_port *p)
+{
+ return rcu_dereference(p->vlgrp);
}
/* Since bridge now depends on 8021Q module, but the time bridge sees the
@@ -853,6 +866,19 @@ static inline struct net_bridge_vlan_group *nbp_vlan_group(
{
return NULL;
}
+
+static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
+ const struct net_bridge *br)
+{
+ return NULL;
+}
+
+static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
+ const struct net_bridge_port *p)
+{
+ return NULL;
+}
+
#endif
struct nf_br_ops {