root/net/inet/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_tail
  6. skb_dequeue
  7. skb_insert
  8. skb_append
  9. skb_unlink
  10. kfree_skb
  11. alloc_skb
  12. kfree_skbmem
  13. skb_clone
  14. skb_device_lock
  15. skb_device_unlock
  16. dev_kfree_skb
  17. 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  *      This program is free software; you can redistribute it and/or
   8  *      modify it under the terms of the GNU General Public License
   9  *      as published by the Free Software Foundation; either version
  10  *      2 of the License, or (at your option) any later version.
  11  */
  12 
  13 /*
  14  *      Note: There are a load of cli()/sti() pairs protecting the net_memory type
  15  *      variables. Without them for some reason the ++/-- operators do not come out
  16  *      atomic. Also with gcc 2.4.5 these counts can come out wrong anyway - use 2.5.8!!
  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  *      Resource tracking variables
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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  *      Debugging paranoia. Can go later when this crud stack works
  65  */
  66 
  67 int skb_check(struct sk_buff *skb, int head, int line, char *file)
     /* [previous][next][first][last][top][bottom][index][help] */
  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         /* Guess it might be acceptable then */
 144         return 0;
 145 }
 146 #endif
 147 
 148 
 149 void skb_queue_head_init(struct sk_buff_head *list)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Insert an sk_buff at the start of a list.
 161  */
 162 void skb_queue_head(struct sk_buff_head *list_,struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Insert an sk_buff at the end of a list.
 188  */
 189 void skb_queue_tail(struct sk_buff_head *list_, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Remove an sk_buff from a list. This routine is also interrupt safe
 215  *      so you can grab read and free buffers as another process adds them.
 216  */
 217 
 218 struct sk_buff *skb_dequeue(struct sk_buff_head *list_)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Insert a packet before another one in a list.
 249  */
 250 void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Place a packet after a given packet in a list.
 276  */
 277 void skb_append(struct sk_buff *old, struct sk_buff *newsk)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Remove an sk_buff from its list. Works even without knowing the list it
 304  *      is sitting on, which can be handy at times. It also means that THE LIST
 305  *      MUST EXIST when you unlink. Thus a list must have its contents unlinked
 306  *      _FIRST_.
 307  */
 308 void skb_unlink(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 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    /* This is legal but we sometimes want to watch it */
 325         else
 326                 printk("skb_unlink: not a linked element\n");
 327 #endif
 328         restore_flags(flags);
 329 }
 330 
 331 /*
 332  *      Free an sk_buff. This still knows about things it should
 333  *      not need to like protocols and sockets.
 334  */
 335 
 336 void kfree_skb(struct sk_buff *skb, int rw)
     /* [previous][next][first][last][top][bottom][index][help] */
 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;    /* Free when unlocked */
 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                         /* Non INET - default wmalloc/rmalloc handler */
 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  *      Allocate a new skbuff. We do this ourselves so we can fill in a few 'private'
 395  *      fields and also do memory statistics to find all the [BEEP] leaks.
 396  */
 397 struct sk_buff *alloc_skb(unsigned int size,int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 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;  /* Invalid so we pick up forgetful users */
 426         skb->lock = 0;
 427         skb->pkt_type = PACKET_HOST;    /* Default type */
 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;    /* No idea about time */
 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  *      Free an skbuff by memory
 455  */
 456 
 457 void kfree_skbmem(struct sk_buff *skb,unsigned size)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *      Duplicate an sk_buff. The new one is not owned by a socket or locked
 488  *      and will be freed on deletion.
 489  */
 490 
 491 struct sk_buff *skb_clone(struct sk_buff *skb, int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  *     Skbuff device locking
 529  */
 530 
 531 void skb_device_lock(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 568 {
 569         return skb->lock? 1 : 0;
 570 }
 571 

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