Message ID | e9342d18b97fc227cacc19db1b43f4c7350eed3f.1501419097.git.lucien.xin@gmail.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On 7/30/17 6:51 AM, Xin Long wrote: > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 4d30c96..187580f 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -2912,9 +2912,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, > cfg->fc_dst_len = rtm->rtm_dst_len; > cfg->fc_src_len = rtm->rtm_src_len; > cfg->fc_flags = RTF_UP; > - cfg->fc_protocol = rtm->rtm_protocol; > cfg->fc_type = rtm->rtm_type; > > + if (rtm->rtm_protocol != RTPROT_REDIRECT) > + cfg->fc_protocol = rtm->rtm_protocol; > + > if (rtm->rtm_type == RTN_UNREACHABLE || > rtm->rtm_type == RTN_BLACKHOLE || > rtm->rtm_type == RTN_PROHIBIT || Did you look at removing this hunk from rt6_fill_node: if (rt->rt6i_flags & RTF_DYNAMIC) rtm->rtm_protocol = RTPROT_REDIRECT; else if (rt->rt6i_flags & RTF_ADDRCONF) { if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) rtm->rtm_protocol = RTPROT_RA; else rtm->rtm_protocol = RTPROT_KERNEL; } And have rtm_protocol set properly on the route when it is installed?
On Mon, Jul 31, 2017 at 2:35 PM, David Ahern <dsahern@gmail.com> wrote: > On 7/30/17 6:51 AM, Xin Long wrote: >> diff --git a/net/ipv6/route.c b/net/ipv6/route.c >> index 4d30c96..187580f 100644 >> --- a/net/ipv6/route.c >> +++ b/net/ipv6/route.c >> @@ -2912,9 +2912,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, >> cfg->fc_dst_len = rtm->rtm_dst_len; >> cfg->fc_src_len = rtm->rtm_src_len; >> cfg->fc_flags = RTF_UP; >> - cfg->fc_protocol = rtm->rtm_protocol; >> cfg->fc_type = rtm->rtm_type; >> >> + if (rtm->rtm_protocol != RTPROT_REDIRECT) >> + cfg->fc_protocol = rtm->rtm_protocol; >> + >> if (rtm->rtm_type == RTN_UNREACHABLE || >> rtm->rtm_type == RTN_BLACKHOLE || >> rtm->rtm_type == RTN_PROHIBIT || Hi, David > > Did you look at removing this hunk from rt6_fill_node: > > if (rt->rt6i_flags & RTF_DYNAMIC) > rtm->rtm_protocol = RTPROT_REDIRECT; > else if (rt->rt6i_flags & RTF_ADDRCONF) { > if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO)) > rtm->rtm_protocol = RTPROT_RA; > else > rtm->rtm_protocol = RTPROT_KERNEL; > } The issue seems to affect "ip -6 route flush all" as well, not only cache since 'else if {}' also causes rtm proto being different from rt6 proto. > > And have rtm_protocol set properly on the route when it is installed? The codes not keeping rtm proto consistent with rt6 proto day 1, any idea on why it didn't use rt6 proto in kernel properly? Thanks.
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4d30c96..187580f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2912,9 +2912,11 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_dst_len = rtm->rtm_dst_len; cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_flags = RTF_UP; - cfg->fc_protocol = rtm->rtm_protocol; cfg->fc_type = rtm->rtm_type; + if (rtm->rtm_protocol != RTPROT_REDIRECT) + cfg->fc_protocol = rtm->rtm_protocol; + if (rtm->rtm_type == RTN_UNREACHABLE || rtm->rtm_type == RTN_BLACKHOLE || rtm->rtm_type == RTN_PROHIBIT ||
After commit c2ed1880fd61 ("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 when flushing caches with iproute, in which all route caches get dumped from kernel then removed one by one by sending RTM_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 found and removed. As rt6_fill_node always sets rtm proto with RTPROT_REDIRECT when rt cache info goes to rtmsg, the reverse process is needed when users remove a route cache and rtmsg goes to cfg. This patch is to fix it by keeping cfg proto as 0 when rtm proto is REDIRECT. It's a safe fix as rtm proto is set with REDIRECT only if rt flag has RTF_DYNAMIC which is set when creating a rt cache in rt6_do_redirect where the cache's proto is always 0. Note that this issue can also be avoided in iproute by changing rtm proto back to 0 before sending DELROUTE requests for cache. But in kernel part, the fix is still necessary as kernel should do the reverse conversion when rtm goes to cfg. Fixes: c2ed1880fd61 ("net: ipv6: check route protocol when deleting routes") Signed-off-by: Xin Long <lucien.xin@gmail.com> --- net/ipv6/route.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)