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