[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <16936451-6fbc-d498-0d51-63d43d899edf@gmail.com>
Date: Mon, 26 Feb 2018 13:20:27 -0700
From: David Ahern <dsahern@...il.com>
To: David Miller <davem@...emloft.net>
Cc: netdev@...r.kernel.org, idosch@...sch.org,
roopa@...ulusnetworks.com, eric.dumazet@...il.com,
weiwan@...gle.com, kafai@...com, yoshfuji@...ux-ipv6.org
Subject: Re: [PATCH RFC net-next 08/20] net/ipv6: Defer initialization of dst
to data path
On 2/26/18 12:17 PM, David Miller wrote:
> From: David Ahern <dsahern@...il.com>
> 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.
Powered by blists - more mailing lists