Commit 707ee8ac authored by Andrii Nakryiko's avatar Andrii Nakryiko

Merge branch 'migrate from bpf_prog_test_run{,_xattr}'

Delyan Kratunov says:

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

Fairly straight-forward mechanical transformation from bpf_prog_test_run
and bpf_prog_test_run_xattr to the bpf_prog_test_run_opts goodness.

I did a fair amount of drive-by CHECK/CHECK_ATTR cleanups as well, though
certainly not everything possible. Primarily, I did not want to just change
arguments to CHECK calls, though I had to do a bit more than that
in some cases (overall, -119 CHECK calls and all CHECK_ATTR calls).

v2 -> v3:
Don't introduce CHECK_OPTS, replace CHECK/CHECK_ATTR usages we need to touch
with ASSERT_* calls instead.
Don't be prescriptive about the opts var name and keep old names where that would
minimize unnecessary code churn.
Drop _xattr-specific checks in prog_run_xattr and rename accordingly.

v1 -> v2:
Split selftests/bpf changes into two commits to appease the mailing list.
====================
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
parents dd5152ab 3e1ab843
...@@ -1272,12 +1272,12 @@ static int do_run(int argc, char **argv) ...@@ -1272,12 +1272,12 @@ static int do_run(int argc, char **argv)
{ {
char *data_fname_in = NULL, *data_fname_out = NULL; char *data_fname_in = NULL, *data_fname_out = NULL;
char *ctx_fname_in = NULL, *ctx_fname_out = NULL; char *ctx_fname_in = NULL, *ctx_fname_out = NULL;
struct bpf_prog_test_run_attr test_attr = {0};
const unsigned int default_size = SZ_32K; const unsigned int default_size = SZ_32K;
void *data_in = NULL, *data_out = NULL; void *data_in = NULL, *data_out = NULL;
void *ctx_in = NULL, *ctx_out = NULL; void *ctx_in = NULL, *ctx_out = NULL;
unsigned int repeat = 1; unsigned int repeat = 1;
int fd, err; int fd, err;
LIBBPF_OPTS(bpf_test_run_opts, test_attr);
if (!REQ_ARGS(4)) if (!REQ_ARGS(4))
return -1; return -1;
...@@ -1395,14 +1395,13 @@ static int do_run(int argc, char **argv) ...@@ -1395,14 +1395,13 @@ static int do_run(int argc, char **argv)
goto free_ctx_in; goto free_ctx_in;
} }
test_attr.prog_fd = fd;
test_attr.repeat = repeat; test_attr.repeat = repeat;
test_attr.data_in = data_in; test_attr.data_in = data_in;
test_attr.data_out = data_out; test_attr.data_out = data_out;
test_attr.ctx_in = ctx_in; test_attr.ctx_in = ctx_in;
test_attr.ctx_out = ctx_out; test_attr.ctx_out = ctx_out;
err = bpf_prog_test_run_xattr(&test_attr); err = bpf_prog_test_run_opts(fd, &test_attr);
if (err) { if (err) {
p_err("failed to run program: %s", strerror(errno)); p_err("failed to run program: %s", strerror(errno));
goto free_ctx_out; goto free_ctx_out;
......
...@@ -453,12 +453,14 @@ struct bpf_prog_test_run_attr { ...@@ -453,12 +453,14 @@ struct bpf_prog_test_run_attr {
* out: length of cxt_out */ * out: length of cxt_out */
}; };
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_prog_test_run_opts() instead")
LIBBPF_API int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr); LIBBPF_API int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr);
/* /*
* bpf_prog_test_run does not check that data_out is large enough. Consider * bpf_prog_test_run does not check that data_out is large enough. Consider
* using bpf_prog_test_run_xattr instead. * using bpf_prog_test_run_opts instead.
*/ */
LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_prog_test_run_opts() instead")
LIBBPF_API int bpf_prog_test_run(int prog_fd, int repeat, void *data, LIBBPF_API int bpf_prog_test_run(int prog_fd, int repeat, void *data,
__u32 size, void *data_out, __u32 *size_out, __u32 size, void *data_out, __u32 *size_out,
__u32 *retval, __u32 *duration); __u32 *retval, __u32 *duration);
......
...@@ -7,18 +7,18 @@ ...@@ -7,18 +7,18 @@
static void test_add(struct atomics_lskel *skel) static void test_add(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__add__attach(skel); link_fd = atomics_lskel__add__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(add)")) if (!ASSERT_GT(link_fd, 0, "attach(add)"))
return; return;
prog_fd = skel->progs.add.prog_fd; prog_fd = skel->progs.add.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run add", goto cleanup;
"err %d errno %d retval %d duration %d\n", err, errno, retval, duration)) if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->add64_value, 3, "add64_value"); ASSERT_EQ(skel->data->add64_value, 3, "add64_value");
...@@ -39,19 +39,18 @@ static void test_add(struct atomics_lskel *skel) ...@@ -39,19 +39,18 @@ static void test_add(struct atomics_lskel *skel)
static void test_sub(struct atomics_lskel *skel) static void test_sub(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__sub__attach(skel); link_fd = atomics_lskel__sub__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(sub)")) if (!ASSERT_GT(link_fd, 0, "attach(sub)"))
return; return;
prog_fd = skel->progs.sub.prog_fd; prog_fd = skel->progs.sub.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run sub", goto cleanup;
"err %d errno %d retval %d duration %d\n", if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
err, errno, retval, duration))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->sub64_value, -1, "sub64_value"); ASSERT_EQ(skel->data->sub64_value, -1, "sub64_value");
...@@ -72,18 +71,18 @@ static void test_sub(struct atomics_lskel *skel) ...@@ -72,18 +71,18 @@ static void test_sub(struct atomics_lskel *skel)
static void test_and(struct atomics_lskel *skel) static void test_and(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__and__attach(skel); link_fd = atomics_lskel__and__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(and)")) if (!ASSERT_GT(link_fd, 0, "attach(and)"))
return; return;
prog_fd = skel->progs.and.prog_fd; prog_fd = skel->progs.and.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run and", goto cleanup;
"err %d errno %d retval %d duration %d\n", err, errno, retval, duration)) if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->and64_value, 0x010ull << 32, "and64_value"); ASSERT_EQ(skel->data->and64_value, 0x010ull << 32, "and64_value");
...@@ -100,19 +99,18 @@ static void test_and(struct atomics_lskel *skel) ...@@ -100,19 +99,18 @@ static void test_and(struct atomics_lskel *skel)
static void test_or(struct atomics_lskel *skel) static void test_or(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__or__attach(skel); link_fd = atomics_lskel__or__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(or)")) if (!ASSERT_GT(link_fd, 0, "attach(or)"))
return; return;
prog_fd = skel->progs.or.prog_fd; prog_fd = skel->progs.or.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run or", goto cleanup;
"err %d errno %d retval %d duration %d\n", if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
err, errno, retval, duration))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->or64_value, 0x111ull << 32, "or64_value"); ASSERT_EQ(skel->data->or64_value, 0x111ull << 32, "or64_value");
...@@ -129,18 +127,18 @@ static void test_or(struct atomics_lskel *skel) ...@@ -129,18 +127,18 @@ static void test_or(struct atomics_lskel *skel)
static void test_xor(struct atomics_lskel *skel) static void test_xor(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__xor__attach(skel); link_fd = atomics_lskel__xor__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(xor)")) if (!ASSERT_GT(link_fd, 0, "attach(xor)"))
return; return;
prog_fd = skel->progs.xor.prog_fd; prog_fd = skel->progs.xor.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run xor", goto cleanup;
"err %d errno %d retval %d duration %d\n", err, errno, retval, duration)) if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->xor64_value, 0x101ull << 32, "xor64_value"); ASSERT_EQ(skel->data->xor64_value, 0x101ull << 32, "xor64_value");
...@@ -157,18 +155,18 @@ static void test_xor(struct atomics_lskel *skel) ...@@ -157,18 +155,18 @@ static void test_xor(struct atomics_lskel *skel)
static void test_cmpxchg(struct atomics_lskel *skel) static void test_cmpxchg(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__cmpxchg__attach(skel); link_fd = atomics_lskel__cmpxchg__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(cmpxchg)")) if (!ASSERT_GT(link_fd, 0, "attach(cmpxchg)"))
return; return;
prog_fd = skel->progs.cmpxchg.prog_fd; prog_fd = skel->progs.cmpxchg.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run cmpxchg", goto cleanup;
"err %d errno %d retval %d duration %d\n", err, errno, retval, duration)) if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->cmpxchg64_value, 2, "cmpxchg64_value"); ASSERT_EQ(skel->data->cmpxchg64_value, 2, "cmpxchg64_value");
...@@ -186,18 +184,18 @@ static void test_cmpxchg(struct atomics_lskel *skel) ...@@ -186,18 +184,18 @@ static void test_cmpxchg(struct atomics_lskel *skel)
static void test_xchg(struct atomics_lskel *skel) static void test_xchg(struct atomics_lskel *skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
int link_fd; int link_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
link_fd = atomics_lskel__xchg__attach(skel); link_fd = atomics_lskel__xchg__attach(skel);
if (!ASSERT_GT(link_fd, 0, "attach(xchg)")) if (!ASSERT_GT(link_fd, 0, "attach(xchg)"))
return; return;
prog_fd = skel->progs.xchg.prog_fd; prog_fd = skel->progs.xchg.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run_opts err"))
if (CHECK(err || retval, "test_run xchg", goto cleanup;
"err %d errno %d retval %d duration %d\n", err, errno, retval, duration)) if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
goto cleanup; goto cleanup;
ASSERT_EQ(skel->data->xchg64_value, 2, "xchg64_value"); ASSERT_EQ(skel->data->xchg64_value, 2, "xchg64_value");
......
...@@ -11,7 +11,12 @@ enum { ...@@ -11,7 +11,12 @@ enum {
void test_bpf_nf_ct(int mode) void test_bpf_nf_ct(int mode)
{ {
struct test_bpf_nf *skel; struct test_bpf_nf *skel;
int prog_fd, err, retval; int prog_fd, err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = test_bpf_nf__open_and_load(); skel = test_bpf_nf__open_and_load();
if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load")) if (!ASSERT_OK_PTR(skel, "test_bpf_nf__open_and_load"))
...@@ -22,8 +27,7 @@ void test_bpf_nf_ct(int mode) ...@@ -22,8 +27,7 @@ void test_bpf_nf_ct(int mode)
else else
prog_fd = bpf_program__fd(skel->progs.nf_skb_ct_test); prog_fd = bpf_program__fd(skel->progs.nf_skb_ct_test);
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), NULL, NULL, err = bpf_prog_test_run_opts(prog_fd, &topts);
(__u32 *)&retval, NULL);
if (!ASSERT_OK(err, "bpf_prog_test_run")) if (!ASSERT_OK(err, "bpf_prog_test_run"))
goto end; goto end;
......
...@@ -79,28 +79,21 @@ static void test_check_mtu_run_xdp(struct test_check_mtu *skel, ...@@ -79,28 +79,21 @@ static void test_check_mtu_run_xdp(struct test_check_mtu *skel,
struct bpf_program *prog, struct bpf_program *prog,
__u32 mtu_expect) __u32 mtu_expect)
{ {
const char *prog_name = bpf_program__name(prog);
int retval_expect = XDP_PASS; int retval_expect = XDP_PASS;
__u32 mtu_result = 0; __u32 mtu_result = 0;
char buf[256] = {}; char buf[256] = {};
int err; int err, prog_fd = bpf_program__fd(prog);
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.repeat = 1, .repeat = 1,
.data_in = &pkt_v4, .data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4), .data_size_in = sizeof(pkt_v4),
.data_out = buf, .data_out = buf,
.data_size_out = sizeof(buf), .data_size_out = sizeof(buf),
.prog_fd = bpf_program__fd(prog), );
};
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err != 0, "bpf_prog_test_run",
"prog_name:%s (err %d errno %d retval %d)\n",
prog_name, err, errno, tattr.retval);
CHECK(tattr.retval != retval_expect, "retval", err = bpf_prog_test_run_opts(prog_fd, &topts);
"progname:%s unexpected retval=%d expected=%d\n", ASSERT_OK(err, "test_run");
prog_name, tattr.retval, retval_expect); ASSERT_EQ(topts.retval, retval_expect, "retval");
/* Extract MTU that BPF-prog got */ /* Extract MTU that BPF-prog got */
mtu_result = skel->bss->global_bpf_mtu_xdp; mtu_result = skel->bss->global_bpf_mtu_xdp;
...@@ -139,28 +132,21 @@ static void test_check_mtu_run_tc(struct test_check_mtu *skel, ...@@ -139,28 +132,21 @@ static void test_check_mtu_run_tc(struct test_check_mtu *skel,
struct bpf_program *prog, struct bpf_program *prog,
__u32 mtu_expect) __u32 mtu_expect)
{ {
const char *prog_name = bpf_program__name(prog);
int retval_expect = BPF_OK; int retval_expect = BPF_OK;
__u32 mtu_result = 0; __u32 mtu_result = 0;
char buf[256] = {}; char buf[256] = {};
int err; int err, prog_fd = bpf_program__fd(prog);
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.repeat = 1,
.data_in = &pkt_v4, .data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4), .data_size_in = sizeof(pkt_v4),
.data_out = buf, .data_out = buf,
.data_size_out = sizeof(buf), .data_size_out = sizeof(buf),
.prog_fd = bpf_program__fd(prog), .repeat = 1,
}; );
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err != 0, "bpf_prog_test_run",
"prog_name:%s (err %d errno %d retval %d)\n",
prog_name, err, errno, tattr.retval);
CHECK(tattr.retval != retval_expect, "retval", err = bpf_prog_test_run_opts(prog_fd, &topts);
"progname:%s unexpected retval=%d expected=%d\n", ASSERT_OK(err, "test_run");
prog_name, tattr.retval, retval_expect); ASSERT_EQ(topts.retval, retval_expect, "retval");
/* Extract MTU that BPF-prog got */ /* Extract MTU that BPF-prog got */
mtu_result = skel->bss->global_bpf_mtu_tc; mtu_result = skel->bss->global_bpf_mtu_tc;
......
...@@ -161,7 +161,7 @@ static socklen_t prepare_addr(struct sockaddr_storage *addr, int family) ...@@ -161,7 +161,7 @@ static socklen_t prepare_addr(struct sockaddr_storage *addr, int family)
} }
} }
static bool was_decapsulated(struct bpf_prog_test_run_attr *tattr) static bool was_decapsulated(struct bpf_test_run_opts *tattr)
{ {
return tattr->data_size_out < tattr->data_size_in; return tattr->data_size_out < tattr->data_size_in;
} }
...@@ -367,12 +367,12 @@ static void close_fds(int *fds, int n) ...@@ -367,12 +367,12 @@ static void close_fds(int *fds, int n)
static void test_cls_redirect_common(struct bpf_program *prog) static void test_cls_redirect_common(struct bpf_program *prog)
{ {
struct bpf_prog_test_run_attr tattr = {}; LIBBPF_OPTS(bpf_test_run_opts, tattr);
int families[] = { AF_INET, AF_INET6 }; int families[] = { AF_INET, AF_INET6 };
struct sockaddr_storage ss; struct sockaddr_storage ss;
struct sockaddr *addr; struct sockaddr *addr;
socklen_t slen; socklen_t slen;
int i, j, err; int i, j, err, prog_fd;
int servers[__NR_KIND][ARRAY_SIZE(families)] = {}; int servers[__NR_KIND][ARRAY_SIZE(families)] = {};
int conns[__NR_KIND][ARRAY_SIZE(families)] = {}; int conns[__NR_KIND][ARRAY_SIZE(families)] = {};
struct tuple tuples[__NR_KIND][ARRAY_SIZE(families)]; struct tuple tuples[__NR_KIND][ARRAY_SIZE(families)];
...@@ -394,7 +394,7 @@ static void test_cls_redirect_common(struct bpf_program *prog) ...@@ -394,7 +394,7 @@ static void test_cls_redirect_common(struct bpf_program *prog)
goto cleanup; goto cleanup;
} }
tattr.prog_fd = bpf_program__fd(prog); prog_fd = bpf_program__fd(prog);
for (i = 0; i < ARRAY_SIZE(tests); i++) { for (i = 0; i < ARRAY_SIZE(tests); i++) {
struct test_cfg *test = &tests[i]; struct test_cfg *test = &tests[i];
...@@ -415,7 +415,7 @@ static void test_cls_redirect_common(struct bpf_program *prog) ...@@ -415,7 +415,7 @@ static void test_cls_redirect_common(struct bpf_program *prog)
if (CHECK_FAIL(!tattr.data_size_in)) if (CHECK_FAIL(!tattr.data_size_in))
continue; continue;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
continue; continue;
......
...@@ -26,10 +26,10 @@ static void test_dummy_st_ops_attach(void) ...@@ -26,10 +26,10 @@ static void test_dummy_st_ops_attach(void)
static void test_dummy_init_ret_value(void) static void test_dummy_init_ret_value(void)
{ {
__u64 args[1] = {0}; __u64 args[1] = {0};
struct bpf_prog_test_run_attr attr = { LIBBPF_OPTS(bpf_test_run_opts, attr,
.ctx_size_in = sizeof(args),
.ctx_in = args, .ctx_in = args,
}; .ctx_size_in = sizeof(args),
);
struct dummy_st_ops *skel; struct dummy_st_ops *skel;
int fd, err; int fd, err;
...@@ -38,8 +38,7 @@ static void test_dummy_init_ret_value(void) ...@@ -38,8 +38,7 @@ static void test_dummy_init_ret_value(void)
return; return;
fd = bpf_program__fd(skel->progs.test_1); fd = bpf_program__fd(skel->progs.test_1);
attr.prog_fd = fd; err = bpf_prog_test_run_opts(fd, &attr);
err = bpf_prog_test_run_xattr(&attr);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(attr.retval, 0xf2f3f4f5, "test_ret"); ASSERT_EQ(attr.retval, 0xf2f3f4f5, "test_ret");
...@@ -53,10 +52,10 @@ static void test_dummy_init_ptr_arg(void) ...@@ -53,10 +52,10 @@ static void test_dummy_init_ptr_arg(void)
.val = exp_retval, .val = exp_retval,
}; };
__u64 args[1] = {(unsigned long)&in_state}; __u64 args[1] = {(unsigned long)&in_state};
struct bpf_prog_test_run_attr attr = { LIBBPF_OPTS(bpf_test_run_opts, attr,
.ctx_size_in = sizeof(args),
.ctx_in = args, .ctx_in = args,
}; .ctx_size_in = sizeof(args),
);
struct dummy_st_ops *skel; struct dummy_st_ops *skel;
int fd, err; int fd, err;
...@@ -65,8 +64,7 @@ static void test_dummy_init_ptr_arg(void) ...@@ -65,8 +64,7 @@ static void test_dummy_init_ptr_arg(void)
return; return;
fd = bpf_program__fd(skel->progs.test_1); fd = bpf_program__fd(skel->progs.test_1);
attr.prog_fd = fd; err = bpf_prog_test_run_opts(fd, &attr);
err = bpf_prog_test_run_xattr(&attr);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(in_state.val, 0x5a, "test_ptr_ret"); ASSERT_EQ(in_state.val, 0x5a, "test_ptr_ret");
ASSERT_EQ(attr.retval, exp_retval, "test_ret"); ASSERT_EQ(attr.retval, exp_retval, "test_ret");
...@@ -77,10 +75,10 @@ static void test_dummy_init_ptr_arg(void) ...@@ -77,10 +75,10 @@ static void test_dummy_init_ptr_arg(void)
static void test_dummy_multiple_args(void) static void test_dummy_multiple_args(void)
{ {
__u64 args[5] = {0, -100, 0x8a5f, 'c', 0x1234567887654321ULL}; __u64 args[5] = {0, -100, 0x8a5f, 'c', 0x1234567887654321ULL};
struct bpf_prog_test_run_attr attr = { LIBBPF_OPTS(bpf_test_run_opts, attr,
.ctx_size_in = sizeof(args),
.ctx_in = args, .ctx_in = args,
}; .ctx_size_in = sizeof(args),
);
struct dummy_st_ops *skel; struct dummy_st_ops *skel;
int fd, err; int fd, err;
size_t i; size_t i;
...@@ -91,8 +89,7 @@ static void test_dummy_multiple_args(void) ...@@ -91,8 +89,7 @@ static void test_dummy_multiple_args(void)
return; return;
fd = bpf_program__fd(skel->progs.test_2); fd = bpf_program__fd(skel->progs.test_2);
attr.prog_fd = fd; err = bpf_prog_test_run_opts(fd, &attr);
err = bpf_prog_test_run_xattr(&attr);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
for (i = 0; i < ARRAY_SIZE(args); i++) { for (i = 0; i < ARRAY_SIZE(args); i++) {
snprintf(name, sizeof(name), "arg %zu", i); snprintf(name, sizeof(name), "arg %zu", i);
......
...@@ -9,38 +9,34 @@ void test_fentry_fexit(void) ...@@ -9,38 +9,34 @@ void test_fentry_fexit(void)
struct fentry_test_lskel *fentry_skel = NULL; struct fentry_test_lskel *fentry_skel = NULL;
struct fexit_test_lskel *fexit_skel = NULL; struct fexit_test_lskel *fexit_skel = NULL;
__u64 *fentry_res, *fexit_res; __u64 *fentry_res, *fexit_res;
__u32 duration = 0, retval;
int err, prog_fd, i; int err, prog_fd, i;
LIBBPF_OPTS(bpf_test_run_opts, topts);
fentry_skel = fentry_test_lskel__open_and_load(); fentry_skel = fentry_test_lskel__open_and_load();
if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) if (!ASSERT_OK_PTR(fentry_skel, "fentry_skel_load"))
goto close_prog; goto close_prog;
fexit_skel = fexit_test_lskel__open_and_load(); fexit_skel = fexit_test_lskel__open_and_load();
if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) if (!ASSERT_OK_PTR(fexit_skel, "fexit_skel_load"))
goto close_prog; goto close_prog;
err = fentry_test_lskel__attach(fentry_skel); err = fentry_test_lskel__attach(fentry_skel);
if (CHECK(err, "fentry_attach", "fentry attach failed: %d\n", err)) if (!ASSERT_OK(err, "fentry_attach"))
goto close_prog; goto close_prog;
err = fexit_test_lskel__attach(fexit_skel); err = fexit_test_lskel__attach(fexit_skel);
if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) if (!ASSERT_OK(err, "fexit_attach"))
goto close_prog; goto close_prog;
prog_fd = fexit_skel->progs.test1.prog_fd; prog_fd = fexit_skel->progs.test1.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "ipv6 test_run");
CHECK(err || retval, "ipv6", ASSERT_OK(topts.retval, "ipv6 test retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
fentry_res = (__u64 *)fentry_skel->bss; fentry_res = (__u64 *)fentry_skel->bss;
fexit_res = (__u64 *)fexit_skel->bss; fexit_res = (__u64 *)fexit_skel->bss;
printf("%lld\n", fentry_skel->bss->test1_result); printf("%lld\n", fentry_skel->bss->test1_result);
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
CHECK(fentry_res[i] != 1, "result", ASSERT_EQ(fentry_res[i], 1, "fentry result");
"fentry_test%d failed err %lld\n", i + 1, fentry_res[i]); ASSERT_EQ(fexit_res[i], 1, "fexit result");
CHECK(fexit_res[i] != 1, "result",
"fexit_test%d failed err %lld\n", i + 1, fexit_res[i]);
} }
close_prog: close_prog:
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
static int fentry_test(struct fentry_test_lskel *fentry_skel) static int fentry_test(struct fentry_test_lskel *fentry_skel)
{ {
int err, prog_fd, i; int err, prog_fd, i;
__u32 duration = 0, retval;
int link_fd; int link_fd;
__u64 *result; __u64 *result;
LIBBPF_OPTS(bpf_test_run_opts, topts);
err = fentry_test_lskel__attach(fentry_skel); err = fentry_test_lskel__attach(fentry_skel);
if (!ASSERT_OK(err, "fentry_attach")) if (!ASSERT_OK(err, "fentry_attach"))
...@@ -20,10 +20,9 @@ static int fentry_test(struct fentry_test_lskel *fentry_skel) ...@@ -20,10 +20,9 @@ static int fentry_test(struct fentry_test_lskel *fentry_skel)
return -1; return -1;
prog_fd = fentry_skel->progs.test1.prog_fd; prog_fd = fentry_skel->progs.test1.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
result = (__u64 *)fentry_skel->bss; result = (__u64 *)fentry_skel->bss;
for (i = 0; i < sizeof(*fentry_skel->bss) / sizeof(__u64); i++) { for (i = 0; i < sizeof(*fentry_skel->bss) / sizeof(__u64); i++) {
......
...@@ -58,12 +58,17 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, ...@@ -58,12 +58,17 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
test_cb cb) test_cb cb)
{ {
struct bpf_object *obj = NULL, *tgt_obj; struct bpf_object *obj = NULL, *tgt_obj;
__u32 retval, tgt_prog_id, info_len; __u32 tgt_prog_id, info_len;
struct bpf_prog_info prog_info = {}; struct bpf_prog_info prog_info = {};
struct bpf_program **prog = NULL, *p; struct bpf_program **prog = NULL, *p;
struct bpf_link **link = NULL; struct bpf_link **link = NULL;
int err, tgt_fd, i; int err, tgt_fd, i;
struct btf *btf; struct btf *btf;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v6,
.data_size_in = sizeof(pkt_v6),
.repeat = 1,
);
err = bpf_prog_test_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, err = bpf_prog_test_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
&tgt_obj, &tgt_fd); &tgt_obj, &tgt_fd);
...@@ -147,10 +152,9 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, ...@@ -147,10 +152,9 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
if (!run_prog) if (!run_prog)
goto close_prog; goto close_prog;
err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), err = bpf_prog_test_run_opts(tgt_fd, &topts);
NULL, NULL, &retval, NULL);
ASSERT_OK(err, "prog_run"); ASSERT_OK(err, "prog_run");
ASSERT_EQ(retval, 0, "prog_run_ret"); ASSERT_EQ(topts.retval, 0, "prog_run_ret");
if (check_data_map(obj, prog_cnt, false)) if (check_data_map(obj, prog_cnt, false))
goto close_prog; goto close_prog;
...@@ -225,29 +229,31 @@ static int test_second_attach(struct bpf_object *obj) ...@@ -225,29 +229,31 @@ static int test_second_attach(struct bpf_object *obj)
const char *tgt_obj_file = "./test_pkt_access.o"; const char *tgt_obj_file = "./test_pkt_access.o";
struct bpf_program *prog = NULL; struct bpf_program *prog = NULL;
struct bpf_object *tgt_obj; struct bpf_object *tgt_obj;
__u32 duration = 0, retval;
struct bpf_link *link; struct bpf_link *link;
int err = 0, tgt_fd; int err = 0, tgt_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v6,
.data_size_in = sizeof(pkt_v6),
.repeat = 1,
);
prog = bpf_object__find_program_by_name(obj, prog_name); prog = bpf_object__find_program_by_name(obj, prog_name);
if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name)) if (!ASSERT_OK_PTR(prog, "find_prog"))
return -ENOENT; return -ENOENT;
err = bpf_prog_test_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC, err = bpf_prog_test_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC,
&tgt_obj, &tgt_fd); &tgt_obj, &tgt_fd);
if (CHECK(err, "second_prog_load", "file %s err %d errno %d\n", if (!ASSERT_OK(err, "second_prog_load"))
tgt_obj_file, err, errno))
return err; return err;
link = bpf_program__attach_freplace(prog, tgt_fd, tgt_name); link = bpf_program__attach_freplace(prog, tgt_fd, tgt_name);
if (!ASSERT_OK_PTR(link, "second_link")) if (!ASSERT_OK_PTR(link, "second_link"))
goto out; goto out;
err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), err = bpf_prog_test_run_opts(tgt_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "ipv6 test_run"))
if (CHECK(err || retval, "ipv6", goto out;
"err %d errno %d retval %d duration %d\n", if (!ASSERT_OK(topts.retval, "ipv6 retval"))
err, errno, retval, duration))
goto out; goto out;
err = check_data_map(obj, 1, true); err = check_data_map(obj, 1, true);
......
...@@ -10,9 +10,7 @@ void test_fexit_stress(void) ...@@ -10,9 +10,7 @@ void test_fexit_stress(void)
char test_skb[128] = {}; char test_skb[128] = {};
int fexit_fd[CNT] = {}; int fexit_fd[CNT] = {};
int link_fd[CNT] = {}; int link_fd[CNT] = {};
__u32 duration = 0;
char error[4096]; char error[4096];
__u32 prog_ret;
int err, i, filter_fd; int err, i, filter_fd;
const struct bpf_insn trace_program[] = { const struct bpf_insn trace_program[] = {
...@@ -36,9 +34,15 @@ void test_fexit_stress(void) ...@@ -36,9 +34,15 @@ void test_fexit_stress(void)
.log_size = sizeof(error), .log_size = sizeof(error),
); );
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = test_skb,
.data_size_in = sizeof(test_skb),
.repeat = 1,
);
err = libbpf_find_vmlinux_btf_id("bpf_fentry_test1", err = libbpf_find_vmlinux_btf_id("bpf_fentry_test1",
trace_opts.expected_attach_type); trace_opts.expected_attach_type);
if (CHECK(err <= 0, "find_vmlinux_btf_id", "failed: %d\n", err)) if (!ASSERT_GT(err, 0, "find_vmlinux_btf_id"))
goto out; goto out;
trace_opts.attach_btf_id = err; trace_opts.attach_btf_id = err;
...@@ -47,24 +51,20 @@ void test_fexit_stress(void) ...@@ -47,24 +51,20 @@ void test_fexit_stress(void)
trace_program, trace_program,
sizeof(trace_program) / sizeof(struct bpf_insn), sizeof(trace_program) / sizeof(struct bpf_insn),
&trace_opts); &trace_opts);
if (CHECK(fexit_fd[i] < 0, "fexit loaded", if (!ASSERT_GE(fexit_fd[i], 0, "fexit load"))
"failed: %d errno %d\n", fexit_fd[i], errno))
goto out; goto out;
link_fd[i] = bpf_raw_tracepoint_open(NULL, fexit_fd[i]); link_fd[i] = bpf_raw_tracepoint_open(NULL, fexit_fd[i]);
if (CHECK(link_fd[i] < 0, "fexit attach failed", if (!ASSERT_GE(link_fd[i], 0, "fexit attach"))
"prog %d failed: %d err %d\n", i, link_fd[i], errno))
goto out; goto out;
} }
filter_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", filter_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
skb_program, sizeof(skb_program) / sizeof(struct bpf_insn), skb_program, sizeof(skb_program) / sizeof(struct bpf_insn),
&skb_opts); &skb_opts);
if (CHECK(filter_fd < 0, "test_program_loaded", "failed: %d errno %d\n", if (!ASSERT_GE(filter_fd, 0, "test_program_loaded"))
filter_fd, errno))
goto out; goto out;
err = bpf_prog_test_run(filter_fd, 1, test_skb, sizeof(test_skb), 0, err = bpf_prog_test_run_opts(filter_fd, &topts);
0, &prog_ret, 0);
close(filter_fd); close(filter_fd);
CHECK_FAIL(err); CHECK_FAIL(err);
out: out:
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
static int fexit_test(struct fexit_test_lskel *fexit_skel) static int fexit_test(struct fexit_test_lskel *fexit_skel)
{ {
int err, prog_fd, i; int err, prog_fd, i;
__u32 duration = 0, retval;
int link_fd; int link_fd;
__u64 *result; __u64 *result;
LIBBPF_OPTS(bpf_test_run_opts, topts);
err = fexit_test_lskel__attach(fexit_skel); err = fexit_test_lskel__attach(fexit_skel);
if (!ASSERT_OK(err, "fexit_attach")) if (!ASSERT_OK(err, "fexit_attach"))
...@@ -20,10 +20,9 @@ static int fexit_test(struct fexit_test_lskel *fexit_skel) ...@@ -20,10 +20,9 @@ static int fexit_test(struct fexit_test_lskel *fexit_skel)
return -1; return -1;
prog_fd = fexit_skel->progs.test1.prog_fd; prog_fd = fexit_skel->progs.test1.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
result = (__u64 *)fexit_skel->bss; result = (__u64 *)fexit_skel->bss;
for (i = 0; i < sizeof(*fexit_skel->bss) / sizeof(__u64); i++) { for (i = 0; i < sizeof(*fexit_skel->bss) / sizeof(__u64); i++) {
......
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
#endif #endif
#define CHECK_FLOW_KEYS(desc, got, expected) \ #define CHECK_FLOW_KEYS(desc, got, expected) \
CHECK_ATTR(memcmp(&got, &expected, sizeof(got)) != 0, \ _CHECK(memcmp(&got, &expected, sizeof(got)) != 0, \
desc, \ desc, \
topts.duration, \
"nhoff=%u/%u " \ "nhoff=%u/%u " \
"thoff=%u/%u " \ "thoff=%u/%u " \
"addr_proto=0x%x/0x%x " \ "addr_proto=0x%x/0x%x " \
...@@ -487,7 +488,7 @@ static void run_tests_skb_less(int tap_fd, struct bpf_map *keys) ...@@ -487,7 +488,7 @@ static void run_tests_skb_less(int tap_fd, struct bpf_map *keys)
/* Keep in sync with 'flags' from eth_get_headlen. */ /* Keep in sync with 'flags' from eth_get_headlen. */
__u32 eth_get_headlen_flags = __u32 eth_get_headlen_flags =
BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG; BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG;
struct bpf_prog_test_run_attr tattr = {}; LIBBPF_OPTS(bpf_test_run_opts, topts);
struct bpf_flow_keys flow_keys = {}; struct bpf_flow_keys flow_keys = {};
__u32 key = (__u32)(tests[i].keys.sport) << 16 | __u32 key = (__u32)(tests[i].keys.sport) << 16 |
tests[i].keys.dport; tests[i].keys.dport;
...@@ -503,13 +504,12 @@ static void run_tests_skb_less(int tap_fd, struct bpf_map *keys) ...@@ -503,13 +504,12 @@ static void run_tests_skb_less(int tap_fd, struct bpf_map *keys)
CHECK(err < 0, "tx_tap", "err %d errno %d\n", err, errno); CHECK(err < 0, "tx_tap", "err %d errno %d\n", err, errno);
err = bpf_map_lookup_elem(keys_fd, &key, &flow_keys); err = bpf_map_lookup_elem(keys_fd, &key, &flow_keys);
CHECK_ATTR(err, tests[i].name, "bpf_map_lookup_elem %d\n", err); ASSERT_OK(err, "bpf_map_lookup_elem");
CHECK_ATTR(err, tests[i].name, "skb-less err %d\n", err);
CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys); CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys);
err = bpf_map_delete_elem(keys_fd, &key); err = bpf_map_delete_elem(keys_fd, &key);
CHECK_ATTR(err, tests[i].name, "bpf_map_delete_elem %d\n", err); ASSERT_OK(err, "bpf_map_delete_elem");
} }
} }
...@@ -573,27 +573,24 @@ void test_flow_dissector(void) ...@@ -573,27 +573,24 @@ void test_flow_dissector(void)
for (i = 0; i < ARRAY_SIZE(tests); i++) { for (i = 0; i < ARRAY_SIZE(tests); i++) {
struct bpf_flow_keys flow_keys; struct bpf_flow_keys flow_keys;
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.prog_fd = prog_fd,
.data_in = &tests[i].pkt, .data_in = &tests[i].pkt,
.data_size_in = sizeof(tests[i].pkt), .data_size_in = sizeof(tests[i].pkt),
.data_out = &flow_keys, .data_out = &flow_keys,
}; );
static struct bpf_flow_keys ctx = {}; static struct bpf_flow_keys ctx = {};
if (tests[i].flags) { if (tests[i].flags) {
tattr.ctx_in = &ctx; topts.ctx_in = &ctx;
tattr.ctx_size_in = sizeof(ctx); topts.ctx_size_in = sizeof(ctx);
ctx.flags = tests[i].flags; ctx.flags = tests[i].flags;
} }
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &topts);
CHECK_ATTR(tattr.data_size_out != sizeof(flow_keys) || ASSERT_OK(err, "test_run");
err || tattr.retval != 1, ASSERT_EQ(topts.retval, 1, "test_run retval");
tests[i].name, ASSERT_EQ(topts.data_size_out, sizeof(flow_keys),
"err %d errno %d retval %d duration %d size %u/%zu\n", "test_run data_size_out");
err, errno, tattr.retval, tattr.duration,
tattr.data_size_out, sizeof(flow_keys));
CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys); CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys);
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
void serial_test_flow_dissector_load_bytes(void) void serial_test_flow_dissector_load_bytes(void)
{ {
struct bpf_flow_keys flow_keys; struct bpf_flow_keys flow_keys;
__u32 duration = 0, retval, size;
struct bpf_insn prog[] = { struct bpf_insn prog[] = {
// BPF_REG_1 - 1st argument: context // BPF_REG_1 - 1st argument: context
// BPF_REG_2 - 2nd argument: offset, start at first byte // BPF_REG_2 - 2nd argument: offset, start at first byte
...@@ -27,22 +26,25 @@ void serial_test_flow_dissector_load_bytes(void) ...@@ -27,22 +26,25 @@ void serial_test_flow_dissector_load_bytes(void)
BPF_EXIT_INSN(), BPF_EXIT_INSN(),
}; };
int fd, err; int fd, err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = &flow_keys,
.data_size_out = sizeof(flow_keys),
.repeat = 1,
);
/* make sure bpf_skb_load_bytes is not allowed from skb-less context /* make sure bpf_skb_load_bytes is not allowed from skb-less context
*/ */
fd = bpf_test_load_program(BPF_PROG_TYPE_FLOW_DISSECTOR, prog, fd = bpf_test_load_program(BPF_PROG_TYPE_FLOW_DISSECTOR, prog,
ARRAY_SIZE(prog), "GPL", 0, NULL, 0); ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
CHECK(fd < 0, ASSERT_GE(fd, 0, "bpf_test_load_program good fd");
"flow_dissector-bpf_skb_load_bytes-load",
"fd %d errno %d\n",
fd, errno);
err = bpf_prog_test_run(fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(fd, &topts);
&flow_keys, &size, &retval, &duration); ASSERT_OK(err, "test_run");
CHECK(size != sizeof(flow_keys) || err || retval != 1, ASSERT_EQ(topts.data_size_out, sizeof(flow_keys),
"flow_dissector-bpf_skb_load_bytes", "test_run data_size_out");
"err %d errno %d retval %d duration %d size %u/%zu\n", ASSERT_EQ(topts.retval, 1, "test_run retval");
err, errno, retval, duration, size, sizeof(flow_keys));
if (fd >= -1) if (fd >= -1)
close(fd); close(fd);
......
...@@ -12,8 +12,13 @@ static void test_hash_map(void) ...@@ -12,8 +12,13 @@ static void test_hash_map(void)
int i, err, hashmap_fd, max_entries, percpu_map_fd; int i, err, hashmap_fd, max_entries, percpu_map_fd;
struct for_each_hash_map_elem *skel; struct for_each_hash_map_elem *skel;
__u64 *percpu_valbuf = NULL; __u64 *percpu_valbuf = NULL;
__u32 key, num_cpus, retval; __u32 key, num_cpus;
__u64 val; __u64 val;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = for_each_hash_map_elem__open_and_load(); skel = for_each_hash_map_elem__open_and_load();
if (!ASSERT_OK_PTR(skel, "for_each_hash_map_elem__open_and_load")) if (!ASSERT_OK_PTR(skel, "for_each_hash_map_elem__open_and_load"))
...@@ -42,11 +47,10 @@ static void test_hash_map(void) ...@@ -42,11 +47,10 @@ static void test_hash_map(void)
if (!ASSERT_OK(err, "percpu_map_update")) if (!ASSERT_OK(err, "percpu_map_update"))
goto out; goto out;
err = bpf_prog_test_run(bpf_program__fd(skel->progs.test_pkt_access), err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_pkt_access), &topts);
1, &pkt_v4, sizeof(pkt_v4), NULL, NULL, duration = topts.duration;
&retval, &duration); if (CHECK(err || topts.retval, "ipv4", "err %d errno %d retval %d\n",
if (CHECK(err || retval, "ipv4", "err %d errno %d retval %d\n", err, errno, topts.retval))
err, errno, retval))
goto out; goto out;
ASSERT_EQ(skel->bss->hashmap_output, 4, "hashmap_output"); ASSERT_EQ(skel->bss->hashmap_output, 4, "hashmap_output");
...@@ -69,11 +73,16 @@ static void test_hash_map(void) ...@@ -69,11 +73,16 @@ static void test_hash_map(void)
static void test_array_map(void) static void test_array_map(void)
{ {
__u32 key, num_cpus, max_entries, retval; __u32 key, num_cpus, max_entries;
int i, arraymap_fd, percpu_map_fd, err; int i, arraymap_fd, percpu_map_fd, err;
struct for_each_array_map_elem *skel; struct for_each_array_map_elem *skel;
__u64 *percpu_valbuf = NULL; __u64 *percpu_valbuf = NULL;
__u64 val, expected_total; __u64 val, expected_total;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = for_each_array_map_elem__open_and_load(); skel = for_each_array_map_elem__open_and_load();
if (!ASSERT_OK_PTR(skel, "for_each_array_map_elem__open_and_load")) if (!ASSERT_OK_PTR(skel, "for_each_array_map_elem__open_and_load"))
...@@ -106,11 +115,10 @@ static void test_array_map(void) ...@@ -106,11 +115,10 @@ static void test_array_map(void)
if (!ASSERT_OK(err, "percpu_map_update")) if (!ASSERT_OK(err, "percpu_map_update"))
goto out; goto out;
err = bpf_prog_test_run(bpf_program__fd(skel->progs.test_pkt_access), err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_pkt_access), &topts);
1, &pkt_v4, sizeof(pkt_v4), NULL, NULL, duration = topts.duration;
&retval, &duration); if (CHECK(err || topts.retval, "ipv4", "err %d errno %d retval %d\n",
if (CHECK(err || retval, "ipv4", "err %d errno %d retval %d\n", err, errno, topts.retval))
err, errno, retval))
goto out; goto out;
ASSERT_EQ(skel->bss->arraymap_output, expected_total, "array_output"); ASSERT_EQ(skel->bss->arraymap_output, expected_total, "array_output");
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
void test_get_func_args_test(void) void test_get_func_args_test(void)
{ {
struct get_func_args_test *skel = NULL; struct get_func_args_test *skel = NULL;
__u32 duration = 0, retval;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
skel = get_func_args_test__open_and_load(); skel = get_func_args_test__open_and_load();
if (!ASSERT_OK_PTR(skel, "get_func_args_test__open_and_load")) if (!ASSERT_OK_PTR(skel, "get_func_args_test__open_and_load"))
...@@ -20,19 +20,17 @@ void test_get_func_args_test(void) ...@@ -20,19 +20,17 @@ void test_get_func_args_test(void)
* fentry/fexit programs. * fentry/fexit programs.
*/ */
prog_fd = bpf_program__fd(skel->progs.test1); prog_fd = bpf_program__fd(skel->progs.test1);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
/* This runs bpf_modify_return_test function and triggers /* This runs bpf_modify_return_test function and triggers
* fmod_ret_test and fexit_test programs. * fmod_ret_test and fexit_test programs.
*/ */
prog_fd = bpf_program__fd(skel->progs.fmod_ret_test); prog_fd = bpf_program__fd(skel->progs.fmod_ret_test);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 1234, "test_run"); ASSERT_EQ(topts.retval, 1234, "test_run");
ASSERT_EQ(skel->bss->test1_result, 1, "test1_result"); ASSERT_EQ(skel->bss->test1_result, 1, "test1_result");
ASSERT_EQ(skel->bss->test2_result, 1, "test2_result"); ASSERT_EQ(skel->bss->test2_result, 1, "test2_result");
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
void test_get_func_ip_test(void) void test_get_func_ip_test(void)
{ {
struct get_func_ip_test *skel = NULL; struct get_func_ip_test *skel = NULL;
__u32 duration = 0, retval;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts);
skel = get_func_ip_test__open(); skel = get_func_ip_test__open();
if (!ASSERT_OK_PTR(skel, "get_func_ip_test__open")) if (!ASSERT_OK_PTR(skel, "get_func_ip_test__open"))
...@@ -29,14 +29,12 @@ void test_get_func_ip_test(void) ...@@ -29,14 +29,12 @@ void test_get_func_ip_test(void)
goto cleanup; goto cleanup;
prog_fd = bpf_program__fd(skel->progs.test1); prog_fd = bpf_program__fd(skel->progs.test1);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
prog_fd = bpf_program__fd(skel->progs.test5); prog_fd = bpf_program__fd(skel->progs.test5);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
......
...@@ -132,24 +132,26 @@ static void test_global_data_rdonly(struct bpf_object *obj, __u32 duration) ...@@ -132,24 +132,26 @@ static void test_global_data_rdonly(struct bpf_object *obj, __u32 duration)
void test_global_data(void) void test_global_data(void)
{ {
const char *file = "./test_global_data.o"; const char *file = "./test_global_data.o";
__u32 duration = 0, retval;
struct bpf_object *obj; struct bpf_object *obj;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
if (CHECK(err, "load program", "error %d loading %s\n", err, file)) if (!ASSERT_OK(err, "load program"))
return; return;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "pass global data run err");
CHECK(err || retval, "pass global data run", ASSERT_OK(topts.retval, "pass global data run retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
test_global_data_number(obj, duration); test_global_data_number(obj, topts.duration);
test_global_data_string(obj, duration); test_global_data_string(obj, topts.duration);
test_global_data_struct(obj, duration); test_global_data_struct(obj, topts.duration);
test_global_data_rdonly(obj, duration); test_global_data_rdonly(obj, topts.duration);
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -40,19 +40,21 @@ static void test_global_func_args0(struct bpf_object *obj) ...@@ -40,19 +40,21 @@ static void test_global_func_args0(struct bpf_object *obj)
void test_global_func_args(void) void test_global_func_args(void)
{ {
const char *file = "./test_global_func_args.o"; const char *file = "./test_global_func_args.o";
__u32 retval;
struct bpf_object *obj; struct bpf_object *obj;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd);
if (CHECK(err, "load program", "error %d loading %s\n", err, file)) if (CHECK(err, "load program", "error %d loading %s\n", err, file))
return; return;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "test_run");
CHECK(err || retval, "pass global func args run", ASSERT_OK(topts.retval, "test_run retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
test_global_func_args0(obj); test_global_func_args0(obj);
......
...@@ -53,24 +53,24 @@ static void on_sample(void *ctx, int cpu, void *data, __u32 size) ...@@ -53,24 +53,24 @@ static void on_sample(void *ctx, int cpu, void *data, __u32 size)
void serial_test_kfree_skb(void) void serial_test_kfree_skb(void)
{ {
struct __sk_buff skb = {}; struct __sk_buff skb = {};
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v6, .data_in = &pkt_v6,
.data_size_in = sizeof(pkt_v6), .data_size_in = sizeof(pkt_v6),
.ctx_in = &skb, .ctx_in = &skb,
.ctx_size_in = sizeof(skb), .ctx_size_in = sizeof(skb),
}; );
struct kfree_skb *skel = NULL; struct kfree_skb *skel = NULL;
struct bpf_link *link; struct bpf_link *link;
struct bpf_object *obj; struct bpf_object *obj;
struct perf_buffer *pb = NULL; struct perf_buffer *pb = NULL;
int err; int err, prog_fd;
bool passed = false; bool passed = false;
__u32 duration = 0; __u32 duration = 0;
const int zero = 0; const int zero = 0;
bool test_ok[2]; bool test_ok[2];
err = bpf_prog_test_load("./test_pkt_access.o", BPF_PROG_TYPE_SCHED_CLS, err = bpf_prog_test_load("./test_pkt_access.o", BPF_PROG_TYPE_SCHED_CLS,
&obj, &tattr.prog_fd); &obj, &prog_fd);
if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno)) if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
return; return;
...@@ -100,11 +100,9 @@ void serial_test_kfree_skb(void) ...@@ -100,11 +100,9 @@ void serial_test_kfree_skb(void)
goto close_prog; goto close_prog;
memcpy(skb.cb, &cb, sizeof(cb)); memcpy(skb.cb, &cb, sizeof(cb));
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &topts);
duration = tattr.duration; ASSERT_OK(err, "ipv6 test_run");
CHECK(err || tattr.retval, "ipv6", ASSERT_OK(topts.retval, "ipv6 test_run retval");
"err %d errno %d retval %d duration %d\n",
err, errno, tattr.retval, duration);
/* read perf buffer */ /* read perf buffer */
err = perf_buffer__poll(pb, 100); err = perf_buffer__poll(pb, 100);
......
...@@ -9,29 +9,31 @@ ...@@ -9,29 +9,31 @@
static void test_main(void) static void test_main(void)
{ {
struct kfunc_call_test_lskel *skel; struct kfunc_call_test_lskel *skel;
int prog_fd, retval, err; int prog_fd, err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = kfunc_call_test_lskel__open_and_load(); skel = kfunc_call_test_lskel__open_and_load();
if (!ASSERT_OK_PTR(skel, "skel")) if (!ASSERT_OK_PTR(skel, "skel"))
return; return;
prog_fd = skel->progs.kfunc_call_test1.prog_fd; prog_fd = skel->progs.kfunc_call_test1.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
ASSERT_OK(err, "bpf_prog_test_run(test1)"); ASSERT_OK(err, "bpf_prog_test_run(test1)");
ASSERT_EQ(retval, 12, "test1-retval"); ASSERT_EQ(topts.retval, 12, "test1-retval");
prog_fd = skel->progs.kfunc_call_test2.prog_fd; prog_fd = skel->progs.kfunc_call_test2.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
ASSERT_OK(err, "bpf_prog_test_run(test2)"); ASSERT_OK(err, "bpf_prog_test_run(test2)");
ASSERT_EQ(retval, 3, "test2-retval"); ASSERT_EQ(topts.retval, 3, "test2-retval");
prog_fd = skel->progs.kfunc_call_test_ref_btf_id.prog_fd; prog_fd = skel->progs.kfunc_call_test_ref_btf_id.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
ASSERT_OK(err, "bpf_prog_test_run(test_ref_btf_id)"); ASSERT_OK(err, "bpf_prog_test_run(test_ref_btf_id)");
ASSERT_EQ(retval, 0, "test_ref_btf_id-retval"); ASSERT_EQ(topts.retval, 0, "test_ref_btf_id-retval");
kfunc_call_test_lskel__destroy(skel); kfunc_call_test_lskel__destroy(skel);
} }
...@@ -39,17 +41,21 @@ static void test_main(void) ...@@ -39,17 +41,21 @@ static void test_main(void)
static void test_subprog(void) static void test_subprog(void)
{ {
struct kfunc_call_test_subprog *skel; struct kfunc_call_test_subprog *skel;
int prog_fd, retval, err; int prog_fd, err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = kfunc_call_test_subprog__open_and_load(); skel = kfunc_call_test_subprog__open_and_load();
if (!ASSERT_OK_PTR(skel, "skel")) if (!ASSERT_OK_PTR(skel, "skel"))
return; return;
prog_fd = bpf_program__fd(skel->progs.kfunc_call_test1); prog_fd = bpf_program__fd(skel->progs.kfunc_call_test1);
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
ASSERT_OK(err, "bpf_prog_test_run(test1)"); ASSERT_OK(err, "bpf_prog_test_run(test1)");
ASSERT_EQ(retval, 10, "test1-retval"); ASSERT_EQ(topts.retval, 10, "test1-retval");
ASSERT_NEQ(skel->data->active_res, -1, "active_res"); ASSERT_NEQ(skel->data->active_res, -1, "active_res");
ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res"); ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res");
...@@ -59,17 +65,21 @@ static void test_subprog(void) ...@@ -59,17 +65,21 @@ static void test_subprog(void)
static void test_subprog_lskel(void) static void test_subprog_lskel(void)
{ {
struct kfunc_call_test_subprog_lskel *skel; struct kfunc_call_test_subprog_lskel *skel;
int prog_fd, retval, err; int prog_fd, err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
skel = kfunc_call_test_subprog_lskel__open_and_load(); skel = kfunc_call_test_subprog_lskel__open_and_load();
if (!ASSERT_OK_PTR(skel, "skel")) if (!ASSERT_OK_PTR(skel, "skel"))
return; return;
prog_fd = skel->progs.kfunc_call_test1.prog_fd; prog_fd = skel->progs.kfunc_call_test1.prog_fd;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
ASSERT_OK(err, "bpf_prog_test_run(test1)"); ASSERT_OK(err, "bpf_prog_test_run(test1)");
ASSERT_EQ(retval, 10, "test1-retval"); ASSERT_EQ(topts.retval, 10, "test1-retval");
ASSERT_NEQ(skel->data->active_res, -1, "active_res"); ASSERT_NEQ(skel->data->active_res, -1, "active_res");
ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res"); ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res");
......
...@@ -9,8 +9,12 @@ ...@@ -9,8 +9,12 @@
void test_ksyms_module_lskel(void) void test_ksyms_module_lskel(void)
{ {
struct test_ksyms_module_lskel *skel; struct test_ksyms_module_lskel *skel;
int retval;
int err; int err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
if (!env.has_testmod) { if (!env.has_testmod) {
test__skip(); test__skip();
...@@ -20,11 +24,10 @@ void test_ksyms_module_lskel(void) ...@@ -20,11 +24,10 @@ void test_ksyms_module_lskel(void)
skel = test_ksyms_module_lskel__open_and_load(); skel = test_ksyms_module_lskel__open_and_load();
if (!ASSERT_OK_PTR(skel, "test_ksyms_module_lskel__open_and_load")) if (!ASSERT_OK_PTR(skel, "test_ksyms_module_lskel__open_and_load"))
return; return;
err = bpf_prog_test_run(skel->progs.load.prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(skel->progs.load.prog_fd, &topts);
NULL, NULL, (__u32 *)&retval, NULL);
if (!ASSERT_OK(err, "bpf_prog_test_run")) if (!ASSERT_OK(err, "bpf_prog_test_run"))
goto cleanup; goto cleanup;
ASSERT_EQ(retval, 0, "retval"); ASSERT_EQ(topts.retval, 0, "retval");
ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym"); ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym");
cleanup: cleanup:
test_ksyms_module_lskel__destroy(skel); test_ksyms_module_lskel__destroy(skel);
...@@ -33,7 +36,12 @@ void test_ksyms_module_lskel(void) ...@@ -33,7 +36,12 @@ void test_ksyms_module_lskel(void)
void test_ksyms_module_libbpf(void) void test_ksyms_module_libbpf(void)
{ {
struct test_ksyms_module *skel; struct test_ksyms_module *skel;
int retval, err; int err;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
if (!env.has_testmod) { if (!env.has_testmod) {
test__skip(); test__skip();
...@@ -43,11 +51,10 @@ void test_ksyms_module_libbpf(void) ...@@ -43,11 +51,10 @@ void test_ksyms_module_libbpf(void)
skel = test_ksyms_module__open_and_load(); skel = test_ksyms_module__open_and_load();
if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open")) if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open"))
return; return;
err = bpf_prog_test_run(bpf_program__fd(skel->progs.load), 1, &pkt_v4, err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.load), &topts);
sizeof(pkt_v4), NULL, NULL, (__u32 *)&retval, NULL);
if (!ASSERT_OK(err, "bpf_prog_test_run")) if (!ASSERT_OK(err, "bpf_prog_test_run"))
goto cleanup; goto cleanup;
ASSERT_EQ(retval, 0, "retval"); ASSERT_EQ(topts.retval, 0, "retval");
ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym"); ASSERT_EQ(skel->bss->out_bpf_testmod_ksym, 42, "bpf_testmod_ksym");
cleanup: cleanup:
test_ksyms_module__destroy(skel); test_ksyms_module__destroy(skel);
......
...@@ -23,12 +23,16 @@ static void test_l4lb(const char *file) ...@@ -23,12 +23,16 @@ static void test_l4lb(const char *file)
__u8 flags; __u8 flags;
} real_def = {.dst = MAGIC_VAL}; } real_def = {.dst = MAGIC_VAL};
__u32 ch_key = 11, real_num = 3; __u32 ch_key = 11, real_num = 3;
__u32 duration, retval, size;
int err, i, prog_fd, map_fd; int err, i, prog_fd, map_fd;
__u64 bytes = 0, pkts = 0; __u64 bytes = 0, pkts = 0;
struct bpf_object *obj; struct bpf_object *obj;
char buf[128]; char buf[128];
u32 *magic = (u32 *)buf; u32 *magic = (u32 *)buf;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = NUM_ITER,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
...@@ -49,19 +53,24 @@ static void test_l4lb(const char *file) ...@@ -49,19 +53,24 @@ static void test_l4lb(const char *file)
goto out; goto out;
bpf_map_update_elem(map_fd, &real_num, &real_def, 0); bpf_map_update_elem(map_fd, &real_num, &real_def, 0);
err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v4, sizeof(pkt_v4), topts.data_in = &pkt_v4;
buf, &size, &retval, &duration); topts.data_size_in = sizeof(pkt_v4);
CHECK(err || retval != 7/*TC_ACT_REDIRECT*/ || size != 54 ||
*magic != MAGIC_VAL, "ipv4",
"err %d errno %d retval %d size %d magic %x\n",
err, errno, retval, size, *magic);
err = bpf_prog_test_run(prog_fd, NUM_ITER, &pkt_v6, sizeof(pkt_v6), err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration); ASSERT_OK(err, "test_run");
CHECK(err || retval != 7/*TC_ACT_REDIRECT*/ || size != 74 || ASSERT_EQ(topts.retval, 7 /*TC_ACT_REDIRECT*/, "ipv4 test_run retval");
*magic != MAGIC_VAL, "ipv6", ASSERT_EQ(topts.data_size_out, 54, "ipv4 test_run data_size_out");
"err %d errno %d retval %d size %d magic %x\n", ASSERT_EQ(*magic, MAGIC_VAL, "ipv4 magic");
err, errno, retval, size, *magic);
topts.data_in = &pkt_v6;
topts.data_size_in = sizeof(pkt_v6);
topts.data_size_out = sizeof(buf); /* reset out size */
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "test_run");
ASSERT_EQ(topts.retval, 7 /*TC_ACT_REDIRECT*/, "ipv6 test_run retval");
ASSERT_EQ(topts.data_size_out, 74, "ipv6 test_run data_size_out");
ASSERT_EQ(*magic, MAGIC_VAL, "ipv6 magic");
map_fd = bpf_find_map(__func__, obj, "stats"); map_fd = bpf_find_map(__func__, obj, "stats");
if (map_fd < 0) if (map_fd < 0)
......
...@@ -4,14 +4,17 @@ ...@@ -4,14 +4,17 @@
static void *spin_lock_thread(void *arg) static void *spin_lock_thread(void *arg)
{ {
__u32 duration, retval;
int err, prog_fd = *(u32 *) arg; int err, prog_fd = *(u32 *) arg;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 10000,
);
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "test_run_opts err");
ASSERT_OK(topts.retval, "test_run_opts retval");
err = bpf_prog_test_run(prog_fd, 10000, &pkt_v4, sizeof(pkt_v4),
NULL, NULL, &retval, &duration);
CHECK(err || retval, "",
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
pthread_exit(arg); pthread_exit(arg);
} }
......
...@@ -9,10 +9,16 @@ ...@@ -9,10 +9,16 @@
void test_map_ptr(void) void test_map_ptr(void)
{ {
struct map_ptr_kern_lskel *skel; struct map_ptr_kern_lskel *skel;
__u32 duration = 0, retval;
char buf[128]; char buf[128];
int err; int err;
int page_size = getpagesize(); int page_size = getpagesize();
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
skel = map_ptr_kern_lskel__open(); skel = map_ptr_kern_lskel__open();
if (!ASSERT_OK_PTR(skel, "skel_open")) if (!ASSERT_OK_PTR(skel, "skel_open"))
...@@ -26,14 +32,12 @@ void test_map_ptr(void) ...@@ -26,14 +32,12 @@ void test_map_ptr(void)
skel->bss->page_size = page_size; skel->bss->page_size = page_size;
err = bpf_prog_test_run(skel->progs.cg_skb.prog_fd, 1, &pkt_v4, err = bpf_prog_test_run_opts(skel->progs.cg_skb.prog_fd, &topts);
sizeof(pkt_v4), buf, NULL, &retval, NULL);
if (CHECK(err, "test_run", "err=%d errno=%d\n", err, errno)) if (!ASSERT_OK(err, "test_run"))
goto cleanup; goto cleanup;
if (CHECK(!retval, "retval", "retval=%d map_type=%u line=%u\n", retval, if (!ASSERT_NEQ(topts.retval, 0, "test_run retval"))
skel->bss->g_map_type, skel->bss->g_line))
goto cleanup; goto cleanup;
cleanup: cleanup:
......
...@@ -15,39 +15,31 @@ static void run_test(__u32 input_retval, __u16 want_side_effect, __s16 want_ret) ...@@ -15,39 +15,31 @@ static void run_test(__u32 input_retval, __u16 want_side_effect, __s16 want_ret)
{ {
struct modify_return *skel = NULL; struct modify_return *skel = NULL;
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval;
__u16 side_effect; __u16 side_effect;
__s16 ret; __s16 ret;
LIBBPF_OPTS(bpf_test_run_opts, topts);
skel = modify_return__open_and_load(); skel = modify_return__open_and_load();
if (CHECK(!skel, "skel_load", "modify_return skeleton failed\n")) if (!ASSERT_OK_PTR(skel, "skel_load"))
goto cleanup; goto cleanup;
err = modify_return__attach(skel); err = modify_return__attach(skel);
if (CHECK(err, "modify_return", "attach failed: %d\n", err)) if (!ASSERT_OK(err, "modify_return__attach failed"))
goto cleanup; goto cleanup;
skel->bss->input_retval = input_retval; skel->bss->input_retval = input_retval;
prog_fd = bpf_program__fd(skel->progs.fmod_ret_test); prog_fd = bpf_program__fd(skel->progs.fmod_ret_test);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
&retval, &duration); ASSERT_OK(err, "test_run");
CHECK(err, "test_run", "err %d errno %d\n", err, errno); side_effect = UPPER(topts.retval);
ret = LOWER(topts.retval);
side_effect = UPPER(retval); ASSERT_EQ(ret, want_ret, "test_run ret");
ret = LOWER(retval); ASSERT_EQ(side_effect, want_side_effect, "modify_return side_effect");
ASSERT_EQ(skel->bss->fentry_result, 1, "modify_return fentry_result");
CHECK(ret != want_ret, "test_run", ASSERT_EQ(skel->bss->fexit_result, 1, "modify_return fexit_result");
"unexpected ret: %d, expected: %d\n", ret, want_ret); ASSERT_EQ(skel->bss->fmod_ret_result, 1, "modify_return fmod_ret_result");
CHECK(side_effect != want_side_effect, "modify_return",
"unexpected side_effect: %d\n", side_effect);
CHECK(skel->bss->fentry_result != 1, "modify_return",
"fentry failed\n");
CHECK(skel->bss->fexit_result != 1, "modify_return",
"fexit failed\n");
CHECK(skel->bss->fmod_ret_result != 1, "modify_return",
"fmod_ret failed\n");
cleanup: cleanup:
modify_return__destroy(skel); modify_return__destroy(skel);
...@@ -63,4 +55,3 @@ void serial_test_modify_return(void) ...@@ -63,4 +55,3 @@ void serial_test_modify_return(void)
0 /* want_side_effect */, 0 /* want_side_effect */,
-EINVAL /* want_ret */); -EINVAL /* want_ret */);
} }
...@@ -6,23 +6,27 @@ void test_pkt_access(void) ...@@ -6,23 +6,27 @@ void test_pkt_access(void)
{ {
const char *file = "./test_pkt_access.o"; const char *file = "./test_pkt_access.o";
struct bpf_object *obj; struct bpf_object *obj;
__u32 duration, retval;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 100000,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
return; return;
err = bpf_prog_test_run(prog_fd, 100000, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "ipv4 test_run_opts err");
CHECK(err || retval, "ipv4", ASSERT_OK(topts.retval, "ipv4 test_run_opts retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration); topts.data_in = &pkt_v6;
topts.data_size_in = sizeof(pkt_v6);
topts.data_size_out = 0; /* reset from last call */
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "ipv6 test_run_opts err");
ASSERT_OK(topts.retval, "ipv6 test_run_opts retval");
err = bpf_prog_test_run(prog_fd, 100000, &pkt_v6, sizeof(pkt_v6),
NULL, NULL, &retval, &duration);
CHECK(err || retval, "ipv6",
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -6,18 +6,20 @@ void test_pkt_md_access(void) ...@@ -6,18 +6,20 @@ void test_pkt_md_access(void)
{ {
const char *file = "./test_pkt_md_access.o"; const char *file = "./test_pkt_md_access.o";
struct bpf_object *obj; struct bpf_object *obj;
__u32 duration, retval;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 10,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
return; return;
err = bpf_prog_test_run(prog_fd, 10, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "test_run_opts err");
CHECK(err || retval, "", ASSERT_OK(topts.retval, "test_run_opts retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -20,60 +20,54 @@ static void check_run_cnt(int prog_fd, __u64 run_cnt) ...@@ -20,60 +20,54 @@ static void check_run_cnt(int prog_fd, __u64 run_cnt)
"incorrect number of repetitions, want %llu have %llu\n", run_cnt, info.run_cnt); "incorrect number of repetitions, want %llu have %llu\n", run_cnt, info.run_cnt);
} }
void test_prog_run_xattr(void) void test_prog_run_opts(void)
{ {
struct test_pkt_access *skel; struct test_pkt_access *skel;
int err, stats_fd = -1; int err, stats_fd = -1, prog_fd;
char buf[10] = {}; char buf[10] = {};
__u64 run_cnt = 0; __u64 run_cnt = 0;
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.repeat = 1, .repeat = 1,
.data_in = &pkt_v4, .data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4), .data_size_in = sizeof(pkt_v4),
.data_out = buf, .data_out = buf,
.data_size_out = 5, .data_size_out = 5,
}; );
stats_fd = bpf_enable_stats(BPF_STATS_RUN_TIME); stats_fd = bpf_enable_stats(BPF_STATS_RUN_TIME);
if (CHECK_ATTR(stats_fd < 0, "enable_stats", "failed %d\n", errno)) if (!ASSERT_GE(stats_fd, 0, "enable_stats good fd"))
return; return;
skel = test_pkt_access__open_and_load(); skel = test_pkt_access__open_and_load();
if (CHECK_ATTR(!skel, "open_and_load", "failed\n")) if (!ASSERT_OK_PTR(skel, "open_and_load"))
goto cleanup; goto cleanup;
tattr.prog_fd = bpf_program__fd(skel->progs.test_pkt_access); prog_fd = bpf_program__fd(skel->progs.test_pkt_access);
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &topts);
CHECK_ATTR(err >= 0 || errno != ENOSPC || tattr.retval, "run", ASSERT_EQ(errno, ENOSPC, "test_run errno");
"err %d errno %d retval %d\n", err, errno, tattr.retval); ASSERT_ERR(err, "test_run");
ASSERT_OK(topts.retval, "test_run retval");
CHECK_ATTR(tattr.data_size_out != sizeof(pkt_v4), "data_size_out", ASSERT_EQ(topts.data_size_out, sizeof(pkt_v4), "test_run data_size_out");
"incorrect output size, want %zu have %u\n", ASSERT_EQ(buf[5], 0, "overflow, BPF_PROG_TEST_RUN ignored size hint");
sizeof(pkt_v4), tattr.data_size_out);
CHECK_ATTR(buf[5] != 0, "overflow", run_cnt += topts.repeat;
"BPF_PROG_TEST_RUN ignored size hint\n"); check_run_cnt(prog_fd, run_cnt);
run_cnt += tattr.repeat; topts.data_out = NULL;
check_run_cnt(tattr.prog_fd, run_cnt); topts.data_size_out = 0;
topts.repeat = 2;
tattr.data_out = NULL;
tattr.data_size_out = 0;
tattr.repeat = 2;
errno = 0; errno = 0;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &topts);
CHECK_ATTR(err || errno || tattr.retval, "run_no_output", ASSERT_OK(errno, "run_no_output errno");
"err %d errno %d retval %d\n", err, errno, tattr.retval); ASSERT_OK(err, "run_no_output err");
ASSERT_OK(topts.retval, "run_no_output retval");
tattr.data_size_out = 1;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err != -EINVAL, "run_wrong_size_out", "err %d\n", err);
run_cnt += tattr.repeat; run_cnt += topts.repeat;
check_run_cnt(tattr.prog_fd, run_cnt); check_run_cnt(prog_fd, run_cnt);
cleanup: cleanup:
if (skel) if (skel)
......
...@@ -10,11 +10,18 @@ enum { ...@@ -10,11 +10,18 @@ enum {
static void test_queue_stack_map_by_type(int type) static void test_queue_stack_map_by_type(int type)
{ {
const int MAP_SIZE = 32; const int MAP_SIZE = 32;
__u32 vals[MAP_SIZE], duration, retval, size, val; __u32 vals[MAP_SIZE], val;
int i, err, prog_fd, map_in_fd, map_out_fd; int i, err, prog_fd, map_in_fd, map_out_fd;
char file[32], buf[128]; char file[32], buf[128];
struct bpf_object *obj; struct bpf_object *obj;
struct iphdr iph; struct iphdr iph;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
/* Fill test values to be used */ /* Fill test values to be used */
for (i = 0; i < MAP_SIZE; i++) for (i = 0; i < MAP_SIZE; i++)
...@@ -58,38 +65,37 @@ static void test_queue_stack_map_by_type(int type) ...@@ -58,38 +65,37 @@ static void test_queue_stack_map_by_type(int type)
pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5; pkt_v4.iph.saddr = vals[MAP_SIZE - 1 - i] * 5;
} }
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), topts.data_size_out = sizeof(buf);
buf, &size, &retval, &duration); err = bpf_prog_test_run_opts(prog_fd, &topts);
if (err || retval || size != sizeof(pkt_v4)) if (err || topts.retval ||
topts.data_size_out != sizeof(pkt_v4))
break; break;
memcpy(&iph, buf + sizeof(struct ethhdr), sizeof(iph)); memcpy(&iph, buf + sizeof(struct ethhdr), sizeof(iph));
if (iph.daddr != val) if (iph.daddr != val)
break; break;
} }
CHECK(err || retval || size != sizeof(pkt_v4) || iph.daddr != val, ASSERT_OK(err, "bpf_map_pop_elem");
"bpf_map_pop_elem", ASSERT_OK(topts.retval, "bpf_map_pop_elem test retval");
"err %d errno %d retval %d size %d iph->daddr %u\n", ASSERT_EQ(topts.data_size_out, sizeof(pkt_v4),
err, errno, retval, size, iph.daddr); "bpf_map_pop_elem data_size_out");
ASSERT_EQ(iph.daddr, val, "bpf_map_pop_elem iph.daddr");
/* Queue is empty, program should return TC_ACT_SHOT */ /* Queue is empty, program should return TC_ACT_SHOT */
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), topts.data_size_out = sizeof(buf);
buf, &size, &retval, &duration); err = bpf_prog_test_run_opts(prog_fd, &topts);
CHECK(err || retval != 2 /* TC_ACT_SHOT */|| size != sizeof(pkt_v4), ASSERT_OK(err, "check-queue-stack-map-empty");
"check-queue-stack-map-empty", ASSERT_EQ(topts.retval, 2 /* TC_ACT_SHOT */,
"err %d errno %d retval %d size %d\n", "check-queue-stack-map-empty test retval");
err, errno, retval, size); ASSERT_EQ(topts.data_size_out, sizeof(pkt_v4),
"check-queue-stack-map-empty data_size_out");
/* Check that the program pushed elements correctly */ /* Check that the program pushed elements correctly */
for (i = 0; i < MAP_SIZE; i++) { for (i = 0; i < MAP_SIZE; i++) {
err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val); err = bpf_map_lookup_and_delete_elem(map_out_fd, NULL, &val);
if (err || val != vals[i] * 5) ASSERT_OK(err, "bpf_map_lookup_and_delete_elem");
break; ASSERT_EQ(val, vals[i] * 5, "bpf_map_push_elem val");
} }
CHECK(i != MAP_SIZE && (err || val != vals[i] * 5),
"bpf_map_push_elem", "err %d value %u\n", err, val);
out: out:
pkt_v4.iph.saddr = 0; pkt_v4.iph.saddr = 0;
bpf_object__close(obj); bpf_object__close(obj);
......
...@@ -5,18 +5,15 @@ ...@@ -5,18 +5,15 @@
#include "bpf/libbpf_internal.h" #include "bpf/libbpf_internal.h"
#include "test_raw_tp_test_run.skel.h" #include "test_raw_tp_test_run.skel.h"
static int duration;
void test_raw_tp_test_run(void) void test_raw_tp_test_run(void)
{ {
struct bpf_prog_test_run_attr test_attr = {};
int comm_fd = -1, err, nr_online, i, prog_fd; int comm_fd = -1, err, nr_online, i, prog_fd;
__u64 args[2] = {0x1234ULL, 0x5678ULL}; __u64 args[2] = {0x1234ULL, 0x5678ULL};
int expected_retval = 0x1234 + 0x5678; int expected_retval = 0x1234 + 0x5678;
struct test_raw_tp_test_run *skel; struct test_raw_tp_test_run *skel;
char buf[] = "new_name"; char buf[] = "new_name";
bool *online = NULL; bool *online = NULL;
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, LIBBPF_OPTS(bpf_test_run_opts, opts,
.ctx_in = args, .ctx_in = args,
.ctx_size_in = sizeof(args), .ctx_size_in = sizeof(args),
.flags = BPF_F_TEST_RUN_ON_CPU, .flags = BPF_F_TEST_RUN_ON_CPU,
...@@ -24,40 +21,38 @@ void test_raw_tp_test_run(void) ...@@ -24,40 +21,38 @@ void test_raw_tp_test_run(void)
err = parse_cpu_mask_file("/sys/devices/system/cpu/online", &online, err = parse_cpu_mask_file("/sys/devices/system/cpu/online", &online,
&nr_online); &nr_online);
if (CHECK(err, "parse_cpu_mask_file", "err %d\n", err)) if (!ASSERT_OK(err, "parse_cpu_mask_file"))
return; return;
skel = test_raw_tp_test_run__open_and_load(); skel = test_raw_tp_test_run__open_and_load();
if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) if (!ASSERT_OK_PTR(skel, "skel_open"))
goto cleanup; goto cleanup;
err = test_raw_tp_test_run__attach(skel); err = test_raw_tp_test_run__attach(skel);
if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err)) if (!ASSERT_OK(err, "skel_attach"))
goto cleanup; goto cleanup;
comm_fd = open("/proc/self/comm", O_WRONLY|O_TRUNC); comm_fd = open("/proc/self/comm", O_WRONLY|O_TRUNC);
if (CHECK(comm_fd < 0, "open /proc/self/comm", "err %d\n", errno)) if (!ASSERT_GE(comm_fd, 0, "open /proc/self/comm"))
goto cleanup; goto cleanup;
err = write(comm_fd, buf, sizeof(buf)); err = write(comm_fd, buf, sizeof(buf));
CHECK(err < 0, "task rename", "err %d", errno); ASSERT_GE(err, 0, "task rename");
CHECK(skel->bss->count == 0, "check_count", "didn't increase\n"); ASSERT_NEQ(skel->bss->count, 0, "check_count");
CHECK(skel->data->on_cpu != 0xffffffff, "check_on_cpu", "got wrong value\n"); ASSERT_EQ(skel->data->on_cpu, 0xffffffff, "check_on_cpu");
prog_fd = bpf_program__fd(skel->progs.rename); prog_fd = bpf_program__fd(skel->progs.rename);
test_attr.prog_fd = prog_fd; opts.ctx_in = args;
test_attr.ctx_in = args; opts.ctx_size_in = sizeof(__u64);
test_attr.ctx_size_in = sizeof(__u64);
err = bpf_prog_test_run_xattr(&test_attr); err = bpf_prog_test_run_opts(prog_fd, &opts);
CHECK(err == 0, "test_run", "should fail for too small ctx\n"); ASSERT_NEQ(err, 0, "test_run should fail for too small ctx");
test_attr.ctx_size_in = sizeof(args); opts.ctx_size_in = sizeof(args);
err = bpf_prog_test_run_xattr(&test_attr); err = bpf_prog_test_run_opts(prog_fd, &opts);
CHECK(err < 0, "test_run", "err %d\n", errno); ASSERT_OK(err, "test_run");
CHECK(test_attr.retval != expected_retval, "check_retval", ASSERT_EQ(opts.retval, expected_retval, "check_retval");
"expect 0x%x, got 0x%x\n", expected_retval, test_attr.retval);
for (i = 0; i < nr_online; i++) { for (i = 0; i < nr_online; i++) {
if (!online[i]) if (!online[i])
...@@ -66,28 +61,23 @@ void test_raw_tp_test_run(void) ...@@ -66,28 +61,23 @@ void test_raw_tp_test_run(void)
opts.cpu = i; opts.cpu = i;
opts.retval = 0; opts.retval = 0;
err = bpf_prog_test_run_opts(prog_fd, &opts); err = bpf_prog_test_run_opts(prog_fd, &opts);
CHECK(err < 0, "test_run_opts", "err %d\n", errno); ASSERT_OK(err, "test_run_opts");
CHECK(skel->data->on_cpu != i, "check_on_cpu", ASSERT_EQ(skel->data->on_cpu, i, "check_on_cpu");
"expect %d got %d\n", i, skel->data->on_cpu); ASSERT_EQ(opts.retval, expected_retval, "check_retval");
CHECK(opts.retval != expected_retval,
"check_retval", "expect 0x%x, got 0x%x\n",
expected_retval, opts.retval);
} }
/* invalid cpu ID should fail with ENXIO */ /* invalid cpu ID should fail with ENXIO */
opts.cpu = 0xffffffff; opts.cpu = 0xffffffff;
err = bpf_prog_test_run_opts(prog_fd, &opts); err = bpf_prog_test_run_opts(prog_fd, &opts);
CHECK(err >= 0 || errno != ENXIO, ASSERT_EQ(errno, ENXIO, "test_run_opts should fail with ENXIO");
"test_run_opts_fail", ASSERT_ERR(err, "test_run_opts_fail");
"should failed with ENXIO\n");
/* non-zero cpu w/o BPF_F_TEST_RUN_ON_CPU should fail with EINVAL */ /* non-zero cpu w/o BPF_F_TEST_RUN_ON_CPU should fail with EINVAL */
opts.cpu = 1; opts.cpu = 1;
opts.flags = 0; opts.flags = 0;
err = bpf_prog_test_run_opts(prog_fd, &opts); err = bpf_prog_test_run_opts(prog_fd, &opts);
CHECK(err >= 0 || errno != EINVAL, ASSERT_EQ(errno, EINVAL, "test_run_opts should fail with EINVAL");
"test_run_opts_fail", ASSERT_ERR(err, "test_run_opts_fail");
"should failed with EINVAL\n");
cleanup: cleanup:
close(comm_fd); close(comm_fd);
......
...@@ -56,21 +56,23 @@ void serial_test_raw_tp_writable_test_run(void) ...@@ -56,21 +56,23 @@ void serial_test_raw_tp_writable_test_run(void)
0, 0,
}; };
__u32 prog_ret; LIBBPF_OPTS(bpf_test_run_opts, topts,
int err = bpf_prog_test_run(filter_fd, 1, test_skb, sizeof(test_skb), 0, .data_in = test_skb,
0, &prog_ret, 0); .data_size_in = sizeof(test_skb),
.repeat = 1,
);
int err = bpf_prog_test_run_opts(filter_fd, &topts);
CHECK(err != 42, "test_run", CHECK(err != 42, "test_run",
"tracepoint did not modify return value\n"); "tracepoint did not modify return value\n");
CHECK(prog_ret != 0, "test_run_ret", CHECK(topts.retval != 0, "test_run_ret",
"socket_filter did not return 0\n"); "socket_filter did not return 0\n");
close(tp_fd); close(tp_fd);
err = bpf_prog_test_run(filter_fd, 1, test_skb, sizeof(test_skb), 0, 0, err = bpf_prog_test_run_opts(filter_fd, &topts);
&prog_ret, 0);
CHECK(err != 0, "test_run_notrace", CHECK(err != 0, "test_run_notrace",
"test_run failed with %d errno %d\n", err, errno); "test_run failed with %d errno %d\n", err, errno);
CHECK(prog_ret != 0, "test_run_ret_notrace", CHECK(topts.retval != 0, "test_run_ret_notrace",
"socket_filter did not return 0\n"); "socket_filter did not return 0\n");
out_filterfd: out_filterfd:
......
...@@ -13,10 +13,14 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type) ...@@ -13,10 +13,14 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type)
struct itimerval timeo = { struct itimerval timeo = {
.it_value.tv_usec = 100000, /* 100ms */ .it_value.tv_usec = 100000, /* 100ms */
}; };
__u32 duration = 0, retval;
int prog_fd; int prog_fd;
int err; int err;
int i; int i;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 0xffffffff,
);
for (i = 0; i < ARRAY_SIZE(prog); i++) for (i = 0; i < ARRAY_SIZE(prog); i++)
prog[i] = BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0); prog[i] = BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0);
...@@ -24,20 +28,17 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type) ...@@ -24,20 +28,17 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type)
prog_fd = bpf_test_load_program(prog_type, prog, ARRAY_SIZE(prog), prog_fd = bpf_test_load_program(prog_type, prog, ARRAY_SIZE(prog),
"GPL", 0, NULL, 0); "GPL", 0, NULL, 0);
CHECK(prog_fd < 0, "test-run", "errno %d\n", errno); ASSERT_GE(prog_fd, 0, "test-run load");
err = sigaction(SIGALRM, &sigalrm_action, NULL); err = sigaction(SIGALRM, &sigalrm_action, NULL);
CHECK(err, "test-run-signal-sigaction", "errno %d\n", errno); ASSERT_OK(err, "test-run-signal-sigaction");
err = setitimer(ITIMER_REAL, &timeo, NULL); err = setitimer(ITIMER_REAL, &timeo, NULL);
CHECK(err, "test-run-signal-timer", "errno %d\n", errno); ASSERT_OK(err, "test-run-signal-timer");
err = bpf_prog_test_run(prog_fd, 0xffffffff, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_LE(topts.duration, 500000000 /* 500ms */,
CHECK(duration > 500000000, /* 500ms */ "test-run-signal-duration");
"test-run-signal-duration",
"duration %dns > 500ms\n",
duration);
signal(SIGALRM, SIG_DFL); signal(SIGALRM, SIG_DFL);
} }
......
...@@ -20,97 +20,72 @@ void test_skb_ctx(void) ...@@ -20,97 +20,72 @@ void test_skb_ctx(void)
.gso_size = 10, .gso_size = 10,
.hwtstamp = 11, .hwtstamp = 11,
}; };
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, tattr,
.data_in = &pkt_v4, .data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4), .data_size_in = sizeof(pkt_v4),
.ctx_in = &skb, .ctx_in = &skb,
.ctx_size_in = sizeof(skb), .ctx_size_in = sizeof(skb),
.ctx_out = &skb, .ctx_out = &skb,
.ctx_size_out = sizeof(skb), .ctx_size_out = sizeof(skb),
}; );
struct bpf_object *obj; struct bpf_object *obj;
int err; int err, prog_fd, i;
int i;
err = bpf_prog_test_load("./test_skb_ctx.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("./test_skb_ctx.o", BPF_PROG_TYPE_SCHED_CLS,
&tattr.prog_fd); &obj, &prog_fd);
if (CHECK_ATTR(err, "load", "err %d errno %d\n", err, errno)) if (!ASSERT_OK(err, "load"))
return; return;
/* ctx_in != NULL, ctx_size_in == 0 */ /* ctx_in != NULL, ctx_size_in == 0 */
tattr.ctx_size_in = 0; tattr.ctx_size_in = 0;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "ctx_size_in", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "ctx_size_in");
tattr.ctx_size_in = sizeof(skb); tattr.ctx_size_in = sizeof(skb);
/* ctx_out != NULL, ctx_size_out == 0 */ /* ctx_out != NULL, ctx_size_out == 0 */
tattr.ctx_size_out = 0; tattr.ctx_size_out = 0;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "ctx_size_out", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "ctx_size_out");
tattr.ctx_size_out = sizeof(skb); tattr.ctx_size_out = sizeof(skb);
/* non-zero [len, tc_index] fields should be rejected*/ /* non-zero [len, tc_index] fields should be rejected*/
skb.len = 1; skb.len = 1;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "len", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "len");
skb.len = 0; skb.len = 0;
skb.tc_index = 1; skb.tc_index = 1;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "tc_index", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "tc_index");
skb.tc_index = 0; skb.tc_index = 0;
/* non-zero [hash, sk] fields should be rejected */ /* non-zero [hash, sk] fields should be rejected */
skb.hash = 1; skb.hash = 1;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "hash", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "hash");
skb.hash = 0; skb.hash = 0;
skb.sk = (struct bpf_sock *)1; skb.sk = (struct bpf_sock *)1;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err == 0, "sk", "err %d errno %d\n", err, errno); ASSERT_NEQ(err, 0, "sk");
skb.sk = 0; skb.sk = 0;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
CHECK_ATTR(err != 0 || tattr.retval, ASSERT_OK(err, "test_run");
"run", ASSERT_OK(tattr.retval, "test_run retval");
"err %d errno %d retval %d\n", ASSERT_EQ(tattr.ctx_size_out, sizeof(skb), "ctx_size_out");
err, errno, tattr.retval);
CHECK_ATTR(tattr.ctx_size_out != sizeof(skb),
"ctx_size_out",
"incorrect output size, want %zu have %u\n",
sizeof(skb), tattr.ctx_size_out);
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
CHECK_ATTR(skb.cb[i] != i + 2, ASSERT_EQ(skb.cb[i], i + 2, "ctx_out_cb");
"ctx_out_cb", ASSERT_EQ(skb.priority, 7, "ctx_out_priority");
"skb->cb[i] == %d, expected %d\n", ASSERT_EQ(skb.ifindex, 1, "ctx_out_ifindex");
skb.cb[i], i + 2); ASSERT_EQ(skb.ingress_ifindex, 11, "ctx_out_ingress_ifindex");
CHECK_ATTR(skb.priority != 7, ASSERT_EQ(skb.tstamp, 8, "ctx_out_tstamp");
"ctx_out_priority", ASSERT_EQ(skb.mark, 10, "ctx_out_mark");
"skb->priority == %d, expected %d\n",
skb.priority, 7);
CHECK_ATTR(skb.ifindex != 1,
"ctx_out_ifindex",
"skb->ifindex == %d, expected %d\n",
skb.ifindex, 1);
CHECK_ATTR(skb.ingress_ifindex != 11,
"ctx_out_ingress_ifindex",
"skb->ingress_ifindex == %d, expected %d\n",
skb.ingress_ifindex, 11);
CHECK_ATTR(skb.tstamp != 8,
"ctx_out_tstamp",
"skb->tstamp == %lld, expected %d\n",
skb.tstamp, 8);
CHECK_ATTR(skb.mark != 10,
"ctx_out_mark",
"skb->mark == %u, expected %d\n",
skb.mark, 10);
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -9,22 +9,22 @@ void test_skb_helpers(void) ...@@ -9,22 +9,22 @@ void test_skb_helpers(void)
.gso_segs = 8, .gso_segs = 8,
.gso_size = 10, .gso_size = 10,
}; };
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4, .data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4), .data_size_in = sizeof(pkt_v4),
.ctx_in = &skb, .ctx_in = &skb,
.ctx_size_in = sizeof(skb), .ctx_size_in = sizeof(skb),
.ctx_out = &skb, .ctx_out = &skb,
.ctx_size_out = sizeof(skb), .ctx_size_out = sizeof(skb),
}; );
struct bpf_object *obj; struct bpf_object *obj;
int err; int err, prog_fd;
err = bpf_prog_test_load("./test_skb_helpers.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("./test_skb_helpers.o",
&tattr.prog_fd); BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd);
if (CHECK_ATTR(err, "load", "err %d errno %d\n", err, errno)) if (!ASSERT_OK(err, "load"))
return; return;
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &topts);
CHECK_ATTR(err, "len", "err %d errno %d\n", err, errno); ASSERT_OK(err, "test_run");
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -140,12 +140,16 @@ static void test_skmsg_helpers(enum bpf_map_type map_type) ...@@ -140,12 +140,16 @@ static void test_skmsg_helpers(enum bpf_map_type map_type)
static void test_sockmap_update(enum bpf_map_type map_type) static void test_sockmap_update(enum bpf_map_type map_type)
{ {
struct bpf_prog_test_run_attr tattr;
int err, prog, src, duration = 0; int err, prog, src, duration = 0;
struct test_sockmap_update *skel; struct test_sockmap_update *skel;
struct bpf_map *dst_map; struct bpf_map *dst_map;
const __u32 zero = 0; const __u32 zero = 0;
char dummy[14] = {0}; char dummy[14] = {0};
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = dummy,
.data_size_in = sizeof(dummy),
.repeat = 1,
);
__s64 sk; __s64 sk;
sk = connected_socket_v4(); sk = connected_socket_v4();
...@@ -167,16 +171,10 @@ static void test_sockmap_update(enum bpf_map_type map_type) ...@@ -167,16 +171,10 @@ static void test_sockmap_update(enum bpf_map_type map_type)
if (CHECK(err, "update_elem(src)", "errno=%u\n", errno)) if (CHECK(err, "update_elem(src)", "errno=%u\n", errno))
goto out; goto out;
tattr = (struct bpf_prog_test_run_attr){ err = bpf_prog_test_run_opts(prog, &topts);
.prog_fd = prog, if (!ASSERT_OK(err, "test_run"))
.repeat = 1, goto out;
.data_in = dummy, if (!ASSERT_NEQ(topts.retval, 0, "test_run retval"))
.data_size_in = sizeof(dummy),
};
err = bpf_prog_test_run_xattr(&tattr);
if (CHECK_ATTR(err || !tattr.retval, "bpf_prog_test_run",
"errno=%u retval=%u\n", errno, tattr.retval))
goto out; goto out;
compare_cookies(skel->maps.src, dst_map); compare_cookies(skel->maps.src, dst_map);
......
...@@ -4,14 +4,16 @@ ...@@ -4,14 +4,16 @@
static void *spin_lock_thread(void *arg) static void *spin_lock_thread(void *arg)
{ {
__u32 duration, retval;
int err, prog_fd = *(u32 *) arg; int err, prog_fd = *(u32 *) arg;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 10000,
);
err = bpf_prog_test_run(prog_fd, 10000, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "test_run");
CHECK(err || retval, "", ASSERT_OK(topts.retval, "test_run retval");
"err %d errno %d retval %d duration %d\n",
err, errno, retval, duration);
pthread_exit(arg); pthread_exit(arg);
} }
......
...@@ -20,20 +20,20 @@ void test_syscall(void) ...@@ -20,20 +20,20 @@ void test_syscall(void)
.log_buf = (uintptr_t) verifier_log, .log_buf = (uintptr_t) verifier_log,
.log_size = sizeof(verifier_log), .log_size = sizeof(verifier_log),
}; };
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, tattr,
.ctx_in = &ctx, .ctx_in = &ctx,
.ctx_size_in = sizeof(ctx), .ctx_size_in = sizeof(ctx),
}; );
struct syscall *skel = NULL; struct syscall *skel = NULL;
__u64 key = 12, value = 0; __u64 key = 12, value = 0;
int err; int err, prog_fd;
skel = syscall__open_and_load(); skel = syscall__open_and_load();
if (!ASSERT_OK_PTR(skel, "skel_load")) if (!ASSERT_OK_PTR(skel, "skel_load"))
goto cleanup; goto cleanup;
tattr.prog_fd = bpf_program__fd(skel->progs.bpf_prog); prog_fd = bpf_program__fd(skel->progs.bpf_prog);
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
ASSERT_EQ(err, 0, "err"); ASSERT_EQ(err, 0, "err");
ASSERT_EQ(tattr.retval, 1, "retval"); ASSERT_EQ(tattr.retval, 1, "retval");
ASSERT_GT(ctx.map_fd, 0, "ctx.map_fd"); ASSERT_GT(ctx.map_fd, 0, "ctx.map_fd");
......
...@@ -12,9 +12,13 @@ static void test_tailcall_1(void) ...@@ -12,9 +12,13 @@ static void test_tailcall_1(void)
struct bpf_map *prog_array; struct bpf_map *prog_array;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char prog_name[32]; char prog_name[32];
char buff[128] = {}; char buff[128] = {};
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall1.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("tailcall1.o", BPF_PROG_TYPE_SCHED_CLS, &obj,
&prog_fd); &prog_fd);
...@@ -54,20 +58,18 @@ static void test_tailcall_1(void) ...@@ -54,20 +58,18 @@ static void test_tailcall_1(void)
} }
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != i, "tailcall", ASSERT_EQ(topts.retval, i, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 3, "tailcall retval");
err, errno, retval);
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
snprintf(prog_name, sizeof(prog_name), "classifier_%d", i); snprintf(prog_name, sizeof(prog_name), "classifier_%d", i);
...@@ -85,10 +87,9 @@ static void test_tailcall_1(void) ...@@ -85,10 +87,9 @@ static void test_tailcall_1(void)
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 0, "tailcall", "err %d errno %d retval %d\n", ASSERT_OK(topts.retval, "tailcall retval");
err, errno, retval);
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
j = bpf_map__max_entries(prog_array) - 1 - i; j = bpf_map__max_entries(prog_array) - 1 - i;
...@@ -110,30 +111,27 @@ static void test_tailcall_1(void) ...@@ -110,30 +111,27 @@ static void test_tailcall_1(void)
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
j = bpf_map__max_entries(prog_array) - 1 - i; j = bpf_map__max_entries(prog_array) - 1 - i;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != j, "tailcall", ASSERT_EQ(topts.retval, j, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 3, "tailcall retval");
err, errno, retval);
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err >= 0 || errno != ENOENT)) if (CHECK_FAIL(err >= 0 || errno != ENOENT))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", ASSERT_EQ(topts.retval, 3, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
} }
out: out:
...@@ -150,9 +148,13 @@ static void test_tailcall_2(void) ...@@ -150,9 +148,13 @@ static void test_tailcall_2(void)
struct bpf_map *prog_array; struct bpf_map *prog_array;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char prog_name[32]; char prog_name[32];
char buff[128] = {}; char buff[128] = {};
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall2.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("tailcall2.o", BPF_PROG_TYPE_SCHED_CLS, &obj,
&prog_fd); &prog_fd);
...@@ -191,30 +193,27 @@ static void test_tailcall_2(void) ...@@ -191,30 +193,27 @@ static void test_tailcall_2(void)
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 2, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 2, "tailcall retval");
err, errno, retval);
i = 2; i = 2;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 1, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 1, "tailcall retval");
err, errno, retval);
i = 0; i = 0;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 3, "tailcall retval");
err, errno, retval);
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -225,8 +224,12 @@ static void test_tailcall_count(const char *which) ...@@ -225,8 +224,12 @@ static void test_tailcall_count(const char *which)
struct bpf_map *prog_array, *data_map; struct bpf_map *prog_array, *data_map;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char buff[128] = {}; char buff[128] = {};
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load(which, BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load(which, BPF_PROG_TYPE_SCHED_CLS, &obj,
&prog_fd); &prog_fd);
...@@ -262,10 +265,9 @@ static void test_tailcall_count(const char *which) ...@@ -262,10 +265,9 @@ static void test_tailcall_count(const char *which)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 1, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 1, "tailcall retval");
err, errno, retval);
data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
...@@ -277,18 +279,17 @@ static void test_tailcall_count(const char *which) ...@@ -277,18 +279,17 @@ static void test_tailcall_count(const char *which)
i = 0; i = 0;
err = bpf_map_lookup_elem(data_fd, &i, &val); err = bpf_map_lookup_elem(data_fd, &i, &val);
CHECK(err || val != 33, "tailcall count", "err %d errno %d count %d\n", ASSERT_OK(err, "tailcall count");
err, errno, val); ASSERT_EQ(val, 33, "tailcall count");
i = 0; i = 0;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 0, "tailcall", "err %d errno %d retval %d\n", ASSERT_OK(topts.retval, "tailcall retval");
err, errno, retval);
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -319,10 +320,14 @@ static void test_tailcall_4(void) ...@@ -319,10 +320,14 @@ static void test_tailcall_4(void)
struct bpf_map *prog_array, *data_map; struct bpf_map *prog_array, *data_map;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
static const int zero = 0; static const int zero = 0;
char buff[128] = {}; char buff[128] = {};
char prog_name[32]; char prog_name[32];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall4.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("tailcall4.o", BPF_PROG_TYPE_SCHED_CLS, &obj,
&prog_fd); &prog_fd);
...@@ -374,10 +379,9 @@ static void test_tailcall_4(void) ...@@ -374,10 +379,9 @@ static void test_tailcall_4(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != i, "tailcall", ASSERT_EQ(topts.retval, i, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
} }
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
...@@ -389,10 +393,9 @@ static void test_tailcall_4(void) ...@@ -389,10 +393,9 @@ static void test_tailcall_4(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", ASSERT_EQ(topts.retval, 3, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
} }
out: out:
bpf_object__close(obj); bpf_object__close(obj);
...@@ -407,10 +410,14 @@ static void test_tailcall_5(void) ...@@ -407,10 +410,14 @@ static void test_tailcall_5(void)
struct bpf_map *prog_array, *data_map; struct bpf_map *prog_array, *data_map;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
static const int zero = 0; static const int zero = 0;
char buff[128] = {}; char buff[128] = {};
char prog_name[32]; char prog_name[32];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall5.o", BPF_PROG_TYPE_SCHED_CLS, &obj, err = bpf_prog_test_load("tailcall5.o", BPF_PROG_TYPE_SCHED_CLS, &obj,
&prog_fd); &prog_fd);
...@@ -462,10 +469,9 @@ static void test_tailcall_5(void) ...@@ -462,10 +469,9 @@ static void test_tailcall_5(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != i, "tailcall", ASSERT_EQ(topts.retval, i, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
} }
for (i = 0; i < bpf_map__max_entries(prog_array); i++) { for (i = 0; i < bpf_map__max_entries(prog_array); i++) {
...@@ -477,10 +483,9 @@ static void test_tailcall_5(void) ...@@ -477,10 +483,9 @@ static void test_tailcall_5(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 3, "tailcall", ASSERT_EQ(topts.retval, 3, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
} }
out: out:
bpf_object__close(obj); bpf_object__close(obj);
...@@ -495,8 +500,12 @@ static void test_tailcall_bpf2bpf_1(void) ...@@ -495,8 +500,12 @@ static void test_tailcall_bpf2bpf_1(void)
struct bpf_map *prog_array; struct bpf_map *prog_array;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char prog_name[32]; char prog_name[32];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall_bpf2bpf1.o", BPF_PROG_TYPE_SCHED_CLS, err = bpf_prog_test_load("tailcall_bpf2bpf1.o", BPF_PROG_TYPE_SCHED_CLS,
&obj, &prog_fd); &obj, &prog_fd);
...@@ -536,10 +545,9 @@ static void test_tailcall_bpf2bpf_1(void) ...@@ -536,10 +545,9 @@ static void test_tailcall_bpf2bpf_1(void)
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
0, &retval, &duration); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 1, "tailcall", ASSERT_EQ(topts.retval, 1, "tailcall retval");
"err %d errno %d retval %d\n", err, errno, retval);
/* jmp -> nop, call subprog that will do tailcall */ /* jmp -> nop, call subprog that will do tailcall */
i = 1; i = 1;
...@@ -547,10 +555,9 @@ static void test_tailcall_bpf2bpf_1(void) ...@@ -547,10 +555,9 @@ static void test_tailcall_bpf2bpf_1(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
0, &retval, &duration); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 0, "tailcall", "err %d errno %d retval %d\n", ASSERT_OK(topts.retval, "tailcall retval");
err, errno, retval);
/* make sure that subprog can access ctx and entry prog that /* make sure that subprog can access ctx and entry prog that
* called this subprog can properly return * called this subprog can properly return
...@@ -560,11 +567,9 @@ static void test_tailcall_bpf2bpf_1(void) ...@@ -560,11 +567,9 @@ static void test_tailcall_bpf2bpf_1(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
0, &retval, &duration); ASSERT_OK(err, "tailcall");
CHECK(err || retval != sizeof(pkt_v4) * 2, ASSERT_EQ(topts.retval, sizeof(pkt_v4) * 2, "tailcall retval");
"tailcall", "err %d errno %d retval %d\n",
err, errno, retval);
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -579,8 +584,12 @@ static void test_tailcall_bpf2bpf_2(void) ...@@ -579,8 +584,12 @@ static void test_tailcall_bpf2bpf_2(void)
struct bpf_map *prog_array, *data_map; struct bpf_map *prog_array, *data_map;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char buff[128] = {}; char buff[128] = {};
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = buff,
.data_size_in = sizeof(buff),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall_bpf2bpf2.o", BPF_PROG_TYPE_SCHED_CLS, err = bpf_prog_test_load("tailcall_bpf2bpf2.o", BPF_PROG_TYPE_SCHED_CLS,
&obj, &prog_fd); &obj, &prog_fd);
...@@ -616,10 +625,9 @@ static void test_tailcall_bpf2bpf_2(void) ...@@ -616,10 +625,9 @@ static void test_tailcall_bpf2bpf_2(void)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 1, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, 1, "tailcall retval");
err, errno, retval);
data_map = bpf_object__find_map_by_name(obj, "tailcall.bss"); data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map))) if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
...@@ -631,18 +639,17 @@ static void test_tailcall_bpf2bpf_2(void) ...@@ -631,18 +639,17 @@ static void test_tailcall_bpf2bpf_2(void)
i = 0; i = 0;
err = bpf_map_lookup_elem(data_fd, &i, &val); err = bpf_map_lookup_elem(data_fd, &i, &val);
CHECK(err || val != 33, "tailcall count", "err %d errno %d count %d\n", ASSERT_OK(err, "tailcall count");
err, errno, val); ASSERT_EQ(val, 33, "tailcall count");
i = 0; i = 0;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, buff, sizeof(buff), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != 0, "tailcall", "err %d errno %d retval %d\n", ASSERT_OK(topts.retval, "tailcall retval");
err, errno, retval);
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -657,8 +664,12 @@ static void test_tailcall_bpf2bpf_3(void) ...@@ -657,8 +664,12 @@ static void test_tailcall_bpf2bpf_3(void)
struct bpf_map *prog_array; struct bpf_map *prog_array;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char prog_name[32]; char prog_name[32];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall_bpf2bpf3.o", BPF_PROG_TYPE_SCHED_CLS, err = bpf_prog_test_load("tailcall_bpf2bpf3.o", BPF_PROG_TYPE_SCHED_CLS,
&obj, &prog_fd); &obj, &prog_fd);
...@@ -697,33 +708,27 @@ static void test_tailcall_bpf2bpf_3(void) ...@@ -697,33 +708,27 @@ static void test_tailcall_bpf2bpf_3(void)
goto out; goto out;
} }
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != sizeof(pkt_v4) * 3, ASSERT_EQ(topts.retval, sizeof(pkt_v4) * 3, "tailcall retval");
"tailcall", "err %d errno %d retval %d\n",
err, errno, retval);
i = 1; i = 1;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != sizeof(pkt_v4), ASSERT_EQ(topts.retval, sizeof(pkt_v4), "tailcall retval");
"tailcall", "err %d errno %d retval %d\n",
err, errno, retval);
i = 0; i = 0;
err = bpf_map_delete_elem(map_fd, &i); err = bpf_map_delete_elem(map_fd, &i);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != sizeof(pkt_v4) * 2, ASSERT_EQ(topts.retval, sizeof(pkt_v4) * 2, "tailcall retval");
"tailcall", "err %d errno %d retval %d\n",
err, errno, retval);
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -754,8 +759,12 @@ static void test_tailcall_bpf2bpf_4(bool noise) ...@@ -754,8 +759,12 @@ static void test_tailcall_bpf2bpf_4(bool noise)
struct bpf_map *prog_array, *data_map; struct bpf_map *prog_array, *data_map;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
__u32 retval, duration;
char prog_name[32]; char prog_name[32];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
err = bpf_prog_test_load("tailcall_bpf2bpf4.o", BPF_PROG_TYPE_SCHED_CLS, err = bpf_prog_test_load("tailcall_bpf2bpf4.o", BPF_PROG_TYPE_SCHED_CLS,
&obj, &prog_fd); &obj, &prog_fd);
...@@ -809,15 +818,14 @@ static void test_tailcall_bpf2bpf_4(bool noise) ...@@ -809,15 +818,14 @@ static void test_tailcall_bpf2bpf_4(bool noise)
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
goto out; goto out;
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0, err = bpf_prog_test_run_opts(main_fd, &topts);
&duration, &retval, NULL); ASSERT_OK(err, "tailcall");
CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n", ASSERT_EQ(topts.retval, sizeof(pkt_v4) * 3, "tailcall retval");
err, errno, retval);
i = 0; i = 0;
err = bpf_map_lookup_elem(data_fd, &i, &val); err = bpf_map_lookup_elem(data_fd, &i, &val);
CHECK(err || val.count != 31, "tailcall count", "err %d errno %d count %d\n", ASSERT_OK(err, "tailcall count");
err, errno, val.count); ASSERT_EQ(val.count, 31, "tailcall count");
out: out:
bpf_object__close(obj); bpf_object__close(obj);
......
...@@ -8,20 +8,20 @@ ...@@ -8,20 +8,20 @@
static int sanity_run(struct bpf_program *prog) static int sanity_run(struct bpf_program *prog)
{ {
struct bpf_prog_test_run_attr test_attr = {}; LIBBPF_OPTS(bpf_test_run_opts, test_attr);
__u64 args[] = {1, 2, 3}; __u64 args[] = {1, 2, 3};
__u32 duration = 0;
int err, prog_fd; int err, prog_fd;
prog_fd = bpf_program__fd(prog); prog_fd = bpf_program__fd(prog);
test_attr.prog_fd = prog_fd;
test_attr.ctx_in = args; test_attr.ctx_in = args;
test_attr.ctx_size_in = sizeof(args); test_attr.ctx_size_in = sizeof(args);
err = bpf_prog_test_run_xattr(&test_attr); err = bpf_prog_test_run_opts(prog_fd, &test_attr);
if (CHECK(err || test_attr.retval, "test_run", if (!ASSERT_OK(err, "test_run"))
"err %d errno %d retval %d duration %d\n", return -1;
err, errno, test_attr.retval, duration))
if (!ASSERT_OK(test_attr.retval, "test_run retval"))
return -1; return -1;
return 0; return 0;
} }
......
...@@ -6,15 +6,18 @@ ...@@ -6,15 +6,18 @@
static int sanity_run(struct bpf_program *prog) static int sanity_run(struct bpf_program *prog)
{ {
__u32 duration, retval;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
prog_fd = bpf_program__fd(prog); prog_fd = bpf_program__fd(prog);
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration); if (!ASSERT_OK(err, "test_run"))
if (CHECK(err || retval != 123, "test_run", return -1;
"err %d errno %d retval %d duration %d\n", if (!ASSERT_EQ(topts.retval, 123, "test_run retval"))
err, errno, retval, duration))
return -1; return -1;
return 0; return 0;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
static int timer(struct timer *timer_skel) static int timer(struct timer *timer_skel)
{ {
int err, prog_fd; int err, prog_fd;
__u32 duration = 0, retval; LIBBPF_OPTS(bpf_test_run_opts, topts);
err = timer__attach(timer_skel); err = timer__attach(timer_skel);
if (!ASSERT_OK(err, "timer_attach")) if (!ASSERT_OK(err, "timer_attach"))
...@@ -16,10 +16,9 @@ static int timer(struct timer *timer_skel) ...@@ -16,10 +16,9 @@ static int timer(struct timer *timer_skel)
ASSERT_EQ(timer_skel->data->callback2_check, 52, "callback2_check1"); ASSERT_EQ(timer_skel->data->callback2_check, 52, "callback2_check1");
prog_fd = bpf_program__fd(timer_skel->progs.test1); prog_fd = bpf_program__fd(timer_skel->progs.test1);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
timer__detach(timer_skel); timer__detach(timer_skel);
usleep(50); /* 10 usecs should be enough, but give it extra */ usleep(50); /* 10 usecs should be enough, but give it extra */
......
...@@ -6,19 +6,18 @@ ...@@ -6,19 +6,18 @@
static int timer_mim(struct timer_mim *timer_skel) static int timer_mim(struct timer_mim *timer_skel)
{ {
__u32 duration = 0, retval;
__u64 cnt1, cnt2; __u64 cnt1, cnt2;
int err, prog_fd, key1 = 1; int err, prog_fd, key1 = 1;
LIBBPF_OPTS(bpf_test_run_opts, topts);
err = timer_mim__attach(timer_skel); err = timer_mim__attach(timer_skel);
if (!ASSERT_OK(err, "timer_attach")) if (!ASSERT_OK(err, "timer_attach"))
return err; return err;
prog_fd = bpf_program__fd(timer_skel->progs.test1); prog_fd = bpf_program__fd(timer_skel->progs.test1);
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, err = bpf_prog_test_run_opts(prog_fd, &topts);
NULL, NULL, &retval, &duration);
ASSERT_OK(err, "test_run"); ASSERT_OK(err, "test_run");
ASSERT_EQ(retval, 0, "test_run"); ASSERT_EQ(topts.retval, 0, "test_run");
timer_mim__detach(timer_skel); timer_mim__detach(timer_skel);
/* check that timer_cb[12] are incrementing 'cnt' */ /* check that timer_cb[12] are incrementing 'cnt' */
......
...@@ -23,8 +23,12 @@ void test_trace_ext(void) ...@@ -23,8 +23,12 @@ void test_trace_ext(void)
int err, pkt_fd, ext_fd; int err, pkt_fd, ext_fd;
struct bpf_program *prog; struct bpf_program *prog;
char buf[100]; char buf[100];
__u32 retval;
__u64 len; __u64 len;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.repeat = 1,
);
/* open/load/attach test_pkt_md_access */ /* open/load/attach test_pkt_md_access */
skel_pkt = test_pkt_md_access__open_and_load(); skel_pkt = test_pkt_md_access__open_and_load();
...@@ -77,32 +81,32 @@ void test_trace_ext(void) ...@@ -77,32 +81,32 @@ void test_trace_ext(void)
/* load/attach tracing */ /* load/attach tracing */
err = test_trace_ext_tracing__load(skel_trace); err = test_trace_ext_tracing__load(skel_trace);
if (CHECK(err, "setup", "tracing/test_pkt_md_access_new load failed\n")) { if (!ASSERT_OK(err, "tracing/test_pkt_md_access_new load")) {
libbpf_strerror(err, buf, sizeof(buf)); libbpf_strerror(err, buf, sizeof(buf));
fprintf(stderr, "%s\n", buf); fprintf(stderr, "%s\n", buf);
goto cleanup; goto cleanup;
} }
err = test_trace_ext_tracing__attach(skel_trace); err = test_trace_ext_tracing__attach(skel_trace);
if (CHECK(err, "setup", "tracing/test_pkt_md_access_new attach failed: %d\n", err)) if (!ASSERT_OK(err, "tracing/test_pkt_md_access_new attach"))
goto cleanup; goto cleanup;
/* trigger the test */ /* trigger the test */
err = bpf_prog_test_run(pkt_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(pkt_fd, &topts);
NULL, NULL, &retval, &duration); ASSERT_OK(err, "test_run_opts err");
CHECK(err || retval, "run", "err %d errno %d retval %d\n", err, errno, retval); ASSERT_OK(topts.retval, "test_run_opts retval");
bss_ext = skel_ext->bss; bss_ext = skel_ext->bss;
bss_trace = skel_trace->bss; bss_trace = skel_trace->bss;
len = bss_ext->ext_called; len = bss_ext->ext_called;
CHECK(bss_ext->ext_called == 0, ASSERT_NEQ(bss_ext->ext_called, 0,
"check", "failed to trigger freplace/test_pkt_md_access\n"); "failed to trigger freplace/test_pkt_md_access");
CHECK(bss_trace->fentry_called != len, ASSERT_EQ(bss_trace->fentry_called, len,
"check", "failed to trigger fentry/test_pkt_md_access_new\n"); "failed to trigger fentry/test_pkt_md_access_new");
CHECK(bss_trace->fexit_called != len, ASSERT_EQ(bss_trace->fexit_called, len,
"check", "failed to trigger fexit/test_pkt_md_access_new\n"); "failed to trigger fexit/test_pkt_md_access_new");
cleanup: cleanup:
test_trace_ext_tracing__destroy(skel_trace); test_trace_ext_tracing__destroy(skel_trace);
......
...@@ -13,8 +13,14 @@ void test_xdp(void) ...@@ -13,8 +13,14 @@ void test_xdp(void)
char buf[128]; char buf[128];
struct ipv6hdr iph6; struct ipv6hdr iph6;
struct iphdr iph; struct iphdr iph;
__u32 duration, retval, size;
int err, prog_fd, map_fd; int err, prog_fd, map_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
...@@ -26,21 +32,23 @@ void test_xdp(void) ...@@ -26,21 +32,23 @@ void test_xdp(void)
bpf_map_update_elem(map_fd, &key4, &value4, 0); bpf_map_update_elem(map_fd, &key4, &value4, 0);
bpf_map_update_elem(map_fd, &key6, &value6, 0); bpf_map_update_elem(map_fd, &key6, &value6, 0);
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration);
memcpy(&iph, buf + sizeof(struct ethhdr), sizeof(iph)); memcpy(&iph, buf + sizeof(struct ethhdr), sizeof(iph));
CHECK(err || retval != XDP_TX || size != 74 || ASSERT_OK(err, "test_run");
iph.protocol != IPPROTO_IPIP, "ipv4", ASSERT_EQ(topts.retval, XDP_TX, "ipv4 test_run retval");
"err %d errno %d retval %d size %d\n", ASSERT_EQ(topts.data_size_out, 74, "ipv4 test_run data_size_out");
err, errno, retval, size); ASSERT_EQ(iph.protocol, IPPROTO_IPIP, "ipv4 test_run iph.protocol");
err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6), topts.data_in = &pkt_v6;
buf, &size, &retval, &duration); topts.data_size_in = sizeof(pkt_v6);
topts.data_size_out = sizeof(buf);
err = bpf_prog_test_run_opts(prog_fd, &topts);
memcpy(&iph6, buf + sizeof(struct ethhdr), sizeof(iph6)); memcpy(&iph6, buf + sizeof(struct ethhdr), sizeof(iph6));
CHECK(err || retval != XDP_TX || size != 114 || ASSERT_OK(err, "test_run");
iph6.nexthdr != IPPROTO_IPV6, "ipv6", ASSERT_EQ(topts.retval, XDP_TX, "ipv6 test_run retval");
"err %d errno %d retval %d size %d\n", ASSERT_EQ(topts.data_size_out, 114, "ipv6 test_run data_size_out");
err, errno, retval, size); ASSERT_EQ(iph6.nexthdr, IPPROTO_IPV6, "ipv6 test_run iph6.nexthdr");
out: out:
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
void test_xdp_update_frags(void) void test_xdp_update_frags(void)
{ {
const char *file = "./test_xdp_update_frags.o"; const char *file = "./test_xdp_update_frags.o";
__u32 duration, retval, size;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
int err, prog_fd; int err, prog_fd;
__u32 *offset; __u32 *offset;
__u8 *buf; __u8 *buf;
LIBBPF_OPTS(bpf_test_run_opts, topts);
obj = bpf_object__open(file); obj = bpf_object__open(file);
if (libbpf_get_error(obj)) if (libbpf_get_error(obj))
...@@ -32,12 +32,16 @@ void test_xdp_update_frags(void) ...@@ -32,12 +32,16 @@ void test_xdp_update_frags(void)
buf[*offset] = 0xaa; /* marker at offset 16 (head) */ buf[*offset] = 0xaa; /* marker at offset 16 (head) */
buf[*offset + 15] = 0xaa; /* marker at offset 31 (head) */ buf[*offset + 15] = 0xaa; /* marker at offset 31 (head) */
err = bpf_prog_test_run(prog_fd, 1, buf, 128, topts.data_in = buf;
buf, &size, &retval, &duration); topts.data_out = buf;
topts.data_size_in = 128;
topts.data_size_out = 128;
err = bpf_prog_test_run_opts(prog_fd, &topts);
/* test_xdp_update_frags: buf[16,31]: 0xaa -> 0xbb */ /* test_xdp_update_frags: buf[16,31]: 0xaa -> 0xbb */
ASSERT_OK(err, "xdp_update_frag"); ASSERT_OK(err, "xdp_update_frag");
ASSERT_EQ(retval, XDP_PASS, "xdp_update_frag retval"); ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
ASSERT_EQ(buf[16], 0xbb, "xdp_update_frag buf[16]"); ASSERT_EQ(buf[16], 0xbb, "xdp_update_frag buf[16]");
ASSERT_EQ(buf[31], 0xbb, "xdp_update_frag buf[31]"); ASSERT_EQ(buf[31], 0xbb, "xdp_update_frag buf[31]");
...@@ -53,12 +57,16 @@ void test_xdp_update_frags(void) ...@@ -53,12 +57,16 @@ void test_xdp_update_frags(void)
buf[*offset] = 0xaa; /* marker at offset 5000 (frag0) */ buf[*offset] = 0xaa; /* marker at offset 5000 (frag0) */
buf[*offset + 15] = 0xaa; /* marker at offset 5015 (frag0) */ buf[*offset + 15] = 0xaa; /* marker at offset 5015 (frag0) */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000, topts.data_in = buf;
buf, &size, &retval, &duration); topts.data_out = buf;
topts.data_size_in = 9000;
topts.data_size_out = 9000;
err = bpf_prog_test_run_opts(prog_fd, &topts);
/* test_xdp_update_frags: buf[5000,5015]: 0xaa -> 0xbb */ /* test_xdp_update_frags: buf[5000,5015]: 0xaa -> 0xbb */
ASSERT_OK(err, "xdp_update_frag"); ASSERT_OK(err, "xdp_update_frag");
ASSERT_EQ(retval, XDP_PASS, "xdp_update_frag retval"); ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
ASSERT_EQ(buf[5000], 0xbb, "xdp_update_frag buf[5000]"); ASSERT_EQ(buf[5000], 0xbb, "xdp_update_frag buf[5000]");
ASSERT_EQ(buf[5015], 0xbb, "xdp_update_frag buf[5015]"); ASSERT_EQ(buf[5015], 0xbb, "xdp_update_frag buf[5015]");
...@@ -68,12 +76,11 @@ void test_xdp_update_frags(void) ...@@ -68,12 +76,11 @@ void test_xdp_update_frags(void)
buf[*offset] = 0xaa; /* marker at offset 3510 (head) */ buf[*offset] = 0xaa; /* marker at offset 3510 (head) */
buf[*offset + 15] = 0xaa; /* marker at offset 3525 (frag0) */ buf[*offset + 15] = 0xaa; /* marker at offset 3525 (frag0) */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000, err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration);
/* test_xdp_update_frags: buf[3510,3525]: 0xaa -> 0xbb */ /* test_xdp_update_frags: buf[3510,3525]: 0xaa -> 0xbb */
ASSERT_OK(err, "xdp_update_frag"); ASSERT_OK(err, "xdp_update_frag");
ASSERT_EQ(retval, XDP_PASS, "xdp_update_frag retval"); ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
ASSERT_EQ(buf[3510], 0xbb, "xdp_update_frag buf[3510]"); ASSERT_EQ(buf[3510], 0xbb, "xdp_update_frag buf[3510]");
ASSERT_EQ(buf[3525], 0xbb, "xdp_update_frag buf[3525]"); ASSERT_EQ(buf[3525], 0xbb, "xdp_update_frag buf[3525]");
...@@ -83,12 +90,11 @@ void test_xdp_update_frags(void) ...@@ -83,12 +90,11 @@ void test_xdp_update_frags(void)
buf[*offset] = 0xaa; /* marker at offset 7606 (frag0) */ buf[*offset] = 0xaa; /* marker at offset 7606 (frag0) */
buf[*offset + 15] = 0xaa; /* marker at offset 7621 (frag1) */ buf[*offset + 15] = 0xaa; /* marker at offset 7621 (frag1) */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000, err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration);
/* test_xdp_update_frags: buf[7606,7621]: 0xaa -> 0xbb */ /* test_xdp_update_frags: buf[7606,7621]: 0xaa -> 0xbb */
ASSERT_OK(err, "xdp_update_frag"); ASSERT_OK(err, "xdp_update_frag");
ASSERT_EQ(retval, XDP_PASS, "xdp_update_frag retval"); ASSERT_EQ(topts.retval, XDP_PASS, "xdp_update_frag retval");
ASSERT_EQ(buf[7606], 0xbb, "xdp_update_frag buf[7606]"); ASSERT_EQ(buf[7606], 0xbb, "xdp_update_frag buf[7606]");
ASSERT_EQ(buf[7621], 0xbb, "xdp_update_frag buf[7621]"); ASSERT_EQ(buf[7621], 0xbb, "xdp_update_frag buf[7621]");
......
...@@ -5,26 +5,34 @@ ...@@ -5,26 +5,34 @@
static void test_xdp_adjust_tail_shrink(void) static void test_xdp_adjust_tail_shrink(void)
{ {
const char *file = "./test_xdp_adjust_tail_shrink.o"; const char *file = "./test_xdp_adjust_tail_shrink.o";
__u32 duration, retval, size, expect_sz; __u32 expect_sz;
struct bpf_object *obj; struct bpf_object *obj;
int err, prog_fd; int err, prog_fd;
char buf[128]; char buf[128];
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink")) if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
return; return;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration);
ASSERT_OK(err, "ipv4"); ASSERT_OK(err, "ipv4");
ASSERT_EQ(retval, XDP_DROP, "ipv4 retval"); ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval");
expect_sz = sizeof(pkt_v6) - 20; /* Test shrink with 20 bytes */ expect_sz = sizeof(pkt_v6) - 20; /* Test shrink with 20 bytes */
err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6), topts.data_in = &pkt_v6;
buf, &size, &retval, &duration); topts.data_size_in = sizeof(pkt_v6);
topts.data_size_out = sizeof(buf);
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "ipv6"); ASSERT_OK(err, "ipv6");
ASSERT_EQ(retval, XDP_TX, "ipv6 retval"); ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
ASSERT_EQ(size, expect_sz, "ipv6 size"); ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size");
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -34,24 +42,31 @@ static void test_xdp_adjust_tail_grow(void) ...@@ -34,24 +42,31 @@ static void test_xdp_adjust_tail_grow(void)
const char *file = "./test_xdp_adjust_tail_grow.o"; const char *file = "./test_xdp_adjust_tail_grow.o";
struct bpf_object *obj; struct bpf_object *obj;
char buf[4096]; /* avoid segfault: large buf to hold grow results */ char buf[4096]; /* avoid segfault: large buf to hold grow results */
__u32 duration, retval, size, expect_sz; __u32 expect_sz;
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = 1,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (ASSERT_OK(err, "test_xdp_adjust_tail_grow")) if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
return; return;
err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), err = bpf_prog_test_run_opts(prog_fd, &topts);
buf, &size, &retval, &duration);
ASSERT_OK(err, "ipv4"); ASSERT_OK(err, "ipv4");
ASSERT_EQ(retval, XDP_DROP, "ipv4 retval"); ASSERT_EQ(topts.retval, XDP_DROP, "ipv4 retval");
expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */ expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */
err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6) /* 74 */, topts.data_in = &pkt_v6;
buf, &size, &retval, &duration); topts.data_size_in = sizeof(pkt_v6);
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "ipv6"); ASSERT_OK(err, "ipv6");
ASSERT_EQ(retval, XDP_TX, "ipv6 retval"); ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
ASSERT_EQ(size, expect_sz, "ipv6 size"); ASSERT_EQ(topts.data_size_out, expect_sz, "ipv6 size");
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -63,17 +78,17 @@ static void test_xdp_adjust_tail_grow2(void) ...@@ -63,17 +78,17 @@ static void test_xdp_adjust_tail_grow2(void)
int tailroom = 320; /* SKB_DATA_ALIGN(sizeof(struct skb_shared_info))*/; int tailroom = 320; /* SKB_DATA_ALIGN(sizeof(struct skb_shared_info))*/;
struct bpf_object *obj; struct bpf_object *obj;
int err, cnt, i; int err, cnt, i;
int max_grow; int max_grow, prog_fd;
struct bpf_prog_test_run_attr tattr = { LIBBPF_OPTS(bpf_test_run_opts, tattr,
.repeat = 1, .repeat = 1,
.data_in = &buf, .data_in = &buf,
.data_out = &buf, .data_out = &buf,
.data_size_in = 0, /* Per test */ .data_size_in = 0, /* Per test */
.data_size_out = 0, /* Per test */ .data_size_out = 0, /* Per test */
}; );
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &tattr.prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (ASSERT_OK(err, "test_xdp_adjust_tail_grow")) if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
return; return;
...@@ -82,7 +97,7 @@ static void test_xdp_adjust_tail_grow2(void) ...@@ -82,7 +97,7 @@ static void test_xdp_adjust_tail_grow2(void)
tattr.data_size_in = 64; /* Determine test case via pkt size */ tattr.data_size_in = 64; /* Determine test case via pkt size */
tattr.data_size_out = 128; /* Limit copy_size */ tattr.data_size_out = 128; /* Limit copy_size */
/* Kernel side alloc packet memory area that is zero init */ /* Kernel side alloc packet memory area that is zero init */
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
ASSERT_EQ(errno, ENOSPC, "case-64 errno"); /* Due limit copy_size in bpf_test_finish */ ASSERT_EQ(errno, ENOSPC, "case-64 errno"); /* Due limit copy_size in bpf_test_finish */
ASSERT_EQ(tattr.retval, XDP_TX, "case-64 retval"); ASSERT_EQ(tattr.retval, XDP_TX, "case-64 retval");
...@@ -100,7 +115,7 @@ static void test_xdp_adjust_tail_grow2(void) ...@@ -100,7 +115,7 @@ static void test_xdp_adjust_tail_grow2(void)
memset(buf, 2, sizeof(buf)); memset(buf, 2, sizeof(buf));
tattr.data_size_in = 128; /* Determine test case via pkt size */ tattr.data_size_in = 128; /* Determine test case via pkt size */
tattr.data_size_out = sizeof(buf); /* Copy everything */ tattr.data_size_out = sizeof(buf); /* Copy everything */
err = bpf_prog_test_run_xattr(&tattr); err = bpf_prog_test_run_opts(prog_fd, &tattr);
max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom; /* 3520 */ max_grow = 4096 - XDP_PACKET_HEADROOM - tailroom; /* 3520 */
ASSERT_OK(err, "case-128"); ASSERT_OK(err, "case-128");
...@@ -121,11 +136,12 @@ static void test_xdp_adjust_tail_grow2(void) ...@@ -121,11 +136,12 @@ static void test_xdp_adjust_tail_grow2(void)
void test_xdp_adjust_frags_tail_shrink(void) void test_xdp_adjust_frags_tail_shrink(void)
{ {
const char *file = "./test_xdp_adjust_tail_shrink.o"; const char *file = "./test_xdp_adjust_tail_shrink.o";
__u32 duration, retval, size, exp_size; __u32 exp_size;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
int err, prog_fd; int err, prog_fd;
__u8 *buf; __u8 *buf;
LIBBPF_OPTS(bpf_test_run_opts, topts);
/* For the individual test cases, the first byte in the packet /* For the individual test cases, the first byte in the packet
* indicates which test will be run. * indicates which test will be run.
...@@ -148,32 +164,36 @@ void test_xdp_adjust_frags_tail_shrink(void) ...@@ -148,32 +164,36 @@ void test_xdp_adjust_frags_tail_shrink(void)
/* Test case removing 10 bytes from last frag, NOT freeing it */ /* Test case removing 10 bytes from last frag, NOT freeing it */
exp_size = 8990; /* 9000 - 10 */ exp_size = 8990; /* 9000 - 10 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000, topts.data_in = buf;
buf, &size, &retval, &duration); topts.data_out = buf;
topts.data_size_in = 9000;
topts.data_size_out = 9000;
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "9Kb-10b"); ASSERT_OK(err, "9Kb-10b");
ASSERT_EQ(retval, XDP_TX, "9Kb-10b retval"); ASSERT_EQ(topts.retval, XDP_TX, "9Kb-10b retval");
ASSERT_EQ(size, exp_size, "9Kb-10b size"); ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-10b size");
/* Test case removing one of two pages, assuming 4K pages */ /* Test case removing one of two pages, assuming 4K pages */
buf[0] = 1; buf[0] = 1;
exp_size = 4900; /* 9000 - 4100 */ exp_size = 4900; /* 9000 - 4100 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000,
buf, &size, &retval, &duration); topts.data_size_out = 9000; /* reset from previous invocation */
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "9Kb-4Kb"); ASSERT_OK(err, "9Kb-4Kb");
ASSERT_EQ(retval, XDP_TX, "9Kb-4Kb retval"); ASSERT_EQ(topts.retval, XDP_TX, "9Kb-4Kb retval");
ASSERT_EQ(size, exp_size, "9Kb-4Kb size"); ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-4Kb size");
/* Test case removing two pages resulting in a linear xdp_buff */ /* Test case removing two pages resulting in a linear xdp_buff */
buf[0] = 2; buf[0] = 2;
exp_size = 800; /* 9000 - 8200 */ exp_size = 800; /* 9000 - 8200 */
err = bpf_prog_test_run(prog_fd, 1, buf, 9000, topts.data_size_out = 9000; /* reset from previous invocation */
buf, &size, &retval, &duration); err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "9Kb-9Kb"); ASSERT_OK(err, "9Kb-9Kb");
ASSERT_EQ(retval, XDP_TX, "9Kb-9Kb retval"); ASSERT_EQ(topts.retval, XDP_TX, "9Kb-9Kb retval");
ASSERT_EQ(size, exp_size, "9Kb-9Kb size"); ASSERT_EQ(topts.data_size_out, exp_size, "9Kb-9Kb size");
free(buf); free(buf);
out: out:
...@@ -183,11 +203,12 @@ void test_xdp_adjust_frags_tail_shrink(void) ...@@ -183,11 +203,12 @@ void test_xdp_adjust_frags_tail_shrink(void)
void test_xdp_adjust_frags_tail_grow(void) void test_xdp_adjust_frags_tail_grow(void)
{ {
const char *file = "./test_xdp_adjust_tail_grow.o"; const char *file = "./test_xdp_adjust_tail_grow.o";
__u32 duration, retval, size, exp_size; __u32 exp_size;
struct bpf_program *prog; struct bpf_program *prog;
struct bpf_object *obj; struct bpf_object *obj;
int err, i, prog_fd; int err, i, prog_fd;
__u8 *buf; __u8 *buf;
LIBBPF_OPTS(bpf_test_run_opts, topts);
obj = bpf_object__open(file); obj = bpf_object__open(file);
if (libbpf_get_error(obj)) if (libbpf_get_error(obj))
...@@ -205,14 +226,17 @@ void test_xdp_adjust_frags_tail_grow(void) ...@@ -205,14 +226,17 @@ void test_xdp_adjust_frags_tail_grow(void)
/* Test case add 10 bytes to last frag */ /* Test case add 10 bytes to last frag */
memset(buf, 1, 16384); memset(buf, 1, 16384);
size = 9000; exp_size = 9000 + 10;
exp_size = size + 10;
err = bpf_prog_test_run(prog_fd, 1, buf, size, topts.data_in = buf;
buf, &size, &retval, &duration); topts.data_out = buf;
topts.data_size_in = 9000;
topts.data_size_out = 16384;
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "9Kb+10b"); ASSERT_OK(err, "9Kb+10b");
ASSERT_EQ(retval, XDP_TX, "9Kb+10b retval"); ASSERT_EQ(topts.retval, XDP_TX, "9Kb+10b retval");
ASSERT_EQ(size, exp_size, "9Kb+10b size"); ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size");
for (i = 0; i < 9000; i++) for (i = 0; i < 9000; i++)
ASSERT_EQ(buf[i], 1, "9Kb+10b-old"); ASSERT_EQ(buf[i], 1, "9Kb+10b-old");
...@@ -225,14 +249,16 @@ void test_xdp_adjust_frags_tail_grow(void) ...@@ -225,14 +249,16 @@ void test_xdp_adjust_frags_tail_grow(void)
/* Test a too large grow */ /* Test a too large grow */
memset(buf, 1, 16384); memset(buf, 1, 16384);
size = 9001; exp_size = 9001;
exp_size = size;
err = bpf_prog_test_run(prog_fd, 1, buf, size, topts.data_in = topts.data_out = buf;
buf, &size, &retval, &duration); topts.data_size_in = 9001;
topts.data_size_out = 16384;
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "9Kb+10b"); ASSERT_OK(err, "9Kb+10b");
ASSERT_EQ(retval, XDP_DROP, "9Kb+10b retval"); ASSERT_EQ(topts.retval, XDP_DROP, "9Kb+10b retval");
ASSERT_EQ(size, exp_size, "9Kb+10b size"); ASSERT_EQ(topts.data_size_out, exp_size, "9Kb+10b size");
free(buf); free(buf);
out: out:
......
...@@ -45,9 +45,9 @@ static void run_xdp_bpf2bpf_pkt_size(int pkt_fd, struct perf_buffer *pb, ...@@ -45,9 +45,9 @@ static void run_xdp_bpf2bpf_pkt_size(int pkt_fd, struct perf_buffer *pb,
struct test_xdp_bpf2bpf *ftrace_skel, struct test_xdp_bpf2bpf *ftrace_skel,
int pkt_size) int pkt_size)
{ {
__u32 duration = 0, retval, size;
__u8 *buf, *buf_in; __u8 *buf, *buf_in;
int err; int err;
LIBBPF_OPTS(bpf_test_run_opts, topts);
if (!ASSERT_LE(pkt_size, BUF_SZ, "pkt_size") || if (!ASSERT_LE(pkt_size, BUF_SZ, "pkt_size") ||
!ASSERT_GE(pkt_size, sizeof(pkt_v4), "pkt_size")) !ASSERT_GE(pkt_size, sizeof(pkt_v4), "pkt_size"))
...@@ -73,12 +73,16 @@ static void run_xdp_bpf2bpf_pkt_size(int pkt_fd, struct perf_buffer *pb, ...@@ -73,12 +73,16 @@ static void run_xdp_bpf2bpf_pkt_size(int pkt_fd, struct perf_buffer *pb,
} }
/* Run test program */ /* Run test program */
err = bpf_prog_test_run(pkt_fd, 1, buf_in, pkt_size, topts.data_in = buf_in;
buf, &size, &retval, &duration); topts.data_size_in = pkt_size;
topts.data_out = buf;
topts.data_size_out = BUF_SZ;
err = bpf_prog_test_run_opts(pkt_fd, &topts);
ASSERT_OK(err, "ipv4"); ASSERT_OK(err, "ipv4");
ASSERT_EQ(retval, XDP_PASS, "ipv4 retval"); ASSERT_EQ(topts.retval, XDP_PASS, "ipv4 retval");
ASSERT_EQ(size, pkt_size, "ipv4 size"); ASSERT_EQ(topts.data_size_out, pkt_size, "ipv4 size");
/* Make sure bpf_xdp_output() was triggered and it sent the expected /* Make sure bpf_xdp_output() was triggered and it sent the expected
* data to the perf ring buffer. * data to the perf ring buffer.
......
...@@ -25,43 +25,49 @@ void test_xdp_noinline(void) ...@@ -25,43 +25,49 @@ void test_xdp_noinline(void)
__u8 flags; __u8 flags;
} real_def = {.dst = MAGIC_VAL}; } real_def = {.dst = MAGIC_VAL};
__u32 ch_key = 11, real_num = 3; __u32 ch_key = 11, real_num = 3;
__u32 duration = 0, retval, size;
int err, i; int err, i;
__u64 bytes = 0, pkts = 0; __u64 bytes = 0, pkts = 0;
char buf[128]; char buf[128];
u32 *magic = (u32 *)buf; u32 *magic = (u32 *)buf;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.data_out = buf,
.data_size_out = sizeof(buf),
.repeat = NUM_ITER,
);
skel = test_xdp_noinline__open_and_load(); skel = test_xdp_noinline__open_and_load();
if (CHECK(!skel, "skel_open_and_load", "failed\n")) if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
return; return;
bpf_map_update_elem(bpf_map__fd(skel->maps.vip_map), &key, &value, 0); bpf_map_update_elem(bpf_map__fd(skel->maps.vip_map), &key, &value, 0);
bpf_map_update_elem(bpf_map__fd(skel->maps.ch_rings), &ch_key, &real_num, 0); bpf_map_update_elem(bpf_map__fd(skel->maps.ch_rings), &ch_key, &real_num, 0);
bpf_map_update_elem(bpf_map__fd(skel->maps.reals), &real_num, &real_def, 0); bpf_map_update_elem(bpf_map__fd(skel->maps.reals), &real_num, &real_def, 0);
err = bpf_prog_test_run(bpf_program__fd(skel->progs.balancer_ingress_v4), err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.balancer_ingress_v4), &topts);
NUM_ITER, &pkt_v4, sizeof(pkt_v4), ASSERT_OK(err, "ipv4 test_run");
buf, &size, &retval, &duration); ASSERT_EQ(topts.retval, 1, "ipv4 test_run retval");
CHECK(err || retval != 1 || size != 54 || ASSERT_EQ(topts.data_size_out, 54, "ipv4 test_run data_size_out");
*magic != MAGIC_VAL, "ipv4", ASSERT_EQ(*magic, MAGIC_VAL, "ipv4 test_run magic");
"err %d errno %d retval %d size %d magic %x\n",
err, errno, retval, size, *magic);
err = bpf_prog_test_run(bpf_program__fd(skel->progs.balancer_ingress_v6), topts.data_in = &pkt_v6;
NUM_ITER, &pkt_v6, sizeof(pkt_v6), topts.data_size_in = sizeof(pkt_v6);
buf, &size, &retval, &duration); topts.data_out = buf;
CHECK(err || retval != 1 || size != 74 || topts.data_size_out = sizeof(buf);
*magic != MAGIC_VAL, "ipv6",
"err %d errno %d retval %d size %d magic %x\n", err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.balancer_ingress_v6), &topts);
err, errno, retval, size, *magic); ASSERT_OK(err, "ipv6 test_run");
ASSERT_EQ(topts.retval, 1, "ipv6 test_run retval");
ASSERT_EQ(topts.data_size_out, 74, "ipv6 test_run data_size_out");
ASSERT_EQ(*magic, MAGIC_VAL, "ipv6 test_run magic");
bpf_map_lookup_elem(bpf_map__fd(skel->maps.stats), &stats_key, stats); bpf_map_lookup_elem(bpf_map__fd(skel->maps.stats), &stats_key, stats);
for (i = 0; i < nr_cpus; i++) { for (i = 0; i < nr_cpus; i++) {
bytes += stats[i].bytes; bytes += stats[i].bytes;
pkts += stats[i].pkts; pkts += stats[i].pkts;
} }
CHECK(bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2, ASSERT_EQ(bytes, MAGIC_BYTES * NUM_ITER * 2, "stats bytes");
"stats", "bytes %lld pkts %lld\n", ASSERT_EQ(pkts, NUM_ITER * 2, "stats pkts");
(unsigned long long)bytes, (unsigned long long)pkts);
test_xdp_noinline__destroy(skel); test_xdp_noinline__destroy(skel);
} }
...@@ -4,22 +4,25 @@ ...@@ -4,22 +4,25 @@
void test_xdp_perf(void) void test_xdp_perf(void)
{ {
const char *file = "./xdp_dummy.o"; const char *file = "./xdp_dummy.o";
__u32 duration, retval, size;
struct bpf_object *obj; struct bpf_object *obj;
char in[128], out[128]; char in[128], out[128];
int err, prog_fd; int err, prog_fd;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = in,
.data_size_in = sizeof(in),
.data_out = out,
.data_size_out = sizeof(out),
.repeat = 1000000,
);
err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
if (CHECK_FAIL(err)) if (CHECK_FAIL(err))
return; return;
err = bpf_prog_test_run(prog_fd, 1000000, &in[0], 128, err = bpf_prog_test_run_opts(prog_fd, &topts);
out, &size, &retval, &duration); ASSERT_OK(err, "test_run");
ASSERT_EQ(topts.retval, XDP_PASS, "test_run retval");
CHECK(err || retval != XDP_PASS || size != 128, ASSERT_EQ(topts.data_size_out, 128, "test_run data_size_out");
"xdp-perf",
"err %d errno %d retval %d size %d\n",
err, errno, retval, size);
bpf_object__close(obj); bpf_object__close(obj);
} }
...@@ -61,7 +61,11 @@ static int bpf_map_lookup_elem_with_ref_bit(int fd, unsigned long long key, ...@@ -61,7 +61,11 @@ static int bpf_map_lookup_elem_with_ref_bit(int fd, unsigned long long key,
}; };
__u8 data[64] = {}; __u8 data[64] = {};
int mfd, pfd, ret, zero = 0; int mfd, pfd, ret, zero = 0;
__u32 retval = 0; LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = data,
.data_size_in = sizeof(data),
.repeat = 1,
);
mfd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(int), sizeof(__u64), 1, NULL); mfd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(int), sizeof(__u64), 1, NULL);
if (mfd < 0) if (mfd < 0)
...@@ -75,9 +79,8 @@ static int bpf_map_lookup_elem_with_ref_bit(int fd, unsigned long long key, ...@@ -75,9 +79,8 @@ static int bpf_map_lookup_elem_with_ref_bit(int fd, unsigned long long key,
return -1; return -1;
} }
ret = bpf_prog_test_run(pfd, 1, data, sizeof(data), ret = bpf_prog_test_run_opts(pfd, &topts);
NULL, NULL, &retval, NULL); if (ret < 0 || topts.retval != 42) {
if (ret < 0 || retval != 42) {
ret = -1; ret = -1;
} else { } else {
assert(!bpf_map_lookup_elem(mfd, &zero, value)); assert(!bpf_map_lookup_elem(mfd, &zero, value));
......
...@@ -1021,13 +1021,18 @@ static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val, ...@@ -1021,13 +1021,18 @@ static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
{ {
__u8 tmp[TEST_DATA_LEN << 2]; __u8 tmp[TEST_DATA_LEN << 2];
__u32 size_tmp = sizeof(tmp); __u32 size_tmp = sizeof(tmp);
uint32_t retval;
int err, saved_errno; int err, saved_errno;
LIBBPF_OPTS(bpf_test_run_opts, topts,
.data_in = data,
.data_size_in = size_data,
.data_out = tmp,
.data_size_out = size_tmp,
.repeat = 1,
);
if (unpriv) if (unpriv)
set_admin(true); set_admin(true);
err = bpf_prog_test_run(fd_prog, 1, data, size_data, err = bpf_prog_test_run_opts(fd_prog, &topts);
tmp, &size_tmp, &retval, NULL);
saved_errno = errno; saved_errno = errno;
if (unpriv) if (unpriv)
...@@ -1051,9 +1056,8 @@ static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val, ...@@ -1051,9 +1056,8 @@ static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
} }
} }
if (retval != expected_val && if (topts.retval != expected_val && expected_val != POINTER_VALUE) {
expected_val != POINTER_VALUE) { printf("FAIL retval %d != %d ", topts.retval, expected_val);
printf("FAIL retval %d != %d ", retval, expected_val);
return 1; return 1;
} }
......
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