sbk_buff中的data_len指的是尾部带的page数据的长度,len指的是总共的data的长度,len-data_len是第一个线性buf的数据长度。
sk_buff->len:表示当前协议数据包的长度。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。
比如,处在网络层,len指的是ip包的长度,如果包已经到了应用层,则len是应用层头部和数据载荷的长度。
sk_buff->data_len: data_len只计算分片中数据的长度,即skb_shared_info中有效数据总长度(包括frag_list,frags[]中的扩展数据),一般为0
sk_buff->truesize:这是缓冲区的总长度,包括sk_buff结构和数据部分。如果申请一个len字节的缓冲区,alloc_skb函数会把它初始化成len+sizeof(sk_buff)。当skb->len变化时,这个变量也会变化。
通常,Data Buffer 只是一个简单的线性 buffer,这时 len 就是线性 buffer 中的数据长度;但在有 ‘paged data’ 情况下, Data Buffer 不仅包括第一个线性 buffer ,还包括多个 page buffer;这种情况下, ‘data_len’ 指的是 page buffer 中数据的长度,’len’ 指的是线性 buffer 加上 page buffer 的长度;len – data_len 就是线性 buffer 的长度,即主buffer的中协议头和数据的长度。
通过这alloc_skb()申请的内存空间有两个,一个是存放实际报文数据的内存空间,通过kmalloc()函数申请;一个是sk_buff数据结构的内存空间。dev_alloc_skb()的功能与alloc_skb()类似,它只被驱动程序的中断所调用,与alloc_skb()比较只是申请的内存空间长度多了16个字节。
Linux内核用于分配套接字缓冲区的函数有: struct sk_buff *alloc_skb(unsigned int len,int priority);
struct sk_buff *dev_alloc_skb(unsigned int len); alloc_skb()函数分配一个套接字缓冲区和一个数据缓冲区, 参数 len为数据缓冲区
的空间大小,以16字节对齐,参数priority为内存分配的优先级。
dev_alloc_skb()函数只是以 GFP_ATOMIC优先级(代表分配过程不能被中断)调
用上面的alloc_skb()函数,并保存skb->head和skb->data 之间的 16个字节。
分配成功之后,因为还没有存放具体的网络数据包,所以 sk_buff的 data、tail指
针都指向存储空间的起始地址head,而len的大小则为 0。