Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/aoe-2.6
[sfrench/cifs-2.6.git] / net / core / skbuff.c
index 6766f118f07068719b551644066839a154267cf7..09464fa8d72f8b10c881b44678e8aa1084a3bcfb 100644 (file)
@@ -149,7 +149,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 
        /* Get the DATA. Size must match skb_add_mtu(). */
        size = SKB_DATA_ALIGN(size);
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+       data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
        if (!data)
                goto nodata;
 
@@ -355,6 +355,24 @@ void __kfree_skb(struct sk_buff *skb)
        kfree_skbmem(skb);
 }
 
+/**
+ *     kfree_skb - free an sk_buff
+ *     @skb: buffer to free
+ *
+ *     Drop a reference to the buffer and free it if the usage count has
+ *     hit zero.
+ */
+void kfree_skb(struct sk_buff *skb)
+{
+       if (unlikely(!skb))
+               return;
+       if (likely(atomic_read(&skb->users) == 1))
+               smp_rmb();
+       else if (likely(!atomic_dec_and_test(&skb->users)))
+               return;
+       __kfree_skb(skb);
+}
+
 /**
  *     skb_clone       -       duplicate an sk_buff
  *     @skb: buffer to clone
@@ -411,6 +429,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        C(pkt_type);
        C(ip_summed);
        C(priority);
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+       C(ipvs_property);
+#endif
        C(protocol);
        n->destructor = NULL;
 #ifdef CONFIG_NETFILTER
@@ -422,13 +443,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        C(nfct_reasm);
        nf_conntrack_get_reasm(skb->nfct_reasm);
 #endif
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
-       C(ipvs_property);
-#endif
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-       C(nfct_reasm);
-       nf_conntrack_get_reasm(skb->nfct_reasm);
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
        C(nf_bridge);
        nf_bridge_get(skb->nf_bridge);
@@ -1781,6 +1795,29 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
        return 0;
 }
 
+/**
+ *     skb_pull_rcsum - pull skb and update receive checksum
+ *     @skb: buffer to update
+ *     @start: start of data before pull
+ *     @len: length of data pulled
+ *
+ *     This function performs an skb_pull on the packet and updates
+ *     update the CHECKSUM_HW checksum.  It should be used on receive
+ *     path processing instead of skb_pull unless you know that the
+ *     checksum difference is zero (e.g., a valid IP header) or you
+ *     are setting ip_summed to CHECKSUM_NONE.
+ */
+unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
+{
+       BUG_ON(len > skb->len);
+       skb->len -= len;
+       BUG_ON(skb->len < skb->data_len);
+       skb_postpull_rcsum(skb, skb->data, len);
+       return skb->data += len;
+}
+
+EXPORT_SYMBOL_GPL(skb_pull_rcsum);
+
 void __init skb_init(void)
 {
        skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1803,6 +1840,7 @@ void __init skb_init(void)
 
 EXPORT_SYMBOL(___pskb_trim);
 EXPORT_SYMBOL(__kfree_skb);
+EXPORT_SYMBOL(kfree_skb);
 EXPORT_SYMBOL(__pskb_pull_tail);
 EXPORT_SYMBOL(__alloc_skb);
 EXPORT_SYMBOL(pskb_copy);