在ip_rcv()函数当中遇到了pskb_may_pull()这个函数,进行了简单的注释:
/*
*pskb_may_pull确保skb->data指向的内存包含的数据至少为IP头部大小,由于每个
*IP数据包包括IP分片必须包含一个完整的IP头部。如果小于IP头部大小,则缺失
*的部分将从数据分片中拷贝。这些分片保存在skb_shinfo(skb)->frags[]中。
*/
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
当数据包进入协议栈往上层递交的过程中,比如在IP层,它需要对数据包的IP头部进行分析,比如头部合法性等,这时候就需要确保IP头部在线性缓冲区中,这样才能对它进行分析,如果在非线性缓冲区中,而非线性缓冲区是unmapped的page,因此就需要从这些unmapped page当中把数据复制到线性缓冲区中。
这个艰难的工作就是__pskb_pull_tail完成的。我将对它的代码进行单独的分析。
当然最好情况是skb->data指向的线性缓冲区中的数据至少是大于len的,这样就可以直接返回了成功了。
len一定是不能大于整个skb的数据总长的。这个就不必说明吧...
线性缓冲区中数据不足,不幸还是发生了...调用__pskb_pull_tail。
- static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
- {
- /* skb_headlen定义为skb->len - skb->data_len。即skb->head指向的线性缓冲区里当前
- * 有效数据的长度。*/
- if (likely(len <= skb_headlen(skb)))
- return 1;
- if (unlikely(len > skb->len))
- return 0;
- return __pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL;
- }
MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0
阅读(12551) | 评论(0) | 转发(2) |