root/net/core/skbuff.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. show_net_buffers
  2. skb_check
  3. skb_queue_head_init
  4. skb_queue_head
  5. __skb_queue_head
  6. skb_queue_tail
  7. __skb_queue_tail
  8. skb_dequeue
  9. __skb_dequeue
  10. skb_insert
  11. __skb_insert
  12. skb_append
  13. __skb_append
  14. skb_unlink
  15. __skb_unlink
  16. skb_put
  17. skb_push
  18. skb_pull
  19. skb_headroom
  20. skb_tailroom
  21. skb_reserve
  22. skb_trim
  23. kfree_skb
  24. alloc_skb
  25. __kfree_skbmem
  26. kfree_skbmem
  27. skb_clone
  28. skb_copy
  29. skb_device_lock
  30. skb_device_unlock
  31. dev_kfree_skb
  32. dev_alloc_skb
  33. skb_device_locked

   1 /*
   2  *      Routines having to do with the 'struct sk_buff' memory handlers.
   3  *
   4  *      Authors:        Alan Cox <iiitac@pyr.swan.ac.uk>
   5  *                      Florian La Roche <rzsfl@rz.uni-sb.de>
   6  *
   7  *      Fixes:  
   8  *              Alan Cox        :       Fixed the worst of the load balancer bugs.
   9  *              Dave Platt      :       Interrupt stacking fix.
  10  *      Richard Kooijman        :       Timestamp fixes.
  11  *              Alan Cox        :       Changed buffer format.
  12  *              Alan Cox        :       destructor hook for AF_UNIX etc.
  13  *              Linus Torvalds  :       Better skb_clone.
  14  *              Alan Cox        :       Added skb_copy.
  15  *              Alan Cox        :       Added all the changed routines Linus
  16  *                                      only put in the headers
  17  *              Ray VanTassle   :       Fixed --skb->lock in free
  18  *
  19  *      TO FIX:
  20  *              The __skb_ routines ought to check interrupts are disabled
  21  *      when called, and bitch like crazy if not. Unfortunately I don't think
  22  *      we currently have a portable way to check if interrupts are off - 
  23  *      Linus ???
  24  *
  25  *      This program is free software; you can redistribute it and/or
  26  *      modify it under the terms of the GNU General Public License
  27  *      as published by the Free Software Foundation; either version
  28  *      2 of the License, or (at your option) any later version.
  29  */
  30 
  31 /*
  32  *      The functions in this file will not compile correctly with gcc 2.4.x
  33  */
  34 
  35 #include <linux/config.h>
  36 #include <linux/types.h>
  37 #include <linux/kernel.h>
  38 #include <linux/sched.h>
  39 #include <asm/segment.h>
  40 #include <asm/system.h>
  41 #include <linux/mm.h>
  42 #include <linux/interrupt.h>
  43 #include <linux/in.h>
  44 #include <linux/inet.h>
  45 #include <linux/netdevice.h>
  46 #include <net/ip.h>
  47 #include <net/protocol.h>
  48 #include <linux/string.h>
  49 #include <net/route.h>
  50 #include <net/tcp.h>
  51 #include <net/udp.h>
  52 #include <linux/skbuff.h>
  53 #include <net/sock.h>
  54 
  55 
  56 /*
  57  *      Resource tracking variables
  58  */
  59 
  60 unsigned long net_skbcount = 0;
  61 unsigned long net_locked = 0;
  62 unsigned long net_allocs = 0;
  63 unsigned long net_fails  = 0;
  64 unsigned long net_free_locked = 0;
  65 
  66 extern unsigned long ip_frag_mem;
  67 
  68 void show_net_buffers(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  69 {
  70         printk("Networking buffers in use          : %lu\n",net_skbcount);
  71         printk("Network buffers locked by drivers  : %lu\n",net_locked);
  72         printk("Total network buffer allocations   : %lu\n",net_allocs);
  73         printk("Total failed network buffer allocs : %lu\n",net_fails);
  74         printk("Total free while locked events     : %lu\n",net_free_locked);
  75 #ifdef CONFIG_INET
  76         printk("IP fragment buffer size            : %lu\n",ip_frag_mem);
  77 #endif  
  78 }
  79 
  80 #if CONFIG_SKB_CHECK
  81 
  82 /*
  83  *      Debugging paranoia. Can go later when this crud stack works
  84  */
  85 
  86 int skb_check(struct sk_buff *skb, int head, int line, char *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         if (head) {
  89                 if (skb->magic_debug_cookie != SK_HEAD_SKB) {
  90                         printk("File: %s Line %d, found a bad skb-head\n",
  91                                 file,line);
  92                         return -1;
  93                 }
  94                 if (!skb->next || !skb->prev) {
  95                         printk("skb_check: head without next or prev\n");
  96                         return -1;
  97                 }
  98                 if (skb->next->magic_debug_cookie != SK_HEAD_SKB
  99                         && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
 100                         printk("File: %s Line %d, bad next head-skb member\n",
 101                                 file,line);
 102                         return -1;
 103                 }
 104                 if (skb->prev->magic_debug_cookie != SK_HEAD_SKB
 105                         && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
 106                         printk("File: %s Line %d, bad prev head-skb member\n",
 107                                 file,line);
 108                         return -1;
 109                 }
 110 #if 0
 111                 {
 112                 struct sk_buff *skb2 = skb->next;
 113                 int i = 0;
 114                 while (skb2 != skb && i < 5) {
 115                         if (skb_check(skb2, 0, line, file) < 0) {
 116                                 printk("bad queue element in whole queue\n");
 117                                 return -1;
 118                         }
 119                         i++;
 120                         skb2 = skb2->next;
 121                 }
 122                 }
 123 #endif
 124                 return 0;
 125         }
 126         if (skb->next != NULL && skb->next->magic_debug_cookie != SK_HEAD_SKB
 127                 && skb->next->magic_debug_cookie != SK_GOOD_SKB) {
 128                 printk("File: %s Line %d, bad next skb member\n",
 129                         file,line);
 130                 return -1;
 131         }
 132         if (skb->prev != NULL && skb->prev->magic_debug_cookie != SK_HEAD_SKB
 133                 && skb->prev->magic_debug_cookie != SK_GOOD_SKB) {
 134                 printk("File: %s Line %d, bad prev skb member\n",
 135                         file,line);
 136                 return -1;
 137         }
 138 
 139 
 140         if(skb->magic_debug_cookie==SK_FREED_SKB)
 141         {
 142                 printk("File: %s Line %d, found a freed skb lurking in the undergrowth!\n",
 143                         file,line);
 144                 printk("skb=%p, real size=%d, free=%d\n",
 145                         skb,skb->truesize,skb->free);
 146                 return -1;
 147         }
 148         if(skb->magic_debug_cookie!=SK_GOOD_SKB)
 149         {
 150                 printk("File: %s Line %d, passed a non skb!\n", file,line);
 151                 printk("skb=%p, real size=%d, free=%d\n",
 152                         skb,skb->truesize,skb->free);
 153                 return -1;
 154         }
 155         if(skb->head>skb->data)
 156         {
 157                 printk("File: %s Line %d, head > data !\n", file,line);
 158                 printk("skb=%p, head=%p, data=%p\n",
 159                         skb,skb->head,skb->data);
 160                 return -1;
 161         }
 162         if(skb->tail>skb->end)
 163         {
 164                 printk("File: %s Line %d, tail > end!\n", file,line);
 165                 printk("skb=%p, tail=%p, end=%p\n",
 166                         skb,skb->tail,skb->end);
 167                 return -1;
 168         }
 169         if(skb->data>skb->tail)
 170         {
 171                 printk("File: %s Line %d, data > tail!\n", file,line);
 172                 printk("skb=%p, data=%p, tail=%p\n",
 173                         skb,skb->data,skb->tail);
 174                 return -1;
 175         }
 176         if(skb->tail-skb->data!=skb->len)
 177         {
 178                 printk("File: %s Line %d, wrong length\n", file,line);
 179                 printk("skb=%p, data=%p, end=%p len=%ld\n",
 180                         skb,skb->data,skb->end,skb->len);
 181                 return -1;
 182         }
 183         if((unsigned long) skb->end > (unsigned long) skb)
 184         {
 185                 printk("File: %s Line %d, control overrun\n", file,line);
 186                 printk("skb=%p, end=%p\n",
 187                         skb,skb->end);
 188                 return -1;
 189         }
 190 
 191         /* Guess it might be acceptable then */
 192         return 0;
 193 }
 194 #endif
 195 
 196 
 197 #if CONFIG_SKB_CHECK
 198 void skb_queue_head_init(struct sk_buff_head *list)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {
 200         list->prev = (struct sk_buff *)list;
 201         list->next = (struct sk_buff *)list;
 202         list->qlen = 0;
 203         list->magic_debug_cookie = SK_HEAD_SKB;
 204 }
 205 
 206 
 207 /*
 208  *      Insert an sk_buff at the start of a list.
 209  */
 210 void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212         unsigned long flags;
 213         struct sk_buff *list = (struct sk_buff *)list_;
 214 
 215         save_flags(flags);
 216         cli();
 217 
 218         IS_SKB(newsk);
 219         IS_SKB_HEAD(list);
 220         if (newsk->next || newsk->prev)
 221                 printk("Suspicious queue head: sk_buff on list!\n");
 222 
 223         newsk->next = list->next;
 224         newsk->prev = list;
 225 
 226         newsk->next->prev = newsk;
 227         newsk->prev->next = newsk;
 228         newsk->list = list_;
 229         list_->qlen++;
 230 
 231         restore_flags(flags);
 232 }
 233 
 234 void __skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {
 236         struct sk_buff *list = (struct sk_buff *)list_;
 237 
 238 
 239         IS_SKB(newsk);
 240         IS_SKB_HEAD(list);
 241         if (newsk->next || newsk->prev)
 242                 printk("Suspicious queue head: sk_buff on list!\n");
 243 
 244         newsk->next = list->next;
 245         newsk->prev = list;
 246 
 247         newsk->next->prev = newsk;
 248         newsk->prev->next = newsk;
 249         newsk->list = list_;
 250         list_->qlen++;
 251 
 252 }
 253 
 254 /*
 255  *      Insert an sk_buff at the end of a list.
 256  */
 257 void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 258 {
 259         unsigned long flags;
 260         struct sk_buff *list = (struct sk_buff *)list_;
 261 
 262         save_flags(flags);
 263         cli();
 264 
 265         if (newsk->next || newsk->prev)
 266                 printk("Suspicious queue tail: sk_buff on list!\n");
 267         IS_SKB(newsk);
 268         IS_SKB_HEAD(list);
 269 
 270         newsk->next = list;
 271         newsk->prev = list->prev;
 272 
 273         newsk->next->prev = newsk;
 274         newsk->prev->next = newsk;
 275         
 276         newsk->list = list_;
 277         list_->qlen++;
 278 
 279         restore_flags(flags);
 280 }
 281 
 282 void __skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 283 {
 284         unsigned long flags;
 285         struct sk_buff *list = (struct sk_buff *)list_;
 286 
 287         if (newsk->next || newsk->prev)
 288                 printk("Suspicious queue tail: sk_buff on list!\n");
 289         IS_SKB(newsk);
 290         IS_SKB_HEAD(list);
 291 
 292         newsk->next = list;
 293         newsk->prev = list->prev;
 294 
 295         newsk->next->prev = newsk;
 296         newsk->prev->next = newsk;
 297         
 298         newsk->list = list_;
 299         list_->qlen++;
 300 }
 301 
 302 /*
 303  *      Remove an sk_buff from a list. This routine is also interrupt safe
 304  *      so you can grab read and free buffers as another process adds them.
 305  */
 306 
 307 struct sk_buff *skb_dequeue(struct sk_buff_head *list_)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {
 309         long flags;
 310         struct sk_buff *result;
 311         struct sk_buff *list = (struct sk_buff *)list_;
 312 
 313         save_flags(flags);
 314         cli();
 315 
 316         IS_SKB_HEAD(list);
 317 
 318         result = list->next;
 319         if (result == list) {
 320                 restore_flags(flags);
 321                 return NULL;
 322         }
 323 
 324         result->next->prev = list;
 325         list->next = result->next;
 326 
 327         result->next = NULL;
 328         result->prev = NULL;
 329         list_->qlen--;
 330         result->list = NULL;
 331         
 332         restore_flags(flags);
 333 
 334         IS_SKB(result);
 335         return result;
 336 }
 337 
 338 struct sk_buff *__skb_dequeue(struct sk_buff_head *list_)
     /* [previous][next][first][last][top][bottom][index][help] */
 339 {
 340         struct sk_buff *result;
 341         struct sk_buff *list = (struct sk_buff *)list_;
 342 
 343         IS_SKB_HEAD(list);
 344 
 345         result = list->next;
 346         if (result == list) {
 347                 return NULL;
 348         }
 349 
 350         result->next->prev = list;
 351         list->next = result->next;
 352 
 353         result->next = NULL;
 354         result->prev = NULL;
 355         list_->qlen--;
 356         result->list = NULL;
 357         
 358         IS_SKB(result);
 359         return result;
 360 }
 361 
 362 /*
 363  *      Insert a packet before another one in a list.
 364  */
 365 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 366 {
 367         unsigned long flags;
 368 
 369         IS_SKB(old);
 370         IS_SKB(newsk);
 371 
 372         if(!old->next || !old->prev)
 373                 printk("insert before unlisted item!\n");
 374         if(newsk->next || newsk->prev)
 375                 printk("inserted item is already on a list.\n");
 376 
 377         save_flags(flags);
 378         cli();
 379         newsk->next = old;
 380         newsk->prev = old->prev;
 381         old->prev = newsk;
 382         newsk->prev->next = newsk;
 383         newsk->list = old->list;
 384         newsk->list->qlen++;
 385 
 386         restore_flags(flags);
 387 }
 388 
 389 /*
 390  *      Insert a packet before another one in a list.
 391  */
 392 
 393 void __skb_insert(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 394 {
 395         IS_SKB(old);
 396         IS_SKB(newsk);
 397 
 398         if(!old->next || !old->prev)
 399                 printk("insert before unlisted item!\n");
 400         if(newsk->next || newsk->prev)
 401                 printk("inserted item is already on a list.\n");
 402 
 403         newsk->next = old;
 404         newsk->prev = old->prev;
 405         old->prev = newsk;
 406         newsk->prev->next = newsk;
 407         newsk->list = old->list;
 408         newsk->list->qlen++;
 409 
 410 }
 411 
 412 /*
 413  *      Place a packet after a given packet in a list.
 414  */
 415 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 416 {
 417         unsigned long flags;
 418 
 419         IS_SKB(old);
 420         IS_SKB(newsk);
 421 
 422         if(!old->next || !old->prev)
 423                 printk("append before unlisted item!\n");
 424         if(newsk->next || newsk->prev)
 425                 printk("append item is already on a list.\n");
 426 
 427         save_flags(flags);
 428         cli();
 429 
 430         newsk->prev = old;
 431         newsk->next = old->next;
 432         newsk->next->prev = newsk;
 433         old->next = newsk;
 434         newsk->list = old->list;
 435         newsk->list->qlen++;
 436 
 437         restore_flags(flags);
 438 }
 439 
 440 void __skb_append(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 441 {
 442         IS_SKB(old);
 443         IS_SKB(newsk);
 444 
 445         if(!old->next || !old->prev)
 446                 printk("append before unlisted item!\n");
 447         if(newsk->next || newsk->prev)
 448                 printk("append item is already on a list.\n");
 449 
 450         newsk->prev = old;
 451         newsk->next = old->next;
 452         newsk->next->prev = newsk;
 453         old->next = newsk;
 454         newsk->list = old->list;
 455         newsk->list->qlen++;
 456 
 457 }
 458 
 459 /*
 460  *      Remove an sk_buff from its list. Works even without knowing the list it
 461  *      is sitting on, which can be handy at times. It also means that THE LIST
 462  *      MUST EXIST when you unlink. Thus a list must have its contents unlinked
 463  *      _FIRST_.
 464  */
 465 void skb_unlink(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 466 {
 467         unsigned long flags;
 468 
 469         save_flags(flags);
 470         cli();
 471 
 472         IS_SKB(skb);
 473 
 474         if(skb->list)
 475         {
 476                 skb->list->qlen--;
 477                 skb->next->prev = skb->prev;
 478                 skb->prev->next = skb->next;
 479                 skb->next = NULL;
 480                 skb->prev = NULL;
 481                 skb->list = NULL;
 482         }
 483 #ifdef PARANOID_BUGHUNT_MODE    /* This is legal but we sometimes want to watch it */
 484         else
 485                 printk("skb_unlink: not a linked element\n");
 486 #endif
 487         restore_flags(flags);
 488 }
 489 
 490 void __skb_unlink(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 491 {
 492         IS_SKB(skb);
 493 
 494         if(skb->list)
 495         {
 496                 skb->list->qlen--;
 497                 skb->next->prev = skb->prev;
 498                 skb->prev->next = skb->next;
 499                 skb->next = NULL;
 500                 skb->prev = NULL;
 501                 skb->list = NULL;
 502         }
 503 #ifdef PARANOID_BUGHUNT_MODE    /* This is legal but we sometimes want to watch it */
 504         else
 505                 printk("skb_unlink: not a linked element\n");
 506 #endif
 507 }
 508 
 509 /*
 510  *      Add data to an sk_buff
 511  */
 512  
 513 unsigned char *skb_put(struct sk_buff *skb, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 514 {
 515         unsigned char *tmp=skb->tail;
 516         IS_SKB(skb);
 517         skb->tail+=len;
 518         skb->len+=len;
 519         IS_SKB(skb);
 520         if(skb->tail>skb->end)
 521                 panic("skput:over: %p:%d", __builtin_return_address(0),len);
 522         return tmp;
 523 }
 524 
 525 unsigned char *skb_push(struct sk_buff *skb, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 526 {
 527         IS_SKB(skb);
 528         skb->data-=len;
 529         skb->len+=len;
 530         IS_SKB(skb);
 531         if(skb->data<skb->head)
 532                 panic("skpush:under: %p:%d", __builtin_return_address(0),len);
 533         return skb->data;
 534 }
 535 
 536 unsigned char * skb_pull(struct sk_buff *skb, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538         IS_SKB(skb);
 539         if(len>skb->len)
 540                 return 0;
 541         skb->data+=len;
 542         skb->len-=len;
 543         return skb->data;
 544 }
 545 
 546 int skb_headroom(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 547 {
 548         IS_SKB(skb);
 549         return skb->data-skb->head;
 550 }
 551 
 552 int skb_tailroom(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554         IS_SKB(skb);
 555         return skb->end-skb->tail;
 556 }
 557 
 558 void skb_reserve(struct sk_buff *skb, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 559 {
 560         IS_SKB(skb);
 561         skb->data+=len;
 562         skb->tail+=len;
 563         if(skb->tail>skb->end)
 564                 panic("sk_res: over");
 565         if(skb->data<skb->head)
 566                 panic("sk_res: under");
 567         IS_SKB(skb);
 568 }
 569 
 570 void skb_trim(struct sk_buff *skb, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 571 {
 572         IS_SKB(skb);
 573         if(skb->len>len)
 574         {
 575                 skb->len=len;
 576                 skb->tail=skb->data+len;
 577         }
 578 }
 579 
 580 
 581 
 582 #endif
 583 
 584 /*
 585  *      Free an sk_buff. This still knows about things it should
 586  *      not need to like protocols and sockets.
 587  */
 588 
 589 void kfree_skb(struct sk_buff *skb, int rw)
     /* [previous][next][first][last][top][bottom][index][help] */
 590 {
 591         if (skb == NULL)
 592         {
 593                 printk("kfree_skb: skb = NULL (from %p)\n",
 594                         __builtin_return_address(0));
 595                 return;
 596         }
 597 #if CONFIG_SKB_CHECK
 598         IS_SKB(skb);
 599 #endif
 600         if (skb->lock)
 601         {
 602                 skb->free = 3;    /* Free when unlocked */
 603                 net_free_locked++;
 604                 return;
 605         }
 606         if (skb->free == 2)
 607                 printk("Warning: kfree_skb passed an skb that nobody set the free flag on! (from %p)\n",
 608                         __builtin_return_address(0));
 609         if (skb->list)
 610                 printk("Warning: kfree_skb passed an skb still on a list (from %p).\n",
 611                         __builtin_return_address(0));
 612 
 613         if(skb->destructor)
 614                 skb->destructor(skb);
 615         if (skb->sk)
 616         {
 617                 if(skb->sk->prot!=NULL)
 618                 {
 619                         if (rw)
 620                                 sock_rfree(skb->sk, skb);
 621                         else
 622                                 sock_wfree(skb->sk, skb);
 623 
 624                 }
 625                 else
 626                 {
 627                         unsigned long flags;
 628                         /* Non INET - default wmalloc/rmalloc handler */
 629                         save_flags(flags);
 630                         cli();
 631                         if (rw)
 632                                 skb->sk->rmem_alloc-=skb->truesize;
 633                         else
 634                                 skb->sk->wmem_alloc-=skb->truesize;
 635                         restore_flags(flags);
 636                         if(!skb->sk->dead)
 637                                 skb->sk->write_space(skb->sk);
 638                         kfree_skbmem(skb);
 639                 }
 640         }
 641         else
 642                 kfree_skbmem(skb);
 643 }
 644 
 645 /*
 646  *      Allocate a new skbuff. We do this ourselves so we can fill in a few 'private'
 647  *      fields and also do memory statistics to find all the [BEEP] leaks.
 648  */
 649 struct sk_buff *alloc_skb(unsigned int size,int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 650 {
 651         struct sk_buff *skb;
 652         int len=size;
 653         unsigned char *bptr;
 654 
 655         if (intr_count && priority!=GFP_ATOMIC) 
 656         {
 657                 static int count = 0;
 658                 if (++count < 5) {
 659                         printk("alloc_skb called nonatomically from interrupt %p\n",
 660                                 __builtin_return_address(0));
 661                         priority = GFP_ATOMIC;
 662                 }
 663         }
 664 
 665         size=(size+15)&~15;             /* Allow for alignments. Make a multiple of 16 bytes */
 666         size+=sizeof(struct sk_buff);   /* And stick the control itself on the end */
 667         
 668         /*
 669          *      Allocate some space
 670          */
 671          
 672         bptr=(unsigned char *)kmalloc(size,priority);
 673         if (bptr == NULL)
 674         {
 675                 net_fails++;
 676                 return NULL;
 677         }
 678 #ifdef PARANOID_BUGHUNT_MODE
 679         if(skb->magic_debug_cookie == SK_GOOD_SKB)
 680                 printk("Kernel kmalloc handed us an existing skb (%p)\n",skb);
 681 #endif
 682         /*
 683          *      Now we play a little game with the caches. Linux kmalloc is
 684          *      a bit cache dumb, in fact its just about maximally non 
 685          *      optimal for typical kernel buffers. We actually run faster
 686          *      by doing the following. Which is to deliberately put the
 687          *      skb at the _end_ not the start of the memory block.
 688          */
 689         net_allocs++;
 690         
 691         skb=(struct sk_buff *)(bptr+size)-1;
 692 
 693         skb->count = 1;         /* only one reference to this */
 694         skb->data_skb = NULL;   /* and we're our own data skb */
 695 
 696         skb->free = 2;  /* Invalid so we pick up forgetful users */
 697         skb->lock = 0;
 698         skb->pkt_type = PACKET_HOST;    /* Default type */
 699         skb->prev = skb->next = skb->link3 = NULL;
 700         skb->list = NULL;
 701         skb->sk = NULL;
 702         skb->truesize=size;
 703         skb->localroute=0;
 704         skb->stamp.tv_sec=0;    /* No idea about time */
 705         skb->localroute = 0;
 706         skb->ip_summed = 0;
 707         memset(skb->proto_priv, 0, sizeof(skb->proto_priv));
 708         net_skbcount++;
 709 #if CONFIG_SKB_CHECK
 710         skb->magic_debug_cookie = SK_GOOD_SKB;
 711 #endif
 712         skb->users = 0;
 713         /* Load the data pointers */
 714         skb->head=bptr;
 715         skb->data=bptr;
 716         skb->tail=bptr;
 717         skb->end=bptr+len;
 718         skb->len=0;
 719         skb->destructor=NULL;
 720         return skb;
 721 }
 722 
 723 /*
 724  *      Free an skbuff by memory
 725  */
 726 
 727 static inline void __kfree_skbmem(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 728 {
 729         /* don't do anything if somebody still uses us */
 730         if (--skb->count <= 0) {
 731                 kfree(skb->head);
 732                 net_skbcount--;
 733         }
 734 }
 735 
 736 void kfree_skbmem(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 737 {
 738         unsigned long flags;
 739         void * addr = skb->head;
 740 
 741         save_flags(flags);
 742         cli();
 743         /* don't do anything if somebody still uses us */
 744         if (--skb->count <= 0) {
 745                 /* free the skb that contains the actual data if we've clone()'d */
 746                 if (skb->data_skb) {
 747                         addr = skb;
 748                         __kfree_skbmem(skb->data_skb);
 749                 }
 750                 kfree(addr);
 751                 net_skbcount--;
 752         }
 753         restore_flags(flags);
 754 }
 755 
 756 /*
 757  *      Duplicate an sk_buff. The new one is not owned by a socket or locked
 758  *      and will be freed on deletion.
 759  */
 760 
 761 struct sk_buff *skb_clone(struct sk_buff *skb, int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 762 {
 763         unsigned long flags;
 764         struct sk_buff *n;
 765 
 766         IS_SKB(skb);
 767         n = kmalloc(sizeof(*n), priority);
 768         if (!n)
 769                 return NULL;
 770         memcpy(n, skb, sizeof(*n));
 771         n->count = 1;
 772         if (skb->data_skb)
 773                 skb = skb->data_skb;
 774         save_flags(flags);
 775         cli();
 776         skb->count++;
 777         net_allocs++;
 778         net_skbcount++;
 779         restore_flags(flags);
 780         n->data_skb = skb;
 781         n->next = n->prev = n->link3 = NULL;
 782         n->list = NULL;
 783         n->sk = NULL;
 784         n->free = 1;
 785         n->tries = 0;
 786         n->lock = 0;
 787         n->users = 0;
 788         return n;
 789 }
 790 
 791 /*
 792  *      This is slower, and copies the whole data area 
 793  */
 794  
 795 struct sk_buff *skb_copy(struct sk_buff *skb, int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797         struct sk_buff *n;
 798         unsigned long offset;
 799 
 800         /*
 801          *      Allocate the copy buffer
 802          */
 803          
 804         IS_SKB(skb);
 805         
 806         n=alloc_skb(skb->truesize-sizeof(struct sk_buff),priority);
 807         if(n==NULL)
 808                 return NULL;
 809 
 810         /*
 811          *      Shift between the two data areas in bytes
 812          */
 813          
 814         offset=n->head-skb->head;
 815 
 816         /* Set the data pointer */
 817         skb_reserve(n,skb->data-skb->head);
 818         /* Set the tail pointer and length */
 819         skb_put(n,skb->len);
 820         /* Copy the bytes */
 821         memcpy(n->head,skb->head,skb->end-skb->head);
 822         n->link3=NULL;
 823         n->list=NULL;
 824         n->sk=NULL;
 825         n->when=skb->when;
 826         n->dev=skb->dev;
 827         n->h.raw=skb->h.raw+offset;
 828         n->mac.raw=skb->mac.raw+offset;
 829         n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
 830         n->saddr=skb->saddr;
 831         n->daddr=skb->daddr;
 832         n->raddr=skb->raddr;
 833         n->seq=skb->seq;
 834         n->end_seq=skb->end_seq;
 835         n->ack_seq=skb->ack_seq;
 836         n->acked=skb->acked;
 837         memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
 838         n->used=skb->used;
 839         n->free=1;
 840         n->arp=skb->arp;
 841         n->tries=0;
 842         n->lock=0;
 843         n->users=0;
 844         n->pkt_type=skb->pkt_type;
 845         n->stamp=skb->stamp;
 846         
 847         IS_SKB(n);
 848         return n;
 849 }
 850 
 851 /*
 852  *     Skbuff device locking
 853  */
 854 
 855 void skb_device_lock(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 856 {
 857         if(skb->lock)
 858                 printk("double lock on device queue!\n");
 859         else
 860                 net_locked++;
 861         skb->lock++;
 862 }
 863 
 864 void skb_device_unlock(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 865 {
 866         if(skb->lock==0)
 867                 printk("double unlock on device queue!\n");
 868         skb->lock--;
 869         if(skb->lock==0)
 870                 net_locked--;
 871 }
 872 
 873 void dev_kfree_skb(struct sk_buff *skb, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 874 {
 875         unsigned long flags;
 876 
 877         save_flags(flags);
 878         cli();
 879         if(skb->lock)
 880         {
 881                 net_locked--;
 882                 skb->lock--;
 883         }
 884         if (!skb->lock && (skb->free == 1 || skb->free == 3))
 885         {
 886                 restore_flags(flags);
 887                 kfree_skb(skb,mode);
 888         }
 889         else
 890                 restore_flags(flags);
 891 }
 892 
 893 struct sk_buff *dev_alloc_skb(unsigned int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 894 {
 895         struct sk_buff *skb;
 896 
 897         skb = alloc_skb(length+16, GFP_ATOMIC);
 898         if (skb)
 899                 skb_reserve(skb,16);
 900         return skb;
 901 }
 902 
 903 int skb_device_locked(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905         return skb->lock? 1 : 0;
 906 }

/* [previous][next][first][last][top][bottom][index][help] */