patch-2.1.36 linux/net/core/skbuff.c
Next file: linux/net/core/sock.c
Previous file: linux/net/core/net_alias.c
Back to the patch index
Back to the overall index
- Lines: 692
- Date:
Tue Apr 22 22:46:27 1997
- Orig file:
v2.1.35/linux/net/core/skbuff.c
- Orig date:
Mon Apr 14 16:28:27 1997
diff -u --recursive --new-file v2.1.35/linux/net/core/skbuff.c linux/net/core/skbuff.c
@@ -60,9 +60,9 @@
* Resource tracking variables
*/
-static atomic_t net_skbcount = ATOMIC_INIT;
-static atomic_t net_allocs = ATOMIC_INIT;
-static atomic_t net_fails = ATOMIC_INIT;
+static atomic_t net_skbcount = ATOMIC_INIT(0);
+static atomic_t net_allocs = ATOMIC_INIT(0);
+static atomic_t net_fails = ATOMIC_INIT(0);
extern atomic_t ip_frag_mem;
@@ -87,509 +87,17 @@
#endif
}
-#if CONFIG_SKB_CHECK
-
-/*
- * Debugging paranoia. Used for debugging network stacks.
- */
-
-int skb_check(struct sk_buff *skb, int head, int line, char *file)
-{
- if (head) {
- if (skb->magic_debug_cookie != SK_HEAD_SKB) {
- printk("File: %s Line %d, found a bad skb-head\n",
- file,line);
- return -1;
- }
- if (!skb->next || !skb->prev) {
- printk("skb_check: head without next or prev\n");
- return -1;
- }
- if (skb->next->magic_debug_cookie != SK_HEAD_SKB
- && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
- printk("File: %s Line %d, bad next head-skb member\n",
- file,line);
- return -1;
- }
- if (skb->prev->magic_debug_cookie != SK_HEAD_SKB
- && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
- printk("File: %s Line %d, bad prev head-skb member\n",
- file,line);
- return -1;
- }
- return 0;
- }
- if (skb->next != NULL && skb->next->magic_debug_cookie != SK_HEAD_SKB
- && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
- printk("File: %s Line %d, bad next skb member\n",
- file,line);
- return -1;
- }
- if (skb->prev != NULL && skb->prev->magic_debug_cookie != SK_HEAD_SKB
- && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
- printk("File: %s Line %d, bad prev skb member\n",
- file,line);
- return -1;
- }
-
-
- if(skb->magic_debug_cookie==SK_FREED_SKB)
- {
- printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
- file,line);
- printk("skb=%p, real size=%d, free=%d\n",
- skb,skb->truesize,skb->free);
- return -1;
- }
- if(skb->magic_debug_cookie!=SK_GOOD_SKB)
- {
- printk("File: %s Line %d, passed a non skb!\n", file,line);
- printk("skb=%p, real size=%d, free=%d\n",
- skb,skb->truesize,skb->free);
- return -1;
- }
- if(skb->head>skb->data)
- {
- printk("File: %s Line %d, head > data !\n", file,line);
- printk("skb=%p, head=%p, data=%p\n",
- skb,skb->head,skb->data);
- return -1;
- }
- if(skb->tail>skb->end)
- {
- printk("File: %s Line %d, tail > end!\n", file,line);
- printk("skb=%p, tail=%p, end=%p\n",
- skb,skb->tail,skb->end);
- return -1;
- }
- if(skb->data>skb->tail)
- {
- printk("File: %s Line %d, data > tail!\n", file,line);
- printk("skb=%p, data=%p, tail=%p\n",
- skb,skb->data,skb->tail);
- return -1;
- }
- if(skb->tail-skb->data!=skb->len)
- {
- printk("File: %s Line %d, wrong length\n", file,line);
- printk("skb=%p, data=%p, end=%p len=%ld\n",
- skb,skb->data,skb->end,skb->len);
- return -1;
- }
- if((unsigned long) skb->end > (unsigned long) skb)
- {
- printk("File: %s Line %d, control overrun\n", file,line);
- printk("skb=%p, end=%p\n",
- skb,skb->end);
- return -1;
- }
-
- /* Guess it might be acceptable then */
- return 0;
-}
-#endif
-
-
-#if CONFIG_SKB_CHECK
-void skb_queue_head_init(struct sk_buff_head *list)
-{
- list->prev = (struct sk_buff *)list;
- list->next = (struct sk_buff *)list;
- list->qlen = 0;
- list->magic_debug_cookie = SK_HEAD_SKB;
-}
-
-
-/*
- * Insert an sk_buff at the start of a list.
- */
-void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
-{
- unsigned long flags;
- struct sk_buff *list = (struct sk_buff *)list_;
-
- save_flags(flags);
- cli();
-
- IS_SKB(newsk);
- IS_SKB_HEAD(list);
- if (newsk->next || newsk->prev)
- printk("Suspicious queue head: sk_buff on list!\n");
-
- newsk->next = list->next;
- newsk->prev = list;
-
- newsk->next->prev = newsk;
- newsk->prev->next = newsk;
- newsk->list = list_;
- list_->qlen++;
-
- restore_flags(flags);
-}
-
-void __skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
-{
- struct sk_buff *list = (struct sk_buff *)list_;
-
-
- IS_SKB(newsk);
- IS_SKB_HEAD(list);
- if (newsk->next || newsk->prev)
- printk("Suspicious queue head: sk_buff on list!\n");
-
- newsk->next = list->next;
- newsk->prev = list;
-
- newsk->next->prev = newsk;
- newsk->prev->next = newsk;
- newsk->list = list_;
- list_->qlen++;
-
-}
-
-/*
- * Insert an sk_buff at the end of a list.
- */
-void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
-{
- unsigned long flags;
- struct sk_buff *list = (struct sk_buff *)list_;
-
- save_flags(flags);
- cli();
-
- if (newsk->next || newsk->prev)
- printk("Suspicious queue tail: sk_buff on list!\n");
- IS_SKB(newsk);
- IS_SKB_HEAD(list);
-
- newsk->next = list;
- newsk->prev = list->prev;
-
- newsk->next->prev = newsk;
- newsk->prev->next = newsk;
-
- newsk->list = list_;
- list_->qlen++;
-
- restore_flags(flags);
-}
-
-void __skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
-{
- struct sk_buff *list = (struct sk_buff *)list_;
-
- if (newsk->next || newsk->prev)
- printk("Suspicious queue tail: sk_buff on list!\n");
- IS_SKB(newsk);
- IS_SKB_HEAD(list);
-
- newsk->next = list;
- newsk->prev = list->prev;
-
- newsk->next->prev = newsk;
- newsk->prev->next = newsk;
-
- newsk->list = list_;
- list_->qlen++;
-}
-
-/*
- * Remove an sk_buff from a list. This routine is also interrupt safe
- * so you can grab read and free buffers as another process adds them.
- */
-
-struct sk_buff *skb_dequeue(struct sk_buff_head *list_)
-{
- unsigned long flags;
- struct sk_buff *result;
- struct sk_buff *list = (struct sk_buff *)list_;
-
- save_flags(flags);
- cli();
-
- IS_SKB_HEAD(list);
-
- result = list->next;
- if (result == list) {
- restore_flags(flags);
- return NULL;
- }
-
- result->next->prev = list;
- list->next = result->next;
-
- result->next = NULL;
- result->prev = NULL;
- list_->qlen--;
- result->list = NULL;
-
- restore_flags(flags);
-
- IS_SKB(result);
- return result;
-}
-
-struct sk_buff *__skb_dequeue(struct sk_buff_head *list_)
-{
- struct sk_buff *result;
- struct sk_buff *list = (struct sk_buff *)list_;
-
- IS_SKB_HEAD(list);
-
- result = list->next;
- if (result == list) {
- return NULL;
- }
-
- result->next->prev = list;
- list->next = result->next;
-
- result->next = NULL;
- result->prev = NULL;
- list_->qlen--;
- result->list = NULL;
-
- IS_SKB(result);
- return result;
-}
-
-/*
- * Insert a packet before another one in a list.
- */
-void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- IS_SKB(old);
- IS_SKB(newsk);
-
- if(!old->next || !old->prev)
- printk("insert before unlisted item!\n");
- if(newsk->next || newsk->prev)
- printk("inserted item is already on a list.\n");
-
- save_flags(flags);
- cli();
- newsk->next = old;
- newsk->prev = old->prev;
- old->prev = newsk;
- newsk->prev->next = newsk;
- newsk->list = old->list;
- newsk->list->qlen++;
-
- restore_flags(flags);
-}
-
-/*
- * Insert a packet before another one in a list.
- */
-
-void __skb_insert(struct sk_buff *newsk,
- struct sk_buff * prev, struct sk_buff *next,
- struct sk_buff_head * list)
-{
- IS_SKB(prev);
- IS_SKB(newsk);
- IS_SKB(next);
-
- if(!prev->next || !prev->prev)
- printk("insert after unlisted item!\n");
- if(!next->next || !next->prev)
- printk("insert before unlisted item!\n");
- if(newsk->next || newsk->prev)
- printk("inserted item is already on a list.\n");
-
- newsk->next = next;
- newsk->prev = prev;
- next->prev = newsk;
- prev->next = newsk;
- newsk->list = list;
- list->qlen++;
-
-}
-
-/*
- * Place a packet after a given packet in a list.
- */
-void skb_append(struct sk_buff *old, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- IS_SKB(old);
- IS_SKB(newsk);
-
- if(!old->next || !old->prev)
- printk("append before unlisted item!\n");
- if(newsk->next || newsk->prev)
- printk("append item is already on a list.\n");
-
- save_flags(flags);
- cli();
-
- newsk->prev = old;
- newsk->next = old->next;
- newsk->next->prev = newsk;
- old->next = newsk;
- newsk->list = old->list;
- newsk->list->qlen++;
-
- restore_flags(flags);
-}
-
-/*
- * Remove an sk_buff from its list. Works even without knowing the list it
- * is sitting on, which can be handy at times. It also means that THE LIST
- * MUST EXIST when you unlink. Thus a list must have its contents unlinked
- * _FIRST_.
- */
-void skb_unlink(struct sk_buff *skb)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- IS_SKB(skb);
-
- if(skb->list)
- {
- skb->list->qlen--;
- skb->next->prev = skb->prev;
- skb->prev->next = skb->next;
- skb->next = NULL;
- skb->prev = NULL;
- skb->list = NULL;
- }
-#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */
- else
- printk("skb_unlink: not a linked element\n");
-#endif
- restore_flags(flags);
-}
-
-void __skb_unlink(struct sk_buff *skb)
-{
- IS_SKB(skb);
-
- if(skb->list)
- {
- skb->list->qlen--;
- skb->next->prev = skb->prev;
- skb->prev->next = skb->next;
- skb->next = NULL;
- skb->prev = NULL;
- skb->list = NULL;
- }
-#ifdef PARANOID_BUGHUNT_MODE /* This is legal but we sometimes want to watch it */
- else
- printk("skb_unlink: not a linked element\n");
-#endif
-}
-
-/*
- * Add data to an sk_buff
- */
-
-unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
-{
- unsigned char *tmp=skb->tail;
- IS_SKB(skb);
- skb->tail+=len;
- skb->len+=len;
- IS_SKB(skb);
- if(skb->tail>skb->end)
- panic("skput:over: %p:%d", __builtin_return_address(0),len);
- return tmp;
-}
-
-unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
-{
- IS_SKB(skb);
- skb->data-=len;
- skb->len+=len;
- IS_SKB(skb);
- if(skb->data<skb->head)
- panic("skpush:under: %p:%d", __builtin_return_address(0),len);
- return skb->data;
-}
-
-unsigned char * skb_pull(struct sk_buff *skb, unsigned int len)
-{
- IS_SKB(skb);
- if(len>skb->len)
- return 0;
- skb->data+=len;
- skb->len-=len;
- return skb->data;
-}
-
-int skb_headroom(struct sk_buff *skb)
-{
- IS_SKB(skb);
- return skb->data-skb->head;
-}
-
-int skb_tailroom(struct sk_buff *skb)
-{
- IS_SKB(skb);
- return skb->end-skb->tail;
-}
-
-void skb_reserve(struct sk_buff *skb, unsigned int len)
-{
- IS_SKB(skb);
- skb->data+=len;
- skb->tail+=len;
- if(skb->tail>skb->end)
- panic("sk_res: over");
- if(skb->data<skb->head)
- panic("sk_res: under");
- IS_SKB(skb);
-}
-
-void skb_trim(struct sk_buff *skb, unsigned int len)
-{
- IS_SKB(skb);
- if(skb->len>len)
- {
- skb->len=len;
- skb->tail=skb->data+len;
- }
-}
-
-
-
-#endif
-
-/**************************************************************************
-
- Stuff below this point isn't debugging duplicates of the inlines
- used for buffer handling
-
-***************************************************************************/
-
/*
* Free an sk_buff. Release anything attached to the buffer.
*/
void __kfree_skb(struct sk_buff *skb)
{
-#if CONFIG_SKB_CHECK
- if (skb == NULL)
- {
- printk(KERN_CRIT "kfree_skb: skb = NULL (from %p)\n",
- __builtin_return_address(0));
- return;
- }
- IS_SKB(skb);
-#endif
if (skb->list)
- printk(KERN_WARNING "Warning: kfree_skb passed an skb still on a list (from %p).\n",
- __builtin_return_address(0));
+ printk(KERN_WARNING "Warning: kfree_skb passed an skb still "
+ "on a list (from %p).\n", __builtin_return_address(0));
dst_release(skb->dst);
-
if(skb->destructor)
skb->destructor(skb);
kfree_skbmem(skb);
@@ -607,15 +115,14 @@
struct sk_buff *alloc_skb(unsigned int size,int priority)
{
struct sk_buff *skb;
- int len;
unsigned char *bptr;
+ int len;
- if (in_interrupt() && priority!=GFP_ATOMIC)
- {
+ if (in_interrupt() && priority!=GFP_ATOMIC) {
static int count = 0;
if (++count < 5) {
- printk(KERN_ERR "alloc_skb called nonatomically from interrupt %p\n",
- __builtin_return_address(0));
+ printk(KERN_ERR "alloc_skb called nonatomically "
+ "from interrupt %p\n", __builtin_return_address(0));
priority = GFP_ATOMIC;
}
}
@@ -625,25 +132,23 @@
* 'alignment mask'.
*/
- size=(size+15)&~15; /* Allow for alignments. Make a multiple of 16 bytes */
+ /* Allow for alignments. Make a multiple of 16 bytes */
+ size = (size + 15) & ~15;
len = size;
- size+=sizeof(struct sk_buff); /* And stick the control itself on the end */
+ /* And stick the control itself on the end */
+ size += sizeof(struct sk_buff);
/*
* Allocate some space
*/
- bptr=(unsigned char *)kmalloc(size,priority);
- if (bptr == NULL)
- {
+ bptr = kmalloc(size,priority);
+ if (bptr == NULL) {
atomic_inc(&net_fails);
return NULL;
}
-#ifdef PARANOID_BUGHUNT_MODE
- if(skb->magic_debug_cookie == SK_GOOD_SKB)
- printk("Kernel kmalloc handed us an existing skb (%p)\n",skb);
-#endif
+
/*
* Now we play a little game with the caches. Linux kmalloc is
* a bit cache dumb, in fact its just about maximally non
@@ -653,7 +158,7 @@
*/
atomic_inc(&net_allocs);
- skb=(struct sk_buff *)(bptr+size)-1;
+ skb = (struct sk_buff *)(bptr + size) - 1;
atomic_set(&skb->count, 1); /* only one reference to this */
skb->data_skb = skb; /* and we're our own data skb */
@@ -672,16 +177,14 @@
memset(skb->cb, 0, sizeof(skb->cb));
skb->priority = SOPRI_NORMAL;
atomic_inc(&net_skbcount);
-#if CONFIG_SKB_CHECK
- skb->magic_debug_cookie = SK_GOOD_SKB;
-#endif
atomic_set(&skb->users, 1);
- /* Load the data pointers */
- skb->head=bptr;
- skb->data=bptr;
- skb->tail=bptr;
- skb->end=bptr+len;
- skb->len=0;
+
+ /* Load the data pointers. */
+ skb->head = bptr;
+ skb->data = bptr;
+ skb->tail = bptr;
+ skb->end = bptr + len;
+ skb->len = 0;
skb->inclone = 0;
return skb;
}
@@ -705,10 +208,7 @@
/* don't do anything if somebody still uses us */
if (atomic_dec_and_test(&skb->count)) {
-
- int free_head;
-
- free_head = (skb->inclone != SKB_CLONE_INLINE);
+ int free_head = (skb->inclone != SKB_CLONE_INLINE);
/* free the skb that contains the actual data if we've clone()'d */
if (skb->data_skb != skb) {
@@ -730,16 +230,12 @@
struct sk_buff *n;
int inbuff = 0;
- IS_SKB(skb);
- if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff))
- {
+ if (!skb->inclone && skb_tailroom(skb) >= sizeof(struct sk_buff)) {
n = ((struct sk_buff *) skb->end) - 1;
skb->end -= sizeof(struct sk_buff);
skb->inclone = SKB_CLONE_ORIG;
inbuff = SKB_CLONE_INLINE;
- }
- else
- {
+ } else {
n = kmalloc(sizeof(*n), priority);
if (!n)
return NULL;
@@ -775,8 +271,6 @@
* Allocate the copy buffer
*/
- IS_SKB(skb);
-
n=alloc_skb(skb->end - skb->head, priority);
if(n==NULL)
return NULL;
@@ -806,7 +300,6 @@
n->seq=skb->seq;
n->end_seq=skb->end_seq;
n->ack_seq=skb->ack_seq;
- n->acked=skb->acked;
memcpy(n->cb, skb->cb, sizeof(skb->cb));
n->used=skb->used;
n->arp=skb->arp;
@@ -816,7 +309,6 @@
n->stamp=skb->stamp;
n->destructor = NULL;
n->security=skb->security;
- IS_SKB(n);
return n;
}
@@ -830,8 +322,6 @@
* Allocate the copy buffer
*/
- IS_SKB(skb);
-
n=alloc_skb(skb->truesize+newheadroom-headroom-sizeof(struct sk_buff), GFP_ATOMIC);
if(n==NULL)
return NULL;
@@ -862,7 +352,6 @@
n->seq=skb->seq;
n->end_seq=skb->end_seq;
n->ack_seq=skb->ack_seq;
- n->acked=skb->acked;
n->used=skb->used;
n->arp=skb->arp;
n->tries=0;
@@ -872,7 +361,6 @@
n->destructor = NULL;
n->security=skb->security;
- IS_SKB(n);
return n;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov