]>
Commit | Line | Data |
---|---|---|
d6f39601 AS |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2019 Facebook */ | |
3 | #include <test_progs.h> | |
488a23b8 | 4 | #include <network_helpers.h> |
f6429476 | 5 | #include <bpf/btf.h> |
ffd5cfca | 6 | #include "bind4_prog.skel.h" |
f6429476 THJ |
7 | |
8 | typedef int (*test_cb)(struct bpf_object *obj); | |
9 | ||
10 | static int check_data_map(struct bpf_object *obj, int prog_cnt, bool reset) | |
11 | { | |
12 | struct bpf_map *data_map = NULL, *map; | |
13 | __u64 *result = NULL; | |
14 | const int zero = 0; | |
15 | __u32 duration = 0; | |
16 | int ret = -1, i; | |
17 | ||
18 | result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64)); | |
19 | if (CHECK(!result, "alloc_memory", "failed to alloc memory")) | |
20 | return -ENOMEM; | |
21 | ||
22 | bpf_object__for_each_map(map, obj) | |
23 | if (bpf_map__is_internal(map)) { | |
24 | data_map = map; | |
25 | break; | |
26 | } | |
27 | if (CHECK(!data_map, "find_data_map", "data map not found\n")) | |
28 | goto out; | |
29 | ||
30 | ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); | |
31 | if (CHECK(ret, "get_result", | |
32 | "failed to get output data: %d\n", ret)) | |
33 | goto out; | |
34 | ||
35 | for (i = 0; i < prog_cnt; i++) { | |
36 | if (CHECK(result[i] != 1, "result", | |
37 | "fexit_bpf2bpf result[%d] failed err %llu\n", | |
38 | i, result[i])) | |
39 | goto out; | |
40 | result[i] = 0; | |
41 | } | |
42 | if (reset) { | |
43 | ret = bpf_map_update_elem(bpf_map__fd(data_map), &zero, result, 0); | |
44 | if (CHECK(ret, "reset_result", "failed to reset result\n")) | |
45 | goto out; | |
46 | } | |
47 | ||
48 | ret = 0; | |
49 | out: | |
50 | free(result); | |
51 | return ret; | |
52 | } | |
d6f39601 | 53 | |
8f9081c9 YS |
54 | static void test_fexit_bpf2bpf_common(const char *obj_file, |
55 | const char *target_obj_file, | |
56 | int prog_cnt, | |
1d8a0af5 | 57 | const char **prog_name, |
f6429476 THJ |
58 | bool run_prog, |
59 | test_cb cb) | |
d6f39601 | 60 | { |
f6429476 | 61 | struct bpf_object *obj = NULL, *tgt_obj; |
04fcb5f9 | 62 | __u32 tgt_prog_id, info_len; |
463c2149 | 63 | struct bpf_prog_info prog_info = {}; |
60aed220 | 64 | struct bpf_program **prog = NULL, *p; |
f6429476 | 65 | struct bpf_link **link = NULL; |
f6429476 | 66 | int err, tgt_fd, i; |
463c2149 | 67 | struct btf *btf; |
04fcb5f9 DK |
68 | LIBBPF_OPTS(bpf_test_run_opts, topts, |
69 | .data_in = &pkt_v6, | |
70 | .data_size_in = sizeof(pkt_v6), | |
71 | .repeat = 1, | |
72 | ); | |
d6f39601 | 73 | |
cbdb1461 | 74 | err = bpf_prog_test_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, |
f6429476 | 75 | &tgt_obj, &tgt_fd); |
463c2149 | 76 | if (!ASSERT_OK(err, "tgt_prog_load")) |
d6f39601 | 77 | return; |
d6f39601 | 78 | |
463c2149 THJ |
79 | info_len = sizeof(prog_info); |
80 | err = bpf_obj_get_info_by_fd(tgt_fd, &prog_info, &info_len); | |
81 | if (!ASSERT_OK(err, "tgt_fd_get_info")) | |
82 | goto close_prog; | |
83 | ||
84 | tgt_prog_id = prog_info.id; | |
85 | btf = bpf_object__btf(tgt_obj); | |
86 | ||
8f9081c9 | 87 | link = calloc(sizeof(struct bpf_link *), prog_cnt); |
463c2149 THJ |
88 | if (!ASSERT_OK_PTR(link, "link_ptr")) |
89 | goto close_prog; | |
90 | ||
8f9081c9 | 91 | prog = calloc(sizeof(struct bpf_program *), prog_cnt); |
463c2149 | 92 | if (!ASSERT_OK_PTR(prog, "prog_ptr")) |
8f9081c9 YS |
93 | goto close_prog; |
94 | ||
60aed220 | 95 | obj = bpf_object__open_file(obj_file, NULL); |
463c2149 | 96 | if (!ASSERT_OK_PTR(obj, "obj_open")) |
d6f39601 AS |
97 | goto close_prog; |
98 | ||
60aed220 AN |
99 | bpf_object__for_each_program(p, obj) { |
100 | err = bpf_program__set_attach_target(p, tgt_fd, NULL); | |
101 | ASSERT_OK(err, "set_attach_target"); | |
102 | } | |
103 | ||
d6f39601 | 104 | err = bpf_object__load(obj); |
463c2149 | 105 | if (!ASSERT_OK(err, "obj_load")) |
d6f39601 AS |
106 | goto close_prog; |
107 | ||
8f9081c9 | 108 | for (i = 0; i < prog_cnt; i++) { |
463c2149 | 109 | struct bpf_link_info link_info; |
a393ea80 KFL |
110 | struct bpf_program *pos; |
111 | const char *pos_sec_name; | |
463c2149 THJ |
112 | char *tgt_name; |
113 | __s32 btf_id; | |
114 | ||
115 | tgt_name = strstr(prog_name[i], "/"); | |
116 | if (!ASSERT_OK_PTR(tgt_name, "tgt_name")) | |
117 | goto close_prog; | |
118 | btf_id = btf__find_by_name_kind(btf, tgt_name + 1, BTF_KIND_FUNC); | |
119 | ||
a393ea80 KFL |
120 | prog[i] = NULL; |
121 | bpf_object__for_each_program(pos, obj) { | |
122 | pos_sec_name = bpf_program__section_name(pos); | |
123 | if (pos_sec_name && !strcmp(pos_sec_name, prog_name[i])) { | |
124 | prog[i] = pos; | |
125 | break; | |
126 | } | |
127 | } | |
463c2149 | 128 | if (!ASSERT_OK_PTR(prog[i], prog_name[i])) |
d6f39601 | 129 | goto close_prog; |
463c2149 | 130 | |
d6f39601 | 131 | link[i] = bpf_program__attach_trace(prog[i]); |
463c2149 | 132 | if (!ASSERT_OK_PTR(link[i], "attach_trace")) |
d6f39601 | 133 | goto close_prog; |
463c2149 THJ |
134 | |
135 | info_len = sizeof(link_info); | |
136 | memset(&link_info, 0, sizeof(link_info)); | |
137 | err = bpf_obj_get_info_by_fd(bpf_link__fd(link[i]), | |
138 | &link_info, &info_len); | |
139 | ASSERT_OK(err, "link_fd_get_info"); | |
140 | ASSERT_EQ(link_info.tracing.attach_type, | |
379d19ec | 141 | bpf_program__expected_attach_type(prog[i]), |
463c2149 THJ |
142 | "link_attach_type"); |
143 | ASSERT_EQ(link_info.tracing.target_obj_id, tgt_prog_id, "link_tgt_obj_id"); | |
144 | ASSERT_EQ(link_info.tracing.target_btf_id, btf_id, "link_tgt_btf_id"); | |
d6f39601 | 145 | } |
1d8a0af5 | 146 | |
f6429476 THJ |
147 | if (cb) { |
148 | err = cb(obj); | |
149 | if (err) | |
150 | goto close_prog; | |
151 | } | |
1d8a0af5 | 152 | |
f6429476 | 153 | if (!run_prog) |
d6f39601 AS |
154 | goto close_prog; |
155 | ||
04fcb5f9 | 156 | err = bpf_prog_test_run_opts(tgt_fd, &topts); |
463c2149 | 157 | ASSERT_OK(err, "prog_run"); |
04fcb5f9 | 158 | ASSERT_EQ(topts.retval, 0, "prog_run_ret"); |
d6f39601 | 159 | |
f6429476 | 160 | if (check_data_map(obj, prog_cnt, false)) |
d6f39601 AS |
161 | goto close_prog; |
162 | ||
d6f39601 | 163 | close_prog: |
8f9081c9 | 164 | for (i = 0; i < prog_cnt; i++) |
bad2e478 AN |
165 | bpf_link__destroy(link[i]); |
166 | bpf_object__close(obj); | |
f6429476 | 167 | bpf_object__close(tgt_obj); |
8f9081c9 YS |
168 | free(link); |
169 | free(prog); | |
8f9081c9 YS |
170 | } |
171 | ||
172 | static void test_target_no_callees(void) | |
173 | { | |
174 | const char *prog_name[] = { | |
175 | "fexit/test_pkt_md_access", | |
176 | }; | |
afef88e6 DM |
177 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.bpf.o", |
178 | "./test_pkt_md_access.bpf.o", | |
8f9081c9 | 179 | ARRAY_SIZE(prog_name), |
f6429476 | 180 | prog_name, true, NULL); |
8f9081c9 YS |
181 | } |
182 | ||
183 | static void test_target_yes_callees(void) | |
184 | { | |
185 | const char *prog_name[] = { | |
186 | "fexit/test_pkt_access", | |
187 | "fexit/test_pkt_access_subprog1", | |
188 | "fexit/test_pkt_access_subprog2", | |
7608e4db | 189 | "fexit/test_pkt_access_subprog3", |
8f9081c9 | 190 | }; |
afef88e6 DM |
191 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf.bpf.o", |
192 | "./test_pkt_access.bpf.o", | |
8f9081c9 | 193 | ARRAY_SIZE(prog_name), |
f6429476 | 194 | prog_name, true, NULL); |
8f9081c9 YS |
195 | } |
196 | ||
7805fe84 AS |
197 | static void test_func_replace(void) |
198 | { | |
199 | const char *prog_name[] = { | |
200 | "fexit/test_pkt_access", | |
201 | "fexit/test_pkt_access_subprog1", | |
202 | "fexit/test_pkt_access_subprog2", | |
203 | "fexit/test_pkt_access_subprog3", | |
204 | "freplace/get_skb_len", | |
205 | "freplace/get_skb_ifindex", | |
206 | "freplace/get_constant", | |
6dc03dc7 | 207 | "freplace/test_pkt_write_access_subprog", |
7805fe84 | 208 | }; |
afef88e6 DM |
209 | test_fexit_bpf2bpf_common("./fexit_bpf2bpf.bpf.o", |
210 | "./test_pkt_access.bpf.o", | |
7805fe84 | 211 | ARRAY_SIZE(prog_name), |
f6429476 | 212 | prog_name, true, NULL); |
1d8a0af5 THJ |
213 | } |
214 | ||
215 | static void test_func_replace_verify(void) | |
216 | { | |
217 | const char *prog_name[] = { | |
218 | "freplace/do_bind", | |
219 | }; | |
afef88e6 DM |
220 | test_fexit_bpf2bpf_common("./freplace_connect4.bpf.o", |
221 | "./connect4_prog.bpf.o", | |
1d8a0af5 | 222 | ARRAY_SIZE(prog_name), |
f6429476 THJ |
223 | prog_name, false, NULL); |
224 | } | |
225 | ||
226 | static int test_second_attach(struct bpf_object *obj) | |
227 | { | |
a393ea80 KFL |
228 | const char *prog_name = "security_new_get_constant"; |
229 | const char *tgt_name = "get_constant"; | |
afef88e6 | 230 | const char *tgt_obj_file = "./test_pkt_access.bpf.o"; |
f6429476 THJ |
231 | struct bpf_program *prog = NULL; |
232 | struct bpf_object *tgt_obj; | |
f6429476 THJ |
233 | struct bpf_link *link; |
234 | int err = 0, tgt_fd; | |
04fcb5f9 DK |
235 | LIBBPF_OPTS(bpf_test_run_opts, topts, |
236 | .data_in = &pkt_v6, | |
237 | .data_size_in = sizeof(pkt_v6), | |
238 | .repeat = 1, | |
239 | ); | |
f6429476 | 240 | |
a393ea80 | 241 | prog = bpf_object__find_program_by_name(obj, prog_name); |
04fcb5f9 | 242 | if (!ASSERT_OK_PTR(prog, "find_prog")) |
f6429476 THJ |
243 | return -ENOENT; |
244 | ||
cbdb1461 | 245 | err = bpf_prog_test_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC, |
f6429476 | 246 | &tgt_obj, &tgt_fd); |
04fcb5f9 | 247 | if (!ASSERT_OK(err, "second_prog_load")) |
f6429476 THJ |
248 | return err; |
249 | ||
250 | link = bpf_program__attach_freplace(prog, tgt_fd, tgt_name); | |
bad2e478 | 251 | if (!ASSERT_OK_PTR(link, "second_link")) |
f6429476 THJ |
252 | goto out; |
253 | ||
04fcb5f9 DK |
254 | err = bpf_prog_test_run_opts(tgt_fd, &topts); |
255 | if (!ASSERT_OK(err, "ipv6 test_run")) | |
256 | goto out; | |
257 | if (!ASSERT_OK(topts.retval, "ipv6 retval")) | |
f6429476 THJ |
258 | goto out; |
259 | ||
260 | err = check_data_map(obj, 1, true); | |
261 | if (err) | |
262 | goto out; | |
263 | ||
264 | out: | |
265 | bpf_link__destroy(link); | |
266 | bpf_object__close(tgt_obj); | |
267 | return err; | |
268 | } | |
269 | ||
270 | static void test_func_replace_multi(void) | |
271 | { | |
272 | const char *prog_name[] = { | |
273 | "freplace/get_constant", | |
274 | }; | |
afef88e6 DM |
275 | test_fexit_bpf2bpf_common("./freplace_get_constant.bpf.o", |
276 | "./test_pkt_access.bpf.o", | |
f6429476 THJ |
277 | ARRAY_SIZE(prog_name), |
278 | prog_name, true, test_second_attach); | |
7805fe84 AS |
279 | } |
280 | ||
bee4b7e6 THJ |
281 | static void test_fmod_ret_freplace(void) |
282 | { | |
283 | struct bpf_object *freplace_obj = NULL, *pkt_obj, *fmod_obj = NULL; | |
afef88e6 DM |
284 | const char *freplace_name = "./freplace_get_constant.bpf.o"; |
285 | const char *fmod_ret_name = "./fmod_ret_freplace.bpf.o"; | |
bee4b7e6 | 286 | DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); |
afef88e6 | 287 | const char *tgt_name = "./test_pkt_access.bpf.o"; |
bee4b7e6 THJ |
288 | struct bpf_link *freplace_link = NULL; |
289 | struct bpf_program *prog; | |
290 | __u32 duration = 0; | |
60aed220 | 291 | int err, pkt_fd, attach_prog_fd; |
bee4b7e6 | 292 | |
cbdb1461 | 293 | err = bpf_prog_test_load(tgt_name, BPF_PROG_TYPE_UNSPEC, |
bee4b7e6 THJ |
294 | &pkt_obj, &pkt_fd); |
295 | /* the target prog should load fine */ | |
296 | if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", | |
297 | tgt_name, err, errno)) | |
298 | return; | |
bee4b7e6 | 299 | |
60aed220 | 300 | freplace_obj = bpf_object__open_file(freplace_name, NULL); |
bad2e478 | 301 | if (!ASSERT_OK_PTR(freplace_obj, "freplace_obj_open")) |
bee4b7e6 THJ |
302 | goto out; |
303 | ||
6f2b219b | 304 | prog = bpf_object__next_program(freplace_obj, NULL); |
60aed220 AN |
305 | err = bpf_program__set_attach_target(prog, pkt_fd, NULL); |
306 | ASSERT_OK(err, "freplace__set_attach_target"); | |
307 | ||
bee4b7e6 THJ |
308 | err = bpf_object__load(freplace_obj); |
309 | if (CHECK(err, "freplace_obj_load", "err %d\n", err)) | |
310 | goto out; | |
311 | ||
bee4b7e6 | 312 | freplace_link = bpf_program__attach_trace(prog); |
bad2e478 | 313 | if (!ASSERT_OK_PTR(freplace_link, "freplace_attach_trace")) |
bee4b7e6 THJ |
314 | goto out; |
315 | ||
60aed220 | 316 | fmod_obj = bpf_object__open_file(fmod_ret_name, NULL); |
bad2e478 | 317 | if (!ASSERT_OK_PTR(fmod_obj, "fmod_obj_open")) |
bee4b7e6 THJ |
318 | goto out; |
319 | ||
60aed220 | 320 | attach_prog_fd = bpf_program__fd(prog); |
6f2b219b | 321 | prog = bpf_object__next_program(fmod_obj, NULL); |
60aed220 AN |
322 | err = bpf_program__set_attach_target(prog, attach_prog_fd, NULL); |
323 | ASSERT_OK(err, "fmod_ret_set_attach_target"); | |
324 | ||
bee4b7e6 THJ |
325 | err = bpf_object__load(fmod_obj); |
326 | if (CHECK(!err, "fmod_obj_load", "loading fmod_ret should fail\n")) | |
327 | goto out; | |
328 | ||
329 | out: | |
330 | bpf_link__destroy(freplace_link); | |
331 | bpf_object__close(freplace_obj); | |
332 | bpf_object__close(fmod_obj); | |
333 | bpf_object__close(pkt_obj); | |
334 | } | |
335 | ||
336 | ||
1410620c UP |
337 | static void test_func_sockmap_update(void) |
338 | { | |
339 | const char *prog_name[] = { | |
340 | "freplace/cls_redirect", | |
341 | }; | |
afef88e6 DM |
342 | test_fexit_bpf2bpf_common("./freplace_cls_redirect.bpf.o", |
343 | "./test_cls_redirect.bpf.o", | |
1410620c | 344 | ARRAY_SIZE(prog_name), |
f6429476 | 345 | prog_name, false, NULL); |
1410620c UP |
346 | } |
347 | ||
348 | static void test_obj_load_failure_common(const char *obj_file, | |
60aed220 | 349 | const char *target_obj_file) |
50d19736 UP |
350 | { |
351 | /* | |
352 | * standalone test that asserts failure to load freplace prog | |
353 | * because of invalid return code. | |
354 | */ | |
355 | struct bpf_object *obj = NULL, *pkt_obj; | |
60aed220 | 356 | struct bpf_program *prog; |
50d19736 UP |
357 | int err, pkt_fd; |
358 | __u32 duration = 0; | |
50d19736 | 359 | |
cbdb1461 | 360 | err = bpf_prog_test_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, |
50d19736 UP |
361 | &pkt_obj, &pkt_fd); |
362 | /* the target prog should load fine */ | |
363 | if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", | |
364 | target_obj_file, err, errno)) | |
365 | return; | |
50d19736 | 366 | |
60aed220 | 367 | obj = bpf_object__open_file(obj_file, NULL); |
bad2e478 | 368 | if (!ASSERT_OK_PTR(obj, "obj_open")) |
50d19736 UP |
369 | goto close_prog; |
370 | ||
6f2b219b | 371 | prog = bpf_object__next_program(obj, NULL); |
60aed220 AN |
372 | err = bpf_program__set_attach_target(prog, pkt_fd, NULL); |
373 | ASSERT_OK(err, "set_attach_target"); | |
374 | ||
50d19736 UP |
375 | /* It should fail to load the program */ |
376 | err = bpf_object__load(obj); | |
377 | if (CHECK(!err, "bpf_obj_load should fail", "err %d\n", err)) | |
378 | goto close_prog; | |
379 | ||
380 | close_prog: | |
bad2e478 | 381 | bpf_object__close(obj); |
50d19736 UP |
382 | bpf_object__close(pkt_obj); |
383 | } | |
384 | ||
1410620c UP |
385 | static void test_func_replace_return_code(void) |
386 | { | |
387 | /* test invalid return code in the replaced program */ | |
afef88e6 DM |
388 | test_obj_load_failure_common("./freplace_connect_v4_prog.bpf.o", |
389 | "./connect4_prog.bpf.o"); | |
1410620c UP |
390 | } |
391 | ||
392 | static void test_func_map_prog_compatibility(void) | |
393 | { | |
394 | /* test with spin lock map value in the replaced program */ | |
afef88e6 DM |
395 | test_obj_load_failure_common("./freplace_attach_probe.bpf.o", |
396 | "./test_attach_probe.bpf.o"); | |
1410620c UP |
397 | } |
398 | ||
2cf7b7ff THJ |
399 | static void test_func_replace_global_func(void) |
400 | { | |
401 | const char *prog_name[] = { | |
402 | "freplace/test_pkt_access", | |
403 | }; | |
404 | ||
afef88e6 DM |
405 | test_fexit_bpf2bpf_common("./freplace_global_func.bpf.o", |
406 | "./test_pkt_access.bpf.o", | |
2cf7b7ff THJ |
407 | ARRAY_SIZE(prog_name), |
408 | prog_name, false, NULL); | |
409 | } | |
410 | ||
ffd5cfca SF |
411 | static int find_prog_btf_id(const char *name, __u32 attach_prog_fd) |
412 | { | |
413 | struct bpf_prog_info info = {}; | |
414 | __u32 info_len = sizeof(info); | |
415 | struct btf *btf; | |
416 | int ret; | |
417 | ||
418 | ret = bpf_obj_get_info_by_fd(attach_prog_fd, &info, &info_len); | |
419 | if (ret) | |
420 | return ret; | |
421 | ||
422 | if (!info.btf_id) | |
423 | return -EINVAL; | |
424 | ||
425 | btf = btf__load_from_kernel_by_id(info.btf_id); | |
426 | ret = libbpf_get_error(btf); | |
427 | if (ret) | |
428 | return ret; | |
429 | ||
430 | ret = btf__find_by_name_kind(btf, name, BTF_KIND_FUNC); | |
431 | btf__free(btf); | |
432 | return ret; | |
433 | } | |
434 | ||
435 | static int load_fentry(int attach_prog_fd, int attach_btf_id) | |
436 | { | |
437 | LIBBPF_OPTS(bpf_prog_load_opts, opts, | |
438 | .expected_attach_type = BPF_TRACE_FENTRY, | |
439 | .attach_prog_fd = attach_prog_fd, | |
440 | .attach_btf_id = attach_btf_id, | |
441 | ); | |
442 | struct bpf_insn insns[] = { | |
443 | BPF_MOV64_IMM(BPF_REG_0, 0), | |
444 | BPF_EXIT_INSN(), | |
445 | }; | |
446 | ||
447 | return bpf_prog_load(BPF_PROG_TYPE_TRACING, | |
448 | "bind4_fentry", | |
449 | "GPL", | |
450 | insns, | |
451 | ARRAY_SIZE(insns), | |
452 | &opts); | |
453 | } | |
454 | ||
455 | static void test_fentry_to_cgroup_bpf(void) | |
456 | { | |
457 | struct bind4_prog *skel = NULL; | |
458 | struct bpf_prog_info info = {}; | |
459 | __u32 info_len = sizeof(info); | |
460 | int cgroup_fd = -1; | |
461 | int fentry_fd = -1; | |
462 | int btf_id; | |
463 | ||
464 | cgroup_fd = test__join_cgroup("/fentry_to_cgroup_bpf"); | |
465 | if (!ASSERT_GE(cgroup_fd, 0, "cgroup_fd")) | |
466 | return; | |
467 | ||
468 | skel = bind4_prog__open_and_load(); | |
469 | if (!ASSERT_OK_PTR(skel, "skel")) | |
470 | goto cleanup; | |
471 | ||
472 | skel->links.bind_v4_prog = bpf_program__attach_cgroup(skel->progs.bind_v4_prog, cgroup_fd); | |
473 | if (!ASSERT_OK_PTR(skel->links.bind_v4_prog, "bpf_program__attach_cgroup")) | |
474 | goto cleanup; | |
475 | ||
476 | btf_id = find_prog_btf_id("bind_v4_prog", bpf_program__fd(skel->progs.bind_v4_prog)); | |
477 | if (!ASSERT_GE(btf_id, 0, "find_prog_btf_id")) | |
478 | goto cleanup; | |
479 | ||
480 | fentry_fd = load_fentry(bpf_program__fd(skel->progs.bind_v4_prog), btf_id); | |
481 | if (!ASSERT_GE(fentry_fd, 0, "load_fentry")) | |
482 | goto cleanup; | |
483 | ||
484 | /* Make sure bpf_obj_get_info_by_fd works correctly when attaching | |
485 | * to another BPF program. | |
486 | */ | |
487 | ||
488 | ASSERT_OK(bpf_obj_get_info_by_fd(fentry_fd, &info, &info_len), | |
489 | "bpf_obj_get_info_by_fd"); | |
490 | ||
491 | ASSERT_EQ(info.btf_id, 0, "info.btf_id"); | |
492 | ASSERT_EQ(info.attach_btf_id, btf_id, "info.attach_btf_id"); | |
493 | ASSERT_GT(info.attach_btf_obj_id, 0, "info.attach_btf_obj_id"); | |
494 | ||
495 | cleanup: | |
496 | if (cgroup_fd >= 0) | |
497 | close(cgroup_fd); | |
498 | if (fentry_fd >= 0) | |
499 | close(fentry_fd); | |
500 | bind4_prog__destroy(skel); | |
501 | } | |
502 | ||
d3f7b166 YS |
503 | /* NOTE: affect other tests, must run in serial mode */ |
504 | void serial_test_fexit_bpf2bpf(void) | |
8f9081c9 | 505 | { |
d86687ae AN |
506 | if (test__start_subtest("target_no_callees")) |
507 | test_target_no_callees(); | |
508 | if (test__start_subtest("target_yes_callees")) | |
509 | test_target_yes_callees(); | |
510 | if (test__start_subtest("func_replace")) | |
511 | test_func_replace(); | |
512 | if (test__start_subtest("func_replace_verify")) | |
513 | test_func_replace_verify(); | |
514 | if (test__start_subtest("func_sockmap_update")) | |
515 | test_func_sockmap_update(); | |
516 | if (test__start_subtest("func_replace_return_code")) | |
517 | test_func_replace_return_code(); | |
518 | if (test__start_subtest("func_map_prog_compatibility")) | |
519 | test_func_map_prog_compatibility(); | |
f6429476 THJ |
520 | if (test__start_subtest("func_replace_multi")) |
521 | test_func_replace_multi(); | |
bee4b7e6 THJ |
522 | if (test__start_subtest("fmod_ret_freplace")) |
523 | test_fmod_ret_freplace(); | |
2cf7b7ff THJ |
524 | if (test__start_subtest("func_replace_global_func")) |
525 | test_func_replace_global_func(); | |
ffd5cfca SF |
526 | if (test__start_subtest("fentry_to_cgroup_bpf")) |
527 | test_fentry_to_cgroup_bpf(); | |
d6f39601 | 528 | } |