The current fexit and fentry tests rely on a different program to exercise the functions they attach to. Instead of doing this, implement the test operations for tracing which will also be used for BPF_MODIFY_RETURN in a subsequent patch. Also, clean up the fexit test to use the generated skeleton.
Unified · Split
| @@ -1156,6 +1156,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, · 1155 unmodified lines | ||
| 1156 | 1156 | union bpf_attr __user *uattr); |
| 1157 | 1157 | int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, |
| 1158 | 1158 | union bpf_attr __user *uattr); |
| 1159 | +int bpf_prog_test_run_tracing(struct bpf_prog *prog, | |
| 1160 | + const union bpf_attr *kattr, | |
| 1161 | + union bpf_attr __user *uattr); | |
| 1159 | 1162 | int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, |
| 1160 | 1163 | const union bpf_attr *kattr, |
| 1161 | 1164 | union bpf_attr __user *uattr); |
| @@ -1313,6 +1316,13 @@ static inline int bpf_prog_test_run_skb(struct bpf_prog *prog, · 151 unmodified lines | ||
| 1313 | 1316 | return -ENOTSUPP; |
| 1314 | 1317 | } |
| 1315 | 1318 | |
| 1319 | +static inline int bpf_prog_test_run_tracing(struct bpf_prog *prog, | |
| 1320 | + const union bpf_attr *kattr, | |
| 1321 | + union bpf_attr __user *uattr) | |
| 1322 | +{ | |
| 1323 | + return -ENOTSUPP; | |
| 1324 | +} | |
| 1325 | + | |
| 1316 | 1326 | static inline int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, |
| 1317 | 1327 | const union bpf_attr *kattr, |
| 1318 | 1328 | union bpf_attr __user *uattr) |
| @@ -1266,6 +1266,7 @@ const struct bpf_verifier_ops tracing_verifier_ops = { · 1265 unmodified lines | ||
| 1266 | 1266 | }; |
| 1267 | 1267 | |
| 1268 | 1268 | const struct bpf_prog_ops tracing_prog_ops = { |
| 1269 | + .test_run = bpf_prog_test_run_tracing, | |
| 1269 | 1270 | }; |
| 1270 | 1271 | |
| 1271 | 1272 | static bool raw_tp_writable_prog_is_valid_access(int off, int size, |
| @@ -160,18 +160,37 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 size, · 159 unmodified lines | ||
| 160 | 160 | kfree(data); |
| 161 | 161 | return ERR_PTR(-EFAULT); |
| 162 | 162 | } |
| 163 | − if (bpf_fentry_test1(1) != 2 || | |
| 164 | − bpf_fentry_test2(2, 3) != 5 || | |
| 165 | − bpf_fentry_test3(4, 5, 6) != 15 || | |
| 166 | − bpf_fentry_test4((void *)7, 8, 9, 10) != 34 || | |
| 167 | − bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 || | |
| 168 | − bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111) { | |
| 169 | − kfree(data); | |
| 170 | − return ERR_PTR(-EFAULT); | |
| 171 | − } | |
| 163 | + | |
| 172 | 164 | return data; |
| 173 | 165 | } |
| 174 | 166 | |
| 167 | +int bpf_prog_test_run_tracing(struct bpf_prog *prog, | |
| 168 | + const union bpf_attr *kattr, | |
| 169 | + union bpf_attr __user *uattr) | |
| 170 | +{ | |
| 171 | + int err = -EFAULT; | |
| 172 | + | |
| 173 | + switch (prog->expected_attach_type) { | |
| 174 | + case BPF_TRACE_FENTRY: | |
| 175 | + case BPF_TRACE_FEXIT: | |
| 176 | + if (bpf_fentry_test1(1) != 2 || | |
| 177 | + bpf_fentry_test2(2, 3) != 5 || | |
| 178 | + bpf_fentry_test3(4, 5, 6) != 15 || | |
| 179 | + bpf_fentry_test4((void *)7, 8, 9, 10) != 34 || | |
| 180 | + bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 || | |
| 181 | + bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111) | |
| 182 | + goto out; | |
| 183 | + break; | |
| 184 | + default: | |
| 185 | + goto out; | |
| 186 | + } | |
| 187 | + | |
| 188 | + err = 0; | |
| 189 | +out: | |
| 190 | + trace_bpf_test_finish(&err); | |
| 191 | + return err; | |
| 192 | +} | |
| 193 | + | |
| 175 | 194 | static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size) |
| 176 | 195 | { |
| 177 | 196 | void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in); |
| @@ -1,22 +1,17 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | 3 | #include <test_progs.h> |
| 4 | −#include "test_pkt_access.skel.h" | |
| 5 | 4 | #include "fentry_test.skel.h" |
| 6 | 5 | #include "fexit_test.skel.h" |
| 7 | 6 | |
| 8 | 7 | void test_fentry_fexit(void) |
| 9 | 8 | { |
| 10 | − struct test_pkt_access *pkt_skel = NULL; | |
| 11 | 9 | struct fentry_test *fentry_skel = NULL; |
| 12 | 10 | struct fexit_test *fexit_skel = NULL; |
| 13 | 11 | __u64 *fentry_res, *fexit_res; |
| 14 | 12 | __u32 duration = 0, retval; |
| 15 | − int err, pkt_fd, i; | |
| 13 | + int err, prog_fd, i; | |
| 16 | 14 | |
| 17 | − pkt_skel = test_pkt_access__open_and_load(); | |
| 18 | − if (CHECK(!pkt_skel, "pkt_skel_load", "pkt_access skeleton failed\n")) | |
| 19 | − return; | |
| 20 | 15 | fentry_skel = fentry_test__open_and_load(); |
| 21 | 16 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) |
| 22 | 17 | goto close_prog; |
| @@ -31,8 +26,8 @@ void test_fentry_fexit(void) · 8 unmodified lines | ||
| 31 | 26 | if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) |
| 32 | 27 | goto close_prog; |
| 33 | 28 | |
| 34 | − pkt_fd = bpf_program__fd(pkt_skel->progs.test_pkt_access); | |
| 35 | − err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | |
| 29 | + prog_fd = bpf_program__fd(fexit_skel->progs.test1); | |
| 30 | + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, | |
| 36 | 31 | NULL, NULL, &retval, &duration); |
| 37 | 32 | CHECK(err || retval, "ipv6", |
| 38 | 33 | "err %d errno %d retval %d duration %d\n", |
| @@ -49,7 +44,6 @@ void test_fentry_fexit(void) · 10 unmodified lines | ||
| 49 | 44 | } |
| 50 | 45 | |
| 51 | 46 | close_prog: |
| 52 | − test_pkt_access__destroy(pkt_skel); | |
| 53 | 47 | fentry_test__destroy(fentry_skel); |
| 54 | 48 | fexit_test__destroy(fexit_skel); |
| 55 | 49 | } |
| @@ -1,20 +1,15 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | 3 | #include <test_progs.h> |
| 4 | −#include "test_pkt_access.skel.h" | |
| 5 | 4 | #include "fentry_test.skel.h" |
| 6 | 5 | |
| 7 | 6 | void test_fentry_test(void) |
| 8 | 7 | { |
| 9 | − struct test_pkt_access *pkt_skel = NULL; | |
| 10 | 8 | struct fentry_test *fentry_skel = NULL; |
| 11 | − int err, pkt_fd, i; | |
| 9 | + int err, prog_fd, i; | |
| 12 | 10 | __u32 duration = 0, retval; |
| 13 | 11 | __u64 *result; |
| 14 | 12 | |
| 15 | − pkt_skel = test_pkt_access__open_and_load(); | |
| 16 | − if (CHECK(!pkt_skel, "pkt_skel_load", "pkt_access skeleton failed\n")) | |
| 17 | − return; | |
| 18 | 13 | fentry_skel = fentry_test__open_and_load(); |
| 19 | 14 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) |
| 20 | 15 | goto cleanup; |
| @@ -23,10 +18,10 @@ void test_fentry_test(void) · 2 unmodified lines | ||
| 23 | 18 | if (CHECK(err, "fentry_attach", "fentry attach failed: %d\n", err)) |
| 24 | 19 | goto cleanup; |
| 25 | 20 | |
| 26 | − pkt_fd = bpf_program__fd(pkt_skel->progs.test_pkt_access); | |
| 27 | − err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | |
| 21 | + prog_fd = bpf_program__fd(fentry_skel->progs.test1); | |
| 22 | + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, | |
| 28 | 23 | NULL, NULL, &retval, &duration); |
| 29 | − CHECK(err || retval, "ipv6", | |
| 24 | + CHECK(err || retval, "test_run", | |
| 30 | 25 | "err %d errno %d retval %d duration %d\n", |
| 31 | 26 | err, errno, retval, duration); |
| 32 | 27 | |
| @@ -39,5 +34,4 @@ void test_fentry_test(void) · 6 unmodified lines | ||
| 39 | 34 | |
| 40 | 35 | cleanup: |
| 41 | 36 | fentry_test__destroy(fentry_skel); |
| 42 | − test_pkt_access__destroy(pkt_skel); | |
| 43 | 37 | } |
| @@ -1,64 +1,37 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | 3 | #include <test_progs.h> |
| 4 | +#include "fexit_test.skel.h" | |
| 4 | 5 | |
| 5 | 6 | void test_fexit_test(void) |
| 6 | 7 | { |
| 7 | − struct bpf_prog_load_attr attr = { | |
| 8 | − .file = "./fexit_test.o", | |
| 9 | − }; | |
| 10 | − | |
| 11 | − char prog_name[] = "fexit/bpf_fentry_testX"; | |
| 12 | − struct bpf_object *obj = NULL, *pkt_obj; | |
| 13 | − int err, pkt_fd, kfree_skb_fd, i; | |
| 14 | − struct bpf_link *link[6] = {}; | |
| 15 | − struct bpf_program *prog[6]; | |
| 8 | + struct fexit_test *fexit_skel = NULL; | |
| 9 | + int err, prog_fd, i; | |
| 16 | 10 | __u32 duration = 0, retval; |
| 17 | − struct bpf_map *data_map; | |
| 18 | − const int zero = 0; | |
| 19 | − u64 result[6]; | |
| 11 | + __u64 *result; | |
| 20 | 12 | |
| 21 | − err = bpf_prog_load("./test_pkt_access.o", BPF_PROG_TYPE_SCHED_CLS, | |
| 22 | − &pkt_obj, &pkt_fd); | |
| 23 | − if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno)) | |
| 24 | − return; | |
| 25 | − err = bpf_prog_load_xattr(&attr, &obj, &kfree_skb_fd); | |
| 26 | − if (CHECK(err, "prog_load fail", "err %d errno %d\n", err, errno)) | |
| 27 | − goto close_prog; | |
| 13 | + fexit_skel = fexit_test__open_and_load(); | |
| 14 | + if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) | |
| 15 | + goto cleanup; | |
| 28 | 16 | |
| 29 | − for (i = 0; i < 6; i++) { | |
| 30 | − prog_name[sizeof(prog_name) - 2] = '1' + i; | |
| 31 | − prog[i] = bpf_object__find_program_by_title(obj, prog_name); | |
| 32 | − if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name)) | |
| 33 | − goto close_prog; | |
| 34 | − link[i] = bpf_program__attach_trace(prog[i]); | |
| 35 | − if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n")) | |
| 36 | − goto close_prog; | |
| 37 | − } | |
| 38 | − data_map = bpf_object__find_map_by_name(obj, "fexit_te.bss"); | |
| 39 | − if (CHECK(!data_map, "find_data_map", "data map not found\n")) | |
| 40 | − goto close_prog; | |
| 17 | + err = fexit_test__attach(fexit_skel); | |
| 18 | + if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) | |
| 19 | + goto cleanup; | |
| 41 | 20 | |
| 42 | − err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | |
| 21 | + prog_fd = bpf_program__fd(fexit_skel->progs.test1); | |
| 22 | + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, | |
| 43 | 23 | NULL, NULL, &retval, &duration); |
| 44 | − CHECK(err || retval, "ipv6", | |
| 24 | + CHECK(err || retval, "test_run", | |
| 45 | 25 | "err %d errno %d retval %d duration %d\n", |
| 46 | 26 | err, errno, retval, duration); |
| 47 | 27 | |
| 48 | − err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, &result); | |
| 49 | − if (CHECK(err, "get_result", | |
| 50 | − "failed to get output data: %d\n", err)) | |
| 51 | − goto close_prog; | |
| 52 | − | |
| 53 | − for (i = 0; i < 6; i++) | |
| 54 | − if (CHECK(result[i] != 1, "result", "bpf_fentry_test%d failed err %ld\n", | |
| 55 | − i + 1, result[i])) | |
| 56 | − goto close_prog; | |
| 28 | + result = (__u64 *)fexit_skel->bss; | |
| 29 | + for (i = 0; i < 6; i++) { | |
| 30 | + if (CHECK(result[i] != 1, "result", | |
| 31 | + "fexit_test%d failed err %lld\n", i + 1, result[i])) | |
| 32 | + goto cleanup; | |
| 33 | + } | |
| 57 | 34 | |
| 58 | −close_prog: | |
| 59 | − for (i = 0; i < 6; i++) | |
| 60 | − if (!IS_ERR_OR_NULL(link[i])) | |
| 61 | − bpf_link__destroy(link[i]); | |
| 62 | − bpf_object__close(obj); | |
| 63 | − bpf_object__close(pkt_obj); | |
| 35 | +cleanup: | |
| 36 | + fexit_test__destroy(fexit_skel); | |
| 64 | 37 | } |