Skip to content

Commit b91d532

Browse files
lxindavem330
authored andcommitted
ipv6: set rt6i_protocol properly in the route when it is installed
After commit c2ed188 ("net: ipv6: check route protocol when deleting routes"), ipv6 route checks rt protocol when trying to remove a rt entry. It introduced a side effect causing 'ip -6 route flush cache' not to work well. When flushing caches with iproute, all route caches get dumped from kernel then removed one by one by sending DELROUTE requests to kernel for each cache. The thing is iproute sends the request with the cache whose proto is set with RTPROT_REDIRECT by rt6_fill_node() when kernel dumps it. But in kernel the rt_cache protocol is still 0, which causes the cache not to be matched and removed. So the real reason is rt6i_protocol in the route is not set when it is allocated. As David Ahern's suggestion, this patch is to set rt6i_protocol properly in the route when it is installed and remove the codes setting rtm_protocol according to rt6i_flags in rt6_fill_node. This is also an improvement to keep rt6i_protocol consistent with rtm_protocol. Fixes: c2ed188 ("net: ipv6: check route protocol when deleting routes") Reported-by: Jianlin Shi <jishi@redhat.com> Suggested-by: David Ahern <dsahern@gmail.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2dda640 commit b91d532

File tree

1 file changed

+3
-8
lines changed

1 file changed

+3
-8
lines changed

net/ipv6/route.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
23512351
if (on_link)
23522352
nrt->rt6i_flags &= ~RTF_GATEWAY;
23532353

2354+
nrt->rt6i_protocol = RTPROT_REDIRECT;
23542355
nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
23552356

23562357
if (ip6_ins_rt(nrt))
@@ -2461,6 +2462,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
24612462
.fc_dst_len = prefixlen,
24622463
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
24632464
RTF_UP | RTF_PREF(pref),
2465+
.fc_protocol = RTPROT_RA,
24642466
.fc_nlinfo.portid = 0,
24652467
.fc_nlinfo.nlh = NULL,
24662468
.fc_nlinfo.nl_net = net,
@@ -2513,6 +2515,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
25132515
.fc_ifindex = dev->ifindex,
25142516
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
25152517
RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
2518+
.fc_protocol = RTPROT_RA,
25162519
.fc_nlinfo.portid = 0,
25172520
.fc_nlinfo.nlh = NULL,
25182521
.fc_nlinfo.nl_net = dev_net(dev),
@@ -3424,14 +3427,6 @@ static int rt6_fill_node(struct net *net,
34243427
rtm->rtm_flags = 0;
34253428
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
34263429
rtm->rtm_protocol = rt->rt6i_protocol;
3427-
if (rt->rt6i_flags & RTF_DYNAMIC)
3428-
rtm->rtm_protocol = RTPROT_REDIRECT;
3429-
else if (rt->rt6i_flags & RTF_ADDRCONF) {
3430-
if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO))
3431-
rtm->rtm_protocol = RTPROT_RA;
3432-
else
3433-
rtm->rtm_protocol = RTPROT_KERNEL;
3434-
}
34353430

34363431
if (rt->rt6i_flags & RTF_CACHE)
34373432
rtm->rtm_flags |= RTM_F_CLONED;

0 commit comments

Comments
 (0)