ipv6: Pass fib6_result to fib lookups

Change fib6_lookup and fib6_table_lookup to take a fib6_result and set
f6i and nh rather than returning a fib6_info. For now both always
return 0.

A later patch set can make these more like the IPv4 counterparts and
return EINVAL, EACCESS, etc based on fib6_type.

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David Ahern
2019-04-16 14:36:10 -07:00
committed by David S. Miller
parent 8ff2e5b26c
commit effda4dd97
7 changed files with 46 additions and 53 deletions

View File

@@ -61,16 +61,16 @@ unsigned int fib6_rules_seq_read(struct net *net)
}
/* called with rcu lock held; no reference taken on fib6_info */
struct fib6_info *fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
int flags)
int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
struct fib6_result *res, int flags)
{
struct fib6_info *f6i;
int err;
if (net->ipv6.fib6_has_custom_rules) {
struct fib_lookup_arg arg = {
.lookup_ptr = fib6_table_lookup,
.lookup_data = &oif,
.result = res,
.flags = FIB_LOOKUP_NOREF,
};
@@ -78,19 +78,15 @@ struct fib6_info *fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
err = fib_rules_lookup(net->ipv6.fib6_rules_ops,
flowi6_to_flowi(fl6), flags, &arg);
if (err)
return ERR_PTR(err);
f6i = arg.result ? : net->ipv6.fib6_null_entry;
} else {
f6i = fib6_table_lookup(net, net->ipv6.fib6_local_tbl,
oif, fl6, flags);
if (!f6i || f6i == net->ipv6.fib6_null_entry)
f6i = fib6_table_lookup(net, net->ipv6.fib6_main_tbl,
oif, fl6, flags);
err = fib6_table_lookup(net, net->ipv6.fib6_local_tbl, oif,
fl6, res, flags);
if (err || res->f6i == net->ipv6.fib6_null_entry)
err = fib6_table_lookup(net, net->ipv6.fib6_main_tbl,
oif, fl6, res, flags);
}
return f6i;
return err;
}
struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
@@ -157,10 +153,10 @@ static int fib6_rule_saddr(struct net *net, struct fib_rule *rule, int flags,
static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp,
int flags, struct fib_lookup_arg *arg)
{
struct fib6_result *res = arg->result;
struct flowi6 *flp6 = &flp->u.ip6;
struct net *net = rule->fr_net;
struct fib6_table *table;
struct fib6_info *f6i;
int err = -EAGAIN, *oif;
u32 tb_id;
@@ -182,14 +178,10 @@ static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp,
return -EAGAIN;
oif = (int *)arg->lookup_data;
f6i = fib6_table_lookup(net, table, *oif, flp6, flags);
if (f6i != net->ipv6.fib6_null_entry) {
err = fib6_table_lookup(net, table, *oif, flp6, res, flags);
if (!err && res->f6i != net->ipv6.fib6_null_entry)
err = fib6_rule_saddr(net, rule, flags, flp6,
fib6_info_nh_dev(f6i));
if (likely(!err))
arg->result = f6i;
}
res->nh->fib_nh_dev);
return err;
}