linux skb机制,skb 的分配细节

1. 关于 SKB 的分配细节.LINUX 中 SKB 的分配最终是由函数 : struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,int fclone) 来完成.SKB 可以分为 SKB 描述符与 SKB 数据区两个部分,其中描述符必须从 CACHE 中来分配 : 或者从skbuff_fclone_cache 中分配,或者从 skbuff_head_cache 中来分配.如果从分配描述符失败,则直接反悔 NULL,表示 SKB 分配失败.SKB 描述符分配成功后,即可分配数据区.在具体分配数据区之前首先要对数据区的长度进行 ALIGN 操作, 通过宏 SKB_DATA_ALIGN 来重新确定 size 大小. 然后戏台调用 kmalloc 函数分配数据区 :data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);需要注意的是数据区的大小是 SIZE 的大小加上 skb_shared_info 结构的大小.数据区分配成功后,便对 SKB 描述符进行与此数据区相关的赋值操作 :memset(skb, 0, offsetof(struct sk_buff, truesize));skb->truesize = size + sizeof(struct sk_buff);atomic_set(&skb->users, 1);skb->head = data;skb->data = data;skb->tail = data;skb->end  = data + size;需要主意的是, SKB 的 truesize 的大小并不包含 skb_shared_info 结构的大小. 另外,skb 的 end 成员指针也就事 skb_shared_info 结构的起始指针,系统用一个宏 : skb_shinfo 来完成寻找 skb_shared_info 结构指针的操作.最后,系统初始化 skb_shared_info 结构的成员变量 :atomic_set(&(skb_shinfo(skb)->dataref), 1);skb_shinfo(skb)->nr_frags  = 0;skb_shinfo(skb)->tso_size = 0;skb_shinfo(skb)->tso_segs = 0;skb_shinfo(skb)->frag_list = NULL;skb_shinfo(skb)->ufo_size = 0;skb_shinfo(skb)->ip6_frag_id = 0;最后,返回 SKB 的指针.2. SKB 的分配时机SKB 的分配时机主要有两种,最常见的一种是在网卡的中断中,有数据包到达的时,系统分配 SKB 包进行包处理; 第二种情况是主动分配 SKB 包勇于各种调试或者其他处理环境.3. SKB 的 reserve 操作SKB 在分配的过程中使用了一个小技巧 : 即在数据区中预留了 128 个字节大小的空间作为协议头使用, 通过移动 SKB 的 data 与 tail 指针的位置来实现这个功能.4. SKB 的 put 操作put 操作是 SKB 中一个非常频繁也是非常重要的操作, 胆识, skb_put()函数其实什么也没做!它只是根据数据的长度移动了 tail 指针并改写了 skb->len 的值,其他的什么都没做,然后就返回了 skb->data 指针(就是

tail 指针在移动之前的位置).

看上去此函数仿佛要拷贝数据到 skb 的数据区中,其实这事儿是 insl 这个函数干的,跟 skb_put() 函数毫不相关,不过它仍然很重要.5. 中断环境下 SKB 的分配流程当数据到达网卡后,会触发网卡的中断,从而进入 ISR 中,系统会在 ISR 中计算出此次接收到的数据的字节数 : pkt_len, 然后调用 SKB 分配函数来分配 SKB :skb = dev_alloc_skb(pkt_len+5);我们可以看到, 实际上传入的数据区的长度还要比实际接收到的字节数多,这实际上是一种保护机制.

实际上,在 dev_alloc_skb 函数调用 __dev_alloc_skb 函数,而 __dev_alloc_skb 函数又调用 alloc_skb 函数

时,其数据区的大小又增加了 128 字节, 这 128 字节就事前面我们所说的 reserve 机制预留的 header 空间.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值