|
@@ -55,26 +55,33 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
|
|
struct fib6_table *table;
|
|
|
struct net *net = rule->fr_net;
|
|
|
pol_lookup_t lookup = arg->lookup_ptr;
|
|
|
+ int err = 0;
|
|
|
|
|
|
switch (rule->action) {
|
|
|
case FR_ACT_TO_TBL:
|
|
|
break;
|
|
|
case FR_ACT_UNREACHABLE:
|
|
|
+ err = -ENETUNREACH;
|
|
|
rt = net->ipv6.ip6_null_entry;
|
|
|
goto discard_pkt;
|
|
|
default:
|
|
|
case FR_ACT_BLACKHOLE:
|
|
|
+ err = -EINVAL;
|
|
|
rt = net->ipv6.ip6_blk_hole_entry;
|
|
|
goto discard_pkt;
|
|
|
case FR_ACT_PROHIBIT:
|
|
|
+ err = -EACCES;
|
|
|
rt = net->ipv6.ip6_prohibit_entry;
|
|
|
goto discard_pkt;
|
|
|
}
|
|
|
|
|
|
table = fib6_get_table(net, rule->table);
|
|
|
- if (table)
|
|
|
- rt = lookup(net, table, flp6, flags);
|
|
|
+ if (!table) {
|
|
|
+ err = -EAGAIN;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
+ rt = lookup(net, table, flp6, flags);
|
|
|
if (rt != net->ipv6.ip6_null_entry) {
|
|
|
struct fib6_rule *r = (struct fib6_rule *)rule;
|
|
|
|
|
@@ -101,6 +108,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
|
|
|
}
|
|
|
again:
|
|
|
ip6_rt_put(rt);
|
|
|
+ err = -EAGAIN;
|
|
|
rt = NULL;
|
|
|
goto out;
|
|
|
|
|
@@ -108,7 +116,7 @@ discard_pkt:
|
|
|
dst_hold(&rt->dst);
|
|
|
out:
|
|
|
arg->result = rt;
|
|
|
- return rt == NULL ? -EAGAIN : 0;
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
|