fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / core / skbuff.c
index 750ec6f..830b607 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/cache.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
-#include <linux/highmem.h>
 
 #include <net/protocol.h>
 #include <net/dst.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static kmem_cache_t *skbuff_head_cache __read_mostly;
-static kmem_cache_t *skbuff_fclone_cache __read_mostly;
+#include "kmap_skb.h"
+
+static struct kmem_cache *skbuff_head_cache __read_mostly;
+static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 
 /*
  *     Keep out-of-line to prevent kernel bloat.
@@ -131,6 +132,7 @@ EXPORT_SYMBOL(skb_truesize_bug);
  *     @gfp_mask: allocation mask
  *     @fclone: allocate from fclone cache instead of head cache
  *             and allocate a cloned (child) skb
+ *     @node: numa node to allocate memory on
  *
  *     Allocate a new &sk_buff. The returned buffer has no headroom and a
  *     tail room of size bytes. The object has a reference count of one.
@@ -141,9 +143,9 @@ EXPORT_SYMBOL(skb_truesize_bug);
  */
 #ifndef CONFIG_HAVE_ARCH_ALLOC_SKB
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
-                           int fclone)
+                           int fclone, int node)
 {
-       kmem_cache_t *cache;
+       struct kmem_cache *cache;
        struct skb_shared_info *shinfo;
        struct sk_buff *skb;
        u8 *data;
@@ -151,13 +153,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
 
        /* Get the HEAD */
-       skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA);
+       skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
        if (!skb)
                goto out;
 
        /* 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_node_track_caller(size + sizeof(struct skb_shared_info),
+                       gfp_mask, node);
        if (!data)
                goto nodata;
 
@@ -210,12 +213,12 @@ nodata:
  *     Buffers may only be allocated from interrupts using a @gfp_mask of
  *     %GFP_ATOMIC.
  */
-struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
+struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
                                     unsigned int size,
                                     gfp_t gfp_mask,
                                     int fclone)
 {
-       kmem_cache_t *cache;
+       struct kmem_cache *cache;
        struct sk_buff *skb;
        u8 *data;
 
@@ -280,9 +283,10 @@ nodata:
 struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
                unsigned int length, gfp_t gfp_mask)
 {
+       int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1;
        struct sk_buff *skb;
 
-       skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
+       skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
        if (likely(skb)) {
                skb_reserve(skb, NET_SKB_PAD);
                skb->dev = dev;
@@ -475,6 +479,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        memcpy(n->cb, skb->cb, sizeof(skb->cb));
        C(len);
        C(data_len);
+       C(mac_len);
        C(csum);
        C(local_df);
        n->cloned = 1;
@@ -491,8 +496,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
 #endif
        C(protocol);
        n->destructor = NULL;
+       C(mark);
 #ifdef CONFIG_NETFILTER
-       C(nfmark);
        C(nfct);
        nf_conntrack_get(skb->nfct);
        C(nfctinfo);
@@ -511,7 +516,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
        n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
        n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
-       C(input_dev);
+       C(iif);
 #endif
        skb_copy_secmark(n, skb);
 #endif
@@ -552,8 +557,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->pkt_type   = old->pkt_type;
        new->tstamp     = old->tstamp;
        new->destructor = NULL;
+       new->mark       = old->mark;
 #ifdef CONFIG_NETFILTER
-       new->nfmark     = old->nfmark;
        new->nfct       = old->nfct;
        nf_conntrack_get(old->nfct);
        new->nfctinfo   = old->nfctinfo;
@@ -1258,8 +1263,8 @@ EXPORT_SYMBOL(skb_store_bits);
 
 /* Checksum skb data. */
 
-unsigned int skb_checksum(const struct sk_buff *skb, int offset,
-                         int len, unsigned int csum)
+__wsum skb_checksum(const struct sk_buff *skb, int offset,
+                         int len, __wsum csum)
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
@@ -1283,7 +1288,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
 
                end = start + skb_shinfo(skb)->frags[i].size;
                if ((copy = end - offset) > 0) {
-                       unsigned int csum2;
+                       __wsum csum2;
                        u8 *vaddr;
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
@@ -1312,7 +1317,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
 
                        end = start + list->len;
                        if ((copy = end - offset) > 0) {
-                               unsigned int csum2;
+                               __wsum csum2;
                                if (copy > len)
                                        copy = len;
                                csum2 = skb_checksum(list, offset - start,
@@ -1333,8 +1338,8 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
 
 /* Both of above in one bottle. */
 
-unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
-                                   u8 *to, int len, unsigned int csum)
+__wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
+                                   u8 *to, int len, __wsum csum)
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
@@ -1360,7 +1365,7 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
 
                end = start + skb_shinfo(skb)->frags[i].size;
                if ((copy = end - offset) > 0) {
-                       unsigned int csum2;
+                       __wsum csum2;
                        u8 *vaddr;
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
@@ -1386,7 +1391,7 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
                struct sk_buff *list = skb_shinfo(skb)->frag_list;
 
                for (; list; list = list->next) {
-                       unsigned int csum2;
+                       __wsum csum2;
                        int end;
 
                        BUG_TRAP(start <= offset + len);
@@ -1414,10 +1419,10 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
 
 void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
 {
-       unsigned int csum;
+       __wsum csum;
        long csstart;
 
-       if (skb->ip_summed == CHECKSUM_HW)
+       if (skb->ip_summed == CHECKSUM_PARTIAL)
                csstart = skb->h.raw - skb->data;
        else
                csstart = skb_headlen(skb);
@@ -1431,10 +1436,10 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
                csum = skb_copy_and_csum_bits(skb, csstart, to + csstart,
                                              skb->len - csstart, 0);
 
-       if (skb->ip_summed == CHECKSUM_HW) {
-               long csstuff = csstart + skb->csum;
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               long csstuff = csstart + skb->csum_offset;
 
-               *((unsigned short *)(to + csstuff)) = csum_fold(csum);
+               *((__sum16 *)(to + csstuff)) = csum_fold(csum);
        }
 }
 
@@ -1918,10 +1923,10 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
  *     @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.
+ *     update the CHECKSUM_COMPLETE 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)
 {
@@ -2013,7 +2018,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                frag = skb_shinfo(nskb)->frags;
                k = 0;
 
-               nskb->ip_summed = CHECKSUM_HW;
+               nskb->ip_summed = CHECKSUM_PARTIAL;
                nskb->csum = skb->csum;
                memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
 
@@ -2065,19 +2070,14 @@ void __init skb_init(void)
        skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
                                              sizeof(struct sk_buff),
                                              0,
-                                             SLAB_HWCACHE_ALIGN,
+                                             SLAB_HWCACHE_ALIGN|SLAB_PANIC,
                                              NULL, NULL);
-       if (!skbuff_head_cache)
-               panic("cannot create skbuff cache");
-
        skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache",
                                                (2*sizeof(struct sk_buff)) +
                                                sizeof(atomic_t),
                                                0,
-                                               SLAB_HWCACHE_ALIGN,
+                                               SLAB_HWCACHE_ALIGN|SLAB_PANIC,
                                                NULL, NULL);
-       if (!skbuff_fclone_cache)
-               panic("cannot create skbuff cache");
 }
 
 EXPORT_SYMBOL(___pskb_trim);