加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[八]:IP协议

发布时间:2016-11-19 05:28:12 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 这篇是关于IP层协议接收报文时的处理,重点说明了路由表的查找,以及IP分片重组。 ip_rcv 进入IP层报文接收函数 丢弃掉不是发往本机的报文,skb-pkt_type在网卡接收报文处理以太网头时会根据dst mac设置, 协议栈的书会讲不是发

最后当满足一定条件时,进行IP重组。当收到了第一个和最后一个IP分 片,且收到的IP分片的最大长度等于收到的IP分片的总长度时,表明所有的IP分片已收集齐,调用ip_frag_reasm重组包。具体 的,当收到第一个分片(offset=0且MF=1)时设置q.last_in |= INET_FRAG_FIRST_IN;当收到最后一个分片(offset != 0且MF=0) 时设置q.last_in |= INET_FRAG_LAST_IN。meat和len的区别在于,IP是不可靠传输,到达的IP分片不能保证顺序,而meat表示 到达IP分片的总长度,len表示到达的IP分片中偏移最大的长度。所以当满足上述条件时,IP分片一定是收集齐了的。

if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && qp->q.meat == qp-

>q.len)     
 return ip_frag_reasm(qp, prev, dev);

以下图为例,原始IP报文分成了4片发送,假设收到了1, 3, 4分片,则此时 q.last_in = INET_FRGA_FIRST_IN | INET_FRAG_LAST_IN,q.meat = 30,q.len = 50。表明还未收齐IP分片,等待IP分片2的到 来。

Linux内核分析 - 网络[八]:IP协议

这里还 有一些特殊情况需要处理,它们可能是重新分片或传输时错误造成的,那就是IP分片互相间有重叠。为了避免这种情况发生,在 插入IP分片前会处理掉这些重叠。

第一种重叠是与前个分片重叠,即该分片的的偏移是从前个分片的范围内开始的,这种情 况下i表示重叠部分的大小,offset+=i则将该分片偏移后移i个长度,从而与前个分片隔开,而且减少len,pskb_pull(skb, i) ,见下图图示。

if (prev) {     
 int i = (FRAG_CB(prev)->offset + prev->len) - offset;     
         
 if (i > 0) {     
  offset += i;     
  err = -EINVAL;     
  if (end <= offset)     
   goto err;     
  err = -ENOMEM;     
  if (!pskb_pull(skb, i))     
   goto err;     
  if (skb->ip_summed != CHECKSUM_UNNECESSARY)     
   skb->ip_summed = CHECKSUM_NONE;     
 }     
}

Linux内核分析 - 网络[八]:IP协议

第二 种重叠是与后个分片重叠,即该分片的的结束位置在后个分片的范围内,这种情况下i表示重叠部分的大小。后片重叠稍微复杂 点,被i重叠的部分都要删除掉,如果i比较大,超过了分片长度,则整个分片都被覆盖,从q.fragments链表中删除。使用while 处理i覆盖多个分片的情况。

while (next && FRAG_CB(next)->offset < end)

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读