]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/prog_tests/xdp_link.c
scsi: zfcp: Trace when request remove fails after qdio send fails
[linux.git] / tools / testing / selftests / bpf / prog_tests / xdp_link.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
3 #include <uapi/linux/if_link.h>
4 #include <test_progs.h>
5 #include "test_xdp_link.skel.h"
6
7 #define IFINDEX_LO 1
8
9 void serial_test_xdp_link(void)
10 {
11         struct test_xdp_link *skel1 = NULL, *skel2 = NULL;
12         __u32 id1, id2, id0 = 0, prog_fd1, prog_fd2;
13         LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
14         struct bpf_link_info link_info;
15         struct bpf_prog_info prog_info;
16         struct bpf_link *link;
17         int err;
18         __u32 link_info_len = sizeof(link_info);
19         __u32 prog_info_len = sizeof(prog_info);
20
21         skel1 = test_xdp_link__open_and_load();
22         if (!ASSERT_OK_PTR(skel1, "skel_load"))
23                 goto cleanup;
24         prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);
25
26         skel2 = test_xdp_link__open_and_load();
27         if (!ASSERT_OK_PTR(skel2, "skel_load"))
28                 goto cleanup;
29         prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);
30
31         memset(&prog_info, 0, sizeof(prog_info));
32         err = bpf_obj_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);
33         if (!ASSERT_OK(err, "fd_info1"))
34                 goto cleanup;
35         id1 = prog_info.id;
36
37         memset(&prog_info, 0, sizeof(prog_info));
38         err = bpf_obj_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);
39         if (!ASSERT_OK(err, "fd_info2"))
40                 goto cleanup;
41         id2 = prog_info.id;
42
43         /* set initial prog attachment */
44         err = bpf_xdp_attach(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);
45         if (!ASSERT_OK(err, "fd_attach"))
46                 goto cleanup;
47
48         /* validate prog ID */
49         err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
50         if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
51                 goto cleanup;
52
53         /* BPF link is not allowed to replace prog attachment */
54         link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
55         if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
56                 bpf_link__destroy(link);
57                 /* best-effort detach prog */
58                 opts.old_prog_fd = prog_fd1;
59                 bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
60                 goto cleanup;
61         }
62
63         /* detach BPF program */
64         opts.old_prog_fd = prog_fd1;
65         err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
66         if (!ASSERT_OK(err, "prog_detach"))
67                 goto cleanup;
68
69         /* now BPF link should attach successfully */
70         link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
71         if (!ASSERT_OK_PTR(link, "link_attach"))
72                 goto cleanup;
73         skel1->links.xdp_handler = link;
74
75         /* validate prog ID */
76         err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
77         if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
78                 goto cleanup;
79
80         /* BPF prog attach is not allowed to replace BPF link */
81         opts.old_prog_fd = prog_fd1;
82         err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);
83         if (!ASSERT_ERR(err, "prog_attach_fail"))
84                 goto cleanup;
85
86         /* Can't force-update when BPF link is active */
87         err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, 0, NULL);
88         if (!ASSERT_ERR(err, "prog_update_fail"))
89                 goto cleanup;
90
91         /* Can't force-detach when BPF link is active */
92         err = bpf_xdp_detach(IFINDEX_LO, 0, NULL);
93         if (!ASSERT_ERR(err, "prog_detach_fail"))
94                 goto cleanup;
95
96         /* BPF link is not allowed to replace another BPF link */
97         link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
98         if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
99                 bpf_link__destroy(link);
100                 goto cleanup;
101         }
102
103         bpf_link__destroy(skel1->links.xdp_handler);
104         skel1->links.xdp_handler = NULL;
105
106         /* new link attach should succeed */
107         link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
108         if (!ASSERT_OK_PTR(link, "link_attach"))
109                 goto cleanup;
110         skel2->links.xdp_handler = link;
111
112         err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
113         if (!ASSERT_OK(err, "id2_check_err") || !ASSERT_EQ(id0, id2, "id2_check_val"))
114                 goto cleanup;
115
116         /* updating program under active BPF link works as expected */
117         err = bpf_link__update_program(link, skel1->progs.xdp_handler);
118         if (!ASSERT_OK(err, "link_upd"))
119                 goto cleanup;
120
121         memset(&link_info, 0, sizeof(link_info));
122         err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
123         if (!ASSERT_OK(err, "link_info"))
124                 goto cleanup;
125
126         ASSERT_EQ(link_info.type, BPF_LINK_TYPE_XDP, "link_type");
127         ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
128         ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");
129
130         /* updating program under active BPF link with different type fails */
131         err = bpf_link__update_program(link, skel1->progs.tc_handler);
132         if (!ASSERT_ERR(err, "link_upd_invalid"))
133                 goto cleanup;
134
135         err = bpf_link__detach(link);
136         if (!ASSERT_OK(err, "link_detach"))
137                 goto cleanup;
138
139         memset(&link_info, 0, sizeof(link_info));
140         err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
141
142         ASSERT_OK(err, "link_info");
143         ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
144         /* ifindex should be zeroed out */
145         ASSERT_EQ(link_info.xdp.ifindex, 0, "link_ifindex");
146
147 cleanup:
148         test_xdp_link__destroy(skel1);
149         test_xdp_link__destroy(skel2);
150 }
This page took 0.038093 seconds and 4 git commands to generate.