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,  }  /** - * __vlan_insert_tag - regular VLAN tag inserting + * __vlan_insert_inner_tag - inner VLAN tag inserting   * @skb: skbuff to tag   * @vlan_proto: VLAN encapsulation protocol   * @vlan_tci: VLAN TCI to insert + * @mac_len: MAC header length including outer vlan headers   * - * Inserts the VLAN tag into @skb as part of the payload + * Inserts the VLAN tag into @skb as part of the payload at offset mac_len   * Returns error if skb_cow_head failes.   *   * Does not change skb->protocol so this function can be used during receive.   */ -static inline int __vlan_insert_tag(struct sk_buff *skb, -				    __be16 vlan_proto, u16 vlan_tci) +static inline int __vlan_insert_inner_tag(struct sk_buff *skb, +					  __be16 vlan_proto, u16 vlan_tci, +					  unsigned int mac_len)  {  	struct vlan_ethhdr *veth;  	if (skb_cow_head(skb, VLAN_HLEN) < 0)  		return -ENOMEM; -	veth = skb_push(skb, VLAN_HLEN); +	skb_push(skb, VLAN_HLEN); -	/* Move the mac addresses to the beginning of the new header. */ -	memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN); +	/* Move the mac header sans proto to the beginning of the new header. */ +	memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);  	skb->mac_header -= VLAN_HLEN; +	veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN); +  	/* first, the ethernet type */  	veth->h_vlan_proto = vlan_proto; @@ -334,12 +338,30 @@ static inline int __vlan_insert_tag(struct sk_buff *skb,  }  /** - * vlan_insert_tag - regular VLAN tag inserting + * __vlan_insert_tag - regular VLAN tag inserting   * @skb: skbuff to tag   * @vlan_proto: VLAN encapsulation protocol   * @vlan_tci: VLAN TCI to insert   *   * Inserts the VLAN tag into @skb as part of the payload + * Returns error if skb_cow_head failes. + * + * Does not change skb->protocol so this function can be used during receive. + */ +static inline int __vlan_insert_tag(struct sk_buff *skb, +				    __be16 vlan_proto, u16 vlan_tci) +{ +	return __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); +} + +/** + * vlan_insert_inner_tag - inner VLAN tag inserting + * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol + * @vlan_tci: VLAN TCI to insert + * @mac_len: MAC header length including outer vlan headers + * + * Inserts the VLAN tag into @skb as part of the payload at offset mac_len   * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.   *   * 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,   *   * Does not change skb->protocol so this function can be used during receive.   */ -static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, -					      __be16 vlan_proto, u16 vlan_tci) +static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb, +						    __be16 vlan_proto, +						    u16 vlan_tci, +						    unsigned int mac_len)  {  	int err; -	err = __vlan_insert_tag(skb, vlan_proto, vlan_tci); +	err = __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, mac_len);  	if (err) {  		dev_kfree_skb_any(skb);  		return NULL; @@ -361,6 +385,26 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,  }  /** + * vlan_insert_tag - regular VLAN tag inserting + * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol + * @vlan_tci: VLAN TCI to insert + * + * Inserts the VLAN tag into @skb as part of the payload + * Returns a VLAN tagged skb. If a new skb is created, @skb is freed. + * + * Following the skb_unshare() example, in case of error, the calling function + * doesn't have to worry about freeing the original skb. + * + * Does not change skb->protocol so this function can be used during receive. + */ +static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, +					      __be16 vlan_proto, u16 vlan_tci) +{ +	return vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN); +} + +/**   * vlan_insert_tag_set_proto - regular VLAN tag inserting   * @skb: skbuff to tag   * @vlan_proto: VLAN encapsulation protocol  |