Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab997ad4 authored by lucien's avatar lucien Committed by David S. Miller
Browse files

ipv6: fix the incorrect return value of throw route



The error condition -EAGAIN, which is signaled by throw routes, tells
the rules framework to walk on searching for next matches. If the walk
ends and we stop walking the rules with the result of a throw route we
have to translate the error conditions to -ENETUNREACH.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f23d538b
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct fib6_rule {
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
				   int flags, pol_lookup_t lookup)
{
	struct rt6_info *rt;
	struct fib_lookup_arg arg = {
		.lookup_ptr = lookup,
		.flags = FIB_LOOKUP_NOREF,
@@ -40,13 +41,23 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
	fib_rules_lookup(net->ipv6.fib6_rules_ops,
			 flowi6_to_flowi(fl6), flags, &arg);

	if (arg.result)
		return arg.result;
	rt = arg.result;

	if (!rt) {
		dst_hold(&net->ipv6.ip6_null_entry->dst);
		return &net->ipv6.ip6_null_entry->dst;
	}

	if (rt->rt6i_flags & RTF_REJECT &&
	    rt->dst.error == -EAGAIN) {
		ip6_rt_put(rt);
		rt = net->ipv6.ip6_null_entry;
		dst_hold(&rt->dst);
	}

	return &rt->dst;
}

static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
			    int flags, struct fib_lookup_arg *arg)
{
+11 −1
Original line number Diff line number Diff line
@@ -285,7 +285,17 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
				   int flags, pol_lookup_t lookup)
{
	return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
	struct rt6_info *rt;

	rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
	if (rt->rt6i_flags & RTF_REJECT &&
	    rt->dst.error == -EAGAIN) {
		ip6_rt_put(rt);
		rt = net->ipv6.ip6_null_entry;
		dst_hold(&rt->dst);
	}

	return &rt->dst;
}

static void __net_init fib6_tables_init(struct net *net)