linux TCP/IP协议栈 ---pskb_may_pull()

13172阅读 0评论2012-05-23 PCliangtao
分类:LINUX

在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。

点击(此处)折叠或打开

  1. static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
  2. {
  3.     /* skb_headlen定义为skb->len - skb->data_len。即skb->head指向的线性缓冲区里当前
  4.      * 有效数据的长度。*/
  5.     if (likely(len <= skb_headlen(skb)))
  6.         return 1;
  7.     if (unlikely(len > skb->len))
  8.         return 0;
  9.     return __pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL;
  10. }


MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0
上一篇:linux TCP/IP协议栈 ---IP层收包时处理过程小结(不完整)
下一篇:linux TCP/IP协议栈 ---__pskb_pull_tail()