近来开始结合linux源码看TCP/IP,看到sk_buff时被其各个数据成员弄得有些糊涂,靠死记硬背显然是不行的。最终,结合书本(Understanding LINUX Network Internals)把sk_buff中主要的几个数据成员的变化情况画了出来。这种学习方法我一直在用,效果挺好。
transport layer:
首先,看看通过alloc_skb创建的sk_buff的内存布局:
最初创建sk_buff时,len成员的值是0。该字段应该是表示buffer内有效数据的大小,buffer的大小显然是通过end-head来表示的。最初创建时,head = data = tail。
接下来,我们看看TCP层是如何把数据和HEADER放到buffer中的。
这里,先为TCP、IP、Data Link层的HEADER预留空间,大小为MAX_TCP_HEADER。该大小考虑所有情况下的最大值,所以其定义略复杂。(include/net/tcp.h)预留空间的操作用的是函数skb_reserve,会改变data和tail的值。由于这时buffer中还是没有有效数据的,所以len=0。
为HEADER预留空间后,把app层传给TCP的数据放到data处:
显然,这时buffer内是有有效数据了,len=L1。至于tail是否一定equal to end,我觉得不一定,有待进一步研究。接下来,肯定就是把TCP HEADER填上了:
相应的,len字段更新为L2。
再往下走,规律基本一样,就是为每层加HEADER:
network layer:
data link layer:
由于本人正处于学习阶段,错误之处望不吝赐教,谢谢!