From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl0-f50.google.com ([209.85.160.50]:35839 "EHLO mail-pl0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751367AbeBZUUa (ORCPT ); Mon, 26 Feb 2018 15:20:30 -0500 Received: by mail-pl0-f50.google.com with SMTP id bb3so9939458plb.2 for ; Mon, 26 Feb 2018 12:20:30 -0800 (PST) Subject: Re: [PATCH RFC net-next 08/20] net/ipv6: Defer initialization of dst to data path To: David Miller Cc: netdev@vger.kernel.org, idosch@idosch.org, roopa@cumulusnetworks.com, eric.dumazet@gmail.com, weiwan@google.com, kafai@fb.com, yoshfuji@linux-ipv6.org References: <20180225194730.30063-1-dsahern@gmail.com> <20180225194730.30063-9-dsahern@gmail.com> <20180226.141713.1695207134632325977.davem@davemloft.net> From: David Ahern Message-ID: <16936451-6fbc-d498-0d51-63d43d899edf@gmail.com> Date: Mon, 26 Feb 2018 13:20:27 -0700 MIME-Version: 1.0 In-Reply-To: <20180226.141713.1695207134632325977.davem@davemloft.net> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org List-ID: On 2/26/18 12:17 PM, David Miller wrote: > From: David Ahern > Date: Sun, 25 Feb 2018 11:47:18 -0800 > >> +static void ip6_rt_init_dst(struct rt6_info *rt, struct rt6_info *ort) >> +{ > ... >> + rt->dst.error = 0; >> + rt->dst.output = ip6_output; > ... >> @@ -930,14 +999,12 @@ static void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) >> >> static void ip6_rt_copy_init(struct rt6_info *rt, struct rt6_info *ort) >> { >> - rt->dst.input = ort->dst.input; >> - rt->dst.output = ort->dst.output; >> + ip6_rt_init_dst(rt, ort); >> + >> rt->rt6i_dst = ort->rt6i_dst; >> - rt->dst.error = ort->dst.error; >> rt->rt6i_idev = ort->rt6i_idev; >> if (rt->rt6i_idev) >> in6_dev_hold(rt->rt6i_idev); >> - rt->dst.lastuse = jiffies; >> rt->rt6i_gateway = ort->fib6_nh.nh_gw; >> rt->rt6i_flags = ort->rt6i_flags; >> rt6_set_from(rt, ort); > > This seems to change behavior. > > In the old code, the dst error value is propagated from 'ort' into 'rt'. > > Here you set it to zero and that's it. > > Is it set somewhere else? > > I don't think you can assume that all routes that go via this copy > path are not reject routes or other kinds that need the error code > set, if that is what you were thinking. Only REJECT routes have dst->error set and the only place that happens is ip6_route_info_create: $ egrep -r 'dst.error = |dst->error = ' include net net/core/dst.c: dst->error = 0; net/ipv6/route.c: rt->dst.error = -EINVAL; net/ipv6/route.c: rt->dst.error = -EACCES; net/ipv6/route.c: rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN net/ipv6/route.c: rt->dst.error = ort->dst.error; You cut the context, so I will add the diff here: +static void ip6_rt_init_dst_reject(struct rt6_info *rt, struct rt6_info *ort) +{ + rt->dst.error = ip6_rt_type_to_error(ort->fib6_type); + + switch (ort->fib6_type) { + case RTN_BLACKHOLE: + rt->dst.output = dst_discard_out; + rt->dst.input = dst_discard; + break; + case RTN_PROHIBIT: + rt->dst.output = ip6_pkt_prohibit_out; + rt->dst.input = ip6_pkt_prohibit; + break; + case RTN_THROW: + case RTN_UNREACHABLE: + default: + rt->dst.output = ip6_pkt_discard_out; + rt->dst.input = ip6_pkt_discard; + break; + } +} + +static void ip6_rt_init_dst(struct rt6_info *rt, struct rt6_info *ort) +{ + if (ort->rt6i_flags & RTF_REJECT) { + ip6_rt_init_dst_reject(rt, ort); + return; + } + + rt->dst.error = 0; + rt->dst.output = ip6_output; + +... So for reject routes we have the above helper which is basically a code move from ip6_route_info_create. For non-reject routes dst.error is 0 which is the rest of ip6_rt_init_dst.