aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/if_vlan.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/if_vlan.h')
-rw-r--r--include/linux/if_vlan.h74
1 files changed, 53 insertions, 21 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 515a35e2a48a..b11b28a30b9e 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -78,9 +78,9 @@ static inline bool is_vlan_dev(struct net_device *dev)
78 return dev->priv_flags & IFF_802_1Q_VLAN; 78 return dev->priv_flags & IFF_802_1Q_VLAN;
79} 79}
80 80
81#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) 81#define skb_vlan_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT)
82#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) 82#define skb_vlan_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
83#define vlan_tx_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) 83#define skb_vlan_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK)
84 84
85/** 85/**
86 * struct vlan_pcpu_stats - VLAN percpu rx/tx stats 86 * struct vlan_pcpu_stats - VLAN percpu rx/tx stats
@@ -376,7 +376,7 @@ static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb,
376static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb) 376static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
377{ 377{
378 skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, 378 skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
379 vlan_tx_tag_get(skb)); 379 skb_vlan_tag_get(skb));
380 if (likely(skb)) 380 if (likely(skb))
381 skb->vlan_tci = 0; 381 skb->vlan_tci = 0;
382 return skb; 382 return skb;
@@ -393,7 +393,7 @@ static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb)
393 */ 393 */
394static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb) 394static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb)
395{ 395{
396 if (vlan_tx_tag_present(skb)) 396 if (skb_vlan_tag_present(skb))
397 skb = __vlan_hwaccel_push_inside(skb); 397 skb = __vlan_hwaccel_push_inside(skb);
398 return skb; 398 return skb;
399} 399}
@@ -442,8 +442,8 @@ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
442static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb, 442static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
443 u16 *vlan_tci) 443 u16 *vlan_tci)
444{ 444{
445 if (vlan_tx_tag_present(skb)) { 445 if (skb_vlan_tag_present(skb)) {
446 *vlan_tci = vlan_tx_tag_get(skb); 446 *vlan_tci = skb_vlan_tag_get(skb);
447 return 0; 447 return 0;
448 } else { 448 } else {
449 *vlan_tci = 0; 449 *vlan_tci = 0;
@@ -472,27 +472,59 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
472/** 472/**
473 * vlan_get_protocol - get protocol EtherType. 473 * vlan_get_protocol - get protocol EtherType.
474 * @skb: skbuff to query 474 * @skb: skbuff to query
475 * @type: first vlan protocol
476 * @depth: buffer to store length of eth and vlan tags in bytes
475 * 477 *
476 * Returns the EtherType of the packet, regardless of whether it is 478 * Returns the EtherType of the packet, regardless of whether it is
477 * vlan encapsulated (normal or hardware accelerated) or not. 479 * vlan encapsulated (normal or hardware accelerated) or not.
478 */ 480 */
479static inline __be16 vlan_get_protocol(const struct sk_buff *skb) 481static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
482 int *depth)
480{ 483{
481 __be16 protocol = 0; 484 unsigned int vlan_depth = skb->mac_len;
482 485
483 if (vlan_tx_tag_present(skb) || 486 /* if type is 802.1Q/AD then the header should already be
484 skb->protocol != cpu_to_be16(ETH_P_8021Q)) 487 * present at mac_len - VLAN_HLEN (if mac_len > 0), or at
485 protocol = skb->protocol; 488 * ETH_HLEN otherwise
486 else { 489 */
487 __be16 proto, *protop; 490 if (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
488 protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, 491 if (vlan_depth) {
489 h_vlan_encapsulated_proto), 492 if (WARN_ON(vlan_depth < VLAN_HLEN))
490 sizeof(proto), &proto); 493 return 0;
491 if (likely(protop)) 494 vlan_depth -= VLAN_HLEN;
492 protocol = *protop; 495 } else {
496 vlan_depth = ETH_HLEN;
497 }
498 do {
499 struct vlan_hdr *vh;
500
501 if (unlikely(!pskb_may_pull(skb,
502 vlan_depth + VLAN_HLEN)))
503 return 0;
504
505 vh = (struct vlan_hdr *)(skb->data + vlan_depth);
506 type = vh->h_vlan_encapsulated_proto;
507 vlan_depth += VLAN_HLEN;
508 } while (type == htons(ETH_P_8021Q) ||
509 type == htons(ETH_P_8021AD));
493 } 510 }
494 511
495 return protocol; 512 if (depth)
513 *depth = vlan_depth;
514
515 return type;
516}
517
518/**
519 * vlan_get_protocol - get protocol EtherType.
520 * @skb: skbuff to query
521 *
522 * Returns the EtherType of the packet, regardless of whether it is
523 * vlan encapsulated (normal or hardware accelerated) or not.
524 */
525static inline __be16 vlan_get_protocol(struct sk_buff *skb)
526{
527 return __vlan_get_protocol(skb, skb->protocol, NULL);
496} 528}
497 529
498static inline void vlan_set_encap_proto(struct sk_buff *skb, 530static inline void vlan_set_encap_proto(struct sk_buff *skb,