linux内核 快速分片,linux内核学习笔记------ip报文的分片

本文深入探讨Linux内核中的IP分片过程,包括快速分片和慢速分片的实现细节。当IP报文长度超过MTU时,内核会进行分片。快速分片主要依赖传输层已完成的分片,而慢速分片涉及整个IP数据报的循环分片。代码分析展示了分片判断、数据复制及IP选项处理等关键步骤。
摘要由CSDN通过智能技术生成

对网络比较熟悉的童鞋都知道,当发送的ip报文长度超出了最大的传输单位MTU,且允许分片的情况下,就会对ip报文进行分片。在上层要发送数据时就会调用dst_output,dst_output就会调用ip_output,而ip_output就会调用ip_finish_output,在ip_finish_output把数据发送出去之前就会判断该报文是否进行分片。

static int ip_finish_output(struct sk_buff *skb)

{

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

}从源码中可以看出,当报文的长度大于mtu,gso的长度不为0就会调用ip_fragment进行分片。否则就会调用ip_finish_output2把数据发送出去。

ip分片目前有两种分片方式:1、快速分片;2、慢速分片。在快速分片中,将数据分割成片段已经由传输层完成,三层只需将这写片段组成ip分片;而慢速分片则需要完成全部的工作,即对一个完整的ip数据报根据mtu值循环进行分片,直至完成。整个分片工作都在ip_fragment中完成。

int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))

{

.......

struct rtable *rt = skb_rtable(skb);

int err = 0;

dev = rt->u.dst.dev;

......

/*

* 如果待分片IP数据包禁止分片,则调用

* icmp_send()向发送方发送一个原因为需要

* 分片而设置了不分片标志的目的不可达

* ICMP报文,并丢弃报文,即设置IP状态

* 为分片失败,释放skb,返回消息过长

* 错误码。

*/

if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) {

IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);

icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,

htonl(ip_skb_dst_mtu(skb)));

kfree_skb(skb);

return -EMSGSIZE;

}

hlen &

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值