0001
0002 #include <test_progs.h>
0003
0004 #define IFINDEX_LO 1
0005 #define XDP_FLAGS_REPLACE (1U << 4)
0006
0007 void serial_test_xdp_attach(void)
0008 {
0009 __u32 duration = 0, id1, id2, id0 = 0, len;
0010 struct bpf_object *obj1, *obj2, *obj3;
0011 const char *file = "./test_xdp.o";
0012 struct bpf_prog_info info = {};
0013 int err, fd1, fd2, fd3;
0014 LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
0015
0016 len = sizeof(info);
0017
0018 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj1, &fd1);
0019 if (CHECK_FAIL(err))
0020 return;
0021 err = bpf_obj_get_info_by_fd(fd1, &info, &len);
0022 if (CHECK_FAIL(err))
0023 goto out_1;
0024 id1 = info.id;
0025
0026 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj2, &fd2);
0027 if (CHECK_FAIL(err))
0028 goto out_1;
0029
0030 memset(&info, 0, sizeof(info));
0031 err = bpf_obj_get_info_by_fd(fd2, &info, &len);
0032 if (CHECK_FAIL(err))
0033 goto out_2;
0034 id2 = info.id;
0035
0036 err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj3, &fd3);
0037 if (CHECK_FAIL(err))
0038 goto out_2;
0039
0040 err = bpf_xdp_attach(IFINDEX_LO, fd1, XDP_FLAGS_REPLACE, &opts);
0041 if (CHECK(err, "load_ok", "initial load failed"))
0042 goto out_close;
0043
0044 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0045 if (CHECK(err || id0 != id1, "id1_check",
0046 "loaded prog id %u != id1 %u, err %d", id0, id1, err))
0047 goto out_close;
0048
0049 err = bpf_xdp_attach(IFINDEX_LO, fd2, XDP_FLAGS_REPLACE, &opts);
0050 if (CHECK(!err, "load_fail", "load with expected id didn't fail"))
0051 goto out;
0052
0053 opts.old_prog_fd = fd1;
0054 err = bpf_xdp_attach(IFINDEX_LO, fd2, 0, &opts);
0055 if (CHECK(err, "replace_ok", "replace valid old_fd failed"))
0056 goto out;
0057 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0058 if (CHECK(err || id0 != id2, "id2_check",
0059 "loaded prog id %u != id2 %u, err %d", id0, id2, err))
0060 goto out_close;
0061
0062 err = bpf_xdp_attach(IFINDEX_LO, fd3, 0, &opts);
0063 if (CHECK(!err, "replace_fail", "replace invalid old_fd didn't fail"))
0064 goto out;
0065
0066 err = bpf_xdp_detach(IFINDEX_LO, 0, &opts);
0067 if (CHECK(!err, "remove_fail", "remove invalid old_fd didn't fail"))
0068 goto out;
0069
0070 opts.old_prog_fd = fd2;
0071 err = bpf_xdp_detach(IFINDEX_LO, 0, &opts);
0072 if (CHECK(err, "remove_ok", "remove valid old_fd failed"))
0073 goto out;
0074
0075 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0076 if (CHECK(err || id0 != 0, "unload_check",
0077 "loaded prog id %u != 0, err %d", id0, err))
0078 goto out_close;
0079 out:
0080 bpf_xdp_detach(IFINDEX_LO, 0, NULL);
0081 out_close:
0082 bpf_object__close(obj3);
0083 out_2:
0084 bpf_object__close(obj2);
0085 out_1:
0086 bpf_object__close(obj1);
0087 }