[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20180911010449.GA24677@leo.usersys.redhat.com>
Date: Tue, 11 Sep 2018 09:04:49 +0800
From: Hangbin Liu <liuhangbin@...il.com>
To: David Ahern <dsa@...ulusnetworks.com>
Cc: Xin Long <lucien.xin@...il.com>,
network dev <netdev@...r.kernel.org>,
davem <davem@...emloft.net>,
Roopa Prabhu <roopa@...ulusnetworks.com>
Subject: Re: [PATCH net] ipv6: use rt6_info members when dst is set in
rt6_fill_node
On Mon, Sep 10, 2018 at 01:07:11PM -0600, David Ahern wrote:
> On 9/10/18 11:55 AM, Xin Long wrote:
> > On Tue, Sep 11, 2018 at 12:13 AM David Ahern <dsa@...ulusnetworks.com> wrote:
> >>
> >> On 9/9/18 12:29 AM, Xin Long wrote:
> >>>>> 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.
> >>> If dst, src and prefsrc in rt6_info are always the same as these in fib6_info,
> >>> why do we need them in rt6_info? we could just get it by 'from'.
> >>>
> >>
> >> I just sent a patch removing rt6i_prefsrc. It is set with only 1 reader
> >> that can be converted.
> >>
> >> rt6i_src is checked against the fib6_info to invalidate a dst if the src
> >> has changed, so a valid rt will always have the same rt6i_src as the
> >> rt->from.
> >>
> >> rt6i_dst is set to the dest address / 128 in cases, so it should be used
> >> for rt6_info cases above.
> > So that means, I will use rt6i_dst and rt6i_flags when dst is set?
> > how about I use rt6i_src there as well? just to make it look clear.
> > and plus the gw/nh dump fix in rt6_fill_node():
> > - if (rt->fib6_nsiblings) {
> > + if (rt6) {
> > + if (fib6_flags & RTF_GATEWAY)
> > + if (nla_put_in6_addr(skb, RTA_GATEWAY,
> > + &rt6->rt6i_gateway) < 0)
> > + goto nla_put_failure;
> > +
> > + if (dst->dev && nla_put_u32(skb, RTA_OIF, dst->dev->ifindex))
> > + goto nla_put_failure;
> > + } else if (rt->fib6_nsiblings) {
> > struct fib6_info *sibling, *next_sibling;
> > struct nlattr *mp;
> >
> > looks good to you?
> >
>
> sure
Hmm... Then how to deal the other nh info filled by rt6_nexthop_info()?
I was planed to fix the gw issue[1] by syncing the gw and flags info. Like
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 18e00ce..62621b4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -998,6 +998,21 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct fib6_info *ort)
rt->rt6i_prefsrc = ort->fib6_prefsrc;
}
+static void rt6_update_info(struct rt6_info *rt)
+{
+ struct fib6_info *from;
+
+ rcu_read_lock();
+ from = rcu_dereference(rt->from);
+ fib6_info_hold(from);
+ rcu_read_unlock();
+
+ from->fib6_flags = rt->rt6i_flags;
+ from->fib6_nh.nh_gw = rt->rt6i_gateway;
+
+ fib6_info_release(from);
+}
+
static struct fib6_node* fib6_backtrack(struct fib6_node *fn,
struct in6_addr *saddr)
{
@@ -3446,6 +3463,8 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
goto out;
}
+ rt6_update_info(nrt);
+
netevent.old = &rt->dst;
netevent.new = &nrt->dst;
netevent.daddr = &msg->dest;
--
2.5.5
[1] https://patchwork.ozlabs.org/patch/966972/
Thanks
Hangbin
Powered by blists - more mailing lists