Commit cec9c133631039f82e4a5ff3bf47b3eba14ff1aa
Committed by
David S. Miller
1 parent
f605234066
Exists in
master
and in
38 other branches
vlan: introduce __vlan_find_dev_deep()
Since vlan_group_get_device and vlan_group is not going to be accessible from device drivers, introduce function which substitutes it. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 29 additions and 0 deletions Side-by-side Diff
include/linux/if_vlan.h
... | ... | @@ -120,6 +120,8 @@ |
120 | 120 | |
121 | 121 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
122 | 122 | |
123 | +extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, | |
124 | + u16 vlan_id); | |
123 | 125 | extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); |
124 | 126 | extern u16 vlan_dev_vlan_id(const struct net_device *dev); |
125 | 127 | |
... | ... | @@ -135,6 +137,12 @@ |
135 | 137 | unsigned int vlan_tci); |
136 | 138 | |
137 | 139 | #else |
140 | +static inline struct net_device * | |
141 | +__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id) | |
142 | +{ | |
143 | + return NULL; | |
144 | +} | |
145 | + | |
138 | 146 | static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
139 | 147 | { |
140 | 148 | BUG(); |
net/8021q/vlan_core.c
... | ... | @@ -63,6 +63,27 @@ |
63 | 63 | return true; |
64 | 64 | } |
65 | 65 | |
66 | +/* Must be invoked with rcu_read_lock or with RTNL. */ | |
67 | +struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, | |
68 | + u16 vlan_id) | |
69 | +{ | |
70 | + struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); | |
71 | + | |
72 | + if (grp) { | |
73 | + return vlan_group_get_device(grp, vlan_id); | |
74 | + } else { | |
75 | + /* | |
76 | + * Bonding slaves do not have grp assigned to themselves. | |
77 | + * Grp is assigned to bonding master instead. | |
78 | + */ | |
79 | + if (netif_is_bond_slave(real_dev)) | |
80 | + return __vlan_find_dev_deep(real_dev->master, vlan_id); | |
81 | + } | |
82 | + | |
83 | + return NULL; | |
84 | +} | |
85 | +EXPORT_SYMBOL(__vlan_find_dev_deep); | |
86 | + | |
66 | 87 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
67 | 88 | { |
68 | 89 | return vlan_dev_info(dev)->real_dev; |