On 9/8/18 3:24 AM, Xin Long wrote: > In inet6_rtm_getroute, since Commit 93531c674315 ("net/ipv6: separate > handling of FIB entries from dst based routes"), it has used rt->from > to dump route info instead of rt. > > However for some route like cache, its information is not the same as > that of the 'from' one. It caused 'ip -6 route get' to dump the wrong > route information. > > In Jianlin's testing, the output information even lost the expiration > time for a pmtu route cache due to the wrong fib6_flags.
you are right about the flags ... > > So change to use rt6_info members when it tries to dump a route entry > without fibmatch set. but not the src, dst and prefsrc. > > Note that we will fix the gw/nh dump in another patch. And only the gateway can change do to a redirect and redirects do not change the device - only the gateway. Let's do both changes in a single patch. > > Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst > based routes") > Reported-by: Jianlin Shi <ji...@redhat.com> > Signed-off-by: Xin Long <lucien....@gmail.com> > --- > net/ipv6/route.c | 39 ++++++++++++++++++++++++++------------- > 1 file changed, 26 insertions(+), 13 deletions(-) > > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 18e00ce..e554922 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -4670,20 +4670,33 @@ static int rt6_fill_node(struct net *net, struct > sk_buff *skb, > int iif, int type, u32 portid, u32 seq, > unsigned int flags) > { > - struct rtmsg *rtm; > + struct rt6key *fib6_prefsrc, *fib6_dst, *fib6_src; > + struct rt6_info *rt6 = (struct rt6_info *)dst; > + u32 *pmetrics, table, fib6_flags; > struct nlmsghdr *nlh; > + struct rtmsg *rtm; > long expires = 0; > - u32 *pmetrics; > - u32 table; > > nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags); > if (!nlh) > return -EMSGSIZE; > > + if (rt6) { > + fib6_dst = &rt6->rt6i_dst; > + fib6_src = &rt6->rt6i_src; > + fib6_flags = rt6->rt6i_flags; > + fib6_prefsrc = &rt6->rt6i_prefsrc; > + } else { > + fib6_dst = &rt->fib6_dst; > + fib6_src = &rt->fib6_src; > + fib6_flags = rt->fib6_flags; > + fib6_prefsrc = &rt->fib6_prefsrc; > + } Unless I am missing something at the moment, an rt6_info can only have the same dst, src and prefsrc as the fib6_info on which it is based. Thus, only the flags is needed above. That simplifies this patch a lot.