Skip to content

Commit 7559a7a

Browse files
AsphalttAlexei Starovoitov
authored andcommitted
selftests/bpf: Add testcase for updating attached freplace prog to prog_array map
Add a selftest to confirm the issue, which gets -EINVAL when update attached freplace prog to prog_array map, has been fixed. cd tools/testing/selftests/bpf; ./test_progs -t tailcalls 328/25 tailcalls/tailcall_freplace:OK 328 tailcalls:OK Summary: 1/25 PASSED, 0 SKIPPED, 0 FAILED Acked-by: Yonghong Song <[email protected]> Signed-off-by: Leon Hwang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 50c374c commit 7559a7a

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

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

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
#include "tailcall_poke.skel.h"
66
#include "tailcall_bpf2bpf_hierarchy2.skel.h"
77
#include "tailcall_bpf2bpf_hierarchy3.skel.h"
8-
8+
#include "tailcall_freplace.skel.h"
9+
#include "tc_bpf2bpf.skel.h"
910

1011
/* test_tailcall_1 checks basic functionality by patching multiple locations
1112
* in a single program for a single tail call slot with nop->jmp, jmp->nop
@@ -1495,6 +1496,66 @@ static void test_tailcall_bpf2bpf_hierarchy_3(void)
14951496
RUN_TESTS(tailcall_bpf2bpf_hierarchy3);
14961497
}
14971498

1499+
/* test_tailcall_freplace checks that the attached freplace prog is OK to
1500+
* update the prog_array map.
1501+
*/
1502+
static void test_tailcall_freplace(void)
1503+
{
1504+
struct tailcall_freplace *freplace_skel = NULL;
1505+
struct bpf_link *freplace_link = NULL;
1506+
struct bpf_program *freplace_prog;
1507+
struct tc_bpf2bpf *tc_skel = NULL;
1508+
int prog_fd, map_fd;
1509+
char buff[128] = {};
1510+
int err, key;
1511+
1512+
LIBBPF_OPTS(bpf_test_run_opts, topts,
1513+
.data_in = buff,
1514+
.data_size_in = sizeof(buff),
1515+
.repeat = 1,
1516+
);
1517+
1518+
freplace_skel = tailcall_freplace__open();
1519+
if (!ASSERT_OK_PTR(freplace_skel, "tailcall_freplace__open"))
1520+
return;
1521+
1522+
tc_skel = tc_bpf2bpf__open_and_load();
1523+
if (!ASSERT_OK_PTR(tc_skel, "tc_bpf2bpf__open_and_load"))
1524+
goto out;
1525+
1526+
prog_fd = bpf_program__fd(tc_skel->progs.entry_tc);
1527+
freplace_prog = freplace_skel->progs.entry_freplace;
1528+
err = bpf_program__set_attach_target(freplace_prog, prog_fd, "subprog");
1529+
if (!ASSERT_OK(err, "set_attach_target"))
1530+
goto out;
1531+
1532+
err = tailcall_freplace__load(freplace_skel);
1533+
if (!ASSERT_OK(err, "tailcall_freplace__load"))
1534+
goto out;
1535+
1536+
freplace_link = bpf_program__attach_freplace(freplace_prog, prog_fd,
1537+
"subprog");
1538+
if (!ASSERT_OK_PTR(freplace_link, "attach_freplace"))
1539+
goto out;
1540+
1541+
map_fd = bpf_map__fd(freplace_skel->maps.jmp_table);
1542+
prog_fd = bpf_program__fd(freplace_prog);
1543+
key = 0;
1544+
err = bpf_map_update_elem(map_fd, &key, &prog_fd, BPF_ANY);
1545+
if (!ASSERT_OK(err, "update jmp_table"))
1546+
goto out;
1547+
1548+
prog_fd = bpf_program__fd(tc_skel->progs.entry_tc);
1549+
err = bpf_prog_test_run_opts(prog_fd, &topts);
1550+
ASSERT_OK(err, "test_run");
1551+
ASSERT_EQ(topts.retval, 34, "test_run retval");
1552+
1553+
out:
1554+
bpf_link__destroy(freplace_link);
1555+
tc_bpf2bpf__destroy(tc_skel);
1556+
tailcall_freplace__destroy(freplace_skel);
1557+
}
1558+
14981559
void test_tailcalls(void)
14991560
{
15001561
if (test__start_subtest("tailcall_1"))
@@ -1543,4 +1604,6 @@ void test_tailcalls(void)
15431604
test_tailcall_bpf2bpf_hierarchy_fentry_entry();
15441605
test_tailcall_bpf2bpf_hierarchy_2();
15451606
test_tailcall_bpf2bpf_hierarchy_3();
1607+
if (test__start_subtest("tailcall_freplace"))
1608+
test_tailcall_freplace();
15461609
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/bpf.h>
4+
#include <bpf/bpf_helpers.h>
5+
6+
struct {
7+
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
8+
__uint(max_entries, 1);
9+
__uint(key_size, sizeof(__u32));
10+
__uint(value_size, sizeof(__u32));
11+
} jmp_table SEC(".maps");
12+
13+
int count = 0;
14+
15+
SEC("freplace")
16+
int entry_freplace(struct __sk_buff *skb)
17+
{
18+
count++;
19+
bpf_tail_call_static(skb, &jmp_table, 0);
20+
return count;
21+
}
22+
23+
char __license[] SEC("license") = "GPL";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/bpf.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include "bpf_misc.h"
6+
7+
__noinline
8+
int subprog(struct __sk_buff *skb)
9+
{
10+
int ret = 1;
11+
12+
__sink(ret);
13+
return ret;
14+
}
15+
16+
SEC("tc")
17+
int entry_tc(struct __sk_buff *skb)
18+
{
19+
return subprog(skb);
20+
}
21+
22+
char __license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)