Skip to content

Commit 586c2b5

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
bridge: vlan: use rcu list for the ordered vlan list
When I did the conversion to rhashtable I missed the required locking of one important user of the vlan list - br_get_link_af_size_filtered() which is called: br_ifinfo_notify() -> br_nlmsg_size() -> br_get_link_af_size_filtered() and the notifications can be sent without holding rtnl. Before this conversion the function relied on using rcu and since we already use rcu to destroy the vlans, we can simply migrate the list to use the rcu helpers. Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e96f78a commit 586c2b5

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

net/bridge/br_netlink.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg,
3434

3535
pvid = br_get_pvid(vg);
3636
/* Count number of vlan infos */
37-
list_for_each_entry(v, &vg->vlan_list, vlist) {
37+
list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
3838
flags = 0;
3939
/* only a context, bridge vlan not activated */
4040
if (!br_vlan_should_use(v))
@@ -76,13 +76,19 @@ static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg,
7676
static int br_get_num_vlan_infos(struct net_bridge_vlan_group *vg,
7777
u32 filter_mask)
7878
{
79+
int num_vlans;
80+
7981
if (!vg)
8082
return 0;
8183

8284
if (filter_mask & RTEXT_FILTER_BRVLAN)
8385
return vg->num_vlans;
8486

85-
return __get_num_vlan_infos(vg, filter_mask);
87+
rcu_read_lock();
88+
num_vlans = __get_num_vlan_infos(vg, filter_mask);
89+
rcu_read_unlock();
90+
91+
return num_vlans;
8692
}
8793

8894
static size_t br_get_link_af_size_filtered(const struct net_device *dev,

net/bridge/br_vlan.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ static void __vlan_add_list(struct net_bridge_vlan *v)
111111
else
112112
break;
113113
}
114-
list_add(&v->vlist, hpos);
114+
list_add_rcu(&v->vlist, hpos);
115115
}
116116

117117
static void __vlan_del_list(struct net_bridge_vlan *v)
118118
{
119-
list_del(&v->vlist);
119+
list_del_rcu(&v->vlist);
120120
}
121121

122122
static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,

0 commit comments

Comments
 (0)