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.

Reply via email to