Skip to content

Commit f506439

Browse files
tohojoMartin KaFai Lau
authored andcommitted
selftests/bpf: Add a test for using a cpumap from an freplace-to-XDP program
This adds a simple test for inserting an XDP program into a cpumap that is "owned" by an XDP program that was loaded as PROG_TYPE_EXT (as libxdp does). Prior to the kernel fix this would fail because the map type ownership would be set to PROG_TYPE_EXT instead of being resolved to PROG_TYPE_XDP. v5: - Fix a few nits from Andrii, add his ACK v4: - Use skeletons for selftest v3: - Update comment to better explain the cause - Add Yonghong's ACK Acked-by: Yonghong Song <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Signed-off-by: Toke Høiland-Jørgensen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin KaFai Lau <[email protected]>
1 parent 1c123c5 commit f506439

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <network_helpers.h>
55
#include <bpf/btf.h>
66
#include "bind4_prog.skel.h"
7+
#include "freplace_progmap.skel.h"
8+
#include "xdp_dummy.skel.h"
79

810
typedef int (*test_cb)(struct bpf_object *obj);
911

@@ -500,6 +502,50 @@ static void test_fentry_to_cgroup_bpf(void)
500502
bind4_prog__destroy(skel);
501503
}
502504

505+
static void test_func_replace_progmap(void)
506+
{
507+
struct bpf_cpumap_val value = { .qsize = 1 };
508+
struct freplace_progmap *skel = NULL;
509+
struct xdp_dummy *tgt_skel = NULL;
510+
__u32 key = 0;
511+
int err;
512+
513+
skel = freplace_progmap__open();
514+
if (!ASSERT_OK_PTR(skel, "prog_open"))
515+
return;
516+
517+
tgt_skel = xdp_dummy__open_and_load();
518+
if (!ASSERT_OK_PTR(tgt_skel, "tgt_prog_load"))
519+
goto out;
520+
521+
err = bpf_program__set_attach_target(skel->progs.xdp_cpumap_prog,
522+
bpf_program__fd(tgt_skel->progs.xdp_dummy_prog),
523+
"xdp_dummy_prog");
524+
if (!ASSERT_OK(err, "set_attach_target"))
525+
goto out;
526+
527+
err = freplace_progmap__load(skel);
528+
if (!ASSERT_OK(err, "obj_load"))
529+
goto out;
530+
531+
/* Prior to fixing the kernel, loading the PROG_TYPE_EXT 'redirect'
532+
* program above will cause the map owner type of 'cpumap' to be set to
533+
* PROG_TYPE_EXT. This in turn will cause the bpf_map_update_elem()
534+
* below to fail, because the program we are inserting into the map is
535+
* of PROG_TYPE_XDP. After fixing the kernel, the initial ownership will
536+
* be correctly resolved to the *target* of the PROG_TYPE_EXT program
537+
* (i.e., PROG_TYPE_XDP) and the map update will succeed.
538+
*/
539+
value.bpf_prog.fd = bpf_program__fd(skel->progs.xdp_drop_prog);
540+
err = bpf_map_update_elem(bpf_map__fd(skel->maps.cpu_map),
541+
&key, &value, 0);
542+
ASSERT_OK(err, "map_update");
543+
544+
out:
545+
xdp_dummy__destroy(tgt_skel);
546+
freplace_progmap__destroy(skel);
547+
}
548+
503549
/* NOTE: affect other tests, must run in serial mode */
504550
void serial_test_fexit_bpf2bpf(void)
505551
{
@@ -525,4 +571,6 @@ void serial_test_fexit_bpf2bpf(void)
525571
test_func_replace_global_func();
526572
if (test__start_subtest("fentry_to_cgroup_bpf"))
527573
test_fentry_to_cgroup_bpf();
574+
if (test__start_subtest("func_replace_progmap"))
575+
test_func_replace_progmap();
528576
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/bpf.h>
3+
#include <bpf/bpf_helpers.h>
4+
5+
struct {
6+
__uint(type, BPF_MAP_TYPE_CPUMAP);
7+
__type(key, __u32);
8+
__type(value, struct bpf_cpumap_val);
9+
__uint(max_entries, 1);
10+
} cpu_map SEC(".maps");
11+
12+
SEC("xdp/cpumap")
13+
int xdp_drop_prog(struct xdp_md *ctx)
14+
{
15+
return XDP_DROP;
16+
}
17+
18+
SEC("freplace")
19+
int xdp_cpumap_prog(struct xdp_md *ctx)
20+
{
21+
return bpf_redirect_map(&cpu_map, 0, XDP_PASS);
22+
}
23+
24+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)