vlan: introduce __vlan_insert_tag helper which does not free skb
authorJiri Pirko <jiri@resnulli.us>
Wed, 19 Nov 2014 13:05:00 +0000 (14:05 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 Nov 2014 19:20:17 +0000 (14:20 -0500)
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>
include/linux/if_vlan.h

index 291e6706876e95001e495fa9c897c75fff4b9e2c..515a35e2a48ab7e55d550fcd164466080773b3ce 100644 (file)
@@ -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. */
@@ -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;
 }