IT技术互动交流平台

linux TCP/IP协议栈 pskb_may_pull()

作者:PCliangtao   发布日期:2012-05-24 09:33:33

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

}

 

Tag标签: TCP/IP协议栈   pskb_may_pull  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规