skb_recycle bug

amir knippel amk at kagoor.com
Thu Dec 14 14:02:44 EST 2000


Hi,

	I think I found a bug in skb_recycle function...

if (!skb->cloned || atomic_dec_and_test(skb_datarefp(skb)))

this line decrease the skb rep count and if its not 0 the it calls
kfree_skbmem
witch decrease the count as well so the memory is freed and there are still
skb clones in the system.

I think the line should be

      if ((skb->cloned != 1) && (atomic_read(skb_datarefp(skb)) == 1))

and this solves the problem


thanks,
Amir Knippel
amir_kn at hotmail.com

/*
 * Click: recycle a sk_buff by resetting it. if it can be recycled, return
it.
 */
struct sk_buff *skb_recycle(struct sk_buff *skb)
{ 
  if (atomic_dec_and_test(&skb->users)) { 

    if (skb->list) 
      printk(KERN_WARNING 
	     "Warning: kfree_skb passed an skb still on a list (from %p).\n", 
	     __builtin_return_address(0));
	
    dst_release(skb->dst); 
    if(skb->destructor) skb->destructor(skb);
    skb_headerinit(skb, NULL, 0);  /* clean state */ 
	
 /*   if (!skb->cloned || atomic_dec_and_test(skb_datarefp(skb))) {*/
      if ((skb->cloned != 1) && (atomic_read(skb_datarefp(skb)) == 1))
      { 
         /* Load the data pointers. */
         skb->data = skb->head; 
         skb->tail = skb->data;  
         /* end and truesize should have never changed */
         /* skb->end = skb->data + skb->truesize; */

         /* set up other state */
         skb->len = 0; 
         skb->is_clone = 0; 
         skb->cloned = 0;

         atomic_set(&skb->users, 1); 
         atomic_set(skb_datarefp(skb), 1);

         return skb;
      }
      else
         kfree_skbmem(skb);
  }
  return 0;
}




More information about the click mailing list