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 void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
163 {
164 unsigned long flags;
165 struct sk_buff *list = (struct sk_buff *)list_;
166
167 save_flags(flags);
168 cli();
169
170 #if CONFIG_SKB_CHECK
171 IS_SKB(newsk);
172 IS_SKB_HEAD(list);
173 if (newsk->next || newsk->prev)
174 printk("Suspicious queue head: sk_buff on list!\n");
175 #endif
176
177 newsk->next = list->next;
178 newsk->prev = list;
179
180 newsk->next->prev = newsk;
181 newsk->prev->next = newsk;
182
183 restore_flags(flags);
184 }
185
186
187
188
189 void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
190 {
191 unsigned long flags;
192 struct sk_buff *list = (struct sk_buff *)list_;
193
194 save_flags(flags);
195 cli();
196
197 #if CONFIG_SKB_CHECK
198 if (newsk->next || newsk->prev)
199 printk("Suspicious queue tail: sk_buff on list!\n");
200 IS_SKB(newsk);
201 IS_SKB_HEAD(list);
202 #endif
203
204 newsk->next = list;
205 newsk->prev = list->prev;
206
207 newsk->next->prev = newsk;
208 newsk->prev->next = newsk;
209
210 restore_flags(flags);
211 }
212
213
214
215
216
217
218 struct sk_buff *skb_dequeue(struct sk_buff_head *list_)
219 {
220 long flags;
221 struct sk_buff *result;
222 struct sk_buff *list = (struct sk_buff *)list_;
223
224 save_flags(flags);
225 cli();
226
227 IS_SKB_HEAD(list);
228
229 result = list->next;
230 if (result == list) {
231 restore_flags(flags);
232 return NULL;
233 }
234
235 result->next->prev = list;
236 list->next = result->next;
237
238 result->next = NULL;
239 result->prev = NULL;
240
241 restore_flags(flags);
242
243 IS_SKB(result);
244 return result;
245 }
246
247
248
249
250 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
251 {
252 unsigned long flags;
253
254 #if CONFIG_SKB_CHECK
255 IS_SKB(old);
256 IS_SKB(newsk);
257
258 if(!old->next || !old->prev)
259 printk("insert before unlisted item!\n");
260 if(newsk->next || newsk->prev)
261 printk("inserted item is already on a list.\n");
262 #endif
263
264 save_flags(flags);
265 cli();
266 newsk->next = old;
267 newsk->prev = old->prev;
268 old->prev = newsk;
269 newsk->prev->next = newsk;
270
271 restore_flags(flags);
272 }
273
274
275
276
277 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
278 {
279 unsigned long flags;
280
281 #if CONFIG_SKB_CHECK
282 IS_SKB(old);
283 IS_SKB(newsk);
284
285 if(!old->next || !old->prev)
286 printk("append before unlisted item!\n");
287 if(newsk->next || newsk->prev)
288 printk("append item is already on a list.\n");
289 #endif
290
291 save_flags(flags);
292 cli();
293
294 newsk->prev = old;
295 newsk->next = old->next;
296 newsk->next->prev = newsk;
297 old->next = newsk;
298
299 restore_flags(flags);
300 }
301
302
303
304
305
306
307
308 void skb_unlink(struct sk_buff *skb)
309 {
310 unsigned long flags;
311
312 save_flags(flags);
313 cli();
314
315 IS_SKB(skb);
316
317 if(skb->prev && skb->next)
318 {
319 skb->next->prev = skb->prev;
320 skb->prev->next = skb->next;
321 skb->next = NULL;
322 skb->prev = NULL;
323 }
324 #ifdef PARANOID_BUGHUNT_MODE
325 else
326 printk("skb_unlink: not a linked element\n");
327 #endif
328 restore_flags(flags);
329 }
330
331
332
333
334
335
336 void kfree_skb(struct sk_buff *skb, int rw)
337 {
338 if (skb == NULL)
339 {
340 printk("kfree_skb: skb = NULL (from %p)\n",
341 __builtin_return_address(0));
342 return;
343 }
344 IS_SKB(skb);
345 if (skb->lock)
346 {
347 skb->free = 3;
348 net_free_locked++;
349 return;
350 }
351 if (skb->free == 2)
352 printk("Warning: kfree_skb passed an skb that nobody set the free flag on! (from %p)\n",
353 __builtin_return_address(0));
354 if (skb->next)
355 printk("Warning: kfree_skb passed an skb still on a list (from %p).\n",
356 __builtin_return_address(0));
357 if (skb->sk)
358 {
359 if(skb->sk->prot!=NULL)
360 {
361 if (rw)
362 skb->sk->prot->rfree(skb->sk, skb, skb->mem_len);
363 else
364 skb->sk->prot->wfree(skb->sk, skb, skb->mem_len);
365
366 }
367 else
368 {
369
370 if (rw)
371 skb->sk->rmem_alloc-=skb->mem_len;
372 else
373 skb->sk->wmem_alloc-=skb->mem_len;
374 if(!skb->sk->dead)
375 skb->sk->write_space(skb->sk);
376 #ifdef CONFIG_SLAVE_BALANCING
377 if(skb->in_dev_queue && skb->dev!=NULL)
378 skb->dev->pkt_queue--;
379 #endif
380 kfree_skbmem(skb,skb->mem_len);
381 }
382 }
383 else
384 {
385 #ifdef CONFIG_SLAVE_BALANCING
386 if(skb->in_dev_queue && skb->dev!=NULL)
387 skb->dev->pkt_queue--;
388 #endif
389 kfree_skbmem(skb, skb->mem_len);
390 }
391 }
392
393
394
395
396
397 struct sk_buff *alloc_skb(unsigned int size,int priority)
398 {
399 struct sk_buff *skb;
400 unsigned long flags;
401
402 if (intr_count && priority!=GFP_ATOMIC) {
403 static int count = 0;
404 if (++count < 5) {
405 printk("alloc_skb called nonatomically from interrupt %p\n",
406 __builtin_return_address(0));
407 priority = GFP_ATOMIC;
408 }
409 }
410
411 size+=sizeof(struct sk_buff);
412 skb=(struct sk_buff *)kmalloc(size,priority);
413 if (skb == NULL)
414 {
415 net_fails++;
416 return NULL;
417 }
418 #ifdef PARANOID_BUGHUNT_MODE
419 if(skb->magic_debug_cookie == SK_GOOD_SKB)
420 printk("Kernel kmalloc handed us an existing skb (%p)\n",skb);
421 #endif
422
423 net_allocs++;
424
425 skb->free = 2;
426 skb->lock = 0;
427 skb->pkt_type = PACKET_HOST;
428 skb->truesize = size;
429 skb->mem_len = size;
430 skb->mem_addr = skb;
431 #ifdef CONFIG_SLAVE_BALANCING
432 skb->in_dev_queue = 0;
433 #endif
434 skb->fraglist = NULL;
435 skb->prev = skb->next = NULL;
436 skb->link3 = NULL;
437 skb->sk = NULL;
438 skb->localroute=0;
439 skb->stamp.tv_sec=0;
440 skb->localroute = 0;
441 save_flags(flags);
442 cli();
443 net_memory += size;
444 net_skbcount++;
445 restore_flags(flags);
446 #if CONFIG_SKB_CHECK
447 skb->magic_debug_cookie = SK_GOOD_SKB;
448 #endif
449 skb->users = 0;
450 return skb;
451 }
452
453
454
455
456
457 void kfree_skbmem(struct sk_buff *skb,unsigned size)
458 {
459 unsigned long flags;
460 #ifdef CONFIG_SLAVE_BALANCING
461 save_flags(flags);
462 cli();
463 if(skb->in_dev_queue && skb->dev!=NULL)
464 skb->dev->pkt_queue--;
465 restore_flags(flags);
466 #endif
467 IS_SKB(skb);
468 if(size!=skb->truesize)
469 printk("kfree_skbmem: size mismatch.\n");
470
471 if(skb->magic_debug_cookie == SK_GOOD_SKB)
472 {
473 save_flags(flags);
474 cli();
475 IS_SKB(skb);
476 skb->magic_debug_cookie = SK_FREED_SKB;
477 kfree_s((void *)skb,size);
478 net_skbcount--;
479 net_memory -= size;
480 restore_flags(flags);
481 }
482 else
483 printk("kfree_skbmem: bad magic cookie\n");
484 }
485
486
487
488
489
490
491 struct sk_buff *skb_clone(struct sk_buff *skb, int priority)
492 {
493 struct sk_buff *n;
494 unsigned long offset;
495
496 n=alloc_skb(skb->mem_len-sizeof(struct sk_buff),priority);
497 if(n==NULL)
498 return NULL;
499
500 offset=((char *)n)-((char *)skb);
501
502 memcpy(n->data,skb->data,skb->mem_len-sizeof(struct sk_buff));
503 n->len=skb->len;
504 n->link3=NULL;
505 n->sk=NULL;
506 n->when=skb->when;
507 n->dev=skb->dev;
508 n->h.raw=skb->h.raw+offset;
509 n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
510 n->fraglen=skb->fraglen;
511 n->fraglist=skb->fraglist;
512 n->saddr=skb->saddr;
513 n->daddr=skb->daddr;
514 n->raddr=skb->raddr;
515 n->acked=skb->acked;
516 n->used=skb->used;
517 n->free=1;
518 n->arp=skb->arp;
519 n->tries=0;
520 n->lock=0;
521 n->users=0;
522 n->pkt_type=skb->pkt_type;
523 return n;
524 }
525
526
527
528
529
530
531 void skb_device_lock(struct sk_buff *skb)
532 {
533 if(skb->lock)
534 printk("double lock on device queue!\n");
535 else
536 net_locked++;
537 skb->lock++;
538 }
539
540 void skb_device_unlock(struct sk_buff *skb)
541 {
542 if(skb->lock==0)
543 printk("double unlock on device queue!\n");
544 skb->lock--;
545 if(skb->lock==0)
546 net_locked--;
547 }
548
549 void dev_kfree_skb(struct sk_buff *skb, int mode)
550 {
551 unsigned long flags;
552
553 save_flags(flags);
554 cli();
555 if(skb->lock==1)
556 net_locked--;
557
558 if (!--skb->lock && (skb->free == 1 || skb->free == 3))
559 {
560 restore_flags(flags);
561 kfree_skb(skb,mode);
562 }
563 else
564 restore_flags(flags);
565 }
566
567 int skb_device_locked(struct sk_buff *skb)
568 {
569 return skb->lock? 1 : 0;
570 }
571