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.
|