All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN
@ 2021-06-16 22:47 Zvi Effron
  2021-06-16 22:47 ` [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check Zvi Effron
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Zvi Effron @ 2021-06-16 22:47 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Yonghong Song, Zvi Effron

This patchset adds support for passing an xdp_md via ctx_in/ctx_out in
bpf_attr for BPF_PROG_TEST_RUN of XDP programs.

Patch 1 adds a function to validate XDP meta data lengths.

Patch 2 adds initial support for passing XDP meta data in addition to
packet data.

Patch 3 adds support for also specifying the ingress interface and
rx queue.

Patch 4 adds selftests to ensure functionality is correct.

Changelog:
----------
v4->v5
v4: https://lore.kernel.org/bpf/20210604220235.6758-1-zeffron@riotgames.com/

 * Add new patch to introduce xdp_metalen_valid inline function to avoid
  duplicated code from net/core/filter.c
 * Correct size of bad_ctx in selftests
 * Make all declarations reverse Christmas tree
 * Move data check from xdp_convert_md_to_buff to bpf_prog_test_run_xdp
 * Merge xdp_convert_buff_to_md into bpf_prog_test_run_xdp
 * Fix line too long
 * Extracted common checks in selftests to a helper function
 * Removed redundant assignment in selftests
 * Reordered test cases in selftests
 * Check data against 0 instead of data_meta in selftests
 * Made selftests use EINVAL instead of hardcoded 22
 * Dropped "_" from XDP function name
 * Changed casts in XDP program from unsigned long to long
 * Added a comment explaining the use of the loopback interface in selftests
 * Change parameter order in xdp_convert_md_to_buff to be input first
 * Assigned xdp->ingress_ifindex and xdp->rx_queue_index to local variables in
  xdp_convert_md_to_buff
 * Made use of "meta data" versus "metadata" consistent in comments and commit
  messages

v3->v4
v3: https://lore.kernel.org/bpf/20210602190815.8096-1-zeffron@riotgames.com/

 * Clean up nits
 * Validate xdp_md->data_end in bpf_prog_test_run_xdp
 * Remove intermediate metalen variables

v2 -> v3
v2: https://lore.kernel.org/bpf/20210527201341.7128-1-zeffron@riotgames.com/

 * Check errno first in selftests
 * Use DECLARE_LIBBPF_OPTS
 * Rename tattr to opts in selftests
 * Remove extra new line
 * Rename convert_xdpmd_to_xdpb to xdp_convert_md_to_buff
 * Rename convert_xdpb_to_xdpmd to xdp_convert_buff_to_md
 * Move declaration of device and rxqueue in xdp_convert_md_to_buff to
  patch 2
 * Reorder the kfree calls in bpf_prog_test_run_xdp

v1 -> v2
v1: https://lore.kernel.org/bpf/20210524220555.251473-1-zeffron@riotgames.com

 * Fix null pointer dereference with no context
 * Use the BPF skeleton and replace CHECK with ASSERT macros

Zvi Effron (4):
  bpf: add function for XDP meta data length check
  bpf: support input xdp_md context in BPF_PROG_TEST_RUN
  bpf: support specifying ingress via xdp_md context in
    BPF_PROG_TEST_RUN
  selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN

 include/net/xdp.h                             |   5 +
 include/uapi/linux/bpf.h                      |   3 -
 net/bpf/test_run.c                            |  89 ++++++++++++++-
 net/core/filter.c                             |   4 +-
 .../bpf/prog_tests/xdp_context_test_run.c     | 105 ++++++++++++++++++
 .../bpf/progs/test_xdp_context_test_run.c     |  20 ++++
 6 files changed, 215 insertions(+), 11 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c


base-commit: 1f26622b791b6a1b346d1dfd9d04450e20af0f41
-- 
2.31.1


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

* [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check
  2021-06-16 22:47 [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
@ 2021-06-16 22:47 ` Zvi Effron
  2021-06-17  6:27   ` Yonghong Song
  2021-06-16 22:47 ` [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Zvi Effron @ 2021-06-16 22:47 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Yonghong Song, Zvi Effron, Cody Haas,
	Lisa Watanabe

This commit prepares to use the XDP meta data length check in multiple
places by making it into a defined macro instead of a literal.

Co-developed-by: Cody Haas <chaas@riotgames.com>
Signed-off-by: Cody Haas <chaas@riotgames.com>
Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Zvi Effron <zeffron@riotgames.com>
---
 include/net/xdp.h | 5 +++++
 net/core/filter.c | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/xdp.h b/include/net/xdp.h
index 5533f0ab2afc..8bfd21bfeddc 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -276,6 +276,11 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp)
 	return unlikely(xdp->data_meta > xdp->data);
 }
 
+static __always_inline int
+xdp_metalen_valid(unsigned long metalen) {
+	return (metalen & (sizeof(__u32) - 1)) || (metalen > 32);
+}
+
 struct xdp_attachment_info {
 	struct bpf_prog *prog;
 	u32 flags;
diff --git a/net/core/filter.c b/net/core/filter.c
index 5b86e47ef079..b4a64a07de88 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -77,6 +77,7 @@
 #include <net/transp_v6.h>
 #include <linux/btf_ids.h>
 #include <net/tls.h>
+#include <net/xdp.h>
 
 static const struct bpf_func_proto *
 bpf_sk_base_func_proto(enum bpf_func_id func_id);
@@ -3905,8 +3906,7 @@ BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset)
 	if (unlikely(meta < xdp_frame_end ||
 		     meta > xdp->data))
 		return -EINVAL;
-	if (unlikely((metalen & (sizeof(__u32) - 1)) ||
-		     (metalen > 32)))
+	if (unlikely(xdp_metalen_valid(metalen)))
 		return -EACCES;
 
 	xdp->data_meta = meta;
-- 
2.31.1


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

* [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
  2021-06-16 22:47 ` [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check Zvi Effron
@ 2021-06-16 22:47 ` Zvi Effron
  2021-06-17  6:45   ` Yonghong Song
  2021-06-16 22:47 ` [PATCH bpf-next v5 3/4] bpf: support specifying ingress via " Zvi Effron
  2021-06-16 22:47 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add test for " Zvi Effron
  3 siblings, 1 reply; 12+ messages in thread
From: Zvi Effron @ 2021-06-16 22:47 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Yonghong Song, Zvi Effron, Cody Haas,
	Lisa Watanabe

Support passing a xdp_md via ctx_in/ctx_out in bpf_attr for
BPF_PROG_TEST_RUN.

The intended use case is to pass some XDP meta data to the test runs of
XDP programs that are used as tail calls.

For programs that use bpf_prog_test_run_xdp, support xdp_md input and
output. Unlike with an actual xdp_md during a non-test run, data_meta must
be 0 because it must point to the start of the provided user data. From
the initial xdp_md, use data and data_end to adjust the pointers in the
generated xdp_buff. All other non-zero fields are prohibited (with
EINVAL). If the user has set ctx_out/ctx_size_out, copy the (potentially
different) xdp_md back to the userspace.

We require all fields of input xdp_md except the ones we explicitly
support to be set to zero. The expectation is that in the future we might
add support for more fields and we want to fail explicitly if the user
runs the program on the kernel where we don't yet support them.

Co-developed-by: Cody Haas <chaas@riotgames.com>
Signed-off-by: Cody Haas <chaas@riotgames.com>
Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Zvi Effron <zeffron@riotgames.com>
---
 include/uapi/linux/bpf.h |  3 --
 net/bpf/test_run.c       | 68 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index bf9252c7381e..b46a383e8db7 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -324,9 +324,6 @@ union bpf_iter_link_info {
  *		**BPF_PROG_TYPE_SK_LOOKUP**
  *			*data_in* and *data_out* must be NULL.
  *
- *		**BPF_PROG_TYPE_XDP**
- *			*ctx_in* and *ctx_out* must be NULL.
- *
  *		**BPF_PROG_TYPE_RAW_TRACEPOINT**,
  *		**BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE**
  *
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index aa47af349ba8..f3054f25409c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -15,6 +15,7 @@
 #include <linux/error-injection.h>
 #include <linux/smp.h>
 #include <linux/sock_diag.h>
+#include <net/xdp.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/bpf_test_run.h>
@@ -687,6 +688,22 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
 	return ret;
 }
 
+static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
+{
+	if (!xdp_md)
+		return 0;
+
+	if (xdp_md->egress_ifindex != 0)
+		return -EINVAL;
+
+	if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
+		return -EINVAL;
+
+	xdp->data = xdp->data_meta + xdp_md->data;
+
+	return 0;
+}
+
 int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
 			  union bpf_attr __user *uattr)
 {
@@ -697,35 +714,74 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
 	struct netdev_rx_queue *rxqueue;
 	struct xdp_buff xdp = {};
 	u32 retval, duration;
+	struct xdp_md *ctx;
 	u32 max_data_sz;
 	void *data;
 	int ret;
 
-	if (kattr->test.ctx_in || kattr->test.ctx_out)
-		return -EINVAL;
+	ctx = bpf_ctx_init(kattr, sizeof(struct xdp_md));
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	if (ctx) {
+		/* There can't be user provided data before the meta data */
+		if (ctx->data_meta)
+			return -EINVAL;
+		if (ctx->data_end != size)
+			return -EINVAL;
+		if (ctx->data > ctx->data_end)
+			return -EINVAL;
+		if (unlikely(xdp_metalen_valid(ctx->data)))
+			return -EINVAL;
+		/* Meta data is allocated from the headroom */
+		headroom -= ctx->data;
+	}
 
 	/* XDP have extra tailroom as (most) drivers use full page */
 	max_data_sz = 4096 - headroom - tailroom;
 
 	data = bpf_test_init(kattr, max_data_sz, headroom, tailroom);
-	if (IS_ERR(data))
+	if (IS_ERR(data)) {
+		kfree(ctx);
 		return PTR_ERR(data);
+	}
 
 	rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
 	xdp_init_buff(&xdp, headroom + max_data_sz + tailroom,
 		      &rxqueue->xdp_rxq);
 	xdp_prepare_buff(&xdp, data, headroom, size, true);
 
+	ret = xdp_convert_md_to_buff(ctx, &xdp);
+	if (ret) {
+		kfree(data);
+		kfree(ctx);
+		return ret;
+	}
+
 	bpf_prog_change_xdp(NULL, prog);
 	ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true);
 	if (ret)
 		goto out;
-	if (xdp.data != data + headroom || xdp.data_end != xdp.data + size)
-		size = xdp.data_end - xdp.data;
-	ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
+
+	if (xdp.data_meta != data + headroom ||
+	    xdp.data_end != xdp.data_meta + size)
+		size = xdp.data_end - xdp.data_meta;
+
+	if (ctx) {
+		ctx->data = xdp.data - xdp.data_meta;
+		ctx->data_end = xdp.data_end - xdp.data_meta;
+	}
+
+	ret = bpf_test_finish(kattr, uattr, xdp.data_meta, size, retval,
+			      duration);
+	if (!ret)
+		ret = bpf_ctx_finish(kattr, uattr, ctx,
+				     sizeof(struct xdp_md));
+
 out:
 	bpf_prog_change_xdp(prog, NULL);
 	kfree(data);
+	kfree(ctx);
 	return ret;
 }
 
-- 
2.31.1


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

* [PATCH bpf-next v5 3/4] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
  2021-06-16 22:47 ` [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check Zvi Effron
  2021-06-16 22:47 ` [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
@ 2021-06-16 22:47 ` Zvi Effron
  2021-06-17  6:54   ` Yonghong Song
  2021-06-16 22:47 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add test for " Zvi Effron
  3 siblings, 1 reply; 12+ messages in thread
From: Zvi Effron @ 2021-06-16 22:47 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Yonghong Song, Zvi Effron, Cody Haas,
	Lisa Watanabe

Support specifying the ingress_ifindex and rx_queue_index of xdp_md
contexts for BPF_PROG_TEST_RUN.

The intended use case is to allow testing XDP programs that make decisions
based on the ingress interface or RX queue.

If ingress_ifindex is specified, look up the device by the provided index
in the current namespace and use its xdp_rxq for the xdp_buff. If the
rx_queue_index is out of range, or is non-zero when the ingress_ifindex is
0, return EINVAL.

Co-developed-by: Cody Haas <chaas@riotgames.com>
Signed-off-by: Cody Haas <chaas@riotgames.com>
Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Zvi Effron <zeffron@riotgames.com>
---
 net/bpf/test_run.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index f3054f25409c..0183fefd165c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -690,15 +690,36 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
 
 static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
 {
+	unsigned int ingress_ifindex;
+	unsigned int rx_queue_index;
+	struct netdev_rx_queue *rxqueue;
+	struct net_device *device;
+
 	if (!xdp_md)
 		return 0;
 
 	if (xdp_md->egress_ifindex != 0)
 		return -EINVAL;
 
-	if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
+	ingress_ifindex = xdp_md->ingress_ifindex;
+	rx_queue_index = xdp_md->rx_queue_index;
+
+	if (!ingress_ifindex && rx_queue_index)
 		return -EINVAL;
 
+	if (ingress_ifindex) {
+		device = dev_get_by_index(current->nsproxy->net_ns,
+					  ingress_ifindex);
+		if (!device)
+			return -EINVAL;
+
+		if (rx_queue_index >= device->real_num_rx_queues)
+			return -EINVAL;
+
+		rxqueue = __netif_get_rx_queue(device, rx_queue_index);
+		xdp->rxq = &rxqueue->xdp_rxq;
+	}
+
 	xdp->data = xdp->data_meta + xdp_md->data;
 
 	return 0;
-- 
2.31.1


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

* [PATCH bpf-next v5 4/4] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
                   ` (2 preceding siblings ...)
  2021-06-16 22:47 ` [PATCH bpf-next v5 3/4] bpf: support specifying ingress via " Zvi Effron
@ 2021-06-16 22:47 ` Zvi Effron
  2021-06-17  7:11   ` Yonghong Song
  3 siblings, 1 reply; 12+ messages in thread
From: Zvi Effron @ 2021-06-16 22:47 UTC (permalink / raw)
  To: bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Yonghong Song, Zvi Effron, Cody Haas,
	Lisa Watanabe

Add a test for using xdp_md as a context to BPF_PROG_TEST_RUN for XDP
programs.

The test uses a BPF program that takes in a return value from XDP
meta data, then reduces the size of the XDP meta data by 4 bytes.

Test cases validate the possible failure cases for passing in invalid
xdp_md contexts, that the return value is successfully passed
in, and that the adjusted meta data is successfully copied out.

Co-developed-by: Cody Haas <chaas@riotgames.com>
Signed-off-by: Cody Haas <chaas@riotgames.com>
Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
Signed-off-by: Zvi Effron <zeffron@riotgames.com>
---
 .../bpf/prog_tests/xdp_context_test_run.c     | 105 ++++++++++++++++++
 .../bpf/progs/test_xdp_context_test_run.c     |  20 ++++
 2 files changed, 125 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
new file mode 100644
index 000000000000..4fdb991482cb
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include <network_helpers.h>
+#include "test_xdp_context_test_run.skel.h"
+
+void test_xdp_context_error(int prog_fd, struct bpf_test_run_opts opts,
+			    __u32 data_meta, __u32 data, __u32 data_end,
+			    __u32 ingress_ifindex, __u32 rx_queue_index,
+			    __u32 egress_ifindex)
+{
+	struct xdp_md ctx = {
+		.data = data,
+		.data_end = data_end,
+		.data_meta = data_meta,
+		.ingress_ifindex = ingress_ifindex,
+		.rx_queue_index = rx_queue_index,
+		.egress_ifindex = egress_ifindex,
+	};
+	int err;
+
+	opts.ctx_in = &ctx;
+	opts.ctx_size_in = sizeof(ctx);
+	err = bpf_prog_test_run_opts(prog_fd, &opts);
+	ASSERT_EQ(errno, EINVAL, "errno-EINVAL");
+	ASSERT_ERR(err, "bpf_prog_test_run");
+}
+
+void test_xdp_context_test_run(void)
+{
+	struct test_xdp_context_test_run *skel = NULL;
+	char data[sizeof(pkt_v4) + sizeof(__u32)];
+	char bad_ctx[sizeof(struct xdp_md) + 1];
+	struct xdp_md ctx_in, ctx_out;
+	DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
+			    .data_in = &data,
+			    .data_size_in = sizeof(data),
+			    .ctx_out = &ctx_out,
+			    .ctx_size_out = sizeof(ctx_out),
+			    .repeat = 1,
+		);
+	int err, prog_fd;
+
+	skel = test_xdp_context_test_run__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "skel"))
+		return;
+	prog_fd = bpf_program__fd(skel->progs.xdp_context);
+
+	/* Data past the end of the kernel's struct xdp_md must be 0 */
+	bad_ctx[sizeof(bad_ctx) - 1] = 1;
+	opts.ctx_in = bad_ctx;
+	opts.ctx_size_in = sizeof(bad_ctx);
+	err = bpf_prog_test_run_opts(prog_fd, &opts);
+	ASSERT_EQ(errno, E2BIG, "extradata-errno");
+	ASSERT_ERR(err, "bpf_prog_test_run(extradata)");
+
+	*(__u32 *)data = XDP_PASS;
+	*(struct ipv4_packet *)(data + sizeof(__u32)) = pkt_v4;
+	opts.ctx_in = &ctx_in;
+	opts.ctx_size_in = sizeof(ctx_in);
+	memset(&ctx_in, 0, sizeof(ctx_in));
+	ctx_in.data_meta = 0;
+	ctx_in.data = sizeof(__u32);
+	ctx_in.data_end = ctx_in.data + sizeof(pkt_v4);
+	err = bpf_prog_test_run_opts(prog_fd, &opts);
+	ASSERT_OK(err, "bpf_prog_test_run(valid)");
+	ASSERT_EQ(opts.retval, XDP_PASS, "valid-retval");
+	ASSERT_EQ(opts.data_size_out, sizeof(pkt_v4), "valid-datasize");
+	ASSERT_EQ(opts.ctx_size_out, opts.ctx_size_in, "valid-ctxsize");
+	ASSERT_EQ(ctx_out.data_meta, 0, "valid-datameta");
+	ASSERT_EQ(ctx_out.data, 0, "valid-data");
+	ASSERT_EQ(ctx_out.data_end, sizeof(pkt_v4), "valid-dataend");
+
+	/* Meta data's size must be a multiple of 4 */
+	test_xdp_context_error(prog_fd, opts, 0, 1, sizeof(data), 0, 0, 0);
+
+	/* data_meta must reference the start of data */
+	test_xdp_context_error(prog_fd, opts, 4, sizeof(__u32), sizeof(data),
+			       0, 0, 0);
+
+	/* Meta data must be 32 bytes or smaller */
+	test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0);
+
+	/* Total size of data must match data_end - data_meta */
+	test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32),
+			       sizeof(data) - 1, 0, 0, 0);
+	test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32),
+			       sizeof(data) + 1, 0, 0, 0);
+
+	/* RX queue cannot be specified without specifying an ingress */
+	test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data),
+			       0, 1, 0);
+
+	/* Interface 1 is always the loopback interface which always has only
+	 * one RX queue (index 0). This makes index 1 an invalid index for
+	 * interface 1.
+	 */
+	test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data),
+			       1, 1, 0);
+
+	/* The egress cannot be specified */
+	test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data),
+			       0, 0, 1);
+
+	test_xdp_context_test_run__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c b/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c
new file mode 100644
index 000000000000..d7b88cd05afd
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_xdp_context_test_run.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+SEC("xdp")
+int xdp_context(struct xdp_md *xdp)
+{
+	void *data = (void *)(long)xdp->data;
+	__u32 *metadata = (void *)(long)xdp->data_meta;
+	__u32 ret;
+
+	if (metadata + 1 > data)
+		return XDP_ABORTED;
+	ret = *metadata;
+	if (bpf_xdp_adjust_meta(xdp, 4))
+		return XDP_ABORTED;
+	return ret;
+}
+
+char _license[] SEC("license") = "GPL";
-- 
2.31.1


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

* Re: [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check
  2021-06-16 22:47 ` [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check Zvi Effron
@ 2021-06-17  6:27   ` Yonghong Song
  0 siblings, 0 replies; 12+ messages in thread
From: Yonghong Song @ 2021-06-17  6:27 UTC (permalink / raw)
  To: Zvi Effron, bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe



On 6/16/21 3:47 PM, Zvi Effron wrote:
> This commit prepares to use the XDP meta data length check in multiple
> places by making it into a defined macro instead of a literal.

defined macro => static inline function.

> 
> Co-developed-by: Cody Haas <chaas@riotgames.com>
> Signed-off-by: Cody Haas <chaas@riotgames.com>
> Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Zvi Effron <zeffron@riotgames.com>
> ---
>   include/net/xdp.h | 5 +++++
>   net/core/filter.c | 4 ++--
>   2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/xdp.h b/include/net/xdp.h
> index 5533f0ab2afc..8bfd21bfeddc 100644
> --- a/include/net/xdp.h
> +++ b/include/net/xdp.h
> @@ -276,6 +276,11 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp)
>   	return unlikely(xdp->data_meta > xdp->data);
>   }
>   
> +static __always_inline int
> +xdp_metalen_valid(unsigned long metalen) {
> +	return (metalen & (sizeof(__u32) - 1)) || (metalen > 32);
> +}

Maybe change the signature and function name to
static inline bool
xdp_metalen_invalid(...) { ...}

The function returns true if it is invalid.

Let us just use "static inline bool". Return type "int"
changed to "bool" as it is indeed return a boolean.

"__always_inline" gives stronger hint to do inlining.
Most kernel static inline functions use "inline" attribute to
indicate it is good to inline, but if for whatever reason
compiler didn't inline, it won't be a disaster. For a function
like below, I would be surprised if it is not inlined with
"inline" attribute.


> +
>   struct xdp_attachment_info {
>   	struct bpf_prog *prog;
>   	u32 flags;
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 5b86e47ef079..b4a64a07de88 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -77,6 +77,7 @@
>   #include <net/transp_v6.h>
>   #include <linux/btf_ids.h>
>   #include <net/tls.h>
> +#include <net/xdp.h>
>   
>   static const struct bpf_func_proto *
>   bpf_sk_base_func_proto(enum bpf_func_id func_id);
> @@ -3905,8 +3906,7 @@ BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset)
>   	if (unlikely(meta < xdp_frame_end ||
>   		     meta > xdp->data))
>   		return -EINVAL;
> -	if (unlikely((metalen & (sizeof(__u32) - 1)) ||
> -		     (metalen > 32)))
> +	if (unlikely(xdp_metalen_valid(metalen)))
>   		return -EACCES;
>   
>   	xdp->data_meta = meta;
> 

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

* Re: [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 ` [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
@ 2021-06-17  6:45   ` Yonghong Song
  0 siblings, 0 replies; 12+ messages in thread
From: Yonghong Song @ 2021-06-17  6:45 UTC (permalink / raw)
  To: Zvi Effron, bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe



On 6/16/21 3:47 PM, Zvi Effron wrote:
> Support passing a xdp_md via ctx_in/ctx_out in bpf_attr for
> BPF_PROG_TEST_RUN.
> 
> The intended use case is to pass some XDP meta data to the test runs of
> XDP programs that are used as tail calls.
> 
> For programs that use bpf_prog_test_run_xdp, support xdp_md input and
> output. Unlike with an actual xdp_md during a non-test run, data_meta must
> be 0 because it must point to the start of the provided user data. From
> the initial xdp_md, use data and data_end to adjust the pointers in the
> generated xdp_buff. All other non-zero fields are prohibited (with
> EINVAL). If the user has set ctx_out/ctx_size_out, copy the (potentially
> different) xdp_md back to the userspace.
> 
> We require all fields of input xdp_md except the ones we explicitly
> support to be set to zero. The expectation is that in the future we might
> add support for more fields and we want to fail explicitly if the user
> runs the program on the kernel where we don't yet support them.
> 
> Co-developed-by: Cody Haas <chaas@riotgames.com>
> Signed-off-by: Cody Haas <chaas@riotgames.com>
> Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Zvi Effron <zeffron@riotgames.com>
> ---
>   include/uapi/linux/bpf.h |  3 --
>   net/bpf/test_run.c       | 68 ++++++++++++++++++++++++++++++++++++----
>   2 files changed, 62 insertions(+), 9 deletions(-)
> 
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index bf9252c7381e..b46a383e8db7 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -324,9 +324,6 @@ union bpf_iter_link_info {
>    *		**BPF_PROG_TYPE_SK_LOOKUP**
>    *			*data_in* and *data_out* must be NULL.
>    *
> - *		**BPF_PROG_TYPE_XDP**
> - *			*ctx_in* and *ctx_out* must be NULL.
> - *
>    *		**BPF_PROG_TYPE_RAW_TRACEPOINT**,
>    *		**BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE**
>    *
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index aa47af349ba8..f3054f25409c 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -15,6 +15,7 @@
>   #include <linux/error-injection.h>
>   #include <linux/smp.h>
>   #include <linux/sock_diag.h>
> +#include <net/xdp.h>
>   
>   #define CREATE_TRACE_POINTS
>   #include <trace/events/bpf_test_run.h>
> @@ -687,6 +688,22 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>   	return ret;
>   }
>   
> +static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
> +{
> +	if (!xdp_md)
> +		return 0;
> +
> +	if (xdp_md->egress_ifindex != 0)
> +		return -EINVAL;
> +
> +	if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
> +		return -EINVAL;
> +
> +	xdp->data = xdp->data_meta + xdp_md->data;
> +
> +	return 0;
> +}
> +
>   int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
>   			  union bpf_attr __user *uattr)
>   {
> @@ -697,35 +714,74 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
>   	struct netdev_rx_queue *rxqueue;
>   	struct xdp_buff xdp = {};
>   	u32 retval, duration;
> +	struct xdp_md *ctx;
>   	u32 max_data_sz;
>   	void *data;
>   	int ret;

Let us initialize ret = -EINVAL;

>   
> -	if (kattr->test.ctx_in || kattr->test.ctx_out)
> -		return -EINVAL;
> +	ctx = bpf_ctx_init(kattr, sizeof(struct xdp_md));
> +	if (IS_ERR(ctx))
> +		return PTR_ERR(ctx);
> +
> +	if (ctx) {
> +		/* There can't be user provided data before the meta data */
> +		if (ctx->data_meta)
> +			return -EINVAL;
> +		if (ctx->data_end != size)
> +			return -EINVAL;
> +		if (ctx->data > ctx->data_end)
> +			return -EINVAL;
> +		if (unlikely(xdp_metalen_valid(ctx->data)))
> +			return -EINVAL;

For all above four failures, "kfree(ctx)" is missed,
I suggest to add a label "free_ctx" in later code and jump there.

		if (ctx->data_meta || ctx->data_end != size ||
		    ctx->data > ctx->data_end ||
		    unlikely(xdp_metalen_invalid(ctx->data)))
			goto free_ctx;



> +		/* Meta data is allocated from the headroom */
> +		headroom -= ctx->data;
> +	}
>   
>   	/* XDP have extra tailroom as (most) drivers use full page */
>   	max_data_sz = 4096 - headroom - tailroom;
>   
>   	data = bpf_test_init(kattr, max_data_sz, headroom, tailroom);
> -	if (IS_ERR(data))
> +	if (IS_ERR(data)) {
> +		kfree(ctx);
>   		return PTR_ERR(data);

		err = PTR_ERR(data);
		goto free_ctx;

> +	}
>   
>   	rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
>   	xdp_init_buff(&xdp, headroom + max_data_sz + tailroom,
>   		      &rxqueue->xdp_rxq);
>   	xdp_prepare_buff(&xdp, data, headroom, size, true);
>   
> +	ret = xdp_convert_md_to_buff(ctx, &xdp);
> +	if (ret) {
> +		kfree(data);
> +		kfree(ctx);
> +		return ret;

		goto free_data;
> +	}
> +
>   	bpf_prog_change_xdp(NULL, prog);
>   	ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true);
>   	if (ret)
>   		goto out;
> -	if (xdp.data != data + headroom || xdp.data_end != xdp.data + size)
> -		size = xdp.data_end - xdp.data;
> -	ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
> +
> +	if (xdp.data_meta != data + headroom ||
> +	    xdp.data_end != xdp.data_meta + size)
> +		size = xdp.data_end - xdp.data_meta;
> +
> +	if (ctx) {
> +		ctx->data = xdp.data - xdp.data_meta;
> +		ctx->data_end = xdp.data_end - xdp.data_meta;
> +	}
> +
> +	ret = bpf_test_finish(kattr, uattr, xdp.data_meta, size, retval,
> +			      duration);
> +	if (!ret)
> +		ret = bpf_ctx_finish(kattr, uattr, ctx,
> +				     sizeof(struct xdp_md));
> +
>   out:
>   	bpf_prog_change_xdp(prog, NULL);
     free_data:
>   	kfree(data);
     free_ctx:
> +	kfree(ctx);
>   	return ret;
>   }
>   
> 

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

* Re: [PATCH bpf-next v5 3/4] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 ` [PATCH bpf-next v5 3/4] bpf: support specifying ingress via " Zvi Effron
@ 2021-06-17  6:54   ` Yonghong Song
  2021-06-17 22:47     ` Zvi Effron
  0 siblings, 1 reply; 12+ messages in thread
From: Yonghong Song @ 2021-06-17  6:54 UTC (permalink / raw)
  To: Zvi Effron, bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe



On 6/16/21 3:47 PM, Zvi Effron wrote:
> Support specifying the ingress_ifindex and rx_queue_index of xdp_md
> contexts for BPF_PROG_TEST_RUN.
> 
> The intended use case is to allow testing XDP programs that make decisions
> based on the ingress interface or RX queue.
> 
> If ingress_ifindex is specified, look up the device by the provided index
> in the current namespace and use its xdp_rxq for the xdp_buff. If the
> rx_queue_index is out of range, or is non-zero when the ingress_ifindex is
> 0, return EINVAL.

Let us match actual implementation.
    EINVAL => -EINVAL

> 
> Co-developed-by: Cody Haas <chaas@riotgames.com>
> Signed-off-by: Cody Haas <chaas@riotgames.com>
> Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Zvi Effron <zeffron@riotgames.com>
> ---
>   net/bpf/test_run.c | 23 ++++++++++++++++++++++-
>   1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index f3054f25409c..0183fefd165c 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -690,15 +690,36 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
>   
>   static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
>   {
> +	unsigned int ingress_ifindex;
> +	unsigned int rx_queue_index;

nit: the above two definitions have the same type, let us merge them 
into one line.

> +	struct netdev_rx_queue *rxqueue;
> +	struct net_device *device;
> +
>   	if (!xdp_md)
>   		return 0;
>   
>   	if (xdp_md->egress_ifindex != 0)
>   		return -EINVAL;
>   
> -	if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
> +	ingress_ifindex = xdp_md->ingress_ifindex;
> +	rx_queue_index = xdp_md->rx_queue_index;
> +
> +	if (!ingress_ifindex && rx_queue_index)
>   		return -EINVAL;
>   
> +	if (ingress_ifindex) {
> +		device = dev_get_by_index(current->nsproxy->net_ns,
> +					  ingress_ifindex);
> +		if (!device)
> +			return -EINVAL;
> +
> +		if (rx_queue_index >= device->real_num_rx_queues)
> +			return -EINVAL;

Does rx_queue_index = 0 is valid? I don't know whether it is valid
or not, just asking.

> +
> +		rxqueue = __netif_get_rx_queue(device, rx_queue_index);
> +		xdp->rxq = &rxqueue->xdp_rxq;
> +	}
> +
>   	xdp->data = xdp->data_meta + xdp_md->data;
>   
>   	return 0;
> 

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

* Re: [PATCH bpf-next v5 4/4] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN
  2021-06-16 22:47 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add test for " Zvi Effron
@ 2021-06-17  7:11   ` Yonghong Song
  2021-06-17 15:18     ` Zvi Effron
  0 siblings, 1 reply; 12+ messages in thread
From: Yonghong Song @ 2021-06-17  7:11 UTC (permalink / raw)
  To: Zvi Effron, bpf
  Cc: Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe



On 6/16/21 3:47 PM, Zvi Effron wrote:
> Add a test for using xdp_md as a context to BPF_PROG_TEST_RUN for XDP
> programs.
> 
> The test uses a BPF program that takes in a return value from XDP
> meta data, then reduces the size of the XDP meta data by 4 bytes.
> 
> Test cases validate the possible failure cases for passing in invalid
> xdp_md contexts, that the return value is successfully passed
> in, and that the adjusted meta data is successfully copied out.
> 
> Co-developed-by: Cody Haas <chaas@riotgames.com>
> Signed-off-by: Cody Haas <chaas@riotgames.com>
> Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> Signed-off-by: Zvi Effron <zeffron@riotgames.com>

Acked-by: Yonghong Song <yhs@fb.com>

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

* Re: [PATCH bpf-next v5 4/4] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN
  2021-06-17  7:11   ` Yonghong Song
@ 2021-06-17 15:18     ` Zvi Effron
  2021-06-17 15:30       ` Yonghong Song
  0 siblings, 1 reply; 12+ messages in thread
From: Zvi Effron @ 2021-06-17 15:18 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe

On Thu, Jun 17, 2021 at 2:11 AM Yonghong Song <yhs@fb.com> wrote:
>
> On 6/16/21 3:47 PM, Zvi Effron wrote:
> > Add a test for using xdp_md as a context to BPF_PROG_TEST_RUN for XDP
> > programs.
> >
> > The test uses a BPF program that takes in a return value from XDP
> > meta data, then reduces the size of the XDP meta data by 4 bytes.
> >
> > Test cases validate the possible failure cases for passing in invalid
> > xdp_md contexts, that the return value is successfully passed
> > in, and that the adjusted meta data is successfully copied out.
> >
> > Co-developed-by: Cody Haas <chaas@riotgames.com>
> > Signed-off-by: Cody Haas <chaas@riotgames.com>
> > Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> > Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> > Signed-off-by: Zvi Effron <zeffron@riotgames.com>
>
> Acked-by: Yonghong Song <yhs@fb.com>

Thank you for all of your feedback on our patchset.

Question about process for Acks: do we add your Acked-by line to the
commit message in our next version of the patchset?

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

* Re: [PATCH bpf-next v5 4/4] selftests/bpf: Add test for xdp_md context in BPF_PROG_TEST_RUN
  2021-06-17 15:18     ` Zvi Effron
@ 2021-06-17 15:30       ` Yonghong Song
  0 siblings, 0 replies; 12+ messages in thread
From: Yonghong Song @ 2021-06-17 15:30 UTC (permalink / raw)
  To: Zvi Effron
  Cc: bpf, Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe



On 6/17/21 8:18 AM, Zvi Effron wrote:
> On Thu, Jun 17, 2021 at 2:11 AM Yonghong Song <yhs@fb.com> wrote:
>>
>> On 6/16/21 3:47 PM, Zvi Effron wrote:
>>> Add a test for using xdp_md as a context to BPF_PROG_TEST_RUN for XDP
>>> programs.
>>>
>>> The test uses a BPF program that takes in a return value from XDP
>>> meta data, then reduces the size of the XDP meta data by 4 bytes.
>>>
>>> Test cases validate the possible failure cases for passing in invalid
>>> xdp_md contexts, that the return value is successfully passed
>>> in, and that the adjusted meta data is successfully copied out.
>>>
>>> Co-developed-by: Cody Haas <chaas@riotgames.com>
>>> Signed-off-by: Cody Haas <chaas@riotgames.com>
>>> Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
>>> Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
>>> Signed-off-by: Zvi Effron <zeffron@riotgames.com>
>>
>> Acked-by: Yonghong Song <yhs@fb.com>
> 
> Thank you for all of your feedback on our patchset.
> 
> Question about process for Acks: do we add your Acked-by line to the
> commit message in our next version of the patchset?

Yes, just add my Ack to this ack'ed commit in the next revision. Thanks!

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

* Re: [PATCH bpf-next v5 3/4] bpf: support specifying ingress via xdp_md context in BPF_PROG_TEST_RUN
  2021-06-17  6:54   ` Yonghong Song
@ 2021-06-17 22:47     ` Zvi Effron
  0 siblings, 0 replies; 12+ messages in thread
From: Zvi Effron @ 2021-06-17 22:47 UTC (permalink / raw)
  To: Yonghong Song
  Cc: bpf, Alexei Starovoitov, David S. Miller, Daniel Borkmann,
	Jesper Dangaard Brouer, Andrii Nakryiko, Maciej Fijalkowski,
	Martin KaFai Lau, Cody Haas, Lisa Watanabe

On Thu, Jun 17, 2021 at 1:55 AM Yonghong Song <yhs@fb.com> wrote:
>
> On 6/16/21 3:47 PM, Zvi Effron wrote:
> > Support specifying the ingress_ifindex and rx_queue_index of xdp_md
> > contexts for BPF_PROG_TEST_RUN.
> >
> > The intended use case is to allow testing XDP programs that make decisions
> > based on the ingress interface or RX queue.
> >
> > If ingress_ifindex is specified, look up the device by the provided index
> > in the current namespace and use its xdp_rxq for the xdp_buff. If the
> > rx_queue_index is out of range, or is non-zero when the ingress_ifindex is
> > 0, return EINVAL.
>
> Let us match actual implementation.
>     EINVAL => -EINVAL
>
> >
> > Co-developed-by: Cody Haas <chaas@riotgames.com>
> > Signed-off-by: Cody Haas <chaas@riotgames.com>
> > Co-developed-by: Lisa Watanabe <lwatanabe@riotgames.com>
> > Signed-off-by: Lisa Watanabe <lwatanabe@riotgames.com>
> > Signed-off-by: Zvi Effron <zeffron@riotgames.com>
> > ---
> >   net/bpf/test_run.c | 23 ++++++++++++++++++++++-
> >   1 file changed, 22 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> > index f3054f25409c..0183fefd165c 100644
> > --- a/net/bpf/test_run.c
> > +++ b/net/bpf/test_run.c
> > @@ -690,15 +690,36 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
> >
> >   static int xdp_convert_md_to_buff(struct xdp_md *xdp_md, struct xdp_buff *xdp)
> >   {
> > +     unsigned int ingress_ifindex;
> > +     unsigned int rx_queue_index;
>
> nit: the above two definitions have the same type, let us merge them
> into one line.
>
> > +     struct netdev_rx_queue *rxqueue;
> > +     struct net_device *device;
> > +
> >       if (!xdp_md)
> >               return 0;
> >
> >       if (xdp_md->egress_ifindex != 0)
> >               return -EINVAL;
> >
> > -     if (xdp_md->ingress_ifindex != 0 || xdp_md->rx_queue_index != 0)
> > +     ingress_ifindex = xdp_md->ingress_ifindex;
> > +     rx_queue_index = xdp_md->rx_queue_index;
> > +
> > +     if (!ingress_ifindex && rx_queue_index)
> >               return -EINVAL;
> >
> > +     if (ingress_ifindex) {
> > +             device = dev_get_by_index(current->nsproxy->net_ns,
> > +                                       ingress_ifindex);
> > +             if (!device)
> > +                     return -EINVAL;
> > +
> > +             if (rx_queue_index >= device->real_num_rx_queues)
> > +                     return -EINVAL;
>
> Does rx_queue_index = 0 is valid? I don't know whether it is valid
> or not, just asking.

Yes. RX queues are 0 indexed.

>
> > +
> > +             rxqueue = __netif_get_rx_queue(device, rx_queue_index);
> > +             xdp->rxq = &rxqueue->xdp_rxq;
> > +     }
> > +
> >       xdp->data = xdp->data_meta + xdp_md->data;
> >
> >       return 0;
> >

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

end of thread, other threads:[~2021-06-17 22:47 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-16 22:47 [PATCH bpf-next v5 0/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
2021-06-16 22:47 ` [PATCH bpf-next v5 1/4] bpf: add function for XDP meta data length check Zvi Effron
2021-06-17  6:27   ` Yonghong Song
2021-06-16 22:47 ` [PATCH bpf-next v5 2/4] bpf: support input xdp_md context in BPF_PROG_TEST_RUN Zvi Effron
2021-06-17  6:45   ` Yonghong Song
2021-06-16 22:47 ` [PATCH bpf-next v5 3/4] bpf: support specifying ingress via " Zvi Effron
2021-06-17  6:54   ` Yonghong Song
2021-06-17 22:47     ` Zvi Effron
2021-06-16 22:47 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add test for " Zvi Effron
2021-06-17  7:11   ` Yonghong Song
2021-06-17 15:18     ` Zvi Effron
2021-06-17 15:30       ` Yonghong Song

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.