首页 > Linux > [读书笔记] sk_buff套接口缓存结构
2014
10-09

[读书笔记] sk_buff套接口缓存结构

《Linux 内核源码剖析- TCP/IP 实现》这书很好啊,根据网络部分的源码讲解的,觉得记录下来笔记可能会更有帮助些,文中图片均来自此书。

此书用的是2.6.20的内核,我在看的同时对比了3.14.17的内核源码,所以内容有变动,都是基于3.14.17内核源码。

sk_buffer

include/linux/skbuff.h

net/core/skbuff.c

套接口缓存,主要用途是保存在进程和网络接口之间相互传递的用户数据以及其他的一些信息。

SKB在不同网络协议层之间传递,传的过程中某些成员变量会发生改变。

假如A选项会生成B宏,而某些程序有#ifdef B这条语句,则A选项是不能被编译成内核模块的。因为若某些选项所控制的数据结构是固定的而不是动态变化的。

在一个SKB结点前面会插入一个辅助的sk_buff_head的头结点,方便查找。就类似普通双链表的头结点。

即如下图:

sk_buff结构,将成员变量的含义说明了一下,来自Linux-3.14.17源码。

其中end指针指向了skb_shared_info结构体,保存了数据块的附加信息。

在网络模块中,有很多函数有两个版本,名字分别是do_something()和__do_something(),通常前者是一个封装函数,会在后者的基础上加上合法性校验或者获取锁等操作。

SKB缓存池、分配函数

在网络模块中,分配SKB描述符的高速缓存在skb_init()函数中创建。

其中第二个kmem_cache_create中创建了2倍的sk_buff的大小,以便用来克隆,这样效率会得到提高。

alloc_skb():用来分配SKB描述符和数据缓存区这两块内存。

kmem_cache_alloc_node():用来分配头部

kmalloc_reserve() 中的kmalloc_node_track_caller()用来分配数据缓存区。

可以看到size中包含了struct skb_shared_info的大小。

dev_alloc_skb():也是一个缓存区分配函数,通常被设备驱动用在中断上下文中。是alloc_skb()的封装函数,增加了原子操作。

dev_kfree_skb(),kfree_skb()dev_kfree_skb()consume_skb()的一个宏,这两个函数最终都是调用__kfree_skb()用以释放SKB

数据预留和对齐

skb_reserve():用于空的SKB,向下移动tail指针,把空间让给数据区。

skb_push():将数据区的一部分空间让给其他层用来增加头部信息。

skb_put():扩大了数据区。

skb_pull():数据区首部忽略一部分空间。

克隆和复制SKB

skb_clone():克隆过程只赋值SKB描述符,同时增加数据缓存区的引用计数,以免共享数据被提前释放。

pskb_copy():复制数据缓存区。

skb_copy():完全复制一个SKB,包括局和分散I/O存储区中的数据。

最后编辑:
作者:zxy_snow
吃好,喝好,学习好!

  1. hi~~我想问一下,以前网络层报头结构如下union { struct iphdr *iph; struct ipv6dr *ipv6h; struct arphdr *arph; unsigned char *raw;} nh;现在变成__u16 network_header之后,要怎么才能正确引用nh.iph呢?谢谢!

    • 我对你这个了解不多,我查了一下,看到了以下类似的代码http://lxr.free-electrons.com/source/include/linux/ip.h#L23 23 static inline struct iphdr *ip_hdr(const struct sk_buff *skb) 24 { 25 return (struct iphdr *)skb_network_header(skb); 26 }不知道是否有帮助http://lxr.free-electrons.com/source/net/ipv4/xfrm4_mode_transport.c 23 struct iphdr *iph = ip_hdr(skb); 24 int ihl = iph->ihl * 4; 25 26 skb_set_network_header(skb, -x->props.header_len); 27 skb->mac_header = skb->network_header + 28 offsetof(struct iphdr, protocol);

  2. Pingback: 关于sk_buff | X-SLAM