mirror of https://gitee.com/openkylin/linux.git
vlan: introduce __vlan_insert_tag helper which does not free skb
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>
This commit is contained in:
parent
5968250c86
commit
15255a43e6
|
@ -281,6 +281,40 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features,
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* __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)
|
||||
{
|
||||
struct vlan_ethhdr *veth;
|
||||
|
||||
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. */
|
||||
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
|
||||
/* first, the ethernet type */
|
||||
veth->h_vlan_proto = vlan_proto;
|
||||
|
||||
/* now, the TCI */
|
||||
veth->h_vlan_TCI = htons(vlan_tci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vlan_insert_tag - regular VLAN tag inserting
|
||||
* @skb: skbuff to tag
|
||||
|
@ -298,24 +332,13 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features,
|
|||
static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
|
||||
__be16 vlan_proto, u16 vlan_tci)
|
||||
{
|
||||
struct vlan_ethhdr *veth;
|
||||
int err;
|
||||
|
||||
if (skb_cow_head(skb, VLAN_HLEN) < 0) {
|
||||
err = __vlan_insert_tag(skb, vlan_proto, vlan_tci);
|
||||
if (err) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NULL;
|
||||
}
|
||||
veth = (struct vlan_ethhdr *)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);
|
||||
skb->mac_header -= VLAN_HLEN;
|
||||
|
||||
/* first, the ethernet type */
|
||||
veth->h_vlan_proto = vlan_proto;
|
||||
|
||||
/* now, the TCI */
|
||||
veth->h_vlan_TCI = htons(vlan_tci);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue