aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/fib6_rules.c
diff options
context:
space:
mode:
authorlucien <lucien.xin@gmail.com>2015-10-23 03:36:53 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-23 05:38:18 -0400
commitab997ad408394bcaf7f3015d4c4e38047eaf2ad6 (patch)
tree7a42dc942c501f16c4526ff88583e53f64be23e9 /net/ipv6/fib6_rules.c
parentf23d538bc24a83c16127c2eb82c9cf1adc2b5149 (diff)
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: Xin Long <lucien.xin@gmail.com> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/fib6_rules.c')
-rw-r--r--net/ipv6/fib6_rules.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 9f777ec59a59..ed33abf57abd 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -32,6 +32,7 @@ struct fib6_rule {
32struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, 32struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
33 int flags, pol_lookup_t lookup) 33 int flags, pol_lookup_t lookup)
34{ 34{
35 struct rt6_info *rt;
35 struct fib_lookup_arg arg = { 36 struct fib_lookup_arg arg = {
36 .lookup_ptr = lookup, 37 .lookup_ptr = lookup,
37 .flags = FIB_LOOKUP_NOREF, 38 .flags = FIB_LOOKUP_NOREF,
@@ -40,11 +41,21 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
40 fib_rules_lookup(net->ipv6.fib6_rules_ops, 41 fib_rules_lookup(net->ipv6.fib6_rules_ops,
41 flowi6_to_flowi(fl6), flags, &arg); 42 flowi6_to_flowi(fl6), flags, &arg);
42 43
43 if (arg.result) 44 rt = arg.result;
44 return arg.result;
45 45
46 dst_hold(&net->ipv6.ip6_null_entry->dst); 46 if (!rt) {
47 return &net->ipv6.ip6_null_entry->dst; 47 dst_hold(&net->ipv6.ip6_null_entry->dst);
48 return &net->ipv6.ip6_null_entry->dst;
49 }
50
51 if (rt->rt6i_flags & RTF_REJECT &&
52 rt->dst.error == -EAGAIN) {
53 ip6_rt_put(rt);
54 rt = net->ipv6.ip6_null_entry;
55 dst_hold(&rt->dst);
56 }
57
58 return &rt->dst;
48} 59}
49 60
50static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, 61static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,