Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371274
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类: LINUX

2012-05-23 21:47:30

在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
阅读(12211) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~