All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 bpf-next 0/2] Better handling of xskmap entries
@ 2019-06-03 16:38 Jonathan Lemon
  2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jonathan Lemon @ 2019-06-03 16:38 UTC (permalink / raw)
  To: netdev; +Cc: kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

v3->v4:
 - Clarify error handling path.

v2->v3:
 - Use correct map type.

Jonathan Lemon (2):
  bpf: Allow bpf_map_lookup_elem() on an xskmap
  libbpf: remove qidconf and better support external bpf programs.

 include/net/xdp_sock.h                        |   6 +-
 kernel/bpf/verifier.c                         |   6 +-
 kernel/bpf/xskmap.c                           |   4 +-
 tools/lib/bpf/xsk.c                           | 103 +++++-------------
 .../bpf/verifier/prevent_map_lookup.c         |  15 ---
 5 files changed, 39 insertions(+), 95 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-03 16:38 [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Jonathan Lemon
@ 2019-06-03 16:38 ` Jonathan Lemon
  2019-06-04 14:54   ` Daniel Borkmann
  2019-06-04 16:43   ` Jesper Dangaard Brouer
  2019-06-03 16:38 ` [PATCH v4 bpf-next 2/2] libbpf: remove qidconf and better support external bpf programs Jonathan Lemon
  2019-06-04  6:06 ` [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Björn Töpel
  2 siblings, 2 replies; 13+ messages in thread
From: Jonathan Lemon @ 2019-06-03 16:38 UTC (permalink / raw)
  To: netdev; +Cc: kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

Currently, the AF_XDP code uses a separate map in order to
determine if an xsk is bound to a queue.  Instead of doing this,
have bpf_map_lookup_elem() return the queue_id, as a way of
indicating that there is a valid entry at the map index.

Rearrange some xdp_sock members to eliminate structure holes.

Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Björn Töpel <bjorn.topel@intel.com>
---
 include/net/xdp_sock.h                            |  6 +++---
 kernel/bpf/verifier.c                             |  6 +++++-
 kernel/bpf/xskmap.c                               |  4 +++-
 .../selftests/bpf/verifier/prevent_map_lookup.c   | 15 ---------------
 4 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
index d074b6d60f8a..7d84b1da43d2 100644
--- a/include/net/xdp_sock.h
+++ b/include/net/xdp_sock.h
@@ -57,12 +57,12 @@ struct xdp_sock {
 	struct net_device *dev;
 	struct xdp_umem *umem;
 	struct list_head flush_node;
-	u16 queue_id;
-	struct xsk_queue *tx ____cacheline_aligned_in_smp;
-	struct list_head list;
+	u32 queue_id;
 	bool zc;
 	/* Protects multiple processes in the control path */
 	struct mutex mutex;
+	struct xsk_queue *tx ____cacheline_aligned_in_smp;
+	struct list_head list;
 	/* Mutual exclusion of NAPI TX thread and sendmsg error paths
 	 * in the SKB destructor callback.
 	 */
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2778417e6e0c..91c730f85e92 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2905,10 +2905,14 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
 	 * appear.
 	 */
 	case BPF_MAP_TYPE_CPUMAP:
-	case BPF_MAP_TYPE_XSKMAP:
 		if (func_id != BPF_FUNC_redirect_map)
 			goto error;
 		break;
+	case BPF_MAP_TYPE_XSKMAP:
+		if (func_id != BPF_FUNC_redirect_map &&
+		    func_id != BPF_FUNC_map_lookup_elem)
+			goto error;
+		break;
 	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
 	case BPF_MAP_TYPE_HASH_OF_MAPS:
 		if (func_id != BPF_FUNC_map_lookup_elem)
diff --git a/kernel/bpf/xskmap.c b/kernel/bpf/xskmap.c
index 686d244e798d..249b22089014 100644
--- a/kernel/bpf/xskmap.c
+++ b/kernel/bpf/xskmap.c
@@ -154,7 +154,9 @@ void __xsk_map_flush(struct bpf_map *map)
 
 static void *xsk_map_lookup_elem(struct bpf_map *map, void *key)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	struct xdp_sock *xs = __xsk_map_lookup_elem(map, *(u32 *)key);
+
+	return xs ? &xs->queue_id : NULL;
 }
 
 static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
diff --git a/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c b/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
index bbdba990fefb..da7a4b37cb98 100644
--- a/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
+++ b/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
@@ -28,21 +28,6 @@
 	.errstr = "cannot pass map_type 18 into func bpf_map_lookup_elem",
 	.prog_type = BPF_PROG_TYPE_SOCK_OPS,
 },
-{
-	"prevent map lookup in xskmap",
-	.insns = {
-	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
-	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
-	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
-	BPF_LD_MAP_FD(BPF_REG_1, 0),
-	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
-	BPF_EXIT_INSN(),
-	},
-	.fixup_map_xskmap = { 3 },
-	.result = REJECT,
-	.errstr = "cannot pass map_type 17 into func bpf_map_lookup_elem",
-	.prog_type = BPF_PROG_TYPE_XDP,
-},
 {
 	"prevent map lookup in stack trace",
 	.insns = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 bpf-next 2/2] libbpf: remove qidconf and better support external bpf programs.
  2019-06-03 16:38 [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Jonathan Lemon
  2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
@ 2019-06-03 16:38 ` Jonathan Lemon
  2019-06-04  6:06 ` [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Björn Töpel
  2 siblings, 0 replies; 13+ messages in thread
From: Jonathan Lemon @ 2019-06-03 16:38 UTC (permalink / raw)
  To: netdev; +Cc: kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

Use the recent change to XSKMAP bpf_map_lookup_elem() to test if
there is a xsk present in the map instead of duplicating the work
with qidconf.

Fix things so callers using XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD
bypass any internal bpf maps, so xsk_socket__{create|delete} works
properly.

Clean up error handling path.

Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Tested-by: Björn Töpel <bjorn.topel@intel.com>
---
 tools/lib/bpf/xsk.c | 103 ++++++++++++--------------------------------
 1 file changed, 28 insertions(+), 75 deletions(-)

diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
index 38667b62f1fe..7ef6293b4fd7 100644
--- a/tools/lib/bpf/xsk.c
+++ b/tools/lib/bpf/xsk.c
@@ -60,10 +60,8 @@ struct xsk_socket {
 	struct xsk_umem *umem;
 	struct xsk_socket_config config;
 	int fd;
-	int xsks_map;
 	int ifindex;
 	int prog_fd;
-	int qidconf_map_fd;
 	int xsks_map_fd;
 	__u32 queue_id;
 	char ifname[IFNAMSIZ];
@@ -265,15 +263,11 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
 	/* This is the C-program:
 	 * SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
 	 * {
-	 *     int *qidconf, index = ctx->rx_queue_index;
+	 *     int index = ctx->rx_queue_index;
 	 *
 	 *     // A set entry here means that the correspnding queue_id
 	 *     // has an active AF_XDP socket bound to it.
-	 *     qidconf = bpf_map_lookup_elem(&qidconf_map, &index);
-	 *     if (!qidconf)
-	 *         return XDP_ABORTED;
-	 *
-	 *     if (*qidconf)
+	 *     if (bpf_map_lookup_elem(&xsks_map, &index))
 	 *         return bpf_redirect_map(&xsks_map, index, 0);
 	 *
 	 *     return XDP_PASS;
@@ -286,15 +280,10 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
 		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_1, -4),
 		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
-		BPF_LD_MAP_FD(BPF_REG_1, xsk->qidconf_map_fd),
+		BPF_LD_MAP_FD(BPF_REG_1, xsk->xsks_map_fd),
 		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
 		BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
-		BPF_MOV32_IMM(BPF_REG_0, 0),
-		/* if r1 == 0 goto +8 */
-		BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
 		BPF_MOV32_IMM(BPF_REG_0, 2),
-		/* r1 = *(u32 *)(r1 + 0) */
-		BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, 0),
 		/* if r1 == 0 goto +5 */
 		BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 5),
 		/* r2 = *(u32 *)(r10 - 4) */
@@ -366,18 +355,11 @@ static int xsk_create_bpf_maps(struct xsk_socket *xsk)
 	if (max_queues < 0)
 		return max_queues;
 
-	fd = bpf_create_map_name(BPF_MAP_TYPE_ARRAY, "qidconf_map",
+	fd = bpf_create_map_name(BPF_MAP_TYPE_XSKMAP, "xsks_map",
 				 sizeof(int), sizeof(int), max_queues, 0);
 	if (fd < 0)
 		return fd;
-	xsk->qidconf_map_fd = fd;
 
-	fd = bpf_create_map_name(BPF_MAP_TYPE_XSKMAP, "xsks_map",
-				 sizeof(int), sizeof(int), max_queues, 0);
-	if (fd < 0) {
-		close(xsk->qidconf_map_fd);
-		return fd;
-	}
 	xsk->xsks_map_fd = fd;
 
 	return 0;
@@ -385,10 +367,8 @@ static int xsk_create_bpf_maps(struct xsk_socket *xsk)
 
 static void xsk_delete_bpf_maps(struct xsk_socket *xsk)
 {
-	close(xsk->qidconf_map_fd);
+	bpf_map_delete_elem(xsk->xsks_map_fd, &xsk->queue_id);
 	close(xsk->xsks_map_fd);
-	xsk->qidconf_map_fd = -1;
-	xsk->xsks_map_fd = -1;
 }
 
 static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
@@ -417,10 +397,9 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
 	if (err)
 		goto out_map_ids;
 
-	for (i = 0; i < prog_info.nr_map_ids; i++) {
-		if (xsk->qidconf_map_fd != -1 && xsk->xsks_map_fd != -1)
-			break;
+	xsk->xsks_map_fd = -1;
 
+	for (i = 0; i < prog_info.nr_map_ids; i++) {
 		fd = bpf_map_get_fd_by_id(map_ids[i]);
 		if (fd < 0)
 			continue;
@@ -431,11 +410,6 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
 			continue;
 		}
 
-		if (!strcmp(map_info.name, "qidconf_map")) {
-			xsk->qidconf_map_fd = fd;
-			continue;
-		}
-
 		if (!strcmp(map_info.name, "xsks_map")) {
 			xsk->xsks_map_fd = fd;
 			continue;
@@ -445,40 +419,18 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
 	}
 
 	err = 0;
-	if (xsk->qidconf_map_fd < 0 || xsk->xsks_map_fd < 0) {
+	if (xsk->xsks_map_fd == -1)
 		err = -ENOENT;
-		xsk_delete_bpf_maps(xsk);
-	}
 
 out_map_ids:
 	free(map_ids);
 	return err;
 }
 
-static void xsk_clear_bpf_maps(struct xsk_socket *xsk)
-{
-	int qid = false;
-
-	bpf_map_update_elem(xsk->qidconf_map_fd, &xsk->queue_id, &qid, 0);
-	bpf_map_delete_elem(xsk->xsks_map_fd, &xsk->queue_id);
-}
-
 static int xsk_set_bpf_maps(struct xsk_socket *xsk)
 {
-	int qid = true, fd = xsk->fd, err;
-
-	err = bpf_map_update_elem(xsk->qidconf_map_fd, &xsk->queue_id, &qid, 0);
-	if (err)
-		goto out;
-
-	err = bpf_map_update_elem(xsk->xsks_map_fd, &xsk->queue_id, &fd, 0);
-	if (err)
-		goto out;
-
-	return 0;
-out:
-	xsk_clear_bpf_maps(xsk);
-	return err;
+	return bpf_map_update_elem(xsk->xsks_map_fd, &xsk->queue_id,
+				   &xsk->fd, 0);
 }
 
 static int xsk_setup_xdp_prog(struct xsk_socket *xsk)
@@ -497,26 +449,27 @@ static int xsk_setup_xdp_prog(struct xsk_socket *xsk)
 			return err;
 
 		err = xsk_load_xdp_prog(xsk);
-		if (err)
-			goto out_maps;
+		if (err) {
+			xsk_delete_bpf_maps(xsk);
+			return err;
+		}
 	} else {
 		xsk->prog_fd = bpf_prog_get_fd_by_id(prog_id);
 		err = xsk_lookup_bpf_maps(xsk);
-		if (err)
-			goto out_load;
+		if (err) {
+			close(xsk->prog_fd);
+			return err;
+		}
 	}
 
 	err = xsk_set_bpf_maps(xsk);
-	if (err)
-		goto out_load;
+	if (err) {
+		xsk_delete_bpf_maps(xsk);
+		close(xsk->prog_fd);
+		return err;
+	}
 
 	return 0;
-
-out_load:
-	close(xsk->prog_fd);
-out_maps:
-	xsk_delete_bpf_maps(xsk);
-	return err;
 }
 
 int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
@@ -643,9 +596,7 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
 		goto out_mmap_tx;
 	}
 
-	xsk->qidconf_map_fd = -1;
-	xsk->xsks_map_fd = -1;
-
+	xsk->prog_fd = -1;
 	if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
 		err = xsk_setup_xdp_prog(xsk);
 		if (err)
@@ -708,8 +659,10 @@ void xsk_socket__delete(struct xsk_socket *xsk)
 	if (!xsk)
 		return;
 
-	xsk_clear_bpf_maps(xsk);
-	xsk_delete_bpf_maps(xsk);
+	if (xsk->prog_fd != -1) {
+		xsk_delete_bpf_maps(xsk);
+		close(xsk->prog_fd);
+	}
 
 	optlen = sizeof(off);
 	err = getsockopt(xsk->fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 0/2] Better handling of xskmap entries
  2019-06-03 16:38 [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Jonathan Lemon
  2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
  2019-06-03 16:38 ` [PATCH v4 bpf-next 2/2] libbpf: remove qidconf and better support external bpf programs Jonathan Lemon
@ 2019-06-04  6:06 ` Björn Töpel
  2 siblings, 0 replies; 13+ messages in thread
From: Björn Töpel @ 2019-06-04  6:06 UTC (permalink / raw)
  To: Jonathan Lemon
  Cc: Netdev, Kernel Team, Björn Töpel, Karlsson, Magnus,
	Alexei Starovoitov, Daniel Borkmann

On Mon, 3 Jun 2019 at 19:49, Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
>
> v3->v4:
>  - Clarify error handling path.
>
> v2->v3:
>  - Use correct map type.
>
> Jonathan Lemon (2):
>   bpf: Allow bpf_map_lookup_elem() on an xskmap
>   libbpf: remove qidconf and better support external bpf programs.
>

Nice work!

For the series,

Acked-by: Björn Töpel <bjorn.topel@intel.com>


>  include/net/xdp_sock.h                        |   6 +-
>  kernel/bpf/verifier.c                         |   6 +-
>  kernel/bpf/xskmap.c                           |   4 +-
>  tools/lib/bpf/xsk.c                           | 103 +++++-------------
>  .../bpf/verifier/prevent_map_lookup.c         |  15 ---
>  5 files changed, 39 insertions(+), 95 deletions(-)
>
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
@ 2019-06-04 14:54   ` Daniel Borkmann
  2019-06-04 15:30     ` Daniel Borkmann
  2019-06-04 16:43   ` Jesper Dangaard Brouer
  1 sibling, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2019-06-04 14:54 UTC (permalink / raw)
  To: Jonathan Lemon, netdev; +Cc: kernel-team, bjorn.topel, magnus.karlsson, ast

On 06/03/2019 06:38 PM, Jonathan Lemon wrote:
> Currently, the AF_XDP code uses a separate map in order to
> determine if an xsk is bound to a queue.  Instead of doing this,
> have bpf_map_lookup_elem() return the queue_id, as a way of
> indicating that there is a valid entry at the map index.
> 
> Rearrange some xdp_sock members to eliminate structure holes.
> 
> Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
> Acked-by: Song Liu <songliubraving@fb.com>
> Acked-by: Björn Töpel <bjorn.topel@intel.com>
> ---
>  include/net/xdp_sock.h                            |  6 +++---
>  kernel/bpf/verifier.c                             |  6 +++++-
>  kernel/bpf/xskmap.c                               |  4 +++-
>  .../selftests/bpf/verifier/prevent_map_lookup.c   | 15 ---------------
>  4 files changed, 11 insertions(+), 20 deletions(-)
> 
> diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
> index d074b6d60f8a..7d84b1da43d2 100644
> --- a/include/net/xdp_sock.h
> +++ b/include/net/xdp_sock.h
> @@ -57,12 +57,12 @@ struct xdp_sock {
>  	struct net_device *dev;
>  	struct xdp_umem *umem;
>  	struct list_head flush_node;
> -	u16 queue_id;
> -	struct xsk_queue *tx ____cacheline_aligned_in_smp;
> -	struct list_head list;
> +	u32 queue_id;
>  	bool zc;
>  	/* Protects multiple processes in the control path */
>  	struct mutex mutex;
> +	struct xsk_queue *tx ____cacheline_aligned_in_smp;
> +	struct list_head list;
>  	/* Mutual exclusion of NAPI TX thread and sendmsg error paths
>  	 * in the SKB destructor callback.
>  	 */
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 2778417e6e0c..91c730f85e92 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -2905,10 +2905,14 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
>  	 * appear.
>  	 */
>  	case BPF_MAP_TYPE_CPUMAP:
> -	case BPF_MAP_TYPE_XSKMAP:
>  		if (func_id != BPF_FUNC_redirect_map)
>  			goto error;
>  		break;
> +	case BPF_MAP_TYPE_XSKMAP:
> +		if (func_id != BPF_FUNC_redirect_map &&
> +		    func_id != BPF_FUNC_map_lookup_elem)
> +			goto error;
> +		break;
>  	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
>  	case BPF_MAP_TYPE_HASH_OF_MAPS:
>  		if (func_id != BPF_FUNC_map_lookup_elem)
> diff --git a/kernel/bpf/xskmap.c b/kernel/bpf/xskmap.c
> index 686d244e798d..249b22089014 100644
> --- a/kernel/bpf/xskmap.c
> +++ b/kernel/bpf/xskmap.c
> @@ -154,7 +154,9 @@ void __xsk_map_flush(struct bpf_map *map)
>  
>  static void *xsk_map_lookup_elem(struct bpf_map *map, void *key)
>  {
> -	return ERR_PTR(-EOPNOTSUPP);
> +	struct xdp_sock *xs = __xsk_map_lookup_elem(map, *(u32 *)key);
> +
> +	return xs ? &xs->queue_id : NULL;
>  }

How do you guarantee that BPf programs don't mess around with the map values
e.g. overriding xs->queue_id from the lookup? This should be read-only map
from BPF program side.

>  static int xsk_map_update_elem(struct bpf_map *map, void *key, void *value,
> diff --git a/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c b/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
> index bbdba990fefb..da7a4b37cb98 100644
> --- a/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
> +++ b/tools/testing/selftests/bpf/verifier/prevent_map_lookup.c
> @@ -28,21 +28,6 @@
>  	.errstr = "cannot pass map_type 18 into func bpf_map_lookup_elem",
>  	.prog_type = BPF_PROG_TYPE_SOCK_OPS,
>  },
> -{
> -	"prevent map lookup in xskmap",
> -	.insns = {
> -	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
> -	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
> -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
> -	BPF_LD_MAP_FD(BPF_REG_1, 0),
> -	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
> -	BPF_EXIT_INSN(),
> -	},
> -	.fixup_map_xskmap = { 3 },
> -	.result = REJECT,
> -	.errstr = "cannot pass map_type 17 into func bpf_map_lookup_elem",
> -	.prog_type = BPF_PROG_TYPE_XDP,
> -},
>  {
>  	"prevent map lookup in stack trace",
>  	.insns = {
> 


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 14:54   ` Daniel Borkmann
@ 2019-06-04 15:30     ` Daniel Borkmann
  0 siblings, 0 replies; 13+ messages in thread
From: Daniel Borkmann @ 2019-06-04 15:30 UTC (permalink / raw)
  To: Jonathan Lemon, netdev; +Cc: kernel-team, bjorn.topel, magnus.karlsson, ast

On 06/04/2019 04:54 PM, Daniel Borkmann wrote:
> On 06/03/2019 06:38 PM, Jonathan Lemon wrote:
>> Currently, the AF_XDP code uses a separate map in order to
>> determine if an xsk is bound to a queue.  Instead of doing this,
>> have bpf_map_lookup_elem() return the queue_id, as a way of
>> indicating that there is a valid entry at the map index.
>>
>> Rearrange some xdp_sock members to eliminate structure holes.
>>
>> Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
>> Acked-by: Song Liu <songliubraving@fb.com>
>> Acked-by: Björn Töpel <bjorn.topel@intel.com>
>> ---
>>  include/net/xdp_sock.h                            |  6 +++---
>>  kernel/bpf/verifier.c                             |  6 +++++-
>>  kernel/bpf/xskmap.c                               |  4 +++-
>>  .../selftests/bpf/verifier/prevent_map_lookup.c   | 15 ---------------
>>  4 files changed, 11 insertions(+), 20 deletions(-)
>>
>> diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
>> index d074b6d60f8a..7d84b1da43d2 100644
>> --- a/include/net/xdp_sock.h
>> +++ b/include/net/xdp_sock.h
>> @@ -57,12 +57,12 @@ struct xdp_sock {
>>  	struct net_device *dev;
>>  	struct xdp_umem *umem;
>>  	struct list_head flush_node;
>> -	u16 queue_id;
>> -	struct xsk_queue *tx ____cacheline_aligned_in_smp;
>> -	struct list_head list;
>> +	u32 queue_id;
>>  	bool zc;
>>  	/* Protects multiple processes in the control path */
>>  	struct mutex mutex;
>> +	struct xsk_queue *tx ____cacheline_aligned_in_smp;
>> +	struct list_head list;
>>  	/* Mutual exclusion of NAPI TX thread and sendmsg error paths
>>  	 * in the SKB destructor callback.
>>  	 */
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 2778417e6e0c..91c730f85e92 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -2905,10 +2905,14 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
>>  	 * appear.
>>  	 */
>>  	case BPF_MAP_TYPE_CPUMAP:
>> -	case BPF_MAP_TYPE_XSKMAP:
>>  		if (func_id != BPF_FUNC_redirect_map)
>>  			goto error;
>>  		break;
>> +	case BPF_MAP_TYPE_XSKMAP:
>> +		if (func_id != BPF_FUNC_redirect_map &&
>> +		    func_id != BPF_FUNC_map_lookup_elem)
>> +			goto error;
>> +		break;
>>  	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
>>  	case BPF_MAP_TYPE_HASH_OF_MAPS:
>>  		if (func_id != BPF_FUNC_map_lookup_elem)
>> diff --git a/kernel/bpf/xskmap.c b/kernel/bpf/xskmap.c
>> index 686d244e798d..249b22089014 100644
>> --- a/kernel/bpf/xskmap.c
>> +++ b/kernel/bpf/xskmap.c
>> @@ -154,7 +154,9 @@ void __xsk_map_flush(struct bpf_map *map)
>>  
>>  static void *xsk_map_lookup_elem(struct bpf_map *map, void *key)
>>  {
>> -	return ERR_PTR(-EOPNOTSUPP);
>> +	struct xdp_sock *xs = __xsk_map_lookup_elem(map, *(u32 *)key);
>> +
>> +	return xs ? &xs->queue_id : NULL;
>>  }
> 
> How do you guarantee that BPf programs don't mess around with the map values
> e.g. overriding xs->queue_id from the lookup? This should be read-only map
> from BPF program side.

(Or via per-cpu scratch var where you move xs->queue_id into and return from here.)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
  2019-06-04 14:54   ` Daniel Borkmann
@ 2019-06-04 16:43   ` Jesper Dangaard Brouer
  2019-06-04 17:25     ` Jonathan Lemon
  1 sibling, 1 reply; 13+ messages in thread
From: Jesper Dangaard Brouer @ 2019-06-04 16:43 UTC (permalink / raw)
  To: Jonathan Lemon
  Cc: brouer, netdev, kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

On Mon, 3 Jun 2019 09:38:51 -0700
Jonathan Lemon <jonathan.lemon@gmail.com> wrote:

> Currently, the AF_XDP code uses a separate map in order to
> determine if an xsk is bound to a queue.  Instead of doing this,
> have bpf_map_lookup_elem() return the queue_id, as a way of
> indicating that there is a valid entry at the map index.

Just a reminder, that once we choose a return value, there the
queue_id, then it basically becomes UAPI, and we cannot change it.

Can we somehow use BTF to allow us to extend this later?



I was also going to point out that, you cannot return a direct pointer
to queue_id, as BPF-prog side can modify this... but Daniel already
pointed this out.
-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 16:43   ` Jesper Dangaard Brouer
@ 2019-06-04 17:25     ` Jonathan Lemon
  2019-06-04 18:12       ` Martin Lau
                         ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jonathan Lemon @ 2019-06-04 17:25 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev, kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:

> On Mon, 3 Jun 2019 09:38:51 -0700
> Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
>
>> Currently, the AF_XDP code uses a separate map in order to
>> determine if an xsk is bound to a queue.  Instead of doing this,
>> have bpf_map_lookup_elem() return the queue_id, as a way of
>> indicating that there is a valid entry at the map index.
>
> Just a reminder, that once we choose a return value, there the
> queue_id, then it basically becomes UAPI, and we cannot change it.

Yes - Alexei initially wanted to return the sk_cookie instead, but
that's 64 bits and opens up a whole other can of worms.


> Can we somehow use BTF to allow us to extend this later?
>
> I was also going to point out that, you cannot return a direct pointer
> to queue_id, as BPF-prog side can modify this... but Daniel already
> pointed this out.

So, I see three solutions here (for this and Toke's patchset also,
which is encountering the same problem).

1) add a scratch register (Toke's approach)
2) add a PTR_TO_<type>, which has the access checked.  This is the most
   flexible approach, but does seem a bit overkill at the moment.
3) add another helper function, say, bpf_map_elem_present() which just
   returns a boolean value indicating whether there is a valid map entry
   or not.

I was starting to do 2), but wanted to get some more feedback first.
-- 
Jonathan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 17:25     ` Jonathan Lemon
@ 2019-06-04 18:12       ` Martin Lau
  2019-06-05  8:45         ` Björn Töpel
  2019-06-04 18:18       ` Björn Töpel
  2019-06-04 20:07       ` Toke Høiland-Jørgensen
  2 siblings, 1 reply; 13+ messages in thread
From: Martin Lau @ 2019-06-04 18:12 UTC (permalink / raw)
  To: Jonathan Lemon
  Cc: Jesper Dangaard Brouer, netdev, Kernel Team, bjorn.topel,
	magnus.karlsson, ast, daniel

On Tue, Jun 04, 2019 at 10:25:23AM -0700, Jonathan Lemon wrote:
> On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:
> 
> > On Mon, 3 Jun 2019 09:38:51 -0700
> > Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
> >
> >> Currently, the AF_XDP code uses a separate map in order to
> >> determine if an xsk is bound to a queue.  Instead of doing this,
> >> have bpf_map_lookup_elem() return the queue_id, as a way of
> >> indicating that there is a valid entry at the map index.
> >
> > Just a reminder, that once we choose a return value, there the
> > queue_id, then it basically becomes UAPI, and we cannot change it.
> 
> Yes - Alexei initially wanted to return the sk_cookie instead, but
> that's 64 bits and opens up a whole other can of worms.
> 
> 
> > Can we somehow use BTF to allow us to extend this later?
> >
> > I was also going to point out that, you cannot return a direct pointer
> > to queue_id, as BPF-prog side can modify this... but Daniel already
> > pointed this out.
> 
> So, I see three solutions here (for this and Toke's patchset also,
> which is encountering the same problem).
> 
> 1) add a scratch register (Toke's approach)
> 2) add a PTR_TO_<type>, which has the access checked.  This is the most
>    flexible approach, but does seem a bit overkill at the moment.
I think it would be nice and more extensible to have PTR_TO_xxx.
It could start with the existing PTR_TO_SOCKET

or starting with a new PTR_TO_XDP_SOCK from the beginning is also fine.

> 3) add another helper function, say, bpf_map_elem_present() which just
>    returns a boolean value indicating whether there is a valid map entry
>    or not.
> 
> I was starting to do 2), but wanted to get some more feedback first.
> -- 
> Jonathan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 17:25     ` Jonathan Lemon
  2019-06-04 18:12       ` Martin Lau
@ 2019-06-04 18:18       ` Björn Töpel
  2019-06-04 20:07       ` Toke Høiland-Jørgensen
  2 siblings, 0 replies; 13+ messages in thread
From: Björn Töpel @ 2019-06-04 18:18 UTC (permalink / raw)
  To: Jonathan Lemon, Jesper Dangaard Brouer
  Cc: netdev, kernel-team, magnus.karlsson, ast, daniel

On 2019-06-04 19:25, Jonathan Lemon wrote:
> On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:
> 
>> On Mon, 3 Jun 2019 09:38:51 -0700
>> Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
>>
>>> Currently, the AF_XDP code uses a separate map in order to
>>> determine if an xsk is bound to a queue.  Instead of doing this,
>>> have bpf_map_lookup_elem() return the queue_id, as a way of
>>> indicating that there is a valid entry at the map index.
>>
>> Just a reminder, that once we choose a return value, there the
>> queue_id, then it basically becomes UAPI, and we cannot change it.
> 
> Yes - Alexei initially wanted to return the sk_cookie instead, but
> that's 64 bits and opens up a whole other can of worms.
>

Hmm, what other info would be useful? ifindex? Or going the the
other way, with read-only and just returning boolean?

> 
>> Can we somehow use BTF to allow us to extend this later?
>>
>> I was also going to point out that, you cannot return a direct pointer
>> to queue_id, as BPF-prog side can modify this... but Daniel already
>> pointed this out.
>

Ugh, good thing Daniel found this!


Björn

> So, I see three solutions here (for this and Toke's patchset also,
> which is encountering the same problem).
> 
> 1) add a scratch register (Toke's approach)
> 2) add a PTR_TO_<type>, which has the access checked.  This is the most
>     flexible approach, but does seem a bit overkill at the moment.
> 3) add another helper function, say, bpf_map_elem_present() which just
>     returns a boolean value indicating whether there is a valid map entry
>     or not.
> 
> I was starting to do 2), but wanted to get some more feedback first.
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 17:25     ` Jonathan Lemon
  2019-06-04 18:12       ` Martin Lau
  2019-06-04 18:18       ` Björn Töpel
@ 2019-06-04 20:07       ` Toke Høiland-Jørgensen
  2 siblings, 0 replies; 13+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-06-04 20:07 UTC (permalink / raw)
  To: Jonathan Lemon, Jesper Dangaard Brouer
  Cc: netdev, kernel-team, bjorn.topel, magnus.karlsson, ast, daniel

Jonathan Lemon <jonathan.lemon@gmail.com> writes:

> On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:
>
>> On Mon, 3 Jun 2019 09:38:51 -0700
>> Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
>>
>>> Currently, the AF_XDP code uses a separate map in order to
>>> determine if an xsk is bound to a queue.  Instead of doing this,
>>> have bpf_map_lookup_elem() return the queue_id, as a way of
>>> indicating that there is a valid entry at the map index.
>>
>> Just a reminder, that once we choose a return value, there the
>> queue_id, then it basically becomes UAPI, and we cannot change it.
>
> Yes - Alexei initially wanted to return the sk_cookie instead, but
> that's 64 bits and opens up a whole other can of worms.
>
>
>> Can we somehow use BTF to allow us to extend this later?
>>
>> I was also going to point out that, you cannot return a direct pointer
>> to queue_id, as BPF-prog side can modify this... but Daniel already
>> pointed this out.
>
> So, I see three solutions here (for this and Toke's patchset also,
> which is encountering the same problem).
>
> 1) add a scratch register (Toke's approach)
> 2) add a PTR_TO_<type>, which has the access checked.  This is the most
>    flexible approach, but does seem a bit overkill at the moment.
> 3) add another helper function, say, bpf_map_elem_present() which just
>    returns a boolean value indicating whether there is a valid map entry
>    or not.
>
> I was starting to do 2), but wanted to get some more feedback first.

I think I prefer 2) over 3); since we have a verifier that can actually
enforce something like read-only behaviour, actually having access to
the value will probably be useful to someone.

I can obviously live with 1) as well, of course (since I already did
that; though I just now realise that I forgot to make the scratch space
per-CPU)... :)

-Toke

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-04 18:12       ` Martin Lau
@ 2019-06-05  8:45         ` Björn Töpel
  2019-06-05 15:42           ` Jonathan Lemon
  0 siblings, 1 reply; 13+ messages in thread
From: Björn Töpel @ 2019-06-05  8:45 UTC (permalink / raw)
  To: Martin Lau
  Cc: Jonathan Lemon, Jesper Dangaard Brouer, netdev, Kernel Team,
	bjorn.topel, magnus.karlsson, ast, daniel

On Tue, 4 Jun 2019 at 20:13, Martin Lau <kafai@fb.com> wrote:
>
> On Tue, Jun 04, 2019 at 10:25:23AM -0700, Jonathan Lemon wrote:
> > On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:
> >
> > > On Mon, 3 Jun 2019 09:38:51 -0700
> > > Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
> > >
> > >> Currently, the AF_XDP code uses a separate map in order to
> > >> determine if an xsk is bound to a queue.  Instead of doing this,
> > >> have bpf_map_lookup_elem() return the queue_id, as a way of
> > >> indicating that there is a valid entry at the map index.
> > >
> > > Just a reminder, that once we choose a return value, there the
> > > queue_id, then it basically becomes UAPI, and we cannot change it.
> >
> > Yes - Alexei initially wanted to return the sk_cookie instead, but
> > that's 64 bits and opens up a whole other can of worms.
> >
> >
> > > Can we somehow use BTF to allow us to extend this later?
> > >
> > > I was also going to point out that, you cannot return a direct pointer
> > > to queue_id, as BPF-prog side can modify this... but Daniel already
> > > pointed this out.
> >
> > So, I see three solutions here (for this and Toke's patchset also,
> > which is encountering the same problem).
> >
> > 1) add a scratch register (Toke's approach)
> > 2) add a PTR_TO_<type>, which has the access checked.  This is the most
> >    flexible approach, but does seem a bit overkill at the moment.
> I think it would be nice and more extensible to have PTR_TO_xxx.
> It could start with the existing PTR_TO_SOCKET
>
> or starting with a new PTR_TO_XDP_SOCK from the beginning is also fine.
>

Doesn't the PTR_TO_SOCKET path involve taking a ref and mandating
sk_release() from the fast path? :-(


Björn


> > 3) add another helper function, say, bpf_map_elem_present() which just
> >    returns a boolean value indicating whether there is a valid map entry
> >    or not.
> >
> > I was starting to do 2), but wanted to get some more feedback first.
> > --
> > Jonathan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap
  2019-06-05  8:45         ` Björn Töpel
@ 2019-06-05 15:42           ` Jonathan Lemon
  0 siblings, 0 replies; 13+ messages in thread
From: Jonathan Lemon @ 2019-06-05 15:42 UTC (permalink / raw)
  To: Björn Töpel
  Cc: Martin Lau, Jesper Dangaard Brouer, netdev, Kernel Team,
	bjorn.topel, magnus.karlsson, ast, daniel



On 5 Jun 2019, at 1:45, Björn Töpel wrote:

> On Tue, 4 Jun 2019 at 20:13, Martin Lau <kafai@fb.com> wrote:
>>
>> On Tue, Jun 04, 2019 at 10:25:23AM -0700, Jonathan Lemon wrote:
>>> On 4 Jun 2019, at 9:43, Jesper Dangaard Brouer wrote:
>>>
>>>> On Mon, 3 Jun 2019 09:38:51 -0700
>>>> Jonathan Lemon <jonathan.lemon@gmail.com> wrote:
>>>>
>>>>> Currently, the AF_XDP code uses a separate map in order to
>>>>> determine if an xsk is bound to a queue.  Instead of doing this,
>>>>> have bpf_map_lookup_elem() return the queue_id, as a way of
>>>>> indicating that there is a valid entry at the map index.
>>>>
>>>> Just a reminder, that once we choose a return value, there the
>>>> queue_id, then it basically becomes UAPI, and we cannot change it.
>>>
>>> Yes - Alexei initially wanted to return the sk_cookie instead, but
>>> that's 64 bits and opens up a whole other can of worms.
>>>
>>>
>>>> Can we somehow use BTF to allow us to extend this later?
>>>>
>>>> I was also going to point out that, you cannot return a direct pointer
>>>> to queue_id, as BPF-prog side can modify this... but Daniel already
>>>> pointed this out.
>>>
>>> So, I see three solutions here (for this and Toke's patchset also,
>>> which is encountering the same problem).
>>>
>>> 1) add a scratch register (Toke's approach)
>>> 2) add a PTR_TO_<type>, which has the access checked.  This is the most
>>>    flexible approach, but does seem a bit overkill at the moment.
>> I think it would be nice and more extensible to have PTR_TO_xxx.
>> It could start with the existing PTR_TO_SOCKET
>>
>> or starting with a new PTR_TO_XDP_SOCK from the beginning is also fine.
>>
>
> Doesn't the PTR_TO_SOCKET path involve taking a ref and mandating
> sk_release() from the fast path? :-(

AF_XDP sockets are created with SOCK_RCU_FREE, and used under rcu, so
I don't think that they need to be refcounted.  bpf_sk_release is a NOP
in the RCU_FREE case.
-- 
Jonathan

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-06-05 15:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-03 16:38 [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Jonathan Lemon
2019-06-03 16:38 ` [PATCH v4 bpf-next 1/2] bpf: Allow bpf_map_lookup_elem() on an xskmap Jonathan Lemon
2019-06-04 14:54   ` Daniel Borkmann
2019-06-04 15:30     ` Daniel Borkmann
2019-06-04 16:43   ` Jesper Dangaard Brouer
2019-06-04 17:25     ` Jonathan Lemon
2019-06-04 18:12       ` Martin Lau
2019-06-05  8:45         ` Björn Töpel
2019-06-05 15:42           ` Jonathan Lemon
2019-06-04 18:18       ` Björn Töpel
2019-06-04 20:07       ` Toke Høiland-Jørgensen
2019-06-03 16:38 ` [PATCH v4 bpf-next 2/2] libbpf: remove qidconf and better support external bpf programs Jonathan Lemon
2019-06-04  6:06 ` [PATCH v4 bpf-next 0/2] Better handling of xskmap entries Björn Töpel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.