mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 21:33:00 +00:00
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>
This commit is contained in:
parent
f23d538bc2
commit
ab997ad408
@ -32,6 +32,7 @@ struct fib6_rule {
|
|||||||
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
||||||
int flags, pol_lookup_t lookup)
|
int flags, pol_lookup_t lookup)
|
||||||
{
|
{
|
||||||
|
struct rt6_info *rt;
|
||||||
struct fib_lookup_arg arg = {
|
struct fib_lookup_arg arg = {
|
||||||
.lookup_ptr = lookup,
|
.lookup_ptr = lookup,
|
||||||
.flags = FIB_LOOKUP_NOREF,
|
.flags = FIB_LOOKUP_NOREF,
|
||||||
@ -40,11 +41,21 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
|||||||
fib_rules_lookup(net->ipv6.fib6_rules_ops,
|
fib_rules_lookup(net->ipv6.fib6_rules_ops,
|
||||||
flowi6_to_flowi(fl6), flags, &arg);
|
flowi6_to_flowi(fl6), flags, &arg);
|
||||||
|
|
||||||
if (arg.result)
|
rt = arg.result;
|
||||||
return arg.result;
|
|
||||||
|
|
||||||
dst_hold(&net->ipv6.ip6_null_entry->dst);
|
if (!rt) {
|
||||||
return &net->ipv6.ip6_null_entry->dst;
|
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,
|
static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
||||||
|
@ -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,
|
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
|
||||||
int flags, pol_lookup_t lookup)
|
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)
|
static void __net_init fib6_tables_init(struct net *net)
|
||||||
|
Loading…
Reference in New Issue
Block a user