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