if ( unlikely(skb->data < skb->head ) ) skb_under_panic(skb , len , __builtin_return_address(0)) ; return skb->data ; } /** * skb_pull - remove data from the start of a buffer * @skb : buffer to use * @len : amount of data to remove * * This function removes data ...
unsigned char *skb_put(struct sk_buff *skb, unsigned int len) 将tail指针下移,并增加skb的 len值。data和 tail之间的空间就是可以存放网络报文的空间。这个操作增加了可以存储网络报文的空间,但是增加不能使tail的值大于end的值,skb的 len值大于truesize的值。 unsigned char *skb_push(struct sk_buff *s...
释放控制结构skb和它所指的存储空间。由于一个存储空间可以有多个控制结构,所以只有在存储空间的引用计数为1的情况下才释放存储空间,一般情况下,只释放控制结构skb。unsigned char *skb_put(struct sk_buff *skb, unsigned int len)将tail指针下移,并增加skb的 len值。data和 tail之间的空间就是可以存放网络报文的...
增加headroom区域的协议头:skb_push函数用于移动data指针,增加头部协议,与skb_reserve()类似,也并没有真正向数据缓存区中添加数据,而只是移动数据缓存区的头指针data。数据由其他函数复制到数据缓存区中。函数如下: void *skb_push(struct sk_buff *skb, unsigned int len) { skb->data -= len; skb->len +=...
skb->len //大哥、小弟和兄弟的总和,即data的总长度,线性和非线性的总和。 skb->data_len //小弟和兄弟的总和,即大哥缺少的份额,非线性数据长度。 skb_headlen() //即大哥长度,线性长度。和skb_headroom()不一样,这个是只头部空间剩余长度。 skb_pagelen() //大哥和小弟的总和,即线性数据长度和页面碎片的...
* | skb_shared_info | * |---| * | PAD | * --- */sk_buff_data_ttail;/* 偏移位置: 指向当前数据的尾部,随数据的添加、移除而改变 */sk_buff_data_tend;/* 偏移位置: 可用数据空间的尾部。end 后还跟有 skb_shared_info */unsignedchar*head,/* 数据指针: 指向可用数据空间数据头部 */*d...
进入核心流程skb_get_hash(),即计算skb hash值 /* * get_rps_cpu is called from netif_receive_skb and returns the target * CPU from the RPS map of the receiving queue for a given skb. * rcu_read_lock must be held on entry.
staticinlinevoidskb_reset_tail_pointer(struct sk_buff *skb) { skb->tail = skb->data; } 最终四大指针初始化为以下图所示: 此时head、data、tail三个指针指向一起,end指向数据缓冲区的尾部。 预留协议头空间:在sk_stream_alloc_skb调用__alloc_skb函数进行内存分配后,下一步就会预留协议头空间,使得head、...
Linux内核的网络操作是基于分层设计的,可以形象地比喻为一个数据包的“栈”操作。数据包的形成是通过逐层封装,即所谓的push操作,而解封装则是逐层弹出,即pop操作。核心数据结构sk_buff在这一过程中起到了关键作用。sk_buff操作涉及的步骤包括:首先,通过alloc_skb分配sk_buff结构和数据包缓冲区,...
//file: net/core/dev.cstatic int __init net_dev_init(void){... for_each_possible_cpu(i) { structsoftnet_data *sd = &per_cpu(softnet_data, i); memset(sd, 0, sizeof(*sd)); skb_queue_head_init(&sd->input_pkt_queue); skb_queue_head_init(&sd->process_queue)...