1b62eba56SJesper Dangaard Brouer // SPDX-License-Identifier: GPL-2.0
2b62eba56SJesper Dangaard Brouer /* Copyright (c) 2020 Jesper Dangaard Brouer */
3b62eba56SJesper Dangaard Brouer
4b62eba56SJesper Dangaard Brouer #include <linux/if_link.h> /* before test_progs.h, avoid bpf_util.h redefines */
5b62eba56SJesper Dangaard Brouer #include <test_progs.h>
6b62eba56SJesper Dangaard Brouer #include "test_check_mtu.skel.h"
7b62eba56SJesper Dangaard Brouer #include "network_helpers.h"
8b62eba56SJesper Dangaard Brouer
9b62eba56SJesper Dangaard Brouer #include <stdlib.h>
10b62eba56SJesper Dangaard Brouer #include <inttypes.h>
11b62eba56SJesper Dangaard Brouer
12b62eba56SJesper Dangaard Brouer #define IFINDEX_LO 1
13b62eba56SJesper Dangaard Brouer
14b62eba56SJesper Dangaard Brouer static __u32 duration; /* Hint: needed for CHECK macro */
15b62eba56SJesper Dangaard Brouer
read_mtu_device_lo(void)16b62eba56SJesper Dangaard Brouer static int read_mtu_device_lo(void)
17b62eba56SJesper Dangaard Brouer {
18b62eba56SJesper Dangaard Brouer const char *filename = "/sys/class/net/lo/mtu";
19b62eba56SJesper Dangaard Brouer char buf[11] = {};
20b62eba56SJesper Dangaard Brouer int value, n, fd;
21b62eba56SJesper Dangaard Brouer
22b62eba56SJesper Dangaard Brouer fd = open(filename, 0, O_RDONLY);
23b62eba56SJesper Dangaard Brouer if (fd == -1)
24b62eba56SJesper Dangaard Brouer return -1;
25b62eba56SJesper Dangaard Brouer
26b62eba56SJesper Dangaard Brouer n = read(fd, buf, sizeof(buf));
27b62eba56SJesper Dangaard Brouer close(fd);
28b62eba56SJesper Dangaard Brouer
29b62eba56SJesper Dangaard Brouer if (n == -1)
30b62eba56SJesper Dangaard Brouer return -2;
31b62eba56SJesper Dangaard Brouer
32b62eba56SJesper Dangaard Brouer value = strtoimax(buf, NULL, 10);
33b62eba56SJesper Dangaard Brouer if (errno == ERANGE)
34b62eba56SJesper Dangaard Brouer return -3;
35b62eba56SJesper Dangaard Brouer
36b62eba56SJesper Dangaard Brouer return value;
37b62eba56SJesper Dangaard Brouer }
38b62eba56SJesper Dangaard Brouer
test_check_mtu_xdp_attach(void)39b62eba56SJesper Dangaard Brouer static void test_check_mtu_xdp_attach(void)
40b62eba56SJesper Dangaard Brouer {
41b62eba56SJesper Dangaard Brouer struct bpf_link_info link_info;
42b62eba56SJesper Dangaard Brouer __u32 link_info_len = sizeof(link_info);
43b62eba56SJesper Dangaard Brouer struct test_check_mtu *skel;
44b62eba56SJesper Dangaard Brouer struct bpf_program *prog;
45b62eba56SJesper Dangaard Brouer struct bpf_link *link;
46b62eba56SJesper Dangaard Brouer int err = 0;
47b62eba56SJesper Dangaard Brouer int fd;
48b62eba56SJesper Dangaard Brouer
49b62eba56SJesper Dangaard Brouer skel = test_check_mtu__open_and_load();
50b62eba56SJesper Dangaard Brouer if (CHECK(!skel, "open and load skel", "failed"))
51b62eba56SJesper Dangaard Brouer return; /* Exit if e.g. helper unknown to kernel */
52b62eba56SJesper Dangaard Brouer
53b62eba56SJesper Dangaard Brouer prog = skel->progs.xdp_use_helper_basic;
54b62eba56SJesper Dangaard Brouer
55b62eba56SJesper Dangaard Brouer link = bpf_program__attach_xdp(prog, IFINDEX_LO);
56bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(link, "link_attach"))
57b62eba56SJesper Dangaard Brouer goto out;
58b62eba56SJesper Dangaard Brouer skel->links.xdp_use_helper_basic = link;
59b62eba56SJesper Dangaard Brouer
60b62eba56SJesper Dangaard Brouer memset(&link_info, 0, sizeof(link_info));
61b62eba56SJesper Dangaard Brouer fd = bpf_link__fd(link);
62c5a237a4SIlya Leoshkevich err = bpf_link_get_info_by_fd(fd, &link_info, &link_info_len);
63b62eba56SJesper Dangaard Brouer if (CHECK(err, "link_info", "failed: %d\n", err))
64b62eba56SJesper Dangaard Brouer goto out;
65b62eba56SJesper Dangaard Brouer
66b62eba56SJesper Dangaard Brouer CHECK(link_info.type != BPF_LINK_TYPE_XDP, "link_type",
67b62eba56SJesper Dangaard Brouer "got %u != exp %u\n", link_info.type, BPF_LINK_TYPE_XDP);
68b62eba56SJesper Dangaard Brouer CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex",
69b62eba56SJesper Dangaard Brouer "got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO);
70b62eba56SJesper Dangaard Brouer
71b62eba56SJesper Dangaard Brouer err = bpf_link__detach(link);
72b62eba56SJesper Dangaard Brouer CHECK(err, "link_detach", "failed %d\n", err);
73b62eba56SJesper Dangaard Brouer
74b62eba56SJesper Dangaard Brouer out:
75b62eba56SJesper Dangaard Brouer test_check_mtu__destroy(skel);
76b62eba56SJesper Dangaard Brouer }
77b62eba56SJesper Dangaard Brouer
test_check_mtu_run_xdp(struct test_check_mtu * skel,struct bpf_program * prog,__u32 mtu_expect)78b62eba56SJesper Dangaard Brouer static void test_check_mtu_run_xdp(struct test_check_mtu *skel,
79b62eba56SJesper Dangaard Brouer struct bpf_program *prog,
80b62eba56SJesper Dangaard Brouer __u32 mtu_expect)
81b62eba56SJesper Dangaard Brouer {
82b62eba56SJesper Dangaard Brouer int retval_expect = XDP_PASS;
83b62eba56SJesper Dangaard Brouer __u32 mtu_result = 0;
84b62eba56SJesper Dangaard Brouer char buf[256] = {};
8539316183SDelyan Kratunov int err, prog_fd = bpf_program__fd(prog);
8639316183SDelyan Kratunov LIBBPF_OPTS(bpf_test_run_opts, topts,
87b62eba56SJesper Dangaard Brouer .repeat = 1,
88b62eba56SJesper Dangaard Brouer .data_in = &pkt_v4,
89b62eba56SJesper Dangaard Brouer .data_size_in = sizeof(pkt_v4),
90b62eba56SJesper Dangaard Brouer .data_out = buf,
91b62eba56SJesper Dangaard Brouer .data_size_out = sizeof(buf),
9239316183SDelyan Kratunov );
93b62eba56SJesper Dangaard Brouer
9439316183SDelyan Kratunov err = bpf_prog_test_run_opts(prog_fd, &topts);
9539316183SDelyan Kratunov ASSERT_OK(err, "test_run");
9639316183SDelyan Kratunov ASSERT_EQ(topts.retval, retval_expect, "retval");
97b62eba56SJesper Dangaard Brouer
98b62eba56SJesper Dangaard Brouer /* Extract MTU that BPF-prog got */
99b62eba56SJesper Dangaard Brouer mtu_result = skel->bss->global_bpf_mtu_xdp;
100b62eba56SJesper Dangaard Brouer ASSERT_EQ(mtu_result, mtu_expect, "MTU-compare-user");
101b62eba56SJesper Dangaard Brouer }
102b62eba56SJesper Dangaard Brouer
103b62eba56SJesper Dangaard Brouer
test_check_mtu_xdp(__u32 mtu,__u32 ifindex)104b62eba56SJesper Dangaard Brouer static void test_check_mtu_xdp(__u32 mtu, __u32 ifindex)
105b62eba56SJesper Dangaard Brouer {
106b62eba56SJesper Dangaard Brouer struct test_check_mtu *skel;
107b62eba56SJesper Dangaard Brouer int err;
108b62eba56SJesper Dangaard Brouer
109b62eba56SJesper Dangaard Brouer skel = test_check_mtu__open();
110b62eba56SJesper Dangaard Brouer if (CHECK(!skel, "skel_open", "failed"))
111b62eba56SJesper Dangaard Brouer return;
112b62eba56SJesper Dangaard Brouer
113b62eba56SJesper Dangaard Brouer /* Update "constants" in BPF-prog *BEFORE* libbpf load */
114b62eba56SJesper Dangaard Brouer skel->rodata->GLOBAL_USER_MTU = mtu;
115b62eba56SJesper Dangaard Brouer skel->rodata->GLOBAL_USER_IFINDEX = ifindex;
116b62eba56SJesper Dangaard Brouer
117b62eba56SJesper Dangaard Brouer err = test_check_mtu__load(skel);
118b62eba56SJesper Dangaard Brouer if (CHECK(err, "skel_load", "failed: %d\n", err))
119b62eba56SJesper Dangaard Brouer goto cleanup;
120b62eba56SJesper Dangaard Brouer
121b62eba56SJesper Dangaard Brouer test_check_mtu_run_xdp(skel, skel->progs.xdp_use_helper, mtu);
122b62eba56SJesper Dangaard Brouer test_check_mtu_run_xdp(skel, skel->progs.xdp_exceed_mtu, mtu);
123b62eba56SJesper Dangaard Brouer test_check_mtu_run_xdp(skel, skel->progs.xdp_minus_delta, mtu);
124e5e010a3SJesper Dangaard Brouer test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len, mtu);
125e5e010a3SJesper Dangaard Brouer test_check_mtu_run_xdp(skel, skel->progs.xdp_input_len_exceed, mtu);
126b62eba56SJesper Dangaard Brouer
127b62eba56SJesper Dangaard Brouer cleanup:
128b62eba56SJesper Dangaard Brouer test_check_mtu__destroy(skel);
129b62eba56SJesper Dangaard Brouer }
130b62eba56SJesper Dangaard Brouer
test_check_mtu_run_tc(struct test_check_mtu * skel,struct bpf_program * prog,__u32 mtu_expect)131b62eba56SJesper Dangaard Brouer static void test_check_mtu_run_tc(struct test_check_mtu *skel,
132b62eba56SJesper Dangaard Brouer struct bpf_program *prog,
133b62eba56SJesper Dangaard Brouer __u32 mtu_expect)
134b62eba56SJesper Dangaard Brouer {
135b62eba56SJesper Dangaard Brouer int retval_expect = BPF_OK;
136b62eba56SJesper Dangaard Brouer __u32 mtu_result = 0;
137b62eba56SJesper Dangaard Brouer char buf[256] = {};
13839316183SDelyan Kratunov int err, prog_fd = bpf_program__fd(prog);
13939316183SDelyan Kratunov LIBBPF_OPTS(bpf_test_run_opts, topts,
140b62eba56SJesper Dangaard Brouer .data_in = &pkt_v4,
141b62eba56SJesper Dangaard Brouer .data_size_in = sizeof(pkt_v4),
142b62eba56SJesper Dangaard Brouer .data_out = buf,
143b62eba56SJesper Dangaard Brouer .data_size_out = sizeof(buf),
14439316183SDelyan Kratunov .repeat = 1,
14539316183SDelyan Kratunov );
146b62eba56SJesper Dangaard Brouer
14739316183SDelyan Kratunov err = bpf_prog_test_run_opts(prog_fd, &topts);
14839316183SDelyan Kratunov ASSERT_OK(err, "test_run");
14939316183SDelyan Kratunov ASSERT_EQ(topts.retval, retval_expect, "retval");
150b62eba56SJesper Dangaard Brouer
151b62eba56SJesper Dangaard Brouer /* Extract MTU that BPF-prog got */
152b62eba56SJesper Dangaard Brouer mtu_result = skel->bss->global_bpf_mtu_tc;
153b62eba56SJesper Dangaard Brouer ASSERT_EQ(mtu_result, mtu_expect, "MTU-compare-user");
154b62eba56SJesper Dangaard Brouer }
155b62eba56SJesper Dangaard Brouer
156b62eba56SJesper Dangaard Brouer
test_check_mtu_tc(__u32 mtu,__u32 ifindex)157b62eba56SJesper Dangaard Brouer static void test_check_mtu_tc(__u32 mtu, __u32 ifindex)
158b62eba56SJesper Dangaard Brouer {
159b62eba56SJesper Dangaard Brouer struct test_check_mtu *skel;
160b62eba56SJesper Dangaard Brouer int err;
161b62eba56SJesper Dangaard Brouer
162b62eba56SJesper Dangaard Brouer skel = test_check_mtu__open();
163b62eba56SJesper Dangaard Brouer if (CHECK(!skel, "skel_open", "failed"))
164b62eba56SJesper Dangaard Brouer return;
165b62eba56SJesper Dangaard Brouer
166b62eba56SJesper Dangaard Brouer /* Update "constants" in BPF-prog *BEFORE* libbpf load */
167b62eba56SJesper Dangaard Brouer skel->rodata->GLOBAL_USER_MTU = mtu;
168b62eba56SJesper Dangaard Brouer skel->rodata->GLOBAL_USER_IFINDEX = ifindex;
169b62eba56SJesper Dangaard Brouer
170b62eba56SJesper Dangaard Brouer err = test_check_mtu__load(skel);
171b62eba56SJesper Dangaard Brouer if (CHECK(err, "skel_load", "failed: %d\n", err))
172b62eba56SJesper Dangaard Brouer goto cleanup;
173b62eba56SJesper Dangaard Brouer
174b62eba56SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_use_helper, mtu);
175b62eba56SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu, mtu);
176b62eba56SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_exceed_mtu_da, mtu);
177b62eba56SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_minus_delta, mtu);
178e5e010a3SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_input_len, mtu);
179e5e010a3SJesper Dangaard Brouer test_check_mtu_run_tc(skel, skel->progs.tc_input_len_exceed, mtu);
180b62eba56SJesper Dangaard Brouer cleanup:
181b62eba56SJesper Dangaard Brouer test_check_mtu__destroy(skel);
182b62eba56SJesper Dangaard Brouer }
183b62eba56SJesper Dangaard Brouer
serial_test_check_mtu(void)184d3f7b166SYucong Sun void serial_test_check_mtu(void)
185b62eba56SJesper Dangaard Brouer {
186*09564181SJesper Dangaard Brouer int mtu_lo;
187b62eba56SJesper Dangaard Brouer
188b62eba56SJesper Dangaard Brouer if (test__start_subtest("bpf_check_mtu XDP-attach"))
189b62eba56SJesper Dangaard Brouer test_check_mtu_xdp_attach();
190b62eba56SJesper Dangaard Brouer
191b62eba56SJesper Dangaard Brouer mtu_lo = read_mtu_device_lo();
192b62eba56SJesper Dangaard Brouer if (CHECK(mtu_lo < 0, "reading MTU value", "failed (err:%d)", mtu_lo))
193b62eba56SJesper Dangaard Brouer return;
194b62eba56SJesper Dangaard Brouer
195b62eba56SJesper Dangaard Brouer if (test__start_subtest("bpf_check_mtu XDP-run"))
196b62eba56SJesper Dangaard Brouer test_check_mtu_xdp(mtu_lo, 0);
197b62eba56SJesper Dangaard Brouer
198b62eba56SJesper Dangaard Brouer if (test__start_subtest("bpf_check_mtu XDP-run ifindex-lookup"))
199b62eba56SJesper Dangaard Brouer test_check_mtu_xdp(mtu_lo, IFINDEX_LO);
200b62eba56SJesper Dangaard Brouer
201b62eba56SJesper Dangaard Brouer if (test__start_subtest("bpf_check_mtu TC-run"))
202b62eba56SJesper Dangaard Brouer test_check_mtu_tc(mtu_lo, 0);
203b62eba56SJesper Dangaard Brouer
204b62eba56SJesper Dangaard Brouer if (test__start_subtest("bpf_check_mtu TC-run ifindex-lookup"))
205b62eba56SJesper Dangaard Brouer test_check_mtu_tc(mtu_lo, IFINDEX_LO);
206b62eba56SJesper Dangaard Brouer }
207