aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2013-01-03 17:48:59 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-04 16:31:50 -0500
commit1cdfd72f791918ab4690570d7d93a1f86e171cb8 (patch)
tree893eedba01dffce45af04d594a8ba2fdb7ae3e0f /net/8021q
parent0347af510cb8d9bf3014042bf1d2f23d9065f5d2 (diff)
vlan: remove usage of dev->master in __vlan_find_dev_deep()
Also, since all users call __vlan_find_dev_deep() with rcu_read_lock, make no possibility to call this with rtnl mutex held only. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan_core.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 65e06abe023f..380440b8ea89 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -60,21 +60,25 @@ bool vlan_do_receive(struct sk_buff **skbp)
60 return true; 60 return true;
61} 61}
62 62
63/* Must be invoked with rcu_read_lock or with RTNL. */ 63/* Must be invoked with rcu_read_lock. */
64struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, 64struct net_device *__vlan_find_dev_deep(struct net_device *dev,
65 u16 vlan_id) 65 u16 vlan_id)
66{ 66{
67 struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); 67 struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info);
68 68
69 if (vlan_info) { 69 if (vlan_info) {
70 return vlan_group_get_device(&vlan_info->grp, vlan_id); 70 return vlan_group_get_device(&vlan_info->grp, vlan_id);
71 } else { 71 } else {
72 /* 72 /*
73 * Bonding slaves do not have grp assigned to themselves. 73 * Lower devices of master uppers (bonding, team) do not have
74 * Grp is assigned to bonding master instead. 74 * grp assigned to themselves. Grp is assigned to upper device
75 * instead.
75 */ 76 */
76 if (netif_is_bond_slave(real_dev)) 77 struct net_device *upper_dev;
77 return __vlan_find_dev_deep(real_dev->master, vlan_id); 78
79 upper_dev = netdev_master_upper_dev_get_rcu(dev);
80 if (upper_dev)
81 return __vlan_find_dev_deep(upper_dev, vlan_id);
78 } 82 }
79 83
80 return NULL; 84 return NULL;