Skip to content

Commit e8478e8

Browse files
dsaherndavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ae90d86 commit e8478e8

File tree

3 files changed

+23
-26
lines changed

3 files changed

+23
-26
lines changed

include/net/ip6_fib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ struct rt6_info {
174174
int rt6i_nh_weight;
175175
unsigned short rt6i_nfheader_len;
176176
u8 rt6i_protocol;
177+
u8 fib6_type;
177178
u8 exception_bucket_flushed:1,
178179
should_flush:1,
179180
unused:6;

net/ipv6/addrconf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,6 +2331,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
23312331
.fc_flags = RTF_UP | flags,
23322332
.fc_nlinfo.nl_net = dev_net(dev),
23332333
.fc_protocol = RTPROT_KERNEL,
2334+
.fc_type = RTN_UNICAST,
23342335
};
23352336

23362337
cfg.fc_dst = *pfx;
@@ -2394,6 +2395,7 @@ static void addrconf_add_mroute(struct net_device *dev)
23942395
.fc_ifindex = dev->ifindex,
23952396
.fc_dst_len = 8,
23962397
.fc_flags = RTF_UP,
2398+
.fc_type = RTN_UNICAST,
23972399
.fc_nlinfo.nl_net = dev_net(dev),
23982400
};
23992401

net/ipv6/route.c

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ static const struct rt6_info ip6_null_entry_template = {
307307
.rt6i_protocol = RTPROT_KERNEL,
308308
.rt6i_metric = ~(u32) 0,
309309
.rt6i_ref = ATOMIC_INIT(1),
310+
.fib6_type = RTN_UNREACHABLE,
310311
};
311312

312313
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -324,6 +325,7 @@ static const struct rt6_info ip6_prohibit_entry_template = {
324325
.rt6i_protocol = RTPROT_KERNEL,
325326
.rt6i_metric = ~(u32) 0,
326327
.rt6i_ref = ATOMIC_INIT(1),
328+
.fib6_type = RTN_PROHIBIT,
327329
};
328330

329331
static const struct rt6_info ip6_blk_hole_entry_template = {
@@ -339,6 +341,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
339341
.rt6i_protocol = RTPROT_KERNEL,
340342
.rt6i_metric = ~(u32) 0,
341343
.rt6i_ref = ATOMIC_INIT(1),
344+
.fib6_type = RTN_BLACKHOLE,
342345
};
343346

344347
#endif
@@ -2802,6 +2805,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
28022805
goto out;
28032806
}
28042807

2808+
if (cfg->fc_type > RTN_MAX) {
2809+
NL_SET_ERR_MSG(extack, "Invalid route type");
2810+
goto out;
2811+
}
2812+
28052813
if (cfg->fc_dst_len > 128) {
28062814
NL_SET_ERR_MSG(extack, "Invalid prefix length");
28072815
goto out;
@@ -2914,6 +2922,8 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
29142922
rt->rt6i_metric = cfg->fc_metric;
29152923
rt->rt6i_nh_weight = 1;
29162924

2925+
rt->fib6_type = cfg->fc_type;
2926+
29172927
/* We cannot add true routes via loopback here,
29182928
they would result in kernel looping; promote them to reject routes
29192929
*/
@@ -3354,6 +3364,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
33543364
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
33553365
RTF_UP | RTF_PREF(pref),
33563366
.fc_protocol = RTPROT_RA,
3367+
.fc_type = RTN_UNICAST,
33573368
.fc_nlinfo.portid = 0,
33583369
.fc_nlinfo.nlh = NULL,
33593370
.fc_nlinfo.nl_net = net,
@@ -3410,6 +3421,7 @@ struct rt6_info *rt6_add_dflt_router(struct net *net,
34103421
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
34113422
RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
34123423
.fc_protocol = RTPROT_RA,
3424+
.fc_type = RTN_UNICAST,
34133425
.fc_nlinfo.portid = 0,
34143426
.fc_nlinfo.nlh = NULL,
34153427
.fc_nlinfo.nl_net = net,
@@ -3485,6 +3497,7 @@ static void rtmsg_to_fib6_config(struct net *net,
34853497
cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
34863498
cfg->fc_src_len = rtmsg->rtmsg_src_len;
34873499
cfg->fc_flags = rtmsg->rtmsg_flags;
3500+
cfg->fc_type = rtmsg->rtmsg_type;
34883501

34893502
cfg->fc_nlinfo.nl_net = net;
34903503

@@ -3606,10 +3619,13 @@ struct rt6_info *addrconf_dst_alloc(struct net *net,
36063619

36073620
rt->rt6i_protocol = RTPROT_KERNEL;
36083621
rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
3609-
if (anycast)
3622+
if (anycast) {
3623+
rt->fib6_type = RTN_ANYCAST;
36103624
rt->rt6i_flags |= RTF_ANYCAST;
3611-
else
3625+
} else {
3626+
rt->fib6_type = RTN_LOCAL;
36123627
rt->rt6i_flags |= RTF_LOCAL;
3628+
}
36133629

36143630
rt->rt6i_gateway = *addr;
36153631
rt->rt6i_dst.addr = *addr;
@@ -4509,30 +4525,8 @@ static int rt6_fill_node(struct net *net,
45094525
rtm->rtm_table = table;
45104526
if (nla_put_u32(skb, RTA_TABLE, table))
45114527
goto nla_put_failure;
4512-
if (rt->rt6i_flags & RTF_REJECT) {
4513-
switch (rt->dst.error) {
4514-
case -EINVAL:
4515-
rtm->rtm_type = RTN_BLACKHOLE;
4516-
break;
4517-
case -EACCES:
4518-
rtm->rtm_type = RTN_PROHIBIT;
4519-
break;
4520-
case -EAGAIN:
4521-
rtm->rtm_type = RTN_THROW;
4522-
break;
4523-
default:
4524-
rtm->rtm_type = RTN_UNREACHABLE;
4525-
break;
4526-
}
4527-
}
4528-
else if (rt->rt6i_flags & RTF_LOCAL)
4529-
rtm->rtm_type = RTN_LOCAL;
4530-
else if (rt->rt6i_flags & RTF_ANYCAST)
4531-
rtm->rtm_type = RTN_ANYCAST;
4532-
else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
4533-
rtm->rtm_type = RTN_LOCAL;
4534-
else
4535-
rtm->rtm_type = RTN_UNICAST;
4528+
4529+
rtm->rtm_type = rt->fib6_type;
45364530
rtm->rtm_flags = 0;
45374531
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
45384532
rtm->rtm_protocol = rt->rt6i_protocol;

0 commit comments

Comments
 (0)