网络子系统44_ip协议源路由选项处理

简介:
//skb->pkt_type根据l2地址设置,在eth_type_trans(由驱动调用)中,如果数据帧的目的l2地址为接收接口的l2地址,设置为PACKET_HOST
//skb->rt->rt_type根据l3地址设置,在ip_route_input(由ip协议调用)中,如果数据帧的目的l3地址为本机配置的l3地址,设置为RTN_LOCAL

//调用路径ip_rcv->ip_rcv_finish->ip_options_rcv_srr
//	1.skb->dst非本机ip,
//		1.1 严路由选项,向发送方返回错误
//		1.2 宽路由选项,直接返回,继续ip_rcv_finish后续处理
//	2.skb->dst本机ip,
//		寻找源路由选项ptr指示的下一个,非本机ip的单播地址,复制到ip报头,设置ip_changed使ip校验和失效。

//根据源路由选项,选择下一跳地址,并更新skb->dst路由缓存
1.1 int ip_options_rcv_srr(struct sk_buff *skb)
{
	struct ip_options *opt = &(IPCB(skb)->opt);//ip控制块,在ip_options_compile中被初始化
	int srrspace, srrptr;
	u32 nexthop;
	struct iphdr *iph = skb->nh.iph;
	unsigned char * optptr = skb->nh.raw + opt->srr;
	struct rtable *rt = (struct rtable*)skb->dst;
	struct rtable *rt2;
	int err;

	if (!opt->srr)
		return 0;

	if (skb->pkt_type != PACKET_HOST)//l2地址非本机
		return -EINVAL;
	if (rt->rt_type == RTN_UNICAST) {//l3地址非本机,但是可以到达
		if (!opt->is_strictroute)//非严源路由选项,可以跳过,不处理
			return 0;
		icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl(16<<24));//否则通过icmp,报告发送主机,本机不在严路由ip列表中
		return -EINVAL;
	}
	if (rt->rt_type != RTN_LOCAL)//l3地址非主机,则返回错误
		return -EINVAL;
	//从ptr指示的起始位置,逐个遍历后续的路由ip,直到下一跳为非本机单播路由
	for (srrptr=optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4) {
		if (srrptr + 3 > srrspace) {//不足4字节
			icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((opt->srr+2)<<24));//报告错误
			return -EINVAL;
		}
		memcpy(&nexthop, &optptr[srrptr-1], 4);//从源路由选项中,复制下一跳的ip地址

		rt = (struct rtable*)skb->dst;
		skb->dst = NULL;
		err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);//通过源路由选项提供的下一跳地址,路由查询
		rt2 = (struct rtable*)skb->dst;
		if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {//查询出现错误,或者下一跳地址非单播路由,并且非指向本地的路由
			ip_rt_put(rt2);
			skb->dst = &rt->u.dst;//使用之前的路由选项
			return -EINVAL;//返回错误
		}
		ip_rt_put(rt);
		if (rt2->rt_type != RTN_LOCAL)//找到非本机单播地址
			break;
		memcpy(&iph->daddr, &optptr[srrptr-1], 4);//修改ip报头的目的地址
		opt->is_changed = 1;
	}
	if (srrptr <= srrspace) {
		opt->srr_is_hit = 1;
		opt->is_changed = 1;
	}
	return 0;
}

目录
相关文章
|
2天前
|
Ubuntu 网络协议 Linux
Linux(20) Ubuntu 20.04 网络接口自动切换路由配置
Linux(20) Ubuntu 20.04 网络接口自动切换路由配置
23 0
|
6天前
|
安全 网络安全 网络虚拟化
如何保护IP在线隐私,提高网络安全?
如何保护IP在线隐私,提高网络安全?
|
6天前
|
缓存 安全 网络协议
代理ip会不会影响网络速度和稳定性
代理ip会不会影响网络速度和稳定性
|
7天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
8天前
|
存储 网络协议 安全
15.网络协议-Radius协议
15.网络协议-Radius协议
|
8天前
|
存储 网络协议 网络安全
14.网络协议-邮件协议
14.网络协议-邮件协议
|
12天前
|
存储 JSON 前端开发
网络原理(4)HTTP协议(下)
网络原理(4)HTTP协议
25 0
|
15天前
|
存储 网络协议 Linux
|
15天前
|
安全 SDN 数据中心
|
1月前
|
机器学习/深度学习 数据采集 人工智能
m基于深度学习网络的手势识别系统matlab仿真,包含GUI界面
m基于深度学习网络的手势识别系统matlab仿真,包含GUI界面
41 0