1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 4 #define IFINDEX_LO 1 5 #define XDP_FLAGS_REPLACE (1U << 4) 6 7 void serial_test_xdp_attach(void) 8 { 9 __u32 duration = 0, id1, id2, id0 = 0, len; 10 struct bpf_object *obj1, *obj2, *obj3; 11 const char *file = "./test_xdp.o"; 12 struct bpf_prog_info info = {}; 13 int err, fd1, fd2, fd3; 14 DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, 15 .old_fd = -1); 16 17 len = sizeof(info); 18 19 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj1, &fd1); 20 if (CHECK_FAIL(err)) 21 return; 22 err = bpf_obj_get_info_by_fd(fd1, &info, &len); 23 if (CHECK_FAIL(err)) 24 goto out_1; 25 id1 = info.id; 26 27 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj2, &fd2); 28 if (CHECK_FAIL(err)) 29 goto out_1; 30 31 memset(&info, 0, sizeof(info)); 32 err = bpf_obj_get_info_by_fd(fd2, &info, &len); 33 if (CHECK_FAIL(err)) 34 goto out_2; 35 id2 = info.id; 36 37 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj3, &fd3); 38 if (CHECK_FAIL(err)) 39 goto out_2; 40 41 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd1, XDP_FLAGS_REPLACE, 42 &opts); 43 if (CHECK(err, "load_ok", "initial load failed")) 44 goto out_close; 45 46 err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0); 47 if (CHECK(err || id0 != id1, "id1_check", 48 "loaded prog id %u != id1 %u, err %d", id0, id1, err)) 49 goto out_close; 50 51 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd2, XDP_FLAGS_REPLACE, 52 &opts); 53 if (CHECK(!err, "load_fail", "load with expected id didn't fail")) 54 goto out; 55 56 opts.old_fd = fd1; 57 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd2, 0, &opts); 58 if (CHECK(err, "replace_ok", "replace valid old_fd failed")) 59 goto out; 60 err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0); 61 if (CHECK(err || id0 != id2, "id2_check", 62 "loaded prog id %u != id2 %u, err %d", id0, id2, err)) 63 goto out_close; 64 65 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, fd3, 0, &opts); 66 if (CHECK(!err, "replace_fail", "replace invalid old_fd didn't fail")) 67 goto out; 68 69 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, -1, 0, &opts); 70 if (CHECK(!err, "remove_fail", "remove invalid old_fd didn't fail")) 71 goto out; 72 73 opts.old_fd = fd2; 74 err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, -1, 0, &opts); 75 if (CHECK(err, "remove_ok", "remove valid old_fd failed")) 76 goto out; 77 78 err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0); 79 if (CHECK(err || id0 != 0, "unload_check", 80 "loaded prog id %u != 0, err %d", id0, err)) 81 goto out_close; 82 out: 83 bpf_set_link_xdp_fd(IFINDEX_LO, -1, 0); 84 out_close: 85 bpf_object__close(obj3); 86 out_2: 87 bpf_object__close(obj2); 88 out_1: 89 bpf_object__close(obj1); 90 } 91