home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / net / inet / skbuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-07  |  12.3 KB  |  574 lines

  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.  *
  11.  *    This program is free software; you can redistribute it and/or
  12.  *    modify it under the terms of the GNU General Public License
  13.  *    as published by the Free Software Foundation; either version
  14.  *    2 of the License, or (at your option) any later version.
  15.  */
  16.  
  17. /*
  18.  *    Note: There are a load of cli()/sti() pairs protecting the net_memory type
  19.  *    variables. Without them for some reason the ++/-- operators do not come out
  20.  *    atomic. Also with gcc 2.4.5 these counts can come out wrong anyway - use 2.5.8!!
  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.  *    Resource tracking variables
  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.  *    Debugging paranoia. Can go later when this crud stack works
  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.     /* Guess it might be acceptable then */
  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.  *    Insert an sk_buff at the start of a list.
  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.  *    Insert an sk_buff at the end of a list.
  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.  *    Remove an sk_buff from a list. This routine is also interrupt safe
  214.  *    so you can grab read and free buffers as another process adds them.
  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.  *    Insert a packet before another one in a list.
  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.  *    Place a packet after a given packet in a list.
  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.  *    Remove an sk_buff from its list. Works even without knowing the list it
  299.  *    is sitting on, which can be handy at times. It also means that THE LIST
  300.  *    MUST EXIST when you unlink. Thus a list must have its contents unlinked
  301.  *    _FIRST_.
  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    /* This is legal but we sometimes want to watch it */
  320.     else
  321.         printk("skb_unlink: not a linked element\n");
  322. #endif
  323.     restore_flags(flags);
  324. }
  325.  
  326. #endif
  327.  
  328. /*
  329.  *    Free an sk_buff. This still knows about things it should
  330.  *    not need to like protocols and sockets.
  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;    /* Free when unlocked */
  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.             /* Non INET - default wmalloc/rmalloc handler */
  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.  *    Allocate a new skbuff. We do this ourselves so we can fill in a few 'private'
  388.  *    fields and also do memory statistics to find all the [BEEP] leaks.
  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;    /* Invalid so we pick up forgetful users */
  419.     skb->lock = 0;
  420.     skb->pkt_type = PACKET_HOST;    /* Default type */
  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;    /* No idea about time */
  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.  *    Free an skbuff by memory
  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.  *    Duplicate an sk_buff. The new one is not owned by a socket or locked
  490.  *    and will be freed on deletion.
  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.  *     Skbuff device locking
  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.  
  574.