0001
0002
0003 #include <uapi/linux/if_link.h>
0004 #include <test_progs.h>
0005 #include "test_xdp_link.skel.h"
0006
0007 #define IFINDEX_LO 1
0008
0009 void serial_test_xdp_link(void)
0010 {
0011 struct test_xdp_link *skel1 = NULL, *skel2 = NULL;
0012 __u32 id1, id2, id0 = 0, prog_fd1, prog_fd2;
0013 LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
0014 struct bpf_link_info link_info;
0015 struct bpf_prog_info prog_info;
0016 struct bpf_link *link;
0017 int err;
0018 __u32 link_info_len = sizeof(link_info);
0019 __u32 prog_info_len = sizeof(prog_info);
0020
0021 skel1 = test_xdp_link__open_and_load();
0022 if (!ASSERT_OK_PTR(skel1, "skel_load"))
0023 goto cleanup;
0024 prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);
0025
0026 skel2 = test_xdp_link__open_and_load();
0027 if (!ASSERT_OK_PTR(skel2, "skel_load"))
0028 goto cleanup;
0029 prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);
0030
0031 memset(&prog_info, 0, sizeof(prog_info));
0032 err = bpf_obj_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);
0033 if (!ASSERT_OK(err, "fd_info1"))
0034 goto cleanup;
0035 id1 = prog_info.id;
0036
0037 memset(&prog_info, 0, sizeof(prog_info));
0038 err = bpf_obj_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);
0039 if (!ASSERT_OK(err, "fd_info2"))
0040 goto cleanup;
0041 id2 = prog_info.id;
0042
0043
0044 err = bpf_xdp_attach(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);
0045 if (!ASSERT_OK(err, "fd_attach"))
0046 goto cleanup;
0047
0048
0049 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0050 if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
0051 goto cleanup;
0052
0053
0054 link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
0055 if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
0056 bpf_link__destroy(link);
0057
0058 opts.old_prog_fd = prog_fd1;
0059 bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
0060 goto cleanup;
0061 }
0062
0063
0064 opts.old_prog_fd = prog_fd1;
0065 err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
0066 if (!ASSERT_OK(err, "prog_detach"))
0067 goto cleanup;
0068
0069
0070 link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
0071 if (!ASSERT_OK_PTR(link, "link_attach"))
0072 goto cleanup;
0073 skel1->links.xdp_handler = link;
0074
0075
0076 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0077 if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
0078 goto cleanup;
0079
0080
0081 opts.old_prog_fd = prog_fd1;
0082 err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);
0083 if (!ASSERT_ERR(err, "prog_attach_fail"))
0084 goto cleanup;
0085
0086
0087 err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, 0, NULL);
0088 if (!ASSERT_ERR(err, "prog_update_fail"))
0089 goto cleanup;
0090
0091
0092 err = bpf_xdp_detach(IFINDEX_LO, 0, NULL);
0093 if (!ASSERT_ERR(err, "prog_detach_fail"))
0094 goto cleanup;
0095
0096
0097 link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
0098 if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
0099 bpf_link__destroy(link);
0100 goto cleanup;
0101 }
0102
0103 bpf_link__destroy(skel1->links.xdp_handler);
0104 skel1->links.xdp_handler = NULL;
0105
0106
0107 link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
0108 if (!ASSERT_OK_PTR(link, "link_attach"))
0109 goto cleanup;
0110 skel2->links.xdp_handler = link;
0111
0112 err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
0113 if (!ASSERT_OK(err, "id2_check_err") || !ASSERT_EQ(id0, id2, "id2_check_val"))
0114 goto cleanup;
0115
0116
0117 err = bpf_link__update_program(link, skel1->progs.xdp_handler);
0118 if (!ASSERT_OK(err, "link_upd"))
0119 goto cleanup;
0120
0121 memset(&link_info, 0, sizeof(link_info));
0122 err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
0123 if (!ASSERT_OK(err, "link_info"))
0124 goto cleanup;
0125
0126 ASSERT_EQ(link_info.type, BPF_LINK_TYPE_XDP, "link_type");
0127 ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
0128 ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");
0129
0130
0131 err = bpf_link__update_program(link, skel1->progs.tc_handler);
0132 if (!ASSERT_ERR(err, "link_upd_invalid"))
0133 goto cleanup;
0134
0135 err = bpf_link__detach(link);
0136 if (!ASSERT_OK(err, "link_detach"))
0137 goto cleanup;
0138
0139 memset(&link_info, 0, sizeof(link_info));
0140 err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
0141
0142 ASSERT_OK(err, "link_info");
0143 ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
0144
0145 ASSERT_EQ(link_info.xdp.ifindex, 0, "link_ifindex");
0146
0147 cleanup:
0148 test_xdp_link__destroy(skel1);
0149 test_xdp_link__destroy(skel2);
0150 }