1d6f39601SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0 2d6f39601SAlexei Starovoitov /* Copyright (c) 2019 Facebook */ 3d6f39601SAlexei Starovoitov #include <test_progs.h> 4d6f39601SAlexei Starovoitov 58f9081c9SYonghong Song static void test_fexit_bpf2bpf_common(const char *obj_file, 68f9081c9SYonghong Song const char *target_obj_file, 78f9081c9SYonghong Song int prog_cnt, 88f9081c9SYonghong Song const char **prog_name) 9d6f39601SAlexei Starovoitov { 10d6f39601SAlexei Starovoitov struct bpf_object *obj = NULL, *pkt_obj; 11d6f39601SAlexei Starovoitov int err, pkt_fd, i; 128f9081c9SYonghong Song struct bpf_link **link = NULL; 138f9081c9SYonghong Song struct bpf_program **prog = NULL; 141a6fa106SJohn Sperbeck __u32 duration = 0, retval; 15d6f39601SAlexei Starovoitov struct bpf_map *data_map; 16d6f39601SAlexei Starovoitov const int zero = 0; 178f9081c9SYonghong Song u64 *result = NULL; 18d6f39601SAlexei Starovoitov 198f9081c9SYonghong Song err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, 20d6f39601SAlexei Starovoitov &pkt_obj, &pkt_fd); 21d6f39601SAlexei Starovoitov if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno)) 22d6f39601SAlexei Starovoitov return; 23d6f39601SAlexei Starovoitov DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 24d6f39601SAlexei Starovoitov .attach_prog_fd = pkt_fd, 25d6f39601SAlexei Starovoitov ); 26d6f39601SAlexei Starovoitov 278f9081c9SYonghong Song link = calloc(sizeof(struct bpf_link *), prog_cnt); 288f9081c9SYonghong Song prog = calloc(sizeof(struct bpf_program *), prog_cnt); 297805fe84SAlexei Starovoitov result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64)); 308f9081c9SYonghong Song if (CHECK(!link || !prog || !result, "alloc_memory", 318f9081c9SYonghong Song "failed to alloc memory")) 328f9081c9SYonghong Song goto close_prog; 338f9081c9SYonghong Song 348f9081c9SYonghong Song obj = bpf_object__open_file(obj_file, &opts); 35d6f39601SAlexei Starovoitov if (CHECK(IS_ERR_OR_NULL(obj), "obj_open", 36d6f39601SAlexei Starovoitov "failed to open fexit_bpf2bpf: %ld\n", 37d6f39601SAlexei Starovoitov PTR_ERR(obj))) 38d6f39601SAlexei Starovoitov goto close_prog; 39d6f39601SAlexei Starovoitov 40d6f39601SAlexei Starovoitov err = bpf_object__load(obj); 41d6f39601SAlexei Starovoitov if (CHECK(err, "obj_load", "err %d\n", err)) 42d6f39601SAlexei Starovoitov goto close_prog; 43d6f39601SAlexei Starovoitov 448f9081c9SYonghong Song for (i = 0; i < prog_cnt; i++) { 45d6f39601SAlexei Starovoitov prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]); 46d6f39601SAlexei Starovoitov if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i])) 47d6f39601SAlexei Starovoitov goto close_prog; 48d6f39601SAlexei Starovoitov link[i] = bpf_program__attach_trace(prog[i]); 49d6f39601SAlexei Starovoitov if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n")) 50d6f39601SAlexei Starovoitov goto close_prog; 51d6f39601SAlexei Starovoitov } 52d6f39601SAlexei Starovoitov data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss"); 53d6f39601SAlexei Starovoitov if (CHECK(!data_map, "find_data_map", "data map not found\n")) 54d6f39601SAlexei Starovoitov goto close_prog; 55d6f39601SAlexei Starovoitov 56d6f39601SAlexei Starovoitov err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), 57d6f39601SAlexei Starovoitov NULL, NULL, &retval, &duration); 58d6f39601SAlexei Starovoitov CHECK(err || retval, "ipv6", 59d6f39601SAlexei Starovoitov "err %d errno %d retval %d duration %d\n", 60d6f39601SAlexei Starovoitov err, errno, retval, duration); 61d6f39601SAlexei Starovoitov 628f9081c9SYonghong Song err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); 63d6f39601SAlexei Starovoitov if (CHECK(err, "get_result", 64d6f39601SAlexei Starovoitov "failed to get output data: %d\n", err)) 65d6f39601SAlexei Starovoitov goto close_prog; 66d6f39601SAlexei Starovoitov 678f9081c9SYonghong Song for (i = 0; i < prog_cnt; i++) 68d6f39601SAlexei Starovoitov if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n", 69d6f39601SAlexei Starovoitov result[i])) 70d6f39601SAlexei Starovoitov goto close_prog; 71d6f39601SAlexei Starovoitov 72d6f39601SAlexei Starovoitov close_prog: 738f9081c9SYonghong Song for (i = 0; i < prog_cnt; i++) 74d6f39601SAlexei Starovoitov if (!IS_ERR_OR_NULL(link[i])) 75d6f39601SAlexei Starovoitov bpf_link__destroy(link[i]); 76d6f39601SAlexei Starovoitov if (!IS_ERR_OR_NULL(obj)) 77d6f39601SAlexei Starovoitov bpf_object__close(obj); 78d6f39601SAlexei Starovoitov bpf_object__close(pkt_obj); 798f9081c9SYonghong Song free(link); 808f9081c9SYonghong Song free(prog); 818f9081c9SYonghong Song free(result); 828f9081c9SYonghong Song } 838f9081c9SYonghong Song 848f9081c9SYonghong Song static void test_target_no_callees(void) 858f9081c9SYonghong Song { 868f9081c9SYonghong Song const char *prog_name[] = { 878f9081c9SYonghong Song "fexit/test_pkt_md_access", 888f9081c9SYonghong Song }; 898f9081c9SYonghong Song test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o", 908f9081c9SYonghong Song "./test_pkt_md_access.o", 918f9081c9SYonghong Song ARRAY_SIZE(prog_name), 928f9081c9SYonghong Song prog_name); 938f9081c9SYonghong Song } 948f9081c9SYonghong Song 958f9081c9SYonghong Song static void test_target_yes_callees(void) 968f9081c9SYonghong Song { 978f9081c9SYonghong Song const char *prog_name[] = { 988f9081c9SYonghong Song "fexit/test_pkt_access", 998f9081c9SYonghong Song "fexit/test_pkt_access_subprog1", 1008f9081c9SYonghong Song "fexit/test_pkt_access_subprog2", 1017608e4dbSAlexei Starovoitov "fexit/test_pkt_access_subprog3", 1028f9081c9SYonghong Song }; 1038f9081c9SYonghong Song test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 1048f9081c9SYonghong Song "./test_pkt_access.o", 1058f9081c9SYonghong Song ARRAY_SIZE(prog_name), 1068f9081c9SYonghong Song prog_name); 1078f9081c9SYonghong Song } 1088f9081c9SYonghong Song 1097805fe84SAlexei Starovoitov static void test_func_replace(void) 1107805fe84SAlexei Starovoitov { 1117805fe84SAlexei Starovoitov const char *prog_name[] = { 1127805fe84SAlexei Starovoitov "fexit/test_pkt_access", 1137805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog1", 1147805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog2", 1157805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog3", 1167805fe84SAlexei Starovoitov "freplace/get_skb_len", 1177805fe84SAlexei Starovoitov "freplace/get_skb_ifindex", 1187805fe84SAlexei Starovoitov "freplace/get_constant", 1197805fe84SAlexei Starovoitov }; 1207805fe84SAlexei Starovoitov test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 1217805fe84SAlexei Starovoitov "./test_pkt_access.o", 1227805fe84SAlexei Starovoitov ARRAY_SIZE(prog_name), 1237805fe84SAlexei Starovoitov prog_name); 1247805fe84SAlexei Starovoitov } 1257805fe84SAlexei Starovoitov 1268f9081c9SYonghong Song void test_fexit_bpf2bpf(void) 1278f9081c9SYonghong Song { 1288f9081c9SYonghong Song test_target_no_callees(); 1298f9081c9SYonghong Song test_target_yes_callees(); 1307805fe84SAlexei Starovoitov test_func_replace(); 131d6f39601SAlexei Starovoitov } 132