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