一、控制结构 sk_buff 和网络报文的存储空间

二、分片的网络报文与scatter/gather IO
网络报文在内存中不一定是连续存储的,同一个网络报文有可能被分成几片存放在内存的不同位置(不要和IP分片混淆,IP分片是将一个网络报文分成多个网络报文,这里是将一个网络报文分成几片存放在不同的内存空间)。
为了记录网络报文的长度,在sk_buff里增加了一个变量data_len。这个变量记录的是在frags和frag_list里面存储的报文的长度。原有的变量len记录网络报文的总长度。truesize是 head所指的存储区的大小。
Skb比较复杂的部分在于skb_shared_info 部分,alloc_skb()在为数据分配空间的时候,会在这个数据的末尾加上一个skb_shared_info 结构,这个结构就是用于scatter/gather IO的实现的。它主要用于提高性能,避免数据的多次拷贝。例如,当用户用sendmsg分送一个数组结构的数据时,这些数据在物理可能是不连续的(大多数情况),在不支持scatter/gather IO 的网卡上,它只能通过重新拷贝,将它重装成连续的skb(skb_linearize),才可以进行DMA操作。而在支持S/G IO 上,它就省去了这次拷贝。
三、Netfilter架构图与connection trackers
Connectiontracking分为两部分:layer-3和layer-4模块。也有一个layer-5模块的跟踪,这个涉及到“连接辅助模块connectionhelper”,因为他们不仅影响到源方向的链接,也影响到未来的连接。
四、conntrack_in,help与confirm模块的调用过程
连接跟踪主要在nf_conntrack_in和nf_conntrack_confirm这两个函数里面实现。在nf_conntrack_in里面会调用resolve_normal_ct()在连接跟踪表中查找匹配的跟踪记录,如果没有找到则调用init_conntrack创建一个新的记录。最后确定sk_buff结构状态域的值,对其中的nfct和nfctinfo进行赋值。
nf_conntrack_confirm被挂在NF_INET_LOCAL_IN和NF_INET_POST_ROUTING钩子上,对其数据包进行再次连接跟踪记录确认,并最后调用__nf_conntrack_hash_insert将新建的连接跟踪记录添加到连接跟踪表中。考虑到数据包可能被过滤掉,之前新建立的连接跟踪记录实际上并为真正的加到连接跟踪表中,而是在最后由函数nf_conntrack_confirm确认后真正的添加。
五、Netfilter钩子位置
六、Conntrack中的重要数据结构
1, ip_conntrack_info:
IP_CT_NEW 由此数据包创建一个新的连接
IP_CT_RELATED 由此数据包创建一个新的 期望连接
IP_CT_ESTABLISHED 连接建立,数据包在“发起”方向
IP_CT_ESTABLISHED + IP_CT_IS_REPLY 连接建立,数据包在“回复”方向
IP_CT_RELATED + IP_CT_IS_REPLY 期望一个新的开始连接,数据包在“回复”方向。你有可能很惊讶一个连接上的第一个数据包为什么在“回复”方向上(注意:这个期望连接的回复方向不是它的“发起”方向)。这种状态实际上在ICMP的回复数据包中看起来更合逻辑
IP_CT_NEW+ IP_CT_IS_REPLY 未使用和无效的
七 ,参考
IP Connection tracking http://staff.ustc.edu.cn/~james/linux/conntrack.html
writing netfilter modules http://jengelh.medozas.de/documents/Netfilter_Modules.pdf
http://en.wikipedia.org/wiki/Netfilter
http://bbs.chinaunix.net/thread-2005999-1-1.html
转自: http://blog.youkuaiyun.com/appletreesujie/article/details/6871011