Skip to content

Commit

Permalink
vlan: introduce __vlan_insert_tag helper which does not free skb
Browse files Browse the repository at this point in the history
There's a need for helper which inserts vlan tag but does not free the
skb in case of an error.

Suggested-by: Pravin Shelar <pshelar@nicira.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jiri Pirko authored and David S. Miller committed Nov 21, 2014
1 parent 5968250 commit 15255a4
Showing 1 changed file with 34 additions and 11 deletions.
45 changes: 34 additions & 11 deletions include/linux/if_vlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,28 +282,24 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features,
}

/**
* 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 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.
* Returns error if skb_cow_head failes.
*
* 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 int __vlan_insert_tag(struct sk_buff *skb,
__be16 vlan_proto, u16 vlan_tci)
{
struct vlan_ethhdr *veth;

if (skb_cow_head(skb, VLAN_HLEN) < 0) {
dev_kfree_skb_any(skb);
return NULL;
}
if (skb_cow_head(skb, VLAN_HLEN) < 0)
return -ENOMEM;

veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);

/* Move the mac addresses to the beginning of the new header. */
Expand All @@ -316,6 +312,33 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
/* now, the TCI */
veth->h_vlan_TCI = htons(vlan_tci);

return 0;
}

/**
* 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)
{
int err;

err = __vlan_insert_tag(skb, vlan_proto, vlan_tci);
if (err) {
dev_kfree_skb_any(skb);
return NULL;
}
return skb;
}

Expand Down

0 comments on commit 15255a4

Please sign in to comment.