1d6f39601SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0 2d6f39601SAlexei Starovoitov /* Copyright (c) 2019 Facebook */ 3d6f39601SAlexei Starovoitov #include <test_progs.h> 4488a23b8SStanislav Fomichev #include <network_helpers.h> 5f6429476SToke Høiland-Jørgensen #include <bpf/btf.h> 6f6429476SToke Høiland-Jørgensen 7f6429476SToke Høiland-Jørgensen typedef int (*test_cb)(struct bpf_object *obj); 8f6429476SToke Høiland-Jørgensen 9f6429476SToke Høiland-Jørgensen static int check_data_map(struct bpf_object *obj, int prog_cnt, bool reset) 10f6429476SToke Høiland-Jørgensen { 11f6429476SToke Høiland-Jørgensen struct bpf_map *data_map = NULL, *map; 12f6429476SToke Høiland-Jørgensen __u64 *result = NULL; 13f6429476SToke Høiland-Jørgensen const int zero = 0; 14f6429476SToke Høiland-Jørgensen __u32 duration = 0; 15f6429476SToke Høiland-Jørgensen int ret = -1, i; 16f6429476SToke Høiland-Jørgensen 17f6429476SToke Høiland-Jørgensen result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64)); 18f6429476SToke Høiland-Jørgensen if (CHECK(!result, "alloc_memory", "failed to alloc memory")) 19f6429476SToke Høiland-Jørgensen return -ENOMEM; 20f6429476SToke Høiland-Jørgensen 21f6429476SToke Høiland-Jørgensen bpf_object__for_each_map(map, obj) 22f6429476SToke Høiland-Jørgensen if (bpf_map__is_internal(map)) { 23f6429476SToke Høiland-Jørgensen data_map = map; 24f6429476SToke Høiland-Jørgensen break; 25f6429476SToke Høiland-Jørgensen } 26f6429476SToke Høiland-Jørgensen if (CHECK(!data_map, "find_data_map", "data map not found\n")) 27f6429476SToke Høiland-Jørgensen goto out; 28f6429476SToke Høiland-Jørgensen 29f6429476SToke Høiland-Jørgensen ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); 30f6429476SToke Høiland-Jørgensen if (CHECK(ret, "get_result", 31f6429476SToke Høiland-Jørgensen "failed to get output data: %d\n", ret)) 32f6429476SToke Høiland-Jørgensen goto out; 33f6429476SToke Høiland-Jørgensen 34f6429476SToke Høiland-Jørgensen for (i = 0; i < prog_cnt; i++) { 35f6429476SToke Høiland-Jørgensen if (CHECK(result[i] != 1, "result", 36f6429476SToke Høiland-Jørgensen "fexit_bpf2bpf result[%d] failed err %llu\n", 37f6429476SToke Høiland-Jørgensen i, result[i])) 38f6429476SToke Høiland-Jørgensen goto out; 39f6429476SToke Høiland-Jørgensen result[i] = 0; 40f6429476SToke Høiland-Jørgensen } 41f6429476SToke Høiland-Jørgensen if (reset) { 42f6429476SToke Høiland-Jørgensen ret = bpf_map_update_elem(bpf_map__fd(data_map), &zero, result, 0); 43f6429476SToke Høiland-Jørgensen if (CHECK(ret, "reset_result", "failed to reset result\n")) 44f6429476SToke Høiland-Jørgensen goto out; 45f6429476SToke Høiland-Jørgensen } 46f6429476SToke Høiland-Jørgensen 47f6429476SToke Høiland-Jørgensen ret = 0; 48f6429476SToke Høiland-Jørgensen out: 49f6429476SToke Høiland-Jørgensen free(result); 50f6429476SToke Høiland-Jørgensen return ret; 51f6429476SToke Høiland-Jørgensen } 52d6f39601SAlexei Starovoitov 538f9081c9SYonghong Song static void test_fexit_bpf2bpf_common(const char *obj_file, 548f9081c9SYonghong Song const char *target_obj_file, 558f9081c9SYonghong Song int prog_cnt, 561d8a0af5SToke Høiland-Jørgensen const char **prog_name, 57f6429476SToke Høiland-Jørgensen bool run_prog, 58f6429476SToke Høiland-Jørgensen test_cb cb) 59d6f39601SAlexei Starovoitov { 60f6429476SToke Høiland-Jørgensen struct bpf_object *obj = NULL, *tgt_obj; 618f9081c9SYonghong Song struct bpf_program **prog = NULL; 62f6429476SToke Høiland-Jørgensen struct bpf_link **link = NULL; 631a6fa106SJohn Sperbeck __u32 duration = 0, retval; 64f6429476SToke Høiland-Jørgensen int err, tgt_fd, i; 65d6f39601SAlexei Starovoitov 668f9081c9SYonghong Song err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, 67f6429476SToke Høiland-Jørgensen &tgt_obj, &tgt_fd); 681d8a0af5SToke Høiland-Jørgensen if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", 691d8a0af5SToke Høiland-Jørgensen target_obj_file, err, errno)) 70d6f39601SAlexei Starovoitov return; 71d6f39601SAlexei Starovoitov DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 72f6429476SToke Høiland-Jørgensen .attach_prog_fd = tgt_fd, 73d6f39601SAlexei Starovoitov ); 74d6f39601SAlexei Starovoitov 758f9081c9SYonghong Song link = calloc(sizeof(struct bpf_link *), prog_cnt); 768f9081c9SYonghong Song prog = calloc(sizeof(struct bpf_program *), prog_cnt); 77f6429476SToke Høiland-Jørgensen if (CHECK(!link || !prog, "alloc_memory", "failed to alloc memory")) 788f9081c9SYonghong Song goto close_prog; 798f9081c9SYonghong Song 808f9081c9SYonghong Song obj = bpf_object__open_file(obj_file, &opts); 81d6f39601SAlexei Starovoitov if (CHECK(IS_ERR_OR_NULL(obj), "obj_open", 821d8a0af5SToke Høiland-Jørgensen "failed to open %s: %ld\n", obj_file, 83d6f39601SAlexei Starovoitov PTR_ERR(obj))) 84d6f39601SAlexei Starovoitov goto close_prog; 85d6f39601SAlexei Starovoitov 86d6f39601SAlexei Starovoitov err = bpf_object__load(obj); 87d6f39601SAlexei Starovoitov if (CHECK(err, "obj_load", "err %d\n", err)) 88d6f39601SAlexei Starovoitov goto close_prog; 89d6f39601SAlexei Starovoitov 908f9081c9SYonghong Song for (i = 0; i < prog_cnt; i++) { 91d6f39601SAlexei Starovoitov prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]); 92d6f39601SAlexei Starovoitov if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i])) 93d6f39601SAlexei Starovoitov goto close_prog; 94d6f39601SAlexei Starovoitov link[i] = bpf_program__attach_trace(prog[i]); 95d6f39601SAlexei Starovoitov if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n")) 96d6f39601SAlexei Starovoitov goto close_prog; 97d6f39601SAlexei Starovoitov } 981d8a0af5SToke Høiland-Jørgensen 99f6429476SToke Høiland-Jørgensen if (cb) { 100f6429476SToke Høiland-Jørgensen err = cb(obj); 101f6429476SToke Høiland-Jørgensen if (err) 102f6429476SToke Høiland-Jørgensen goto close_prog; 103f6429476SToke Høiland-Jørgensen } 104f6429476SToke Høiland-Jørgensen 1051d8a0af5SToke Høiland-Jørgensen if (!run_prog) 1061d8a0af5SToke Høiland-Jørgensen goto close_prog; 1071d8a0af5SToke Høiland-Jørgensen 108f6429476SToke Høiland-Jørgensen err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), 109d6f39601SAlexei Starovoitov NULL, NULL, &retval, &duration); 110d6f39601SAlexei Starovoitov CHECK(err || retval, "ipv6", 111d6f39601SAlexei Starovoitov "err %d errno %d retval %d duration %d\n", 112d6f39601SAlexei Starovoitov err, errno, retval, duration); 113d6f39601SAlexei Starovoitov 114f6429476SToke Høiland-Jørgensen if (check_data_map(obj, prog_cnt, false)) 115d6f39601SAlexei Starovoitov goto close_prog; 116d6f39601SAlexei Starovoitov 117d6f39601SAlexei Starovoitov close_prog: 1188f9081c9SYonghong Song for (i = 0; i < prog_cnt; i++) 119d6f39601SAlexei Starovoitov if (!IS_ERR_OR_NULL(link[i])) 120d6f39601SAlexei Starovoitov bpf_link__destroy(link[i]); 121d6f39601SAlexei Starovoitov if (!IS_ERR_OR_NULL(obj)) 122d6f39601SAlexei Starovoitov bpf_object__close(obj); 123f6429476SToke Høiland-Jørgensen bpf_object__close(tgt_obj); 1248f9081c9SYonghong Song free(link); 1258f9081c9SYonghong Song free(prog); 1268f9081c9SYonghong Song } 1278f9081c9SYonghong Song 1288f9081c9SYonghong Song static void test_target_no_callees(void) 1298f9081c9SYonghong Song { 1308f9081c9SYonghong Song const char *prog_name[] = { 1318f9081c9SYonghong Song "fexit/test_pkt_md_access", 1328f9081c9SYonghong Song }; 1338f9081c9SYonghong Song test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o", 1348f9081c9SYonghong Song "./test_pkt_md_access.o", 1358f9081c9SYonghong Song ARRAY_SIZE(prog_name), 136f6429476SToke Høiland-Jørgensen prog_name, true, NULL); 1378f9081c9SYonghong Song } 1388f9081c9SYonghong Song 1398f9081c9SYonghong Song static void test_target_yes_callees(void) 1408f9081c9SYonghong Song { 1418f9081c9SYonghong Song const char *prog_name[] = { 1428f9081c9SYonghong Song "fexit/test_pkt_access", 1438f9081c9SYonghong Song "fexit/test_pkt_access_subprog1", 1448f9081c9SYonghong Song "fexit/test_pkt_access_subprog2", 1457608e4dbSAlexei Starovoitov "fexit/test_pkt_access_subprog3", 1468f9081c9SYonghong Song }; 1478f9081c9SYonghong Song test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 1488f9081c9SYonghong Song "./test_pkt_access.o", 1498f9081c9SYonghong Song ARRAY_SIZE(prog_name), 150f6429476SToke Høiland-Jørgensen prog_name, true, NULL); 1518f9081c9SYonghong Song } 1528f9081c9SYonghong Song 1537805fe84SAlexei Starovoitov static void test_func_replace(void) 1547805fe84SAlexei Starovoitov { 1557805fe84SAlexei Starovoitov const char *prog_name[] = { 1567805fe84SAlexei Starovoitov "fexit/test_pkt_access", 1577805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog1", 1587805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog2", 1597805fe84SAlexei Starovoitov "fexit/test_pkt_access_subprog3", 1607805fe84SAlexei Starovoitov "freplace/get_skb_len", 1617805fe84SAlexei Starovoitov "freplace/get_skb_ifindex", 1627805fe84SAlexei Starovoitov "freplace/get_constant", 1636dc03dc7SUdip Pant "freplace/test_pkt_write_access_subprog", 1647805fe84SAlexei Starovoitov }; 1657805fe84SAlexei Starovoitov test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 1667805fe84SAlexei Starovoitov "./test_pkt_access.o", 1677805fe84SAlexei Starovoitov ARRAY_SIZE(prog_name), 168f6429476SToke Høiland-Jørgensen prog_name, true, NULL); 1691d8a0af5SToke Høiland-Jørgensen } 1701d8a0af5SToke Høiland-Jørgensen 1711d8a0af5SToke Høiland-Jørgensen static void test_func_replace_verify(void) 1721d8a0af5SToke Høiland-Jørgensen { 1731d8a0af5SToke Høiland-Jørgensen const char *prog_name[] = { 1741d8a0af5SToke Høiland-Jørgensen "freplace/do_bind", 1751d8a0af5SToke Høiland-Jørgensen }; 1761d8a0af5SToke Høiland-Jørgensen test_fexit_bpf2bpf_common("./freplace_connect4.o", 1771d8a0af5SToke Høiland-Jørgensen "./connect4_prog.o", 1781d8a0af5SToke Høiland-Jørgensen ARRAY_SIZE(prog_name), 179f6429476SToke Høiland-Jørgensen prog_name, false, NULL); 180f6429476SToke Høiland-Jørgensen } 181f6429476SToke Høiland-Jørgensen 182f6429476SToke Høiland-Jørgensen static int test_second_attach(struct bpf_object *obj) 183f6429476SToke Høiland-Jørgensen { 184f6429476SToke Høiland-Jørgensen const char *prog_name = "freplace/get_constant"; 185f6429476SToke Høiland-Jørgensen const char *tgt_name = prog_name + 9; /* cut off freplace/ */ 186f6429476SToke Høiland-Jørgensen const char *tgt_obj_file = "./test_pkt_access.o"; 187f6429476SToke Høiland-Jørgensen struct bpf_program *prog = NULL; 188f6429476SToke Høiland-Jørgensen struct bpf_object *tgt_obj; 189f6429476SToke Høiland-Jørgensen __u32 duration = 0, retval; 190f6429476SToke Høiland-Jørgensen struct bpf_link *link; 191f6429476SToke Høiland-Jørgensen int err = 0, tgt_fd; 192f6429476SToke Høiland-Jørgensen 193f6429476SToke Høiland-Jørgensen prog = bpf_object__find_program_by_title(obj, prog_name); 194f6429476SToke Høiland-Jørgensen if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name)) 195f6429476SToke Høiland-Jørgensen return -ENOENT; 196f6429476SToke Høiland-Jørgensen 197f6429476SToke Høiland-Jørgensen err = bpf_prog_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC, 198f6429476SToke Høiland-Jørgensen &tgt_obj, &tgt_fd); 199f6429476SToke Høiland-Jørgensen if (CHECK(err, "second_prog_load", "file %s err %d errno %d\n", 200f6429476SToke Høiland-Jørgensen tgt_obj_file, err, errno)) 201f6429476SToke Høiland-Jørgensen return err; 202f6429476SToke Høiland-Jørgensen 203f6429476SToke Høiland-Jørgensen link = bpf_program__attach_freplace(prog, tgt_fd, tgt_name); 204f6429476SToke Høiland-Jørgensen if (CHECK(IS_ERR(link), "second_link", "failed to attach second link prog_fd %d tgt_fd %d\n", bpf_program__fd(prog), tgt_fd)) 205f6429476SToke Høiland-Jørgensen goto out; 206f6429476SToke Høiland-Jørgensen 207f6429476SToke Høiland-Jørgensen err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), 208f6429476SToke Høiland-Jørgensen NULL, NULL, &retval, &duration); 209f6429476SToke Høiland-Jørgensen if (CHECK(err || retval, "ipv6", 210f6429476SToke Høiland-Jørgensen "err %d errno %d retval %d duration %d\n", 211f6429476SToke Høiland-Jørgensen err, errno, retval, duration)) 212f6429476SToke Høiland-Jørgensen goto out; 213f6429476SToke Høiland-Jørgensen 214f6429476SToke Høiland-Jørgensen err = check_data_map(obj, 1, true); 215f6429476SToke Høiland-Jørgensen if (err) 216f6429476SToke Høiland-Jørgensen goto out; 217f6429476SToke Høiland-Jørgensen 218f6429476SToke Høiland-Jørgensen out: 219f6429476SToke Høiland-Jørgensen bpf_link__destroy(link); 220f6429476SToke Høiland-Jørgensen bpf_object__close(tgt_obj); 221f6429476SToke Høiland-Jørgensen return err; 222f6429476SToke Høiland-Jørgensen } 223f6429476SToke Høiland-Jørgensen 224f6429476SToke Høiland-Jørgensen static void test_func_replace_multi(void) 225f6429476SToke Høiland-Jørgensen { 226f6429476SToke Høiland-Jørgensen const char *prog_name[] = { 227f6429476SToke Høiland-Jørgensen "freplace/get_constant", 228f6429476SToke Høiland-Jørgensen }; 229f6429476SToke Høiland-Jørgensen test_fexit_bpf2bpf_common("./freplace_get_constant.o", 230f6429476SToke Høiland-Jørgensen "./test_pkt_access.o", 231f6429476SToke Høiland-Jørgensen ARRAY_SIZE(prog_name), 232f6429476SToke Høiland-Jørgensen prog_name, true, test_second_attach); 2337805fe84SAlexei Starovoitov } 2347805fe84SAlexei Starovoitov 235bee4b7e6SToke Høiland-Jørgensen static void test_fmod_ret_freplace(void) 236bee4b7e6SToke Høiland-Jørgensen { 237bee4b7e6SToke Høiland-Jørgensen struct bpf_object *freplace_obj = NULL, *pkt_obj, *fmod_obj = NULL; 238bee4b7e6SToke Høiland-Jørgensen const char *freplace_name = "./freplace_get_constant.o"; 239bee4b7e6SToke Høiland-Jørgensen const char *fmod_ret_name = "./fmod_ret_freplace.o"; 240bee4b7e6SToke Høiland-Jørgensen DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); 241bee4b7e6SToke Høiland-Jørgensen const char *tgt_name = "./test_pkt_access.o"; 242bee4b7e6SToke Høiland-Jørgensen struct bpf_link *freplace_link = NULL; 243bee4b7e6SToke Høiland-Jørgensen struct bpf_program *prog; 244bee4b7e6SToke Høiland-Jørgensen __u32 duration = 0; 245bee4b7e6SToke Høiland-Jørgensen int err, pkt_fd; 246bee4b7e6SToke Høiland-Jørgensen 247bee4b7e6SToke Høiland-Jørgensen err = bpf_prog_load(tgt_name, BPF_PROG_TYPE_UNSPEC, 248bee4b7e6SToke Høiland-Jørgensen &pkt_obj, &pkt_fd); 249bee4b7e6SToke Høiland-Jørgensen /* the target prog should load fine */ 250bee4b7e6SToke Høiland-Jørgensen if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", 251bee4b7e6SToke Høiland-Jørgensen tgt_name, err, errno)) 252bee4b7e6SToke Høiland-Jørgensen return; 253bee4b7e6SToke Høiland-Jørgensen opts.attach_prog_fd = pkt_fd; 254bee4b7e6SToke Høiland-Jørgensen 255bee4b7e6SToke Høiland-Jørgensen freplace_obj = bpf_object__open_file(freplace_name, &opts); 256bee4b7e6SToke Høiland-Jørgensen if (CHECK(IS_ERR_OR_NULL(freplace_obj), "freplace_obj_open", 257bee4b7e6SToke Høiland-Jørgensen "failed to open %s: %ld\n", freplace_name, 258bee4b7e6SToke Høiland-Jørgensen PTR_ERR(freplace_obj))) 259bee4b7e6SToke Høiland-Jørgensen goto out; 260bee4b7e6SToke Høiland-Jørgensen 261bee4b7e6SToke Høiland-Jørgensen err = bpf_object__load(freplace_obj); 262bee4b7e6SToke Høiland-Jørgensen if (CHECK(err, "freplace_obj_load", "err %d\n", err)) 263bee4b7e6SToke Høiland-Jørgensen goto out; 264bee4b7e6SToke Høiland-Jørgensen 265bee4b7e6SToke Høiland-Jørgensen prog = bpf_program__next(NULL, freplace_obj); 266bee4b7e6SToke Høiland-Jørgensen freplace_link = bpf_program__attach_trace(prog); 267bee4b7e6SToke Høiland-Jørgensen if (CHECK(IS_ERR(freplace_link), "freplace_attach_trace", "failed to link\n")) 268bee4b7e6SToke Høiland-Jørgensen goto out; 269bee4b7e6SToke Høiland-Jørgensen 270bee4b7e6SToke Høiland-Jørgensen opts.attach_prog_fd = bpf_program__fd(prog); 271bee4b7e6SToke Høiland-Jørgensen fmod_obj = bpf_object__open_file(fmod_ret_name, &opts); 272bee4b7e6SToke Høiland-Jørgensen if (CHECK(IS_ERR_OR_NULL(fmod_obj), "fmod_obj_open", 273bee4b7e6SToke Høiland-Jørgensen "failed to open %s: %ld\n", fmod_ret_name, 274bee4b7e6SToke Høiland-Jørgensen PTR_ERR(fmod_obj))) 275bee4b7e6SToke Høiland-Jørgensen goto out; 276bee4b7e6SToke Høiland-Jørgensen 277bee4b7e6SToke Høiland-Jørgensen err = bpf_object__load(fmod_obj); 278bee4b7e6SToke Høiland-Jørgensen if (CHECK(!err, "fmod_obj_load", "loading fmod_ret should fail\n")) 279bee4b7e6SToke Høiland-Jørgensen goto out; 280bee4b7e6SToke Høiland-Jørgensen 281bee4b7e6SToke Høiland-Jørgensen out: 282bee4b7e6SToke Høiland-Jørgensen bpf_link__destroy(freplace_link); 283bee4b7e6SToke Høiland-Jørgensen bpf_object__close(freplace_obj); 284bee4b7e6SToke Høiland-Jørgensen bpf_object__close(fmod_obj); 285bee4b7e6SToke Høiland-Jørgensen bpf_object__close(pkt_obj); 286bee4b7e6SToke Høiland-Jørgensen } 287bee4b7e6SToke Høiland-Jørgensen 288bee4b7e6SToke Høiland-Jørgensen 2891410620cSUdip Pant static void test_func_sockmap_update(void) 2901410620cSUdip Pant { 2911410620cSUdip Pant const char *prog_name[] = { 2921410620cSUdip Pant "freplace/cls_redirect", 2931410620cSUdip Pant }; 2941410620cSUdip Pant test_fexit_bpf2bpf_common("./freplace_cls_redirect.o", 2951410620cSUdip Pant "./test_cls_redirect.o", 2961410620cSUdip Pant ARRAY_SIZE(prog_name), 297f6429476SToke Høiland-Jørgensen prog_name, false, NULL); 2981410620cSUdip Pant } 2991410620cSUdip Pant 3001410620cSUdip Pant static void test_obj_load_failure_common(const char *obj_file, 3011410620cSUdip Pant const char *target_obj_file) 3021410620cSUdip Pant 30350d19736SUdip Pant { 30450d19736SUdip Pant /* 30550d19736SUdip Pant * standalone test that asserts failure to load freplace prog 30650d19736SUdip Pant * because of invalid return code. 30750d19736SUdip Pant */ 30850d19736SUdip Pant struct bpf_object *obj = NULL, *pkt_obj; 30950d19736SUdip Pant int err, pkt_fd; 31050d19736SUdip Pant __u32 duration = 0; 31150d19736SUdip Pant 31250d19736SUdip Pant err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, 31350d19736SUdip Pant &pkt_obj, &pkt_fd); 31450d19736SUdip Pant /* the target prog should load fine */ 31550d19736SUdip Pant if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", 31650d19736SUdip Pant target_obj_file, err, errno)) 31750d19736SUdip Pant return; 31850d19736SUdip Pant DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 31950d19736SUdip Pant .attach_prog_fd = pkt_fd, 32050d19736SUdip Pant ); 32150d19736SUdip Pant 32250d19736SUdip Pant obj = bpf_object__open_file(obj_file, &opts); 32350d19736SUdip Pant if (CHECK(IS_ERR_OR_NULL(obj), "obj_open", 32450d19736SUdip Pant "failed to open %s: %ld\n", obj_file, 32550d19736SUdip Pant PTR_ERR(obj))) 32650d19736SUdip Pant goto close_prog; 32750d19736SUdip Pant 32850d19736SUdip Pant /* It should fail to load the program */ 32950d19736SUdip Pant err = bpf_object__load(obj); 33050d19736SUdip Pant if (CHECK(!err, "bpf_obj_load should fail", "err %d\n", err)) 33150d19736SUdip Pant goto close_prog; 33250d19736SUdip Pant 33350d19736SUdip Pant close_prog: 33450d19736SUdip Pant if (!IS_ERR_OR_NULL(obj)) 33550d19736SUdip Pant bpf_object__close(obj); 33650d19736SUdip Pant bpf_object__close(pkt_obj); 33750d19736SUdip Pant } 33850d19736SUdip Pant 3391410620cSUdip Pant static void test_func_replace_return_code(void) 3401410620cSUdip Pant { 3411410620cSUdip Pant /* test invalid return code in the replaced program */ 3421410620cSUdip Pant test_obj_load_failure_common("./freplace_connect_v4_prog.o", 3431410620cSUdip Pant "./connect4_prog.o"); 3441410620cSUdip Pant } 3451410620cSUdip Pant 3461410620cSUdip Pant static void test_func_map_prog_compatibility(void) 3471410620cSUdip Pant { 3481410620cSUdip Pant /* test with spin lock map value in the replaced program */ 3491410620cSUdip Pant test_obj_load_failure_common("./freplace_attach_probe.o", 3501410620cSUdip Pant "./test_attach_probe.o"); 3511410620cSUdip Pant } 3521410620cSUdip Pant 3538f9081c9SYonghong Song void test_fexit_bpf2bpf(void) 3548f9081c9SYonghong Song { 355d86687aeSAndrii Nakryiko if (test__start_subtest("target_no_callees")) 3568f9081c9SYonghong Song test_target_no_callees(); 357d86687aeSAndrii Nakryiko if (test__start_subtest("target_yes_callees")) 3588f9081c9SYonghong Song test_target_yes_callees(); 359d86687aeSAndrii Nakryiko if (test__start_subtest("func_replace")) 3607805fe84SAlexei Starovoitov test_func_replace(); 361d86687aeSAndrii Nakryiko if (test__start_subtest("func_replace_verify")) 3621d8a0af5SToke Høiland-Jørgensen test_func_replace_verify(); 363d86687aeSAndrii Nakryiko if (test__start_subtest("func_sockmap_update")) 3641410620cSUdip Pant test_func_sockmap_update(); 365d86687aeSAndrii Nakryiko if (test__start_subtest("func_replace_return_code")) 36650d19736SUdip Pant test_func_replace_return_code(); 367d86687aeSAndrii Nakryiko if (test__start_subtest("func_map_prog_compatibility")) 3681410620cSUdip Pant test_func_map_prog_compatibility(); 369f6429476SToke Høiland-Jørgensen if (test__start_subtest("func_replace_multi")) 370f6429476SToke Høiland-Jørgensen test_func_replace_multi(); 371bee4b7e6SToke Høiland-Jørgensen if (test__start_subtest("fmod_ret_freplace")) 372bee4b7e6SToke Høiland-Jørgensen test_fmod_ret_freplace(); 373d6f39601SAlexei Starovoitov } 374