dev_alloc_skb


/****************************************************
* dev_alloc_skb - 分配内存为接受的包
* @length: 分配的长度
* GFP_ATOMIC:原子类型,此函数经常用于终端上下文中
***************************************************/
struct sk_buff *dev_alloc_skb(unsigned int length)
{
return __dev_alloc_skb(length, GFP_ATOMIC);
}
EXPORT_SYMBOL(dev_alloc_skb);

#ifndef NET_SKB_PAD
#define NET_SKB_PAD 32
#endif

/*************************************************************
*gfp_mask: get_free_pages mask, passed to alloc_skb
*alloc_skb()增加32字节的空间,优化读写的效率
**************************************************************/
static inline struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
if (likely(skb))
skb_reserve(skb, NET_SKB_PAD);
return skb;
}

static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority)
{
return __alloc_skb(size, priority, 0, -1);
}

/****************************************************************************
* __alloc_skb 分配network的缓冲区
* @size: 分配的内存大小
* @gfp_mask: 分配的标签
* @fclone: 从fclone缓存分配内存并分配一个克隆的skb
* @node: 分配的节点号,一般为-1
****************************************************************************/
struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, int fclone, int node)
{
struct kmem_cache *cache;
struct skb_shared_info *shinfo;
struct sk_buff *skb;
u8 *data;

cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;

/* 获取头 */
skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
if (!skb)
goto out;

size = SKB_DATA_ALIGN(size); //字节对齐
data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),gfp_mask, node);
if (!data)
goto nodata;


memset(skb, 0, offsetof(struct sk_buff, tail));
skb->truesize = size + sizeof(struct sk_buff);
atomic_set(&skb->users, 1);
skb->head = data;
skb->data = data;
skb_reset_tail_pointer(skb);
skb->end = skb->tail + size;

shinfo = skb_shinfo(skb);
atomic_set(&shinfo->dataref, 1);
shinfo->nr_frags = 0;
shinfo->gso_size = 0;
shinfo->gso_segs = 0;
shinfo->gso_type = 0;
shinfo->ip6_frag_id = 0;
shinfo->tx_flags.flags = 0;
shinfo->frag_list = NULL;
memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));

if (fclone)
{
struct sk_buff *child = skb + 1;
atomic_t *fclone_ref = (atomic_t *) (child + 1);

skb->fclone = SKB_FCLONE_ORIG;
atomic_set(fclone_ref, 1);

child->fclone = SKB_FCLONE_UNAVAILABLE;
}
out:
return skb;
nodata:
kmem_cache_free(cache, skb);
skb = NULL;
goto out;
}
EXPORT_SYMBOL(__alloc_skb);

/**
* @skb: buffer to alter
* @len: bytes to move
*
* Increase the headroom of an empty &sk_buff by reducing the tail
* room. This is only allowed for an empty buffer.
*/
static inline void skb_reserve(struct sk_buff *skb, int len)
{
skb->data += len;
skb->tail += len;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值