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