vlan: remove usage of dev->master in __vlan_find_dev_deep()
authorJiri Pirko <jiri@resnulli.us>
Thu, 3 Jan 2013 22:48:59 +0000 (22:48 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 4 Jan 2013 21:31:50 +0000 (13:31 -0800)
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>
net/8021q/vlan_core.c

index 65e06ab..380440b 100644 (file)
@@ -60,21 +60,25 @@ bool vlan_do_receive(struct sk_buff **skbp)
        return true;
 }
 
-/* Must be invoked with rcu_read_lock or with RTNL. */
-struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
+/* Must be invoked with rcu_read_lock. */
+struct net_device *__vlan_find_dev_deep(struct net_device *dev,
                                        u16 vlan_id)
 {
-       struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info);
+       struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info);
 
        if (vlan_info) {
                return vlan_group_get_device(&vlan_info->grp, vlan_id);
        } else {
                /*
-                * Bonding slaves do not have grp assigned to themselves.
-                * Grp is assigned to bonding master instead.
+                * Lower devices of master uppers (bonding, team) do not have
+                * grp assigned to themselves. Grp is assigned to upper device
+                * instead.
                 */
-               if (netif_is_bond_slave(real_dev))
-                       return __vlan_find_dev_deep(real_dev->master, vlan_id);
+               struct net_device *upper_dev;
+
+               upper_dev = netdev_master_upper_dev_get_rcu(dev);
+               if (upper_dev)
+                       return __vlan_find_dev_deep(upper_dev, vlan_id);
        }
 
        return NULL;