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

Commit 464bc0fd authored by John Fastabend's avatar John Fastabend Committed by David S. Miller
Browse files

bpf: convert sockmap field attach_bpf_fd2 to type



In the initial sockmap API we provided strparser and verdict programs
using a single attach command by extending the attach API with a the
attach_bpf_fd2 field.

However, if we add other programs in the future we will be adding a
field for every new possible type, attach_bpf_fd(3,4,..). This
seems a bit clumsy for an API. So lets push the programs using two
new type fields.

   BPF_SK_SKB_STREAM_PARSER
   BPF_SK_SKB_STREAM_VERDICT

This has the advantage of having a readable name and can easily be
extended in the future.

Updates to samples and sockmap included here also generalize tests
slightly to support upcoming patch for multiple map support.

Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Fixes: 174a79ff ("bpf: sockmap with sk redirect support")
Suggested-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 901c5d2f
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -39,8 +39,6 @@ struct bpf_map_ops {
	void (*map_fd_put_ptr)(void *ptr);
	u32 (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf);
	u32 (*map_fd_sys_lookup_elem)(void *ptr);
	int (*map_attach)(struct bpf_map *map,
			  struct bpf_prog *p1, struct bpf_prog *p2);
};

struct bpf_map {
@@ -387,11 +385,19 @@ static inline void __dev_map_flush(struct bpf_map *map)

#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL)
struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
#else
static inline struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
{
	return NULL;
}

static inline int sock_map_attach_prog(struct bpf_map *map,
				       struct bpf_prog *prog,
				       u32 type)
{
	return -EOPNOTSUPP;
}
#endif

/* verifier prototypes for helper functions called from eBPF programs */
+3 −6
Original line number Diff line number Diff line
@@ -136,7 +136,8 @@ enum bpf_attach_type {
	BPF_CGROUP_INET_EGRESS,
	BPF_CGROUP_INET_SOCK_CREATE,
	BPF_CGROUP_SOCK_OPS,
	BPF_CGROUP_SMAP_INGRESS,
	BPF_SK_SKB_STREAM_PARSER,
	BPF_SK_SKB_STREAM_VERDICT,
	__MAX_BPF_ATTACH_TYPE
};

@@ -224,7 +225,6 @@ union bpf_attr {
		__u32		attach_bpf_fd;	/* eBPF program to attach */
		__u32		attach_type;
		__u32		attach_flags;
		__u32		attach_bpf_fd2;
	};

	struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */
@@ -580,14 +580,11 @@ union bpf_attr {
 *     @flags: reserved for future use
 *     Return: SK_REDIRECT
 *
 * int bpf_sock_map_update(skops, map, key, flags, map_flags)
 * int bpf_sock_map_update(skops, map, key, flags)
 *	@skops: pointer to bpf_sock_ops
 *	@map: pointer to sockmap to update
 *	@key: key to insert/update sock in map
 *	@flags: same flags as map update elem
 *	@map_flags: sock map specific flags
 *	   bit 1: Enable strparser
 *	   other bits: reserved
 */
#define __BPF_FUNC_MAPPER(FN)		\
	FN(unspec),			\
+14 −11
Original line number Diff line number Diff line
@@ -723,20 +723,24 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
	return err;
}

static int sock_map_attach_prog(struct bpf_map *map,
				struct bpf_prog *parse,
				struct bpf_prog *verdict)
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
{
	struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
	struct bpf_prog *_parse, *_verdict;
	struct bpf_prog *orig;

	_parse = xchg(&stab->bpf_parse, parse);
	_verdict = xchg(&stab->bpf_verdict, verdict);
	switch (type) {
	case BPF_SK_SKB_STREAM_PARSER:
		orig = xchg(&stab->bpf_parse, prog);
		break;
	case BPF_SK_SKB_STREAM_VERDICT:
		orig = xchg(&stab->bpf_verdict, prog);
		break;
	default:
		return -EOPNOTSUPP;
	}

	if (_parse)
		bpf_prog_put(_parse);
	if (_verdict)
		bpf_prog_put(_verdict);
	if (orig)
		bpf_prog_put(orig);

	return 0;
}
@@ -777,7 +781,6 @@ const struct bpf_map_ops sock_map_ops = {
	.map_get_next_key = sock_map_get_next_key,
	.map_update_elem = sock_map_update_elem,
	.map_delete_elem = sock_map_delete_elem,
	.map_attach = sock_map_attach_prog,
};

BPF_CALL_5(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
+11 −27
Original line number Diff line number Diff line
@@ -1093,12 +1093,12 @@ static int bpf_obj_get(const union bpf_attr *attr)

#ifdef CONFIG_CGROUP_BPF

#define BPF_PROG_ATTACH_LAST_FIELD attach_bpf_fd2
#define BPF_PROG_ATTACH_LAST_FIELD attach_flags

static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype)
static int sockmap_get_from_fd(const union bpf_attr *attr)
{
	struct bpf_prog *prog1, *prog2;
	int ufd = attr->target_fd;
	struct bpf_prog *prog;
	struct bpf_map *map;
	struct fd f;
	int err;
@@ -1108,29 +1108,16 @@ static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype)
	if (IS_ERR(map))
		return PTR_ERR(map);

	if (!map->ops->map_attach) {
		fdput(f);
		return -EOPNOTSUPP;
	}

	prog1 = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
	if (IS_ERR(prog1)) {
	prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB);
	if (IS_ERR(prog)) {
		fdput(f);
		return PTR_ERR(prog1);
	}

	prog2 = bpf_prog_get_type(attr->attach_bpf_fd2, ptype);
	if (IS_ERR(prog2)) {
		fdput(f);
		bpf_prog_put(prog1);
		return PTR_ERR(prog2);
		return PTR_ERR(prog);
	}

	err = map->ops->map_attach(map, prog1, prog2);
	err = sock_map_attach_prog(map, prog, attr->attach_type);
	if (err) {
		fdput(f);
		bpf_prog_put(prog1);
		bpf_prog_put(prog2);
		bpf_prog_put(prog);
		return err;
	}

@@ -1165,16 +1152,13 @@ static int bpf_prog_attach(const union bpf_attr *attr)
	case BPF_CGROUP_SOCK_OPS:
		ptype = BPF_PROG_TYPE_SOCK_OPS;
		break;
	case BPF_CGROUP_SMAP_INGRESS:
		ptype = BPF_PROG_TYPE_SK_SKB;
		break;
	case BPF_SK_SKB_STREAM_PARSER:
	case BPF_SK_SKB_STREAM_VERDICT:
		return sockmap_get_from_fd(attr);
	default:
		return -EINVAL;
	}

	if (attr->attach_type == BPF_CGROUP_SMAP_INGRESS)
		return sockmap_get_from_fd(attr, ptype);

	prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
	if (IS_ERR(prog))
		return PTR_ERR(prog);
+2 −4
Original line number Diff line number Diff line
@@ -82,8 +82,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops)
		if (lport == 10000) {
			ret = 1;
			err = bpf_sock_map_update(skops, &sock_map, &ret,
						  BPF_NOEXIST,
						  BPF_SOCKMAP_STRPARSER);
						  BPF_NOEXIST);
			bpf_printk("passive(%i -> %i) map ctx update err: %d\n",
				   lport, bpf_ntohl(rport), err);
		}
@@ -95,8 +94,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops)
		if (bpf_ntohl(rport) == 10001) {
			ret = 10;
			err = bpf_sock_map_update(skops, &sock_map, &ret,
						  BPF_NOEXIST,
						  BPF_SOCKMAP_STRPARSER);
						  BPF_NOEXIST);
			bpf_printk("active(%i -> %i) map ctx update err: %d\n",
				   lport, bpf_ntohl(rport), err);
		}
Loading