网络子系统51_ip协议报文分片

//ip分片
//	快速路径的条件:
//		1.skb
//			1.skb的数据长度(主缓存区+frags缓存区)小于输出路径的mtu
//			2.skb的数据长度对齐到8字节的边界
//			3.skb没有被分片
//			4.skb没有被共享
//		2.skb->frag_list
//			1.长度小于(mtu-ip报头-选项)
//			2.除最后一个分片外,长度都需要对齐到8字节边界
//			3.head-data之间的空间,可以容纳ip报头
//	注:skb->frag_list的skb,没有填充ip头,skb填充有ip头
//
//	慢速路径条件:
//		只要不满足快速路径其中的一条,使用慢速路径

//	快速路径处理过程:
//		1.第一个分片使用完整的ip选项
//		2.其余分片使用部分ip选项
//		3.除最后一个分片外,设置MF标志
//		4.设置offset
//		5.使用相同的路由信息,向下层传递

//	慢速路径处理过程:
//		1.分配新的skb,长度为mtu,或者剩余数据量,对齐到8字节边界
//		2.预留l2帧头空间
//		3.拷贝l3报头,以及数据到新skb中
//		4.除第一个分片使用完整的ip选项,其余分片使用部分ip选项
//		5.设置offset
//		5.使用相同的路由信息,向下层传递


//	对比快速路径与慢速路径:
//		1.慢速路径的慢主要表现在分配新的缓存区,从旧缓存区中拷贝数据

//	注:ip报头的offset字段,只针对有效载荷(ip头,ip选项不包括在内)

//调用路径ip_output/ip_mc_output->ip_fragment
1.1 int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
{
	struct iphdr *iph;
	int raw = 0;
	int ptr;
	struct net_device *dev;
	struct sk_buff *skb2;
	unsigned int mtu, hlen, left, len, ll_rs;
	int offset;
	int not_last_frag;
	struct rtable *rt = (struct rtable*)skb->dst;
	int err = 0;
	//出口设备
	dev = rt->u.dst.dev;
	//ip头
	iph = skb->nh.iph;
	//ip报头设置有DF标志,禁止分片
	skb->local_df如果被设置,则在需要分片,但是设置DF标志,不向发送方传送ICMP消息
	if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) {
		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值