skb_reserve(): skb->data和skb->tail同时往下拉(增大);2. 三个拷贝 skb_clone(): 函数仅仅是克隆个sk_buff结构体,其他数据都是共享; pskb_copy(): 函数克隆复制了sk_buff和其数据区(包括分片结构体/非线性区),其他数据共享; skb_copy(): 函数则是完全的复制拷贝函数了,把sk_buff结构体和其数据区(...
例如,某个以太网设备驱动的接收函数,在分配SKB之后,向数据缓存区填充数据之前,会有这样的一条语句skb_reserve(skb, 2),这是因为以太网头长度为14B,再加上2B就正好16字节边界对齐,所以大多数以太网设备都会在数据包之前保留2B。 当SKB在协议栈中向下传递时,每一层协议都把skb->data指针向上移动,然后复制本层首部...
skb操作中的预留和对齐操作主要由skb_put、skb_push、skb_pull、skb_reserve完成;这几个函数的区别通过下面图(图片来自:深入理解linux网络技术内幕)可以清晰的区分;另外,需要注意的是skb_reserve只能操作空skb,即在分配了空间,尚未填充数据时调用; 以下为四个函数的源码分析; 1/**2* skb_put - add data to a...
- skb_reserve(): 数据区空间大小不变,headroom空间增大,tailroom空间降低,skb->data和skb->tail同时下移。 对于带有frag page的分片skb,不能使用上述函数,必须使用以下函数: - pskb_pull(): 对于带有frag page的分片skb来说,data指针往下移动,可能会导致线性区越界,因此需要判断是否线性区有足够的空间用来pull操...
如果该函数成功返回,那么就相当于你已经有了一个大小为size的空数据包缓冲区以及操作该数据包缓冲区的skb元数据。如下图所示: 2.初始定位(skb_reserve) skb 逐层封装的关键在于写指针的定位,即这一层从哪个位置开始写。从协议封装的压栈形象来看,这个定位应该是顺序有规律的。初始定位十分重要,后面的定位就是 ...
在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve将数据部分往后移。协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间,再用skb_push函数将协议头查到skb->data指针之前。
void skb_reserve(struct sk_buff * skb, unsigned int len) skb为要改变的缓冲区,len为要删除的字节数 通过减少尾部空间,增加一个空&sk_buff的首部空间。这仅仅适用于空缓冲区。 skb_trim 从缓冲区删除尾部 void skb_trim (struct sk_buff * skb, unsigned int len); skb为要改变的缓冲区,len为新的长...
skb_push()在数据缓存区的前头加入一块数据,与skb_reserve()类似,也并没有真正向数据缓存区中添加数据,而只是移动数据缓存区的头指针data和尾指针tail。数据由其他函数复制到数据缓存区中。 函数执行步骤如下: 1)当TCP发送数据时,会根据一些条件,如TCP最大分段长度MSS、是否支持聚合分散I/O等,分配一个SKB。
linux协议栈skb操作函数
5. skb提供了多种操作函数,如skb_push、skb_pull、skb_put、skb_reserve等,用于在数据包的不同部分插入或提取数据。 6. skb结构体在网络栈的各个层次中被传递,从网络接口层到传输层,再到应用层。 7. skb结构体中包含了多个指针,如next指针,用于将多个skb结构体链接成链表,这在处理分片数据包时非常有用。