diff options
Diffstat (limited to 'include/linux/if_vlan.h')
| -rw-r--r-- | include/linux/if_vlan.h | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 5e6a2d4dc366..c4a1cff9c768 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
| @@ -300,30 +300,34 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features, | |||
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | /** | 302 | /** |
| 303 | * __vlan_insert_tag - regular VLAN tag inserting | 303 | * __vlan_insert_inner_tag - inner VLAN tag inserting |
| 304 | * @skb: skbuff to tag | 304 | * @skb: skbuff to tag |
| 305 | * @vlan_proto: VLAN encapsulation protocol | 305 | * @vlan_proto: VLAN encapsulation protocol |
| 306 | * @vlan_tci: VLAN TCI to insert | 306 | * @vlan_tci: VLAN TCI to insert |
| 307 | * @mac_len: MAC header length including outer vlan headers | ||
| 307 | * | 308 | * |
| 308 | * Inserts the VLAN tag into @skb as part of the payload | 309 | * Inserts the VLAN tag into @skb as part of the payload at offset mac_len |
| 309 | * Returns error if skb_cow_head failes. | 310 | * Returns error if skb_cow_head failes. |
| 310 | * | 311 | * |
| 311 | * Does not change skb->protocol so this function can be used during receive. | 312 | * Does not change skb->protocol so this function can be used during receive. |
| 312 | */ | 313 | */ |
| 313 | static inline int __vlan_insert_tag(struct sk_buff *skb, | 314 | static inline int __vlan_insert_inner_tag(struct sk_buff *skb, |
| 314 | __be16 vlan_proto, u16 vlan_tci) | 315 | __be16 vlan_proto, u16 vlan_tci, |
| 316 | unsigned int mac_len) | ||
| 315 | { | 317 | { |
| 316 | struct vlan_ethhdr *veth; | 318 | struct vlan_ethhdr *veth; |
| 317 | 319 | ||
| 318 | if (skb_cow_head(skb, VLAN_HLEN) < 0) | 320 | if (skb_cow_head(skb, VLAN_HLEN) < 0) |
| 319 | return -ENOMEM; | 321 | return -ENOMEM; |
| 320 | 322 | ||
| 321 | veth = skb_push(skb, VLAN_HLEN); | 323 | skb_push(skb, VLAN_HLEN); |
| 322 | 324 | ||
| 323 | /* Move the mac addresses to the beginning of the new header. */ | 325 | /* Move the mac header sans proto to the beginning of the new header. */ |
| 324 | memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN); | 326 | memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN); |
| 325 | skb->mac_header -= VLAN_HLEN; | 327 | skb->mac_header -= VLAN_HLEN; |
| 326 | 328 | ||
| 329 | veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN); | ||
| 330 | |||
| 327 | /* first, the ethernet type */ | 331 | /* first, the ethernet type */ |
| 328 | veth->h_vlan_proto = vlan_proto; | 332 | veth->h_vlan_proto = vlan_proto; |
| 329 | 333 | ||
| @@ -334,12 +338,30 @@ static inline int __vlan_insert_tag(struct sk_buff *skb, | |||
| 334 | } | 338 | } |
| 335 | 339 | ||
| 336 | /** | 340 | /** |
| 337 | * vlan_insert_tag - regular VLAN tag inserting | 341 | * __vlan_insert_tag - regular VLAN tag inserting |
| 338 | * @skb: skbuff to tag | 342 | * @skb: skbuff to tag |
| 339 | * @vlan_proto: VLAN encapsulation protocol | 343 | * @vlan_proto: VLAN encapsulation protocol |
| 340 | * @vlan_tci: VLAN TCI to insert | 344 | * @vlan_tci: VLAN TCI to insert |
| 341 | * | 345 | * |
| 342 | * Inserts the VLAN tag into @skb as part of the payload | 346 | * Inserts the VLAN tag into @skb as part of the payload |
| 347 | * Returns error if skb_cow_head failes. | ||
| 348 | * | ||
| 349 | * Does not change skb->protocol so this function can be used during receive. | ||
| 350 | */ | ||
| 351 | static inline int __vlan_insert_tag(struct sk_buff *skb, | ||
| 352 | __be16 vlan_proto, u16 vlan_tci) | ||
| 353 | { | ||
| 354 | return __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); | ||
| 355 | } | ||
| 356 | |||
| 357 | /** | ||
| 358 | * vlan_insert_inner_tag - inner VLAN tag inserting | ||
| 359 | * @skb: skbuff to tag | ||
| 360 | * @vlan_proto: VLAN encapsulation protocol | ||
| 361 | * @vlan_tci: VLAN TCI to insert | ||
| 362 | * @mac_len: MAC header length including outer vlan headers | ||
| 363 | * | ||
| 364 | * Inserts the VLAN tag into @skb as part of the payload at offset mac_len | ||
| 343 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. | 365 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. |
| 344 | * | 366 | * |
| 345 | * Following the skb_unshare() example, in case of error, the calling function | 367 | * Following the skb_unshare() example, in case of error, the calling function |
| @@ -347,12 +369,14 @@ static inline int __vlan_insert_tag(struct sk_buff *skb, | |||
| 347 | * | 369 | * |
| 348 | * Does not change skb->protocol so this function can be used during receive. | 370 | * Does not change skb->protocol so this function can be used during receive. |
| 349 | */ | 371 | */ |
| 350 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | 372 | static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb, |
| 351 | __be16 vlan_proto, u16 vlan_tci) | 373 | __be16 vlan_proto, |
| 374 | u16 vlan_tci, | ||
| 375 | unsigned int mac_len) | ||
| 352 | { | 376 | { |
| 353 | int err; | 377 | int err; |
| 354 | 378 | ||
| 355 | err = __vlan_insert_tag(skb, vlan_proto, vlan_tci); | 379 | err = __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, mac_len); |
| 356 | if (err) { | 380 | if (err) { |
| 357 | dev_kfree_skb_any(skb); | 381 | dev_kfree_skb_any(skb); |
| 358 | return NULL; | 382 | return NULL; |
| @@ -361,6 +385,26 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | |||
| 361 | } | 385 | } |
| 362 | 386 | ||
| 363 | /** | 387 | /** |
| 388 | * vlan_insert_tag - regular VLAN tag inserting | ||
| 389 | * @skb: skbuff to tag | ||
| 390 | * @vlan_proto: VLAN encapsulation protocol | ||
| 391 | * @vlan_tci: VLAN TCI to insert | ||
| 392 | * | ||
| 393 | * Inserts the VLAN tag into @skb as part of the payload | ||
| 394 | * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. | ||
| 395 | * | ||
| 396 | * Following the skb_unshare() example, in case of error, the calling function | ||
| 397 | * doesn't have to worry about freeing the original skb. | ||
| 398 | * | ||
| 399 | * Does not change skb->protocol so this function can be used during receive. | ||
| 400 | */ | ||
| 401 | static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, | ||
| 402 | __be16 vlan_proto, u16 vlan_tci) | ||
| 403 | { | ||
| 404 | return vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); | ||
| 405 | } | ||
| 406 | |||
| 407 | /** | ||
| 364 | * vlan_insert_tag_set_proto - regular VLAN tag inserting | 408 | * vlan_insert_tag_set_proto - regular VLAN tag inserting |
| 365 | * @skb: skbuff to tag | 409 | * @skb: skbuff to tag |
| 366 | * @vlan_proto: VLAN encapsulation protocol | 410 | * @vlan_proto: VLAN encapsulation protocol |
