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