diff options
author | Patrick McHardy <kaber@trash.net> | 2013-04-18 22:04:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-19 14:46:06 -0400 |
commit | 86a9bad3ab6b6f858fd4443b48738cabbb6d094c (patch) | |
tree | 21d41b1c81e0f3e53ac4004627a8c9588099fea1 /include | |
parent | 1fd9b1fc310314911f66d2f14a8e4f0ef37bf47b (diff) |
net: vlan: add protocol argument to packet tagging functions
Add a protocol argument to the VLAN packet tagging functions. In case of HW
tagging, we need that protocol available in the ndo_start_xmit functions,
so it is stored in a new field in the skb. The new field fits into a hole
(on 64 bit) and doesn't increase the sks's size.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/if_vlan.h | 33 | ||||
-rw-r--r-- | include/linux/skbuff.h | 2 |
2 files changed, 26 insertions, 9 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 2c9fb65f8267..8086ff9988b1 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
@@ -157,9 +157,18 @@ static inline bool vlan_uses_dev(const struct net_device *dev) | |||
157 | } | 157 | } |
158 | #endif | 158 | #endif |
159 | 159 | ||
160 | static inline bool vlan_hw_offload_capable(netdev_features_t features, | ||
161 | __be16 proto) | ||
162 | { | ||
163 | if (proto == htons(ETH_P_8021Q) && features & NETIF_F_HW_VLAN_CTAG_TX) | ||
164 | return true; | ||
165 | return false; | ||
166 | } | ||
167 | |||
160 | /** | 168 | /** |
161 | * vlan_insert_tag - regular VLAN tag inserting | 169 | * vlan_insert_tag - regular VLAN tag inserting |
162 | * @skb: skbuff to tag | 170 | * @skb: skbuff to tag |
171 | * @vlan_proto: VLAN encapsulation protocol | ||
163 | * @vlan_tci: VLAN TCI to insert | 172 | * @vlan_tci: VLAN TCI to insert |
164 | * | 173 | * |
165 | * Inserts the VLAN tag into @skb as part of the payload | 174 | * Inserts the VLAN tag into @skb as part of the payload |
@@ -170,7 +179,8 @@ static inline bool vlan_uses_dev(const struct net_device *dev) | |||
170 | * | 179 | * |
171 | * Does not change skb->protocol so this function can be used during receive. | 180 | * Does not change skb->protocol so this function can be used during receive. |
172 | */ | 181 | */ |
173 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) | 182 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, |
183 | __be16 vlan_proto, u16 vlan_tci) | ||
174 | { | 184 | { |
175 | struct vlan_ethhdr *veth; | 185 | struct vlan_ethhdr *veth; |
176 | 186 | ||
@@ -185,7 +195,7 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) | |||
185 | skb->mac_header -= VLAN_HLEN; | 195 | skb->mac_header -= VLAN_HLEN; |
186 | 196 | ||
187 | /* first, the ethernet type */ | 197 | /* first, the ethernet type */ |
188 | veth->h_vlan_proto = htons(ETH_P_8021Q); | 198 | veth->h_vlan_proto = vlan_proto; |
189 | 199 | ||
190 | /* now, the TCI */ | 200 | /* now, the TCI */ |
191 | veth->h_vlan_TCI = htons(vlan_tci); | 201 | veth->h_vlan_TCI = htons(vlan_tci); |
@@ -204,24 +214,28 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) | |||
204 | * Following the skb_unshare() example, in case of error, the calling function | 214 | * Following the skb_unshare() example, in case of error, the calling function |
205 | * doesn't have to worry about freeing the original skb. | 215 | * doesn't have to worry about freeing the original skb. |
206 | */ | 216 | */ |
207 | static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) | 217 | static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, |
218 | __be16 vlan_proto, u16 vlan_tci) | ||
208 | { | 219 | { |
209 | skb = vlan_insert_tag(skb, vlan_tci); | 220 | skb = vlan_insert_tag(skb, vlan_proto, vlan_tci); |
210 | if (skb) | 221 | if (skb) |
211 | skb->protocol = htons(ETH_P_8021Q); | 222 | skb->protocol = vlan_proto; |
212 | return skb; | 223 | return skb; |
213 | } | 224 | } |
214 | 225 | ||
215 | /** | 226 | /** |
216 | * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting | 227 | * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting |
217 | * @skb: skbuff to tag | 228 | * @skb: skbuff to tag |
229 | * @vlan_proto: VLAN encapsulation protocol | ||
218 | * @vlan_tci: VLAN TCI to insert | 230 | * @vlan_tci: VLAN TCI to insert |
219 | * | 231 | * |
220 | * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest | 232 | * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest |
221 | */ | 233 | */ |
222 | static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, | 234 | static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, |
235 | __be16 vlan_proto, | ||
223 | u16 vlan_tci) | 236 | u16 vlan_tci) |
224 | { | 237 | { |
238 | skb->vlan_proto = vlan_proto; | ||
225 | skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; | 239 | skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; |
226 | return skb; | 240 | return skb; |
227 | } | 241 | } |
@@ -236,12 +250,13 @@ static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, | |||
236 | * Assumes skb->dev is the target that will xmit this frame. | 250 | * Assumes skb->dev is the target that will xmit this frame. |
237 | * Returns a VLAN tagged skb. | 251 | * Returns a VLAN tagged skb. |
238 | */ | 252 | */ |
239 | static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) | 253 | static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, |
254 | __be16 vlan_proto, u16 vlan_tci) | ||
240 | { | 255 | { |
241 | if (skb->dev->features & NETIF_F_HW_VLAN_CTAG_TX) { | 256 | if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) { |
242 | return __vlan_hwaccel_put_tag(skb, vlan_tci); | 257 | return __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); |
243 | } else { | 258 | } else { |
244 | return __vlan_put_tag(skb, vlan_tci); | 259 | return __vlan_put_tag(skb, vlan_proto, vlan_tci); |
245 | } | 260 | } |
246 | } | 261 | } |
247 | 262 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e27d1c782f32..f5bed7b31954 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -387,6 +387,7 @@ typedef unsigned char *sk_buff_data_t; | |||
387 | * @secmark: security marking | 387 | * @secmark: security marking |
388 | * @mark: Generic packet mark | 388 | * @mark: Generic packet mark |
389 | * @dropcount: total number of sk_receive_queue overflows | 389 | * @dropcount: total number of sk_receive_queue overflows |
390 | * @vlan_proto: vlan encapsulation protocol | ||
390 | * @vlan_tci: vlan tag control information | 391 | * @vlan_tci: vlan tag control information |
391 | * @inner_transport_header: Inner transport layer header (encapsulation) | 392 | * @inner_transport_header: Inner transport layer header (encapsulation) |
392 | * @inner_network_header: Network layer header (encapsulation) | 393 | * @inner_network_header: Network layer header (encapsulation) |
@@ -465,6 +466,7 @@ struct sk_buff { | |||
465 | 466 | ||
466 | __u32 rxhash; | 467 | __u32 rxhash; |
467 | 468 | ||
469 | __be16 vlan_proto; | ||
468 | __u16 vlan_tci; | 470 | __u16 vlan_tci; |
469 | 471 | ||
470 | #ifdef CONFIG_NET_SCHED | 472 | #ifdef CONFIG_NET_SCHED |