This source file includes following definitions.
- show_net_buffers
- skb_check
- skb_queue_head_init
- skb_queue_head
- skb_queue_tail
- skb_dequeue
- skb_insert
- skb_append
- skb_unlink
- skb_put
- skb_push
- skb_pull
- skb_headroom
- skb_tailroom
- skb_reserve
- skb_trim
- kfree_skb
- alloc_skb
- __kfree_skbmem
- kfree_skbmem
- skb_clone
- skb_copy
- skb_device_lock
- skb_device_unlock
- dev_kfree_skb
- dev_alloc_skb
- skb_device_locked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/config.h>
29 #include <linux/types.h>
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <asm/segment.h>
33 #include <asm/system.h>
34 #include <linux/mm.h>
35 #include <linux/interrupt.h>
36 #include <linux/in.h>
37 #include <linux/inet.h>
38 #include <linux/netdevice.h>
39 #include <net/ip.h>
40 #include <net/protocol.h>
41 #include <linux/string.h>
42 #include <net/route.h>
43 #include <net/tcp.h>
44 #include <net/udp.h>
45 #include <linux/skbuff.h>
46 #include <net/sock.h>
47
48
49
50
51
52
53 unsigned long net_skbcount = 0;
54 unsigned long net_locked = 0;
55 unsigned long net_allocs = 0;
56 unsigned long net_fails = 0;
57 unsigned long net_free_locked = 0;
58
59 extern unsigned long ip_frag_mem;
60
61 void show_net_buffers(void)
62 {
63 printk("Networking buffers in use : %lu\n",net_skbcount);
64 printk("Network buffers locked by drivers : %lu\n",net_locked);
65 printk("Total network buffer allocations : %lu\n",net_allocs);
66 printk("Total failed network buffer allocs : %lu\n",net_fails);
67 printk("Total free while locked events : %lu\n",net_free_locked);
68 #ifdef CONFIG_INET
69 printk("IP fragment buffer size : %lu\n",ip_frag_mem);
70 #endif
71 }
72
73 #if CONFIG_SKB_CHECK
74
75
76
77
78
79 int skb_check(struct sk_buff *skb, int head, int line, char *file)
80 {
81 if (head) {
82 if (skb->magic_debug_cookie != SK_HEAD_SKB) {
83 printk("File: %s Line %d, found a bad skb-head\n",
84 file,line);
85 return -1;
86 }
87 if (!skb->next || !skb->prev) {
88 printk("skb_check: head without next or prev\n");
89 return -1;
90 }
91 if (skb->next->magic_debug_cookie != SK_HEAD_SKB
92 && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
93 printk("File: %s Line %d, bad next head-skb member\n",
94 file,line);
95 return -1;
96 }
97 if (skb->prev->magic_debug_cookie != SK_HEAD_SKB
98 && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
99 printk("File: %s Line %d, bad prev head-skb member\n",
100 file,line);
101 return -1;
102 }
103 #if 0
104 {
105 struct sk_buff *skb2 = skb->next;
106 int i = 0;
107 while (skb2 != skb && i < 5) {
108 if (skb_check(skb2, 0, line, file) < 0) {
109 printk("bad queue element in whole queue\n");
110 return -1;
111 }
112 i++;
113 skb2 = skb2->next;
114 }
115 }
116 #endif
117 return 0;
118 }
119 if (skb->next != NULL && skb->next->magic_debug_cookie != SK_HEAD_SKB
120 && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
121 printk("File: %s Line %d, bad next skb member\n",
122 file,line);
123 return -1;
124 }
125 if (skb->prev != NULL && skb->prev->magic_debug_cookie != SK_HEAD_SKB
126 && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
127 printk("File: %s Line %d, bad prev skb member\n",
128 file,line);
129 return -1;
130 }
131
132
133 if(skb->magic_debug_cookie==SK_FREED_SKB)
134 {
135 printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
136 file,line);
137 printk("skb=%p, real size=%d, free=%d\n",
138 skb,skb->truesize,skb->free);
139 return -1;
140 }
141 if(skb->magic_debug_cookie!=SK_GOOD_SKB)
142 {
143 printk("File: %s Line %d, passed a non skb!\n", file,line);
144 printk("skb=%p, real size=%d, free=%d\n",
145 skb,skb->truesize,skb->free);
146 return -1;
147 }
148 if(skb->head>skb->data)
149 {
150 printk("File: %s Line %d, head > data !\n", file,line);
151 printk("skb=%p, head=%p, data=%p\n",
152 skb,skb->head,skb->data);
153 return -1;
154 }
155 if(skb->tail>skb->end)
156 {
157 printk("File: %s Line %d, tail > end!\n", file,line);
158 printk("skb=%p, tail=%p, end=%p\n",
159 skb,skb->tail,skb->end);
160 return -1;
161 }
162 if(skb->data>skb->tail)
163 {
164 printk("File: %s Line %d, data > tail!\n", file,line);
165 printk("skb=%p, data=%p, tail=%p\n",
166 skb,skb->data,skb->tail);
167 return -1;
168 }
169 if(skb->tail-skb->data!=skb->len)
170 {
171 printk("File: %s Line %d, wrong length\n", file,line);
172 printk("skb=%p, data=%p, end=%p len=%ld\n",
173 skb,skb->data,skb->end,skb->len);
174 return -1;
175 }
176 if((unsigned long) skb->end > (unsigned long) skb)
177 {
178 printk("File: %s Line %d, control overrun\n", file,line);
179 printk("skb=%p, end=%p\n",
180 skb,skb->end);
181 return -1;
182 }
183
184
185 return 0;
186 }
187 #endif
188
189
190 #if CONFIG_SKB_CHECK
191 void skb_queue_head_init(struct sk_buff_head *list)
192 {
193 list->prev = (struct sk_buff *)list;
194 list->next = (struct sk_buff *)list;
195 list->qlen = 0;
196 list->magic_debug_cookie = SK_HEAD_SKB;
197 }
198
199
200
201
202
203 void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
204 {
205 unsigned long flags;
206 struct sk_buff *list = (struct sk_buff *)list_;
207
208 save_flags(flags);
209 cli();
210
211 IS_SKB(newsk);
212 IS_SKB_HEAD(list);
213 if (newsk->next || newsk->prev)
214 printk("Suspicious queue head: sk_buff on list!\n");
215
216 newsk->next = list->next;
217 newsk->prev = list;
218
219 newsk->next->prev = newsk;
220 newsk->prev->next = newsk;
221 newsk->list = list_;
222 list_->qlen++;
223
224 restore_flags(flags);
225 }
226
227
228
229
230 void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
231 {
232 unsigned long flags;
233 struct sk_buff *list = (struct sk_buff *)list_;
234
235 save_flags(flags);
236 cli();
237
238 if (newsk->next || newsk->prev)
239 printk("Suspicious queue tail: sk_buff on list!\n");
240 IS_SKB(newsk);
241 IS_SKB_HEAD(list);
242
243 newsk->next = list;
244 newsk->prev = list->prev;
245
246 newsk->next->prev = newsk;
247 newsk->prev->next = newsk;
248
249 newsk->list = list_;
250 list_->qlen++;
251
252 restore_flags(flags);
253 }
254
255
256
257
258
259
260 struct sk_buff *skb_dequeue(struct sk_buff_head *list_)
261 {
262 long flags;
263 struct sk_buff *result;
264 struct sk_buff *list = (struct sk_buff *)list_;
265
266 save_flags(flags);
267 cli();
268
269 IS_SKB_HEAD(list);
270
271 result = list->next;
272 if (result == list) {
273 restore_flags(flags);
274 return NULL;
275 }
276
277 result->next->prev = list;
278 list->next = result->next;
279
280 result->next = NULL;
281 result->prev = NULL;
282 list_->qlen--;
283 result->list = NULL;
284
285 restore_flags(flags);
286
287 IS_SKB(result);
288 return result;
289 }
290
291
292
293
294 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
295 {
296 unsigned long flags;
297
298 IS_SKB(old);
299 IS_SKB(newsk);
300
301 if(!old->next || !old->prev)
302 printk("insert before unlisted item!\n");
303 if(newsk->next || newsk->prev)
304 printk("inserted item is already on a list.\n");
305
306 save_flags(flags);
307 cli();
308 newsk->next = old;
309 newsk->prev = old->prev;
310 old->prev = newsk;
311 newsk->prev->next = newsk;
312 newsk->list = old->list;
313 newsk->list->qlen++;
314
315 restore_flags(flags);
316 }
317
318
319
320
321 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
322 {
323 unsigned long flags;
324
325 IS_SKB(old);
326 IS_SKB(newsk);
327
328 if(!old->next || !old->prev)
329 printk("append before unlisted item!\n");
330 if(newsk->next || newsk->prev)
331 printk("append item is already on a list.\n");
332
333 save_flags(flags);
334 cli();
335
336 newsk->prev = old;
337 newsk->next = old->next;
338 newsk->next->prev = newsk;
339 old->next = newsk;
340 newsk->list = old->list;
341 newsk->list->qlen++;
342
343 restore_flags(flags);
344 }
345
346
347
348
349
350
351
352 void skb_unlink(struct sk_buff *skb)
353 {
354 unsigned long flags;
355
356 save_flags(flags);
357 cli();
358
359 IS_SKB(skb);
360
361 if(skb->list)
362 {
363 skb->list->qlen--;
364 skb->next->prev = skb->prev;
365 skb->prev->next = skb->next;
366 skb->next = NULL;
367 skb->prev = NULL;
368 skb->list = NULL;
369 }
370 #ifdef PARANOID_BUGHUNT_MODE
371 else
372 printk("skb_unlink: not a linked element\n");
373 #endif
374 restore_flags(flags);
375 }
376
377
378
379
380
381 unsigned char *skb_put(struct sk_buff *skb, int len)
382 {
383 unsigned char *tmp=skb->tail;
384 IS_SKB(skb);
385 skb->tail+=len;
386 skb->len+=len;
387 IS_SKB(skb);
388 if(skb->tail>skb->end)
389 panic("skput:over: %p:%d", __builtin_return_address(0),len);
390 return tmp;
391 }
392
393 unsigned char *skb_push(struct sk_buff *skb, int len)
394 {
395 IS_SKB(skb);
396 skb->data-=len;
397 skb->len+=len;
398 IS_SKB(skb);
399 if(skb->data<skb->head)
400 panic("skpush:under: %p:%d", __builtin_return_address(0),len);
401 return skb->data;
402 }
403
404 unsigned char * skb_pull(struct sk_buff *skb, int len)
405 {
406 IS_SKB(skb);
407 if(len>skb->len)
408 return 0;
409 skb->data+=len;
410 skb->len-=len;
411 return skb->data;
412 }
413
414 int skb_headroom(struct sk_buff *skb)
415 {
416 IS_SKB(skb);
417 return skb->data-skb->head;
418 }
419
420 int skb_tailroom(struct sk_buff *skb)
421 {
422 IS_SKB(skb);
423 return skb->end-skb->tail;
424 }
425
426 void skb_reserve(struct sk_buff *skb, int len)
427 {
428 IS_SKB(skb);
429 skb->data+=len;
430 skb->tail+=len;
431 if(skb->tail>skb->end)
432 panic("sk_res: over");
433 if(skb->data<skb->head)
434 panic("sk_res: under");
435 IS_SKB(skb);
436 }
437
438 void skb_trim(struct sk_buff *skb, int len)
439 {
440 IS_SKB(skb);
441 if(skb->len>len)
442 {
443 skb->len=len;
444 skb->tail=skb->data+len;
445 }
446 }
447
448
449
450 #endif
451
452
453
454
455
456
457 void kfree_skb(struct sk_buff *skb, int rw)
458 {
459 if (skb == NULL)
460 {
461 printk("kfree_skb: skb = NULL (from %p)\n",
462 __builtin_return_address(0));
463 return;
464 }
465 #if CONFIG_SKB_CHECK
466 IS_SKB(skb);
467 #endif
468 if (skb->lock)
469 {
470 skb->free = 3;
471 net_free_locked++;
472 return;
473 }
474 if (skb->free == 2)
475 printk("Warning: kfree_skb passed an skb that nobody set the free flag on! (from %p)\n",
476 __builtin_return_address(0));
477 if (skb->list)
478 printk("Warning: kfree_skb passed an skb still on a list (from %p).\n",
479 __builtin_return_address(0));
480
481 if(skb->destructor)
482 skb->destructor(skb);
483 if (skb->sk)
484 {
485 if(skb->sk->prot!=NULL)
486 {
487 if (rw)
488 sock_rfree(skb->sk, skb);
489 else
490 sock_wfree(skb->sk, skb);
491
492 }
493 else
494 {
495 unsigned long flags;
496
497 save_flags(flags);
498 cli();
499 if (rw)
500 skb->sk->rmem_alloc-=skb->truesize;
501 else
502 skb->sk->wmem_alloc-=skb->truesize;
503 restore_flags(flags);
504 if(!skb->sk->dead)
505 skb->sk->write_space(skb->sk);
506 kfree_skbmem(skb);
507 }
508 }
509 else
510 kfree_skbmem(skb);
511 }
512
513
514
515
516
517 struct sk_buff *alloc_skb(unsigned int size,int priority)
518 {
519 struct sk_buff *skb;
520 int len=size;
521 unsigned char *bptr;
522
523 if (intr_count && priority!=GFP_ATOMIC)
524 {
525 static int count = 0;
526 if (++count < 5) {
527 printk("alloc_skb called nonatomically from interrupt %p\n",
528 __builtin_return_address(0));
529 priority = GFP_ATOMIC;
530 }
531 }
532
533 size=(size+15)&~15;
534 size+=sizeof(struct sk_buff);
535
536
537
538
539
540 bptr=(unsigned char *)kmalloc(size,priority);
541 if (bptr == NULL)
542 {
543 net_fails++;
544 return NULL;
545 }
546 #ifdef PARANOID_BUGHUNT_MODE
547 if(skb->magic_debug_cookie == SK_GOOD_SKB)
548 printk("Kernel kmalloc handed us an existing skb (%p)\n",skb);
549 #endif
550
551
552
553
554
555
556
557 net_allocs++;
558
559 skb=(struct sk_buff *)(bptr+size)-1;
560
561 skb->count = 1;
562 skb->data_skb = NULL;
563
564 skb->free = 2;
565 skb->lock = 0;
566 skb->pkt_type = PACKET_HOST;
567 skb->prev = skb->next = skb->link3 = NULL;
568 skb->list = NULL;
569 skb->sk = NULL;
570 skb->truesize=size;
571 skb->localroute=0;
572 skb->stamp.tv_sec=0;
573 skb->localroute = 0;
574 skb->ip_summed = 0;
575 memset(skb->proto_priv, 0, sizeof(skb->proto_priv));
576 net_skbcount++;
577 #if CONFIG_SKB_CHECK
578 skb->magic_debug_cookie = SK_GOOD_SKB;
579 #endif
580 skb->users = 0;
581
582 skb->head=bptr;
583 skb->data=bptr;
584 skb->tail=bptr;
585 skb->end=bptr+len;
586 skb->len=0;
587 skb->destructor=NULL;
588 return skb;
589 }
590
591
592
593
594
595 static inline void __kfree_skbmem(struct sk_buff *skb)
596 {
597
598 if (--skb->count <= 0) {
599 kfree(skb->head);
600 net_skbcount--;
601 }
602 }
603
604 void kfree_skbmem(struct sk_buff *skb)
605 {
606 unsigned long flags;
607 void * addr = skb->head;
608
609 save_flags(flags);
610 cli();
611
612 if (--skb->count <= 0) {
613
614 if (skb->data_skb) {
615 addr = skb;
616 __kfree_skbmem(skb->data_skb);
617 }
618 kfree(addr);
619 net_skbcount--;
620 }
621 restore_flags(flags);
622 }
623
624
625
626
627
628
629 struct sk_buff *skb_clone(struct sk_buff *skb, int priority)
630 {
631 unsigned long flags;
632 struct sk_buff *n;
633
634 IS_SKB(skb);
635 n = kmalloc(sizeof(*n), priority);
636 if (!n)
637 return NULL;
638 memcpy(n, skb, sizeof(*n));
639 n->count = 1;
640 if (skb->data_skb)
641 skb = skb->data_skb;
642 save_flags(flags);
643 cli();
644 skb->count++;
645 net_allocs++;
646 net_skbcount++;
647 restore_flags(flags);
648 n->data_skb = skb;
649 n->next = n->prev = n->link3 = NULL;
650 n->list = NULL;
651 n->sk = NULL;
652 n->truesize = sizeof(*n);
653 n->free = 1;
654 n->tries = 0;
655 n->lock = 0;
656 n->users = 0;
657 return n;
658 }
659
660
661
662
663
664 struct sk_buff *skb_copy(struct sk_buff *skb, int priority)
665 {
666 struct sk_buff *n;
667 unsigned long offset;
668
669
670
671
672
673 IS_SKB(skb);
674
675 n=alloc_skb(skb->truesize-sizeof(struct sk_buff),priority);
676 if(n==NULL)
677 return NULL;
678
679
680
681
682
683 offset=n->head-skb->head;
684
685
686 skb_reserve(n,skb->data-skb->head);
687
688 skb_put(n,skb->len);
689
690 memcpy(n->head,skb->head,skb->end-skb->head);
691 n->link3=NULL;
692 n->list=NULL;
693 n->sk=NULL;
694 n->when=skb->when;
695 n->dev=skb->dev;
696 n->h.raw=skb->h.raw+offset;
697 n->mac.raw=skb->mac.raw+offset;
698 n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
699 n->saddr=skb->saddr;
700 n->daddr=skb->daddr;
701 n->raddr=skb->raddr;
702 n->seq=skb->seq;
703 n->end_seq=skb->end_seq;
704 n->ack_seq=skb->ack_seq;
705 n->acked=skb->acked;
706 memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
707 n->used=skb->used;
708 n->free=1;
709 n->arp=skb->arp;
710 n->tries=0;
711 n->lock=0;
712 n->users=0;
713 n->pkt_type=skb->pkt_type;
714 n->stamp=skb->stamp;
715
716 IS_SKB(n);
717 return n;
718 }
719
720
721
722
723
724 void skb_device_lock(struct sk_buff *skb)
725 {
726 if(skb->lock)
727 printk("double lock on device queue!\n");
728 else
729 net_locked++;
730 skb->lock++;
731 }
732
733 void skb_device_unlock(struct sk_buff *skb)
734 {
735 if(skb->lock==0)
736 printk("double unlock on device queue!\n");
737 skb->lock--;
738 if(skb->lock==0)
739 net_locked--;
740 }
741
742 void dev_kfree_skb(struct sk_buff *skb, int mode)
743 {
744 unsigned long flags;
745
746 save_flags(flags);
747 cli();
748 if(skb->lock==1)
749 net_locked--;
750
751 if (!--skb->lock && (skb->free == 1 || skb->free == 3))
752 {
753 restore_flags(flags);
754 kfree_skb(skb,mode);
755 }
756 else
757 restore_flags(flags);
758 }
759
760 struct sk_buff *dev_alloc_skb(unsigned int length)
761 {
762 struct sk_buff *skb;
763
764 skb = alloc_skb(length+16, GFP_ATOMIC);
765 if (skb)
766 skb_reserve(skb,16);
767 return skb;
768 }
769
770 int skb_device_locked(struct sk_buff *skb)
771 {
772 return skb->lock? 1 : 0;
773 }