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

Commit effda4dd authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

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: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8ff2e5b2
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -389,12 +389,13 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
/* called with rcu lock held; can return error pointer
 * caller needs to select path
 */
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);

/* called with rcu lock held; caller needs to select path */
struct fib6_info *fib6_table_lookup(struct net *net, struct fib6_table *table,
				    int oif, struct flowi6 *fl6, int strict);
int fib6_table_lookup(struct net *net, struct fib6_table *table,
		      int oif, struct flowi6 *fl6, struct fib6_result *res,
		      int strict);

void fib6_select_path(const struct net *net, struct fib6_result *res,
		      struct flowi6 *fl6, int oif, bool have_oif_match,
+5 −6
Original line number Diff line number Diff line
@@ -29,12 +29,11 @@ struct ipv6_stub {
	int (*ipv6_route_input)(struct sk_buff *skb);

	struct fib6_table *(*fib6_get_table)(struct net *net, u32 id);
	struct fib6_info *(*fib6_lookup)(struct net *net, int oif,
					 struct flowi6 *fl6, int flags);
	struct fib6_info *(*fib6_table_lookup)(struct net *net,
					      struct fib6_table *table,
	int (*fib6_lookup)(struct net *net, int oif, struct flowi6 *fl6,
			   struct fib6_result *res, int flags);
	int (*fib6_table_lookup)(struct net *net, struct fib6_table *table,
				 int oif, struct flowi6 *fl6,
					      int flags);
				 struct fib6_result *res, int flags);
	void (*fib6_select_path)(const struct net *net, struct fib6_result *res,
				 struct flowi6 *fl6, int oif, bool oif_match,
				 const struct sk_buff *skb, int strict);
+5 −5
Original line number Diff line number Diff line
@@ -4684,7 +4684,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
	struct inet6_dev *idev;
	struct flowi6 fl6;
	int strict = 0;
	int oif;
	int oif, err;
	u32 mtu;

	/* link local addresses are never forwarded */
@@ -4726,7 +4726,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
		if (unlikely(!tb))
			return BPF_FIB_LKUP_RET_NOT_FWDED;

		res.f6i = ipv6_stub->fib6_table_lookup(net, tb, oif, &fl6,
		err = ipv6_stub->fib6_table_lookup(net, tb, oif, &fl6, &res,
						   strict);
	} else {
		fl6.flowi6_mark = 0;
@@ -4734,10 +4734,10 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
		fl6.flowi6_tun_key.tun_id = 0;
		fl6.flowi6_uid = sock_net_uid(net, NULL);

		res.f6i = ipv6_stub->fib6_lookup(net, oif, &fl6, strict);
		err = ipv6_stub->fib6_lookup(net, oif, &fl6, &res, strict);
	}

	if (unlikely(IS_ERR_OR_NULL(res.f6i) ||
	if (unlikely(err || IS_ERR_OR_NULL(res.f6i) ||
		     res.f6i == net->ipv6.fib6_null_entry))
		return BPF_FIB_LKUP_RET_NOT_FWDED;

+7 −6
Original line number Diff line number Diff line
@@ -144,18 +144,19 @@ static struct fib6_table *eafnosupport_fib6_get_table(struct net *net, u32 id)
	return NULL;
}

static struct fib6_info *
static int
eafnosupport_fib6_table_lookup(struct net *net, struct fib6_table *table,
			       int oif, struct flowi6 *fl6, int flags)
			       int oif, struct flowi6 *fl6,
			       struct fib6_result *res, int flags)
{
	return NULL;
	return -EAFNOSUPPORT;
}

static struct fib6_info *
static int
eafnosupport_fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
			 int flags)
			 struct fib6_result *res, int flags)
{
	return NULL;
	return -EAFNOSUPPORT;
}

static void
+13 −21
Original line number Diff line number Diff line
@@ -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;
}
Loading