|
@@ -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;
|