forked from mirrors/linux
		
	net/ipv6: Save route type in rt6_info
The RTN_ type for IPv6 FIB entries is currently embedded in rt6i_flags and dst.error. Since dst is going to be removed, it can no longer be relied on for FIB dumps so save the route type as fib6_type. fc_type is set in current users based on the algorithm in rt6_fill_node: - rt6i_flags contains RTF_LOCAL: fc_type = RTN_LOCAL - rt6i_flags contains RTF_ANYCAST: fc_type = RTN_ANYCAST - else fc_type = RTN_UNICAST Similarly, fib6_type is set in the rt6_info templates based on the RTF_REJECT section of rt6_fill_node converting dst.error to RTN type. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									ae90d867f9
								
							
						
					
					
						commit
						e8478e80e5
					
				
					 3 changed files with 23 additions and 26 deletions
				
			
		| 
						 | 
					@ -174,6 +174,7 @@ struct rt6_info {
 | 
				
			||||||
	int				rt6i_nh_weight;
 | 
						int				rt6i_nh_weight;
 | 
				
			||||||
	unsigned short			rt6i_nfheader_len;
 | 
						unsigned short			rt6i_nfheader_len;
 | 
				
			||||||
	u8				rt6i_protocol;
 | 
						u8				rt6i_protocol;
 | 
				
			||||||
 | 
						u8				fib6_type;
 | 
				
			||||||
	u8				exception_bucket_flushed:1,
 | 
						u8				exception_bucket_flushed:1,
 | 
				
			||||||
					should_flush:1,
 | 
										should_flush:1,
 | 
				
			||||||
					unused:6;
 | 
										unused:6;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2331,6 +2331,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
 | 
				
			||||||
		.fc_flags = RTF_UP | flags,
 | 
							.fc_flags = RTF_UP | flags,
 | 
				
			||||||
		.fc_nlinfo.nl_net = dev_net(dev),
 | 
							.fc_nlinfo.nl_net = dev_net(dev),
 | 
				
			||||||
		.fc_protocol = RTPROT_KERNEL,
 | 
							.fc_protocol = RTPROT_KERNEL,
 | 
				
			||||||
 | 
							.fc_type = RTN_UNICAST,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfg.fc_dst = *pfx;
 | 
						cfg.fc_dst = *pfx;
 | 
				
			||||||
| 
						 | 
					@ -2394,6 +2395,7 @@ static void addrconf_add_mroute(struct net_device *dev)
 | 
				
			||||||
		.fc_ifindex = dev->ifindex,
 | 
							.fc_ifindex = dev->ifindex,
 | 
				
			||||||
		.fc_dst_len = 8,
 | 
							.fc_dst_len = 8,
 | 
				
			||||||
		.fc_flags = RTF_UP,
 | 
							.fc_flags = RTF_UP,
 | 
				
			||||||
 | 
							.fc_type = RTN_UNICAST,
 | 
				
			||||||
		.fc_nlinfo.nl_net = dev_net(dev),
 | 
							.fc_nlinfo.nl_net = dev_net(dev),
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,6 +307,7 @@ static const struct rt6_info ip6_null_entry_template = {
 | 
				
			||||||
	.rt6i_protocol  = RTPROT_KERNEL,
 | 
						.rt6i_protocol  = RTPROT_KERNEL,
 | 
				
			||||||
	.rt6i_metric	= ~(u32) 0,
 | 
						.rt6i_metric	= ~(u32) 0,
 | 
				
			||||||
	.rt6i_ref	= ATOMIC_INIT(1),
 | 
						.rt6i_ref	= ATOMIC_INIT(1),
 | 
				
			||||||
 | 
						.fib6_type	= RTN_UNREACHABLE,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | 
					#ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | 
				
			||||||
| 
						 | 
					@ -324,6 +325,7 @@ static const struct rt6_info ip6_prohibit_entry_template = {
 | 
				
			||||||
	.rt6i_protocol  = RTPROT_KERNEL,
 | 
						.rt6i_protocol  = RTPROT_KERNEL,
 | 
				
			||||||
	.rt6i_metric	= ~(u32) 0,
 | 
						.rt6i_metric	= ~(u32) 0,
 | 
				
			||||||
	.rt6i_ref	= ATOMIC_INIT(1),
 | 
						.rt6i_ref	= ATOMIC_INIT(1),
 | 
				
			||||||
 | 
						.fib6_type	= RTN_PROHIBIT,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct rt6_info ip6_blk_hole_entry_template = {
 | 
					static const struct rt6_info ip6_blk_hole_entry_template = {
 | 
				
			||||||
| 
						 | 
					@ -339,6 +341,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
 | 
				
			||||||
	.rt6i_protocol  = RTPROT_KERNEL,
 | 
						.rt6i_protocol  = RTPROT_KERNEL,
 | 
				
			||||||
	.rt6i_metric	= ~(u32) 0,
 | 
						.rt6i_metric	= ~(u32) 0,
 | 
				
			||||||
	.rt6i_ref	= ATOMIC_INIT(1),
 | 
						.rt6i_ref	= ATOMIC_INIT(1),
 | 
				
			||||||
 | 
						.fib6_type	= RTN_BLACKHOLE,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -2802,6 +2805,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cfg->fc_type > RTN_MAX) {
 | 
				
			||||||
 | 
							NL_SET_ERR_MSG(extack, "Invalid route type");
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cfg->fc_dst_len > 128) {
 | 
						if (cfg->fc_dst_len > 128) {
 | 
				
			||||||
		NL_SET_ERR_MSG(extack, "Invalid prefix length");
 | 
							NL_SET_ERR_MSG(extack, "Invalid prefix length");
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
| 
						 | 
					@ -2914,6 +2922,8 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
 | 
				
			||||||
	rt->rt6i_metric = cfg->fc_metric;
 | 
						rt->rt6i_metric = cfg->fc_metric;
 | 
				
			||||||
	rt->rt6i_nh_weight = 1;
 | 
						rt->rt6i_nh_weight = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rt->fib6_type = cfg->fc_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We cannot add true routes via loopback here,
 | 
						/* We cannot add true routes via loopback here,
 | 
				
			||||||
	   they would result in kernel looping; promote them to reject routes
 | 
						   they would result in kernel looping; promote them to reject routes
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -3354,6 +3364,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
 | 
				
			||||||
		.fc_flags	= RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
 | 
							.fc_flags	= RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
 | 
				
			||||||
				  RTF_UP | RTF_PREF(pref),
 | 
									  RTF_UP | RTF_PREF(pref),
 | 
				
			||||||
		.fc_protocol = RTPROT_RA,
 | 
							.fc_protocol = RTPROT_RA,
 | 
				
			||||||
 | 
							.fc_type = RTN_UNICAST,
 | 
				
			||||||
		.fc_nlinfo.portid = 0,
 | 
							.fc_nlinfo.portid = 0,
 | 
				
			||||||
		.fc_nlinfo.nlh = NULL,
 | 
							.fc_nlinfo.nlh = NULL,
 | 
				
			||||||
		.fc_nlinfo.nl_net = net,
 | 
							.fc_nlinfo.nl_net = net,
 | 
				
			||||||
| 
						 | 
					@ -3410,6 +3421,7 @@ struct rt6_info *rt6_add_dflt_router(struct net *net,
 | 
				
			||||||
		.fc_flags	= RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
 | 
							.fc_flags	= RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
 | 
				
			||||||
				  RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
 | 
									  RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
 | 
				
			||||||
		.fc_protocol = RTPROT_RA,
 | 
							.fc_protocol = RTPROT_RA,
 | 
				
			||||||
 | 
							.fc_type = RTN_UNICAST,
 | 
				
			||||||
		.fc_nlinfo.portid = 0,
 | 
							.fc_nlinfo.portid = 0,
 | 
				
			||||||
		.fc_nlinfo.nlh = NULL,
 | 
							.fc_nlinfo.nlh = NULL,
 | 
				
			||||||
		.fc_nlinfo.nl_net = net,
 | 
							.fc_nlinfo.nl_net = net,
 | 
				
			||||||
| 
						 | 
					@ -3485,6 +3497,7 @@ static void rtmsg_to_fib6_config(struct net *net,
 | 
				
			||||||
	cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
 | 
						cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
 | 
				
			||||||
	cfg->fc_src_len = rtmsg->rtmsg_src_len;
 | 
						cfg->fc_src_len = rtmsg->rtmsg_src_len;
 | 
				
			||||||
	cfg->fc_flags = rtmsg->rtmsg_flags;
 | 
						cfg->fc_flags = rtmsg->rtmsg_flags;
 | 
				
			||||||
 | 
						cfg->fc_type = rtmsg->rtmsg_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cfg->fc_nlinfo.nl_net = net;
 | 
						cfg->fc_nlinfo.nl_net = net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3606,10 +3619,13 @@ struct rt6_info *addrconf_dst_alloc(struct net *net,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt->rt6i_protocol = RTPROT_KERNEL;
 | 
						rt->rt6i_protocol = RTPROT_KERNEL;
 | 
				
			||||||
	rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
 | 
						rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
 | 
				
			||||||
	if (anycast)
 | 
						if (anycast) {
 | 
				
			||||||
 | 
							rt->fib6_type = RTN_ANYCAST;
 | 
				
			||||||
		rt->rt6i_flags |= RTF_ANYCAST;
 | 
							rt->rt6i_flags |= RTF_ANYCAST;
 | 
				
			||||||
	else
 | 
						} else {
 | 
				
			||||||
 | 
							rt->fib6_type = RTN_LOCAL;
 | 
				
			||||||
		rt->rt6i_flags |= RTF_LOCAL;
 | 
							rt->rt6i_flags |= RTF_LOCAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt->rt6i_gateway  = *addr;
 | 
						rt->rt6i_gateway  = *addr;
 | 
				
			||||||
	rt->rt6i_dst.addr = *addr;
 | 
						rt->rt6i_dst.addr = *addr;
 | 
				
			||||||
| 
						 | 
					@ -4509,30 +4525,8 @@ static int rt6_fill_node(struct net *net,
 | 
				
			||||||
	rtm->rtm_table = table;
 | 
						rtm->rtm_table = table;
 | 
				
			||||||
	if (nla_put_u32(skb, RTA_TABLE, table))
 | 
						if (nla_put_u32(skb, RTA_TABLE, table))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
	if (rt->rt6i_flags & RTF_REJECT) {
 | 
					
 | 
				
			||||||
		switch (rt->dst.error) {
 | 
						rtm->rtm_type = rt->fib6_type;
 | 
				
			||||||
		case -EINVAL:
 | 
					 | 
				
			||||||
			rtm->rtm_type = RTN_BLACKHOLE;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case -EACCES:
 | 
					 | 
				
			||||||
			rtm->rtm_type = RTN_PROHIBIT;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case -EAGAIN:
 | 
					 | 
				
			||||||
			rtm->rtm_type = RTN_THROW;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			rtm->rtm_type = RTN_UNREACHABLE;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (rt->rt6i_flags & RTF_LOCAL)
 | 
					 | 
				
			||||||
		rtm->rtm_type = RTN_LOCAL;
 | 
					 | 
				
			||||||
	else if (rt->rt6i_flags & RTF_ANYCAST)
 | 
					 | 
				
			||||||
		rtm->rtm_type = RTN_ANYCAST;
 | 
					 | 
				
			||||||
	else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
 | 
					 | 
				
			||||||
		rtm->rtm_type = RTN_LOCAL;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		rtm->rtm_type = RTN_UNICAST;
 | 
					 | 
				
			||||||
	rtm->rtm_flags = 0;
 | 
						rtm->rtm_flags = 0;
 | 
				
			||||||
	rtm->rtm_scope = RT_SCOPE_UNIVERSE;
 | 
						rtm->rtm_scope = RT_SCOPE_UNIVERSE;
 | 
				
			||||||
	rtm->rtm_protocol = rt->rt6i_protocol;
 | 
						rtm->rtm_protocol = rt->rt6i_protocol;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue