Commit 94bbbdfb authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'double-fix bpf_test_run + XDP_PASS recycling'

Alexander Lobakin says:

====================

Enabling skb PP recycling revealed a couple issues in the bpf_test_run
code. Recycling broke the assumption that the headroom won't ever be
touched during the test_run execution: xdp_scrub_frame() invalidates the
XDP frame at the headroom start, while neigh xmit code overwrites 2 bytes
to the left of the Ethernet header. The first makes the kernel panic in
certain cases, while the second breaks xdp_do_redirect selftest on BE.
test_run is a limited-scope entity, so let's hope no more corner cases
will happen here or at least they will be as easy and pleasant to fix
as those two.
====================
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 082cdc69 5640b6d8
...@@ -208,6 +208,16 @@ static void xdp_test_run_teardown(struct xdp_test_data *xdp) ...@@ -208,6 +208,16 @@ static void xdp_test_run_teardown(struct xdp_test_data *xdp)
kfree(xdp->skbs); kfree(xdp->skbs);
} }
static bool frame_was_changed(const struct xdp_page_head *head)
{
/* xdp_scrub_frame() zeroes the data pointer, flags is the last field,
* i.e. has the highest chances to be overwritten. If those two are
* untouched, it's most likely safe to skip the context reset.
*/
return head->frm.data != head->orig_ctx.data ||
head->frm.flags != head->orig_ctx.flags;
}
static bool ctx_was_changed(struct xdp_page_head *head) static bool ctx_was_changed(struct xdp_page_head *head)
{ {
return head->orig_ctx.data != head->ctx.data || return head->orig_ctx.data != head->ctx.data ||
...@@ -217,7 +227,7 @@ static bool ctx_was_changed(struct xdp_page_head *head) ...@@ -217,7 +227,7 @@ static bool ctx_was_changed(struct xdp_page_head *head)
static void reset_ctx(struct xdp_page_head *head) static void reset_ctx(struct xdp_page_head *head)
{ {
if (likely(!ctx_was_changed(head))) if (likely(!frame_was_changed(head) && !ctx_was_changed(head)))
return; return;
head->ctx.data = head->orig_ctx.data; head->ctx.data = head->orig_ctx.data;
......
...@@ -86,12 +86,12 @@ static void test_max_pkt_size(int fd) ...@@ -86,12 +86,12 @@ static void test_max_pkt_size(int fd)
void test_xdp_do_redirect(void) void test_xdp_do_redirect(void)
{ {
int err, xdp_prog_fd, tc_prog_fd, ifindex_src, ifindex_dst; int err, xdp_prog_fd, tc_prog_fd, ifindex_src, ifindex_dst;
char data[sizeof(pkt_udp) + sizeof(__u32)]; char data[sizeof(pkt_udp) + sizeof(__u64)];
struct test_xdp_do_redirect *skel = NULL; struct test_xdp_do_redirect *skel = NULL;
struct nstoken *nstoken = NULL; struct nstoken *nstoken = NULL;
struct bpf_link *link; struct bpf_link *link;
LIBBPF_OPTS(bpf_xdp_query_opts, query_opts); LIBBPF_OPTS(bpf_xdp_query_opts, query_opts);
struct xdp_md ctx_in = { .data = sizeof(__u32), struct xdp_md ctx_in = { .data = sizeof(__u64),
.data_end = sizeof(data) }; .data_end = sizeof(data) };
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
.data_in = &data, .data_in = &data,
...@@ -105,8 +105,9 @@ void test_xdp_do_redirect(void) ...@@ -105,8 +105,9 @@ void test_xdp_do_redirect(void)
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook, DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
.attach_point = BPF_TC_INGRESS); .attach_point = BPF_TC_INGRESS);
memcpy(&data[sizeof(__u32)], &pkt_udp, sizeof(pkt_udp)); memcpy(&data[sizeof(__u64)], &pkt_udp, sizeof(pkt_udp));
*((__u32 *)data) = 0x42; /* metadata test value */ *((__u32 *)data) = 0x42; /* metadata test value */
*((__u32 *)data + 4) = 0;
skel = test_xdp_do_redirect__open(); skel = test_xdp_do_redirect__open();
if (!ASSERT_OK_PTR(skel, "skel")) if (!ASSERT_OK_PTR(skel, "skel"))
......
...@@ -52,7 +52,7 @@ int xdp_redirect(struct xdp_md *xdp) ...@@ -52,7 +52,7 @@ int xdp_redirect(struct xdp_md *xdp)
*payload = MARK_IN; *payload = MARK_IN;
if (bpf_xdp_adjust_meta(xdp, 4)) if (bpf_xdp_adjust_meta(xdp, sizeof(__u64)))
return XDP_ABORTED; return XDP_ABORTED;
if (retcode > XDP_PASS) if (retcode > XDP_PASS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment