1 sk_buff本身并不包含存放网络包的数据的存储区,存储区是另外单独分配的内存空间,但该结构说明了如何访问存储区空间,如何维护多个存储区空间以及存储网络包解析的成果。
2 sk_buff中有四个指针指向存储区:其中head一定指向存储区的开头,end一定指向存储区的结尾。data指向实际内容的开头,tail指向实际内容的结尾。这样做有两个原因,一是在分配空间的时候我们尚不知道具体需要多大的空间,只能按照最大可能空间来分配;二是为了满足字节对齐的需要。
3 sk_buff中data部分内容包括网络包的所有内容:对于输入包而言,其就是从当前层向上的所有层的头和最后的负载,每解析掉一层的头,该协议的协议头对应的数据就不再继续处理,所以data指针在每层会逐渐增大;对于输出包而言,其每向下传输一层,都会添加一层的头,所以sk_buff的data指针也会不断减小。
4 对于输入包而言,存储区的内容是不变的。但分析包时,在每层都会剥除该层的头。为了保留剥除结果,结构中会有三个指针分别指向以太,网络和传输三层的协议头:这三个指针依次分别是union {…} mac,union {…} nh和union{…} h。三个成员都是联合,其中的内容是该层可能的协议类型的指针。
5 注意sk_buff中的几个长度字段含义:len表示存储区的数据长度和分片长度之和;data_len表示分片长度;mac_len表示mac头的长度;truesize表示存储区总长度(即end-head)和sk_buff本身长度之和。
6 刚初始化完的存储区,head,data,tail都指向存储区的开头,end指向结尾。
7 skb_put则是将tail下移,即增加了真正空间的长度。
skb_push是将data上移,也增加了真正空间的长度。
skb_pull将data下移,减少了真正空间的长度。
8 对于sk_buff和存储块,有时是需要拷贝的。分为三种情况,一是只拷贝sk_buff,存储块复用,此时使用skb_clone函数;二是拷贝 sk_buff和存储块的主体,但存储块后的skb_shared_info中frags数组指向的分片数据不拷贝,这使用pskb_copy函数;三是上述的全都拷贝,使用skb_copy函数。在不同情况下不同使用。
没有评论:
发表评论