void __kfree_skb(struct sk_buff *skb) { if (skb->list) { printk(KERN_WARNING "Warning: kfree_skb passed an skb still " "on a list (from %p).\n", NET_CALLER(skb)); BUG(); } dst_release(skb->dst); #ifdef CONFIG_XFRM secpath_put(skb->sp); #endif if(skb->destructor) { if (in_irq()) printk(KERN_WARNING "Warning: kfree_skb on " "hard IRQ %p\n", NET_CALLER(skb)); skb->destructor(skb); } #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); #ifdef CONFIG_BRIDGE_NETFILTER nf_bridge_put(skb->nf_bridge); #endif #endif /* XXX: IS this still necessary? - JHS */ #ifdef CONFIG_NET_SCHED skb->tc_index = 0; #ifdef CONFIG_NET_CLS_ACT skb->tc_verd = 0; skb->tc_classid = 0; #endif #endif kfree_skbmem(skb); }
struct sk_buff *alloc_skb(unsigned int size,int gfp_mask) { struct sk_buff *skb; u8 *data; if (in_interrupt() && (gfp_mask & __GFP_WAIT)) { static int count = 0; if (++count < 5) { printk(KERN_ERR "alloc_skb called nonatomically " "from interrupt %p\n", NET_CALLER(size)); BUG(); } gfp_mask &= ~__GFP_WAIT; } /* Get the HEAD */ skb = skb_head_from_pool(); if (skb == NULL) { skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & ~__GFP_DMA); if (skb == NULL) goto nohead; } /* reserve some place at the tailroom for HW switches that use it for * trailers with switch related information, e.g. port_map, etc. */ if (size < (2048 - sizeof(struct skb_shared_info) - 64)) size += 64; /* Get the DATA. Size must match skb_add_mtu(). */ size = SKB_DATA_ALIGN(size); data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask | GFP_DMA); if (data == NULL) goto nodata; /* XXX: does not include slab overhead */ skb->truesize = size + sizeof(struct sk_buff); /* Load the data pointers. */ skb->head = data; skb->data = data; skb->tail = data; skb->end = data + size; /* Set up other state */ skb->priority = 0; skb->len = 0; skb->cloned = 0; skb->data_len = 0; atomic_set(&skb->users, 1); atomic_set(&(skb_shinfo(skb)->dataref), 1); skb_shinfo(skb)->nr_frags = 0; skb_shinfo(skb)->frag_list = NULL; return skb; nodata: skb_head_to_pool(skb); nohead: return NULL; }
void __kfree_skb(struct sk_buff *skb) { if (skb->list) { printk(KERN_WARNING "Warning: kfree_skb passed an skb still " "on a list (from %p).\n", NET_CALLER(skb)); BUG(); } dst_release(skb->dst); if(skb->destructor) { if (in_irq()) { printk(KERN_WARNING "Warning: kfree_skb on hard IRQ %p\n", NET_CALLER(skb)); } skb->destructor(skb); } #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); #endif skb_headerinit(skb, NULL, 0); /* clean state */ kfree_skbmem(skb); }