netdev
[Top] [All Lists]

[PATCH] skb_copy_expand

To: davem@xxxxxxxxxx
Subject: [PATCH] skb_copy_expand
From: Rusty Russell <rusty@xxxxxxxxxxxxxxxx>
Date: Wed, 22 Dec 1999 19:38:53 +1100
Cc: netdev@xxxxxxxxxxx
Sender: owner-netdev@xxxxxxxxxxx
I just noticed that this never did go in.  Patch against 2.3.34.

1) Adds skb_copy_expand, a generalization of skb_realloc_headroom.
2) Makes skb_realloc_headroom a (deprecated) macro.
3) Merges the common code of skb_copy/skb_realloc_headroom.

Let's avoid having a `realloc_tailroom' implementation outside
skbuff.c, like the ip_masq code in 2.0 and 2.2 does...

Rusty.

diff -ur linux-2.3-official/include/linux/skbuff.h 
linux-tmp/include/linux/skbuff.h
--- linux-2.3-official/include/linux/skbuff.h   Wed Dec 22 18:34:12 1999
+++ linux-tmp/include/linux/skbuff.h    Wed Dec 22 19:31:36 1999
@@ -168,19 +168,25 @@
 extern struct sk_buff *                dev_alloc_skb(unsigned int size);
 extern void                    kfree_skbmem(struct sk_buff *skb);
 extern struct sk_buff *                skb_clone(struct sk_buff *skb, int 
priority);
-extern struct sk_buff *                skb_copy(struct sk_buff *skb, int 
priority);
-extern struct sk_buff *                skb_realloc_headroom(struct sk_buff 
*skb, int newheadroom);
+extern struct sk_buff *                skb_copy(const struct sk_buff *skb, int 
priority);
+extern struct sk_buff *                skb_copy_expand(const struct sk_buff 
*skb, 
+                                               int newheadroom,
+                                               int newtailroom,
+                                               int priority);
 #define dev_kfree_skb(a)       kfree_skb(a)
 extern unsigned char *         skb_put(struct sk_buff *skb, unsigned int len);
 extern unsigned char *         skb_push(struct sk_buff *skb, unsigned int len);
 extern unsigned char *         skb_pull(struct sk_buff *skb, unsigned int len);
-extern int                     skb_headroom(struct sk_buff *skb);
-extern int                     skb_tailroom(struct sk_buff *skb);
+extern int                     skb_headroom(const struct sk_buff *skb);
+extern int                     skb_tailroom(const struct sk_buff *skb);
 extern void                    skb_reserve(struct sk_buff *skb, unsigned int 
len);
 extern void                    skb_trim(struct sk_buff *skb, unsigned int len);
 extern void    skb_over_panic(struct sk_buff *skb, int len, void *here);
 extern void    skb_under_panic(struct sk_buff *skb, int len, void *here);
 
+/* Backwards compatibility */
+#define skb_realloc_headroom(skb, nhr) skb_copy_expand(skb, nhr, 
skb_tailroom(skb), GFP_ATOMIC)
+
 /* Internal */
 extern __inline__ atomic_t *skb_datarefp(struct sk_buff *skb)
 {
@@ -534,12 +540,12 @@
        return __skb_pull(skb,len);
 }
 
-extern __inline__ int skb_headroom(struct sk_buff *skb)
+extern __inline__ int skb_headroom(const struct sk_buff *skb)
 {
        return skb->data-skb->head;
 }
 
-extern __inline__ int skb_tailroom(struct sk_buff *skb)
+extern __inline__ int skb_tailroom(const struct sk_buff *skb)
 {
        return skb->end-skb->tail;
 }
diff -ur linux-2.3-official/net/core/skbuff.c linux-tmp/net/core/skbuff.c
--- linux-2.3-official/net/core/skbuff.c        Tue Nov 30 17:58:36 1999
+++ linux-tmp/net/core/skbuff.c Wed Dec 22 19:31:36 1999
@@ -275,14 +275,48 @@
        return n;
 }
 
+static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
+{
+       /*
+        *      Shift between the two data areas in bytes
+        */
+       unsigned long offset = new->data - old->data;
+
+       new->list=NULL;
+       new->sk=NULL;
+       new->dev=old->dev;
+       new->rx_dev=NULL;
+       new->priority=old->priority;
+       new->protocol=old->protocol;
+       new->dst=dst_clone(old->dst);
+       new->h.raw=old->h.raw+offset;
+       new->nh.raw=old->nh.raw+offset;
+       new->mac.raw=old->mac.raw+offset;
+       memcpy(new->cb, old->cb, sizeof(old->cb));
+       new->used=old->used;
+       new->is_clone=0;
+       atomic_set(&new->users, 1);
+       new->pkt_type=old->pkt_type;
+       new->stamp=old->stamp;
+       new->destructor = NULL;
+       new->security=old->security;
+#ifdef CONFIG_NETFILTER
+       new->nfmark=old->nfmark;
+       new->nfreason=old->nfreason;
+       new->nfcache=old->nfcache;
+#ifdef CONFIG_NETFILTER_DEBUG
+       new->nf_debug=old->nf_debug;
+#endif
+#endif
+}
+
 /*
  *     This is slower, and copies the whole data area 
  */
  
-struct sk_buff *skb_copy(struct sk_buff *skb, int gfp_mask)
+struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask)
 {
        struct sk_buff *n;
-       unsigned long offset;
 
        /*
         *      Allocate the copy buffer
@@ -292,12 +326,6 @@
        if(n==NULL)
                return NULL;
 
-       /*
-        *      Shift between the two data areas in bytes
-        */
-        
-       offset=n->head-skb->head;
-
        /* Set the data pointer */
        skb_reserve(n,skb->data-skb->head);
        /* Set the tail pointer and length */
@@ -305,86 +333,35 @@
        /* Copy the bytes */
        memcpy(n->head,skb->head,skb->end-skb->head);
        n->csum = skb->csum;
-       n->list=NULL;
-       n->sk=NULL;
-       n->dev=skb->dev;
-       n->rx_dev=NULL;
-       n->priority=skb->priority;
-       n->protocol=skb->protocol;
-       n->dst=dst_clone(skb->dst);
-       n->h.raw=skb->h.raw+offset;
-       n->nh.raw=skb->nh.raw+offset;
-       n->mac.raw=skb->mac.raw+offset;
-       memcpy(n->cb, skb->cb, sizeof(skb->cb));
-       n->used=skb->used;
-       n->is_clone=0;
-       atomic_set(&n->users, 1);
-       n->pkt_type=skb->pkt_type;
-       n->stamp=skb->stamp;
-       n->destructor = NULL;
-       n->security=skb->security;
-#ifdef CONFIG_NETFILTER
-       n->nfmark=skb->nfmark;
-       n->nfreason=skb->nfreason;
-       n->nfcache=skb->nfcache;
-#ifdef CONFIG_NETFILTER_DEBUG
-       n->nf_debug=skb->nf_debug;
-#endif
-#endif
+       copy_skb_header(n, skb);
+
        return n;
 }
 
-struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom)
+struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
+                               int newheadroom,
+                               int newtailroom,
+                               int gfp_mask)
 {
        struct sk_buff *n;
-       unsigned long offset;
 
        /*
         *      Allocate the copy buffer
         */
         
-       n=alloc_skb((skb->end-skb->data)+newheadroom, GFP_ATOMIC);
+       n=alloc_skb(newheadroom + (skb->tail - skb->data) + newtailroom,
+                   gfp_mask);
        if(n==NULL)
                return NULL;
 
        skb_reserve(n,newheadroom);
 
-       /*
-        *      Shift between the two data areas in bytes
-        */
-        
-       offset=n->data-skb->data;
-
        /* Set the tail pointer and length */
        skb_put(n,skb->len);
-       /* Copy the bytes */
-       memcpy(n->data,skb->data,skb->len);
-       n->list=NULL;
-       n->sk=NULL;
-       n->priority=skb->priority;
-       n->protocol=skb->protocol;
-       n->dev=skb->dev;
-       n->rx_dev=NULL;
-       n->dst=dst_clone(skb->dst);
-       n->h.raw=skb->h.raw+offset;
-       n->nh.raw=skb->nh.raw+offset;
-       n->mac.raw=skb->mac.raw+offset;
-       memcpy(n->cb, skb->cb, sizeof(skb->cb));
-       n->used=skb->used;
-       n->is_clone=0;
-       atomic_set(&n->users, 1);
-       n->pkt_type=skb->pkt_type;
-       n->stamp=skb->stamp;
-       n->destructor = NULL;
-       n->security=skb->security;
-#ifdef CONFIG_NETFILTER
-       n->nfmark=skb->nfmark;
-       n->nfreason=skb->nfreason;
-       n->nfcache=skb->nfcache;
-#ifdef CONFIG_NETFILTER_DEBUG
-       n->nf_debug=skb->nf_debug;
-#endif
-#endif
+       /* Copy the bytes: data pointers must point to same data. */
+       memcpy(n->data - skb_headroom(skb), skb->head, skb->end-skb->head);
+
+       copy_skb_header(n, skb);
        return n;
 }
 
Only in linux-tmp/net/core: skbuff.c.orig
diff -ur linux-2.3-official/net/netsyms.c linux-tmp/net/netsyms.c
--- linux-2.3-official/net/netsyms.c    Wed Dec 22 10:06:46 1999
+++ linux-tmp/net/netsyms.c     Wed Dec 22 19:31:36 1999
@@ -150,7 +150,7 @@
 EXPORT_SYMBOL(skb_free_datagram);
 EXPORT_SYMBOL(skb_copy_datagram);
 EXPORT_SYMBOL(skb_copy_datagram_iovec);
-EXPORT_SYMBOL(skb_realloc_headroom);
+EXPORT_SYMBOL(skb_copy_expand);
 EXPORT_SYMBOL(datagram_poll);
 EXPORT_SYMBOL(put_cmsg);
 EXPORT_SYMBOL(sock_kmalloc);
Only in linux-tmp/net: netsyms.c.orig

--
Hacking time.

<Prev in Thread] Current Thread [Next in Thread>