加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

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

发布时间:2016-01-23 17:25:18 所属栏目:Linux 来源:网络整理
导读:内核版本:2.6.34 在前一篇IP协议中对报文接收时IP层的处理进行了分析,本篇分析将针对报文发送时IP层的处理。 传输层处理完后,会调用ip_push_pending_frames(
副标题[/!--empirenews.page--]

内核版本:2.6.34

在前一篇”IP协议”中对报文接收时IP层的处理进行了分析,本篇分析将针对报文发送时IP层的处理。

传输层处理完后,会调用ip_push_pending_frames()将报文传递给IP层:

ip_push_pending_frames() -> ip_local_out() -> __ip_local_out()

在ip_push_pending_frames()中,会设置第一个IP分片的报头字段,tot_len和 check不会设置。

int ip_local_out(struct sk_buff *skb)
{
 int err;
 err = __ip_local_out(skb);     
 if (likely(err == 1))
  err = dst_output(skb);
 return err;
}

__ip_local_out():设置IP报头字节总长度tot_len,校验和check。

iph->tot_len = htons(skb-

>len);     
ip_send_check(iph);

最后调用dst_output()发送数据给IP层,dst_output()实际调用skb_dst(skb)->output(skb) ,skb_dst(skb)就是skb所对应的路由项。skb_dst(skb)指向的是路由项dst_entry,它的input在收到报文时赋值 ip_local_deliver(),而output在发送报文时赋值ip_output()。

return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, dst_output);

在IP层的调用过程如下:

ip_output() -> ip_finish_output() - > ip_finish_output2() -> hh->hh_output()

在ip_output()中,设置了dev与协议号,从IP层往下,就是以dev驱 动数据传输了。

skb->dev = dev;     
skb->protocol = htons(ETH_P_IP);

在ip_finish_output()中,判断如果报文过大,则先调用ip_fragment()进行 分片(后面会对这个函数进行分析),然后调用ip_finish_output2()发送。

if (skb->len > ip_skb_dst_mtu

(skb) && !skb_is_gso(skb))     
 return ip_fragment(skb, ip_finish_output2);     
else 
 return ip_finish_output2(skb);

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

情况一:ip_fragment()

ip_fragment()与ip_append_data()是IP层传送报文很重要的 两个函数,弄清它们之间的关系很重要。

ip_append_data()是上层构造向IP层传送数据的skb使用的,它会根据MTU值对传送 数据进行分片,后续分片链在第一个分片的frag_list上;如果设备支持SG,那么同一个分片内容(当分片内容是多次输入得到的 )不一定在一个线性空间上,后续输入的分片内容存在分片的frags数组中。只有第一个分片才有frag_list,而每个分片都能拥 有frags。由ip_append_data()构造好的skb大致如下图所示:

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

ip_fragments()字面 意思是分片,但实际上分片工作已经由ip_append_data()完成了,它只在上层分片出现问题时重新进行分片。它的主要作用还是 完成分片的后续工作。假设一个报文被分成了三份skb1, skb2, skb3,它们将独立的传递到网络上,但显然ip_append_data()得 到的skb还不是独立的,skb1包含了整个报文的信息,分片报文也链在frag_list上;而skb2, skb3则缺少IP报头的信息,如分片 的偏移,分片的标识,校验和等。ip_fragments()做的主要工作就是将skb拆分成能独立发送的报文。由ip_fragments()处理后 的skb如图所示:

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

(编辑:云计算网_泰州站长网)

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

热点阅读