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 | union bpf_attr __user *uattr); | 1156 | union bpf_attr __user *uattr); |
| 1157 | int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, | 1157 | int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, |
| 1158 | union bpf_attr __user *uattr); | 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 | int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, | 1162 | int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, |
| 1160 | const union bpf_attr *kattr, | 1163 | const union bpf_attr *kattr, |
| 1161 | union bpf_attr __user *uattr); | 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 | return -ENOTSUPP; | 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 | static inline int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, | 1326 | static inline int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog, |
| 1317 | const union bpf_attr *kattr, | 1327 | const union bpf_attr *kattr, |
| 1318 | union bpf_attr __user *uattr) | 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 | const struct bpf_prog_ops tracing_prog_ops = { | 1268 | const struct bpf_prog_ops tracing_prog_ops = { |
| 1269 | .test_run = bpf_prog_test_run_tracing, | ||
| 1269 | }; | 1270 | }; |
| 1270 | 1271 | ||
| 1271 | static bool raw_tp_writable_prog_is_valid_access(int off, int size, | 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 | kfree(data); | 160 | kfree(data); |
| 161 | return ERR_PTR(-EFAULT); | 161 | return ERR_PTR(-EFAULT); |
| 162 | } | 162 | } |
| 163 | if (bpf_fentry_test1(1) != 2 || | 163 | |
| 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 | } | ||
| 172 | return data; | 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 | static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size) | 194 | static void *bpf_ctx_init(const union bpf_attr *kattr, u32 max_size) |
| 176 | { | 195 | { |
| 177 | void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in); | 196 | void __user *data_in = u64_to_user_ptr(kattr->test.ctx_in); |
| @@ -1,22 +1,17 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* Copyright (c) 2019 Facebook */ | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | #include <test_progs.h> | 3 | #include <test_progs.h> |
| 4 | #include "test_pkt_access.skel.h" | ||
| 5 | #include "fentry_test.skel.h" | 4 | #include "fentry_test.skel.h" |
| 6 | #include "fexit_test.skel.h" | 5 | #include "fexit_test.skel.h" |
| 7 | 6 | ||
| 8 | void test_fentry_fexit(void) | 7 | void test_fentry_fexit(void) |
| 9 | { | 8 | { |
| 10 | struct test_pkt_access *pkt_skel = NULL; | ||
| 11 | struct fentry_test *fentry_skel = NULL; | 9 | struct fentry_test *fentry_skel = NULL; |
| 12 | struct fexit_test *fexit_skel = NULL; | 10 | struct fexit_test *fexit_skel = NULL; |
| 13 | __u64 *fentry_res, *fexit_res; | 11 | __u64 *fentry_res, *fexit_res; |
| 14 | __u32 duration = 0, retval; | 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 | fentry_skel = fentry_test__open_and_load(); | 15 | fentry_skel = fentry_test__open_and_load(); |
| 21 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) | 16 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) |
| 22 | goto close_prog; | 17 | goto close_prog; |
| @@ -31,8 +26,8 @@ void test_fentry_fexit(void) · 8 unmodified lines | |||
| 31 | if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) | 26 | if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) |
| 32 | goto close_prog; | 27 | goto close_prog; |
| 33 | 28 | ||
| 34 | pkt_fd = bpf_program__fd(pkt_skel->progs.test_pkt_access); | 29 | prog_fd = bpf_program__fd(fexit_skel->progs.test1); |
| 35 | err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | 30 | err = bpf_prog_test_run(prog_fd, 1, NULL, 0, |
| 36 | NULL, NULL, &retval, &duration); | 31 | NULL, NULL, &retval, &duration); |
| 37 | CHECK(err || retval, "ipv6", | 32 | CHECK(err || retval, "ipv6", |
| 38 | "err %d errno %d retval %d duration %d\n", | 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 | close_prog: | 46 | close_prog: |
| 52 | test_pkt_access__destroy(pkt_skel); | ||
| 53 | fentry_test__destroy(fentry_skel); | 47 | fentry_test__destroy(fentry_skel); |
| 54 | fexit_test__destroy(fexit_skel); | 48 | fexit_test__destroy(fexit_skel); |
| 55 | } | 49 | } |
| @@ -1,20 +1,15 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* Copyright (c) 2019 Facebook */ | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | #include <test_progs.h> | 3 | #include <test_progs.h> |
| 4 | #include "test_pkt_access.skel.h" | ||
| 5 | #include "fentry_test.skel.h" | 4 | #include "fentry_test.skel.h" |
| 6 | 5 | ||
| 7 | void test_fentry_test(void) | 6 | void test_fentry_test(void) |
| 8 | { | 7 | { |
| 9 | struct test_pkt_access *pkt_skel = NULL; | ||
| 10 | struct fentry_test *fentry_skel = NULL; | 8 | struct fentry_test *fentry_skel = NULL; |
| 11 | int err, pkt_fd, i; | 9 | int err, prog_fd, i; |
| 12 | __u32 duration = 0, retval; | 10 | __u32 duration = 0, retval; |
| 13 | __u64 *result; | 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 | fentry_skel = fentry_test__open_and_load(); | 13 | fentry_skel = fentry_test__open_and_load(); |
| 19 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) | 14 | if (CHECK(!fentry_skel, "fentry_skel_load", "fentry skeleton failed\n")) |
| 20 | goto cleanup; | 15 | goto cleanup; |
| @@ -23,10 +18,10 @@ void test_fentry_test(void) · 2 unmodified lines | |||
| 23 | if (CHECK(err, "fentry_attach", "fentry attach failed: %d\n", err)) | 18 | if (CHECK(err, "fentry_attach", "fentry attach failed: %d\n", err)) |
| 24 | goto cleanup; | 19 | goto cleanup; |
| 25 | 20 | ||
| 26 | pkt_fd = bpf_program__fd(pkt_skel->progs.test_pkt_access); | 21 | prog_fd = bpf_program__fd(fentry_skel->progs.test1); |
| 27 | err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), | 22 | err = bpf_prog_test_run(prog_fd, 1, NULL, 0, |
| 28 | NULL, NULL, &retval, &duration); | 23 | NULL, NULL, &retval, &duration); |
| 29 | CHECK(err || retval, "ipv6", | 24 | CHECK(err || retval, "test_run", |
| 30 | "err %d errno %d retval %d duration %d\n", | 25 | "err %d errno %d retval %d duration %d\n", |
| 31 | err, errno, retval, duration); | 26 | err, errno, retval, duration); |
| 32 | 27 | ||
| @@ -39,5 +34,4 @@ void test_fentry_test(void) · 6 unmodified lines | |||
| 39 | 34 | ||
| 40 | cleanup: | 35 | cleanup: |
| 41 | fentry_test__destroy(fentry_skel); | 36 | fentry_test__destroy(fentry_skel); |
| 42 | test_pkt_access__destroy(pkt_skel); | ||
| 43 | } | 37 | } |
| @@ -1,64 +1,37 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* Copyright (c) 2019 Facebook */ | 2 | /* Copyright (c) 2019 Facebook */ |
| 3 | #include <test_progs.h> | 3 | #include <test_progs.h> |
| 4 | #include "fexit_test.skel.h" | ||
| 4 | 5 | ||
| 5 | void test_fexit_test(void) | 6 | void test_fexit_test(void) |
| 6 | { | 7 | { |
| 7 | struct bpf_prog_load_attr attr = { | 8 | struct fexit_test *fexit_skel = NULL; |
| 8 | .file = "./fexit_test.o", | 9 | int err, prog_fd, i; |
| 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]; | ||
| 16 | __u32 duration = 0, retval; | 10 | __u32 duration = 0, retval; |
| 17 | struct bpf_map *data_map; | 11 | __u64 *result; |
| 18 | const int zero = 0; | ||
| 19 | u64 result[6]; | ||
| 20 | 12 | ||
| 21 | err = bpf_prog_load("./test_pkt_access.o", BPF_PROG_TYPE_SCHED_CLS, | 13 | fexit_skel = fexit_test__open_and_load(); |
| 22 | &pkt_obj, &pkt_fd); | 14 | if (CHECK(!fexit_skel, "fexit_skel_load", "fexit skeleton failed\n")) |
| 23 | if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno)) | 15 | goto cleanup; |
| 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; | ||
| 28 | 16 | ||
| 29 | for (i = 0; i < 6; i++) { | 17 | err = fexit_test__attach(fexit_skel); |
| 30 | prog_name[sizeof(prog_name) - 2] = '1' + i; | 18 | if (CHECK(err, "fexit_attach", "fexit attach failed: %d\n", err)) |
| 31 | prog[i] = bpf_object__find_program_by_title(obj, prog_name); | 19 | goto cleanup; |
| 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; | ||
| 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 | NULL, NULL, &retval, &duration); | 23 | NULL, NULL, &retval, &duration); |
| 44 | CHECK(err || retval, "ipv6", | 24 | CHECK(err || retval, "test_run", |
| 45 | "err %d errno %d retval %d duration %d\n", | 25 | "err %d errno %d retval %d duration %d\n", |
| 46 | err, errno, retval, duration); | 26 | err, errno, retval, duration); |
| 47 | 27 | ||
| 48 | err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, &result); | 28 | result = (__u64 *)fexit_skel->bss; |
| 49 | if (CHECK(err, "get_result", | 29 | for (i = 0; i < 6; i++) { |
| 50 | "failed to get output data: %d\n", err)) | 30 | if (CHECK(result[i] != 1, "result", |
| 51 | goto close_prog; | 31 | "fexit_test%d failed err %lld\n", i + 1, result[i])) |
| 52 | 32 | goto cleanup; | |
| 53 | for (i = 0; i < 6; i++) | 33 | } |
| 54 | if (CHECK(result[i] != 1, "result", "bpf_fentry_test%d failed err %ld\n", | ||
| 55 | i + 1, result[i])) | ||
| 56 | goto close_prog; | ||
| 57 | 34 | ||
| 58 | close_prog: | 35 | cleanup: |
| 59 | for (i = 0; i < 6; i++) | 36 | fexit_test__destroy(fexit_skel); |
| 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); | ||
| 64 | } | 37 | } |