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