diff mbox series

[net-next,07/21] net/ipv6: Save route type in rt6_info

Message ID 20180416152255.2256-8-dsahern@gmail.com
State Changes Requested, archived
Delegated to: David Miller
Headers show
Series net/ipv6: Separate data structures for FIB and data path | expand

Commit Message

David Ahern April 16, 2018, 3:22 p.m. UTC
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.

Signed-off-by: David Ahern <dsahern@gmail.com>
---
 include/net/ip6_fib.h |  1 +
 net/ipv6/addrconf.c   |  2 ++
 net/ipv6/route.c      | 46 ++++++++++++++++++++--------------------------
 3 files changed, 23 insertions(+), 26 deletions(-)

Comments

David Miller April 16, 2018, 7:20 p.m. UTC | #1
From: David Ahern <dsahern@gmail.com>
Date: Mon, 16 Apr 2018 08:22:41 -0700

> @@ -2394,6 +2395,7 @@ static void addrconf_add_mroute(struct net_device *dev)
>  		.fc_ifindex = dev->ifindex,
>  		.fc_dst_len = 8,
>  		.fc_flags = RTF_UP,
> +		.fc_type = RTN_UNICAST,
>  		.fc_nlinfo.nl_net = dev_net(dev),
>  	};
>  

Multicast route is of type RTN_UNICAST?

All of these cases where passing in a zero initialized value of
fc_type up until this patch.  Perhaps you should discuss that in your
commit message a little bit.

Thanks.
David Ahern April 16, 2018, 7:26 p.m. UTC | #2
On 4/16/18 1:20 PM, David Miller wrote:
> From: David Ahern <dsahern@gmail.com>
> Date: Mon, 16 Apr 2018 08:22:41 -0700
> 
>> @@ -2394,6 +2395,7 @@ static void addrconf_add_mroute(struct net_device *dev)
>>  		.fc_ifindex = dev->ifindex,
>>  		.fc_dst_len = 8,
>>  		.fc_flags = RTF_UP,
>> +		.fc_type = RTN_UNICAST,
>>  		.fc_nlinfo.nl_net = dev_net(dev),
>>  	};
>>  
> 
> Multicast route is of type RTN_UNICAST?

The ff00::/8 route is. Today's code:
# ip -d -6 ro ls table local
..
unicast ff00::/8 dev eth3 proto boot scope global metric 256 pref medium
unicast ff00::/8 dev eth4 proto boot scope global metric 256 pref medium

With this patch set:
# ip -d -6 ro ls table local
...
unicast ff00::/8 dev eth3 proto boot scope global metric 256 pref medium
unicast ff00::/8 dev eth4 proto boot scope global metric 256 pref medium

> 
> All of these cases where passing in a zero initialized value of
> fc_type up until this patch.  Perhaps you should discuss that in your
> commit message a little bit.

ok
David Ahern April 16, 2018, 7:50 p.m. UTC | #3
On 4/16/18 1:20 PM, David Miller wrote:
> From: David Ahern <dsahern@gmail.com>
> Date: Mon, 16 Apr 2018 08:22:41 -0700
> 
>> @@ -2394,6 +2395,7 @@ static void addrconf_add_mroute(struct net_device *dev)
>>  		.fc_ifindex = dev->ifindex,
>>  		.fc_dst_len = 8,
>>  		.fc_flags = RTF_UP,
>> +		.fc_type = RTN_UNICAST,
>>  		.fc_nlinfo.nl_net = dev_net(dev),
>>  	};
>>  
> 
> Multicast route is of type RTN_UNICAST?
> 
> All of these cases where passing in a zero initialized value of
> fc_type up until this patch.  Perhaps you should discuss that in your
> commit message a little bit.

Added this to the commit message:

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.

#####

Will send a v2 later this week.
David Miller April 16, 2018, 7:55 p.m. UTC | #4
From: David Ahern <dsahern@gmail.com>
Date: Mon, 16 Apr 2018 13:50:07 -0600

> Added this to the commit message:
> 
> 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.
> 
> #####
> 
> Will send a v2 later this week.

Looks great.
diff mbox series

Patch

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index f0aaf1c8f1a8..0165820bbafb 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -174,6 +174,7 @@  struct rt6_info {
 	int				rt6i_nh_weight;
 	unsigned short			rt6i_nfheader_len;
 	u8				rt6i_protocol;
+	u8				fib6_type;
 	u8				exception_bucket_flushed:1,
 					should_flush:1,
 					unused:6;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7d455d4df7ef..34d6aa65bf34 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2331,6 +2331,7 @@  addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
 		.fc_flags = RTF_UP | flags,
 		.fc_nlinfo.nl_net = dev_net(dev),
 		.fc_protocol = RTPROT_KERNEL,
+		.fc_type = RTN_UNICAST,
 	};
 
 	cfg.fc_dst = *pfx;
@@ -2394,6 +2395,7 @@  static void addrconf_add_mroute(struct net_device *dev)
 		.fc_ifindex = dev->ifindex,
 		.fc_dst_len = 8,
 		.fc_flags = RTF_UP,
+		.fc_type = RTN_UNICAST,
 		.fc_nlinfo.nl_net = dev_net(dev),
 	};
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1d2b6b1c5dae..177c85e7aa4d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -307,6 +307,7 @@  static const struct rt6_info ip6_null_entry_template = {
 	.rt6i_protocol  = RTPROT_KERNEL,
 	.rt6i_metric	= ~(u32) 0,
 	.rt6i_ref	= ATOMIC_INIT(1),
+	.fib6_type	= RTN_UNREACHABLE,
 };
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -324,6 +325,7 @@  static const struct rt6_info ip6_prohibit_entry_template = {
 	.rt6i_protocol  = RTPROT_KERNEL,
 	.rt6i_metric	= ~(u32) 0,
 	.rt6i_ref	= ATOMIC_INIT(1),
+	.fib6_type	= RTN_PROHIBIT,
 };
 
 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_metric	= ~(u32) 0,
 	.rt6i_ref	= ATOMIC_INIT(1),
+	.fib6_type	= RTN_BLACKHOLE,
 };
 
 #endif
@@ -2802,6 +2805,11 @@  static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
 		goto out;
 	}
 
+	if (cfg->fc_type > RTN_MAX) {
+		NL_SET_ERR_MSG(extack, "Invalid route type");
+		goto out;
+	}
+
 	if (cfg->fc_dst_len > 128) {
 		NL_SET_ERR_MSG(extack, "Invalid prefix length");
 		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_nh_weight = 1;
 
+	rt->fib6_type = cfg->fc_type;
+
 	/* We cannot add true routes via loopback here,
 	   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 |
 				  RTF_UP | RTF_PREF(pref),
 		.fc_protocol = RTPROT_RA,
+		.fc_type = RTN_UNICAST,
 		.fc_nlinfo.portid = 0,
 		.fc_nlinfo.nlh = NULL,
 		.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 |
 				  RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
 		.fc_protocol = RTPROT_RA,
+		.fc_type = RTN_UNICAST,
 		.fc_nlinfo.portid = 0,
 		.fc_nlinfo.nlh = NULL,
 		.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_src_len = rtmsg->rtmsg_src_len;
 	cfg->fc_flags = rtmsg->rtmsg_flags;
+	cfg->fc_type = rtmsg->rtmsg_type;
 
 	cfg->fc_nlinfo.nl_net = net;
 
@@ -3605,10 +3618,13 @@  struct rt6_info *addrconf_dst_alloc(struct net *net,
 
 	rt->rt6i_protocol = RTPROT_KERNEL;
 	rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
-	if (anycast)
+	if (anycast) {
+		rt->fib6_type = RTN_ANYCAST;
 		rt->rt6i_flags |= RTF_ANYCAST;
-	else
+	} else {
+		rt->fib6_type = RTN_LOCAL;
 		rt->rt6i_flags |= RTF_LOCAL;
+	}
 
 	rt->rt6i_gateway  = *addr;
 	rt->rt6i_dst.addr = *addr;
@@ -4508,30 +4524,8 @@  static int rt6_fill_node(struct net *net,
 	rtm->rtm_table = table;
 	if (nla_put_u32(skb, RTA_TABLE, table))
 		goto nla_put_failure;
-	if (rt->rt6i_flags & RTF_REJECT) {
-		switch (rt->dst.error) {
-		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_type = rt->fib6_type;
 	rtm->rtm_flags = 0;
 	rtm->rtm_scope = RT_SCOPE_UNIVERSE;
 	rtm->rtm_protocol = rt->rt6i_protocol;