109903869SMartin KaFai Lau // SPDX-License-Identifier: GPL-2.0
209903869SMartin KaFai Lau /* Copyright (c) 2019 Facebook */
309903869SMartin KaFai Lau
409903869SMartin KaFai Lau #include <linux/err.h>
59cacf81fSStanislav Fomichev #include <netinet/tcp.h>
609903869SMartin KaFai Lau #include <test_progs.h>
7574ee209SMartin KaFai Lau #include "network_helpers.h"
809903869SMartin KaFai Lau #include "bpf_dctcp.skel.h"
96de4a9c4SMartin KaFai Lau #include "bpf_cubic.skel.h"
10d8e8052eSToke Høiland-Jørgensen #include "bpf_tcp_nogpl.skel.h"
1106da9f3bSKui-Feng Lee #include "tcp_ca_update.skel.h"
12574ee209SMartin KaFai Lau #include "bpf_dctcp_release.skel.h"
136e945d57SJörn-Thorben Hinz #include "tcp_ca_write_sk_pacing.skel.h"
140735627dSJörn-Thorben Hinz #include "tcp_ca_incompl_cong_ops.skel.h"
15f14a3f64SJörn-Thorben Hinz #include "tcp_ca_unsupp_cong_op.skel.h"
165da7fb04SMartin KaFai Lau #include "tcp_ca_kfunc.skel.h"
17*96c3490dSMiao Xu #include "bpf_cc_cubic.skel.h"
1809903869SMartin KaFai Lau
19574ee209SMartin KaFai Lau #ifndef ENOTSUPP
20574ee209SMartin KaFai Lau #define ENOTSUPP 524
21574ee209SMartin KaFai Lau #endif
22574ee209SMartin KaFai Lau
2309903869SMartin KaFai Lau static const unsigned int total_bytes = 10 * 1024 * 1024;
24c9b24312SMartin KaFai Lau static int expected_stg = 0xeB9F;
2509903869SMartin KaFai Lau
settcpca(int fd,const char * tcp_ca)2609903869SMartin KaFai Lau static int settcpca(int fd, const char *tcp_ca)
2709903869SMartin KaFai Lau {
2809903869SMartin KaFai Lau int err;
2909903869SMartin KaFai Lau
3009903869SMartin KaFai Lau err = setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, tcp_ca, strlen(tcp_ca));
31b0e2a039SYuran Pereira if (!ASSERT_NEQ(err, -1, "setsockopt"))
3209903869SMartin KaFai Lau return -1;
3309903869SMartin KaFai Lau
3409903869SMartin KaFai Lau return 0;
3509903869SMartin KaFai Lau }
3609903869SMartin KaFai Lau
do_test(const char * tcp_ca,const struct bpf_map * sk_stg_map)37c9b24312SMartin KaFai Lau static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map)
3809903869SMartin KaFai Lau {
3909903869SMartin KaFai Lau int lfd = -1, fd = -1;
4009903869SMartin KaFai Lau int err;
4109903869SMartin KaFai Lau
42c29083f3SGeliang Tang lfd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
43b0e2a039SYuran Pereira if (!ASSERT_NEQ(lfd, -1, "socket"))
4409903869SMartin KaFai Lau return;
45b0e2a039SYuran Pereira
4609903869SMartin KaFai Lau fd = socket(AF_INET6, SOCK_STREAM, 0);
47b0e2a039SYuran Pereira if (!ASSERT_NEQ(fd, -1, "socket")) {
4809903869SMartin KaFai Lau close(lfd);
4909903869SMartin KaFai Lau return;
5009903869SMartin KaFai Lau }
5109903869SMartin KaFai Lau
5242667092SGeliang Tang if (settcpca(lfd, tcp_ca) || settcpca(fd, tcp_ca))
5309903869SMartin KaFai Lau goto done;
5409903869SMartin KaFai Lau
55c9b24312SMartin KaFai Lau if (sk_stg_map) {
56c9b24312SMartin KaFai Lau err = bpf_map_update_elem(bpf_map__fd(sk_stg_map), &fd,
57c9b24312SMartin KaFai Lau &expected_stg, BPF_NOEXIST);
58b0e2a039SYuran Pereira if (!ASSERT_OK(err, "bpf_map_update_elem(sk_stg_map)"))
5909903869SMartin KaFai Lau goto done;
60c9b24312SMartin KaFai Lau }
6109903869SMartin KaFai Lau
6209903869SMartin KaFai Lau /* connect to server */
63e5e1a3aaSGeliang Tang err = connect_fd_to_fd(fd, lfd, 0);
64b0e2a039SYuran Pereira if (!ASSERT_NEQ(err, -1, "connect"))
65c9b24312SMartin KaFai Lau goto done;
66c9b24312SMartin KaFai Lau
67c9b24312SMartin KaFai Lau if (sk_stg_map) {
68c9b24312SMartin KaFai Lau int tmp_stg;
69c9b24312SMartin KaFai Lau
70c9b24312SMartin KaFai Lau err = bpf_map_lookup_elem(bpf_map__fd(sk_stg_map), &fd,
71c9b24312SMartin KaFai Lau &tmp_stg);
72b0e2a039SYuran Pereira if (!ASSERT_ERR(err, "bpf_map_lookup_elem(sk_stg_map)") ||
73b0e2a039SYuran Pereira !ASSERT_EQ(errno, ENOENT, "bpf_map_lookup_elem(sk_stg_map)"))
74c9b24312SMartin KaFai Lau goto done;
75c9b24312SMartin KaFai Lau }
76c9b24312SMartin KaFai Lau
77dc34e44eSGeliang Tang ASSERT_OK(send_recv_data(lfd, fd, total_bytes), "send_recv_data");
78b0e2a039SYuran Pereira
7909903869SMartin KaFai Lau done:
8009903869SMartin KaFai Lau close(lfd);
8109903869SMartin KaFai Lau close(fd);
8209903869SMartin KaFai Lau }
8309903869SMartin KaFai Lau
test_cubic(void)846de4a9c4SMartin KaFai Lau static void test_cubic(void)
856de4a9c4SMartin KaFai Lau {
866de4a9c4SMartin KaFai Lau struct bpf_cubic *cubic_skel;
876de4a9c4SMartin KaFai Lau struct bpf_link *link;
886de4a9c4SMartin KaFai Lau
896de4a9c4SMartin KaFai Lau cubic_skel = bpf_cubic__open_and_load();
90b0e2a039SYuran Pereira if (!ASSERT_OK_PTR(cubic_skel, "bpf_cubic__open_and_load"))
916de4a9c4SMartin KaFai Lau return;
926de4a9c4SMartin KaFai Lau
936de4a9c4SMartin KaFai Lau link = bpf_map__attach_struct_ops(cubic_skel->maps.cubic);
94bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) {
956de4a9c4SMartin KaFai Lau bpf_cubic__destroy(cubic_skel);
966de4a9c4SMartin KaFai Lau return;
976de4a9c4SMartin KaFai Lau }
986de4a9c4SMartin KaFai Lau
99c9b24312SMartin KaFai Lau do_test("bpf_cubic", NULL);
1006de4a9c4SMartin KaFai Lau
10148f5e7d3SSong Liu ASSERT_EQ(cubic_skel->bss->bpf_cubic_acked_called, 1, "pkts_acked called");
10248f5e7d3SSong Liu
1036de4a9c4SMartin KaFai Lau bpf_link__destroy(link);
1046de4a9c4SMartin KaFai Lau bpf_cubic__destroy(cubic_skel);
1056de4a9c4SMartin KaFai Lau }
1066de4a9c4SMartin KaFai Lau
test_dctcp(void)10709903869SMartin KaFai Lau static void test_dctcp(void)
10809903869SMartin KaFai Lau {
10909903869SMartin KaFai Lau struct bpf_dctcp *dctcp_skel;
11009903869SMartin KaFai Lau struct bpf_link *link;
11109903869SMartin KaFai Lau
11209903869SMartin KaFai Lau dctcp_skel = bpf_dctcp__open_and_load();
113b0e2a039SYuran Pereira if (!ASSERT_OK_PTR(dctcp_skel, "bpf_dctcp__open_and_load"))
11409903869SMartin KaFai Lau return;
11509903869SMartin KaFai Lau
11609903869SMartin KaFai Lau link = bpf_map__attach_struct_ops(dctcp_skel->maps.dctcp);
117bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) {
11809903869SMartin KaFai Lau bpf_dctcp__destroy(dctcp_skel);
11909903869SMartin KaFai Lau return;
12009903869SMartin KaFai Lau }
12109903869SMartin KaFai Lau
122c9b24312SMartin KaFai Lau do_test("bpf_dctcp", dctcp_skel->maps.sk_stg_map);
123b0e2a039SYuran Pereira ASSERT_EQ(dctcp_skel->bss->stg_result, expected_stg, "stg_result");
12409903869SMartin KaFai Lau
12509903869SMartin KaFai Lau bpf_link__destroy(link);
12609903869SMartin KaFai Lau bpf_dctcp__destroy(dctcp_skel);
12709903869SMartin KaFai Lau }
12809903869SMartin KaFai Lau
129d8e8052eSToke Høiland-Jørgensen static char *err_str;
130d8e8052eSToke Høiland-Jørgensen static bool found;
131d8e8052eSToke Høiland-Jørgensen
libbpf_debug_print(enum libbpf_print_level level,const char * format,va_list args)132d8e8052eSToke Høiland-Jørgensen static int libbpf_debug_print(enum libbpf_print_level level,
133d8e8052eSToke Høiland-Jørgensen const char *format, va_list args)
134d8e8052eSToke Høiland-Jørgensen {
135acd143eeSJean-Philippe Brucker const char *prog_name, *log_buf;
136d8e8052eSToke Høiland-Jørgensen
137d8e8052eSToke Høiland-Jørgensen if (level != LIBBPF_WARN ||
138ad9a7f96SAndrii Nakryiko !strstr(format, "-- BEGIN PROG LOAD LOG --")) {
139d8e8052eSToke Høiland-Jørgensen vprintf(format, args);
140d8e8052eSToke Høiland-Jørgensen return 0;
141d8e8052eSToke Høiland-Jørgensen }
142d8e8052eSToke Høiland-Jørgensen
143acd143eeSJean-Philippe Brucker prog_name = va_arg(args, char *);
144d8e8052eSToke Høiland-Jørgensen log_buf = va_arg(args, char *);
145d8e8052eSToke Høiland-Jørgensen if (!log_buf)
146d8e8052eSToke Høiland-Jørgensen goto out;
147d8e8052eSToke Høiland-Jørgensen if (err_str && strstr(log_buf, err_str) != NULL)
148d8e8052eSToke Høiland-Jørgensen found = true;
149d8e8052eSToke Høiland-Jørgensen out:
150acd143eeSJean-Philippe Brucker printf(format, prog_name, log_buf);
151d8e8052eSToke Høiland-Jørgensen return 0;
152d8e8052eSToke Høiland-Jørgensen }
153d8e8052eSToke Høiland-Jørgensen
test_invalid_license(void)154d8e8052eSToke Høiland-Jørgensen static void test_invalid_license(void)
155d8e8052eSToke Høiland-Jørgensen {
156d8e8052eSToke Høiland-Jørgensen libbpf_print_fn_t old_print_fn;
157d8e8052eSToke Høiland-Jørgensen struct bpf_tcp_nogpl *skel;
158d8e8052eSToke Høiland-Jørgensen
159d8e8052eSToke Høiland-Jørgensen err_str = "struct ops programs must have a GPL compatible license";
160d8e8052eSToke Høiland-Jørgensen found = false;
161d8e8052eSToke Høiland-Jørgensen old_print_fn = libbpf_set_print(libbpf_debug_print);
162d8e8052eSToke Høiland-Jørgensen
163d8e8052eSToke Høiland-Jørgensen skel = bpf_tcp_nogpl__open_and_load();
164d8e8052eSToke Høiland-Jørgensen ASSERT_NULL(skel, "bpf_tcp_nogpl");
165d8e8052eSToke Høiland-Jørgensen ASSERT_EQ(found, true, "expected_err_msg");
166d8e8052eSToke Høiland-Jørgensen
167d8e8052eSToke Høiland-Jørgensen bpf_tcp_nogpl__destroy(skel);
168d8e8052eSToke Høiland-Jørgensen libbpf_set_print(old_print_fn);
169d8e8052eSToke Høiland-Jørgensen }
170d8e8052eSToke Høiland-Jørgensen
test_dctcp_fallback(void)171574ee209SMartin KaFai Lau static void test_dctcp_fallback(void)
172574ee209SMartin KaFai Lau {
173574ee209SMartin KaFai Lau int err, lfd = -1, cli_fd = -1, srv_fd = -1;
174574ee209SMartin KaFai Lau struct network_helper_opts opts = {
175574ee209SMartin KaFai Lau .cc = "cubic",
176574ee209SMartin KaFai Lau };
177574ee209SMartin KaFai Lau struct bpf_dctcp *dctcp_skel;
178574ee209SMartin KaFai Lau struct bpf_link *link = NULL;
179574ee209SMartin KaFai Lau char srv_cc[16];
180574ee209SMartin KaFai Lau socklen_t cc_len = sizeof(srv_cc);
181574ee209SMartin KaFai Lau
182574ee209SMartin KaFai Lau dctcp_skel = bpf_dctcp__open();
183574ee209SMartin KaFai Lau if (!ASSERT_OK_PTR(dctcp_skel, "dctcp_skel"))
184574ee209SMartin KaFai Lau return;
185574ee209SMartin KaFai Lau strcpy(dctcp_skel->rodata->fallback, "cubic");
186574ee209SMartin KaFai Lau if (!ASSERT_OK(bpf_dctcp__load(dctcp_skel), "bpf_dctcp__load"))
187574ee209SMartin KaFai Lau goto done;
188574ee209SMartin KaFai Lau
189574ee209SMartin KaFai Lau link = bpf_map__attach_struct_ops(dctcp_skel->maps.dctcp);
190574ee209SMartin KaFai Lau if (!ASSERT_OK_PTR(link, "dctcp link"))
191574ee209SMartin KaFai Lau goto done;
192574ee209SMartin KaFai Lau
193574ee209SMartin KaFai Lau lfd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0);
194574ee209SMartin KaFai Lau if (!ASSERT_GE(lfd, 0, "lfd") ||
195574ee209SMartin KaFai Lau !ASSERT_OK(settcpca(lfd, "bpf_dctcp"), "lfd=>bpf_dctcp"))
196574ee209SMartin KaFai Lau goto done;
197574ee209SMartin KaFai Lau
198574ee209SMartin KaFai Lau cli_fd = connect_to_fd_opts(lfd, &opts);
199574ee209SMartin KaFai Lau if (!ASSERT_GE(cli_fd, 0, "cli_fd"))
200574ee209SMartin KaFai Lau goto done;
201574ee209SMartin KaFai Lau
202574ee209SMartin KaFai Lau srv_fd = accept(lfd, NULL, 0);
203574ee209SMartin KaFai Lau if (!ASSERT_GE(srv_fd, 0, "srv_fd"))
204574ee209SMartin KaFai Lau goto done;
205574ee209SMartin KaFai Lau ASSERT_STREQ(dctcp_skel->bss->cc_res, "cubic", "cc_res");
206574ee209SMartin KaFai Lau ASSERT_EQ(dctcp_skel->bss->tcp_cdg_res, -ENOTSUPP, "tcp_cdg_res");
2073411c5b6SMartin KaFai Lau /* All setsockopt(TCP_CONGESTION) in the recurred
2083411c5b6SMartin KaFai Lau * bpf_dctcp->init() should fail with -EBUSY.
2093411c5b6SMartin KaFai Lau */
2103411c5b6SMartin KaFai Lau ASSERT_EQ(dctcp_skel->bss->ebusy_cnt, 3, "ebusy_cnt");
211574ee209SMartin KaFai Lau
212574ee209SMartin KaFai Lau err = getsockopt(srv_fd, SOL_TCP, TCP_CONGESTION, srv_cc, &cc_len);
213574ee209SMartin KaFai Lau if (!ASSERT_OK(err, "getsockopt(srv_fd, TCP_CONGESTION)"))
214574ee209SMartin KaFai Lau goto done;
215574ee209SMartin KaFai Lau ASSERT_STREQ(srv_cc, "cubic", "srv_fd cc");
216574ee209SMartin KaFai Lau
217574ee209SMartin KaFai Lau done:
218574ee209SMartin KaFai Lau bpf_link__destroy(link);
219574ee209SMartin KaFai Lau bpf_dctcp__destroy(dctcp_skel);
220574ee209SMartin KaFai Lau if (lfd != -1)
221574ee209SMartin KaFai Lau close(lfd);
222574ee209SMartin KaFai Lau if (srv_fd != -1)
223574ee209SMartin KaFai Lau close(srv_fd);
224574ee209SMartin KaFai Lau if (cli_fd != -1)
225574ee209SMartin KaFai Lau close(cli_fd);
226574ee209SMartin KaFai Lau }
227574ee209SMartin KaFai Lau
test_rel_setsockopt(void)228574ee209SMartin KaFai Lau static void test_rel_setsockopt(void)
229574ee209SMartin KaFai Lau {
230574ee209SMartin KaFai Lau struct bpf_dctcp_release *rel_skel;
231574ee209SMartin KaFai Lau libbpf_print_fn_t old_print_fn;
232574ee209SMartin KaFai Lau
233786bf0e7SMykyta Yatsenko err_str = "program of this type cannot use helper bpf_setsockopt";
234574ee209SMartin KaFai Lau found = false;
235574ee209SMartin KaFai Lau
236574ee209SMartin KaFai Lau old_print_fn = libbpf_set_print(libbpf_debug_print);
237574ee209SMartin KaFai Lau rel_skel = bpf_dctcp_release__open_and_load();
238574ee209SMartin KaFai Lau libbpf_set_print(old_print_fn);
239574ee209SMartin KaFai Lau
240574ee209SMartin KaFai Lau ASSERT_ERR_PTR(rel_skel, "rel_skel");
241574ee209SMartin KaFai Lau ASSERT_TRUE(found, "expected_err_msg");
242574ee209SMartin KaFai Lau
243574ee209SMartin KaFai Lau bpf_dctcp_release__destroy(rel_skel);
244574ee209SMartin KaFai Lau }
245574ee209SMartin KaFai Lau
test_write_sk_pacing(void)2466e945d57SJörn-Thorben Hinz static void test_write_sk_pacing(void)
2476e945d57SJörn-Thorben Hinz {
2486e945d57SJörn-Thorben Hinz struct tcp_ca_write_sk_pacing *skel;
2496e945d57SJörn-Thorben Hinz struct bpf_link *link;
2506e945d57SJörn-Thorben Hinz
2516e945d57SJörn-Thorben Hinz skel = tcp_ca_write_sk_pacing__open_and_load();
2526e945d57SJörn-Thorben Hinz if (!ASSERT_OK_PTR(skel, "open_and_load"))
2536e945d57SJörn-Thorben Hinz return;
2546e945d57SJörn-Thorben Hinz
2556e945d57SJörn-Thorben Hinz link = bpf_map__attach_struct_ops(skel->maps.write_sk_pacing);
2566e945d57SJörn-Thorben Hinz ASSERT_OK_PTR(link, "attach_struct_ops");
2576e945d57SJörn-Thorben Hinz
2586e945d57SJörn-Thorben Hinz bpf_link__destroy(link);
2596e945d57SJörn-Thorben Hinz tcp_ca_write_sk_pacing__destroy(skel);
2606e945d57SJörn-Thorben Hinz }
2616e945d57SJörn-Thorben Hinz
test_incompl_cong_ops(void)2620735627dSJörn-Thorben Hinz static void test_incompl_cong_ops(void)
2630735627dSJörn-Thorben Hinz {
2640735627dSJörn-Thorben Hinz struct tcp_ca_incompl_cong_ops *skel;
2650735627dSJörn-Thorben Hinz struct bpf_link *link;
2660735627dSJörn-Thorben Hinz
2670735627dSJörn-Thorben Hinz skel = tcp_ca_incompl_cong_ops__open_and_load();
2680735627dSJörn-Thorben Hinz if (!ASSERT_OK_PTR(skel, "open_and_load"))
2690735627dSJörn-Thorben Hinz return;
2700735627dSJörn-Thorben Hinz
2710735627dSJörn-Thorben Hinz /* That cong_avoid() and cong_control() are missing is only reported at
2720735627dSJörn-Thorben Hinz * this point:
2730735627dSJörn-Thorben Hinz */
2740735627dSJörn-Thorben Hinz link = bpf_map__attach_struct_ops(skel->maps.incompl_cong_ops);
2750735627dSJörn-Thorben Hinz ASSERT_ERR_PTR(link, "attach_struct_ops");
2760735627dSJörn-Thorben Hinz
2770735627dSJörn-Thorben Hinz bpf_link__destroy(link);
2780735627dSJörn-Thorben Hinz tcp_ca_incompl_cong_ops__destroy(skel);
2790735627dSJörn-Thorben Hinz }
2800735627dSJörn-Thorben Hinz
test_unsupp_cong_op(void)281f14a3f64SJörn-Thorben Hinz static void test_unsupp_cong_op(void)
282f14a3f64SJörn-Thorben Hinz {
283f14a3f64SJörn-Thorben Hinz libbpf_print_fn_t old_print_fn;
284f14a3f64SJörn-Thorben Hinz struct tcp_ca_unsupp_cong_op *skel;
285f14a3f64SJörn-Thorben Hinz
286f14a3f64SJörn-Thorben Hinz err_str = "attach to unsupported member get_info";
287f14a3f64SJörn-Thorben Hinz found = false;
288f14a3f64SJörn-Thorben Hinz old_print_fn = libbpf_set_print(libbpf_debug_print);
289f14a3f64SJörn-Thorben Hinz
290f14a3f64SJörn-Thorben Hinz skel = tcp_ca_unsupp_cong_op__open_and_load();
291f14a3f64SJörn-Thorben Hinz ASSERT_NULL(skel, "open_and_load");
292f14a3f64SJörn-Thorben Hinz ASSERT_EQ(found, true, "expected_err_msg");
293f14a3f64SJörn-Thorben Hinz
294f14a3f64SJörn-Thorben Hinz tcp_ca_unsupp_cong_op__destroy(skel);
295f14a3f64SJörn-Thorben Hinz libbpf_set_print(old_print_fn);
296f14a3f64SJörn-Thorben Hinz }
297f14a3f64SJörn-Thorben Hinz
test_update_ca(void)29806da9f3bSKui-Feng Lee static void test_update_ca(void)
29906da9f3bSKui-Feng Lee {
30006da9f3bSKui-Feng Lee struct tcp_ca_update *skel;
30106da9f3bSKui-Feng Lee struct bpf_link *link;
30206da9f3bSKui-Feng Lee int saved_ca1_cnt;
30306da9f3bSKui-Feng Lee int err;
30406da9f3bSKui-Feng Lee
30506da9f3bSKui-Feng Lee skel = tcp_ca_update__open_and_load();
30606da9f3bSKui-Feng Lee if (!ASSERT_OK_PTR(skel, "open"))
30706da9f3bSKui-Feng Lee return;
30806da9f3bSKui-Feng Lee
30906da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
31006da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops");
31106da9f3bSKui-Feng Lee
31206da9f3bSKui-Feng Lee do_test("tcp_ca_update", NULL);
31306da9f3bSKui-Feng Lee saved_ca1_cnt = skel->bss->ca1_cnt;
31406da9f3bSKui-Feng Lee ASSERT_GT(saved_ca1_cnt, 0, "ca1_ca1_cnt");
31506da9f3bSKui-Feng Lee
31606da9f3bSKui-Feng Lee err = bpf_link__update_map(link, skel->maps.ca_update_2);
31706da9f3bSKui-Feng Lee ASSERT_OK(err, "update_map");
31806da9f3bSKui-Feng Lee
31906da9f3bSKui-Feng Lee do_test("tcp_ca_update", NULL);
32006da9f3bSKui-Feng Lee ASSERT_EQ(skel->bss->ca1_cnt, saved_ca1_cnt, "ca2_ca1_cnt");
32106da9f3bSKui-Feng Lee ASSERT_GT(skel->bss->ca2_cnt, 0, "ca2_ca2_cnt");
32206da9f3bSKui-Feng Lee
32306da9f3bSKui-Feng Lee bpf_link__destroy(link);
32406da9f3bSKui-Feng Lee tcp_ca_update__destroy(skel);
32506da9f3bSKui-Feng Lee }
32606da9f3bSKui-Feng Lee
test_update_wrong(void)32706da9f3bSKui-Feng Lee static void test_update_wrong(void)
32806da9f3bSKui-Feng Lee {
32906da9f3bSKui-Feng Lee struct tcp_ca_update *skel;
33006da9f3bSKui-Feng Lee struct bpf_link *link;
33106da9f3bSKui-Feng Lee int saved_ca1_cnt;
33206da9f3bSKui-Feng Lee int err;
33306da9f3bSKui-Feng Lee
33406da9f3bSKui-Feng Lee skel = tcp_ca_update__open_and_load();
33506da9f3bSKui-Feng Lee if (!ASSERT_OK_PTR(skel, "open"))
33606da9f3bSKui-Feng Lee return;
33706da9f3bSKui-Feng Lee
33806da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
33906da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops");
34006da9f3bSKui-Feng Lee
34106da9f3bSKui-Feng Lee do_test("tcp_ca_update", NULL);
34206da9f3bSKui-Feng Lee saved_ca1_cnt = skel->bss->ca1_cnt;
34306da9f3bSKui-Feng Lee ASSERT_GT(saved_ca1_cnt, 0, "ca1_ca1_cnt");
34406da9f3bSKui-Feng Lee
34506da9f3bSKui-Feng Lee err = bpf_link__update_map(link, skel->maps.ca_wrong);
34606da9f3bSKui-Feng Lee ASSERT_ERR(err, "update_map");
34706da9f3bSKui-Feng Lee
34806da9f3bSKui-Feng Lee do_test("tcp_ca_update", NULL);
34906da9f3bSKui-Feng Lee ASSERT_GT(skel->bss->ca1_cnt, saved_ca1_cnt, "ca2_ca1_cnt");
35006da9f3bSKui-Feng Lee
35106da9f3bSKui-Feng Lee bpf_link__destroy(link);
35206da9f3bSKui-Feng Lee tcp_ca_update__destroy(skel);
35306da9f3bSKui-Feng Lee }
35406da9f3bSKui-Feng Lee
test_mixed_links(void)35506da9f3bSKui-Feng Lee static void test_mixed_links(void)
35606da9f3bSKui-Feng Lee {
35706da9f3bSKui-Feng Lee struct tcp_ca_update *skel;
35806da9f3bSKui-Feng Lee struct bpf_link *link, *link_nl;
35906da9f3bSKui-Feng Lee int err;
36006da9f3bSKui-Feng Lee
36106da9f3bSKui-Feng Lee skel = tcp_ca_update__open_and_load();
36206da9f3bSKui-Feng Lee if (!ASSERT_OK_PTR(skel, "open"))
36306da9f3bSKui-Feng Lee return;
36406da9f3bSKui-Feng Lee
36506da9f3bSKui-Feng Lee link_nl = bpf_map__attach_struct_ops(skel->maps.ca_no_link);
36606da9f3bSKui-Feng Lee ASSERT_OK_PTR(link_nl, "attach_struct_ops_nl");
36706da9f3bSKui-Feng Lee
36806da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
36906da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops");
37006da9f3bSKui-Feng Lee
37106da9f3bSKui-Feng Lee do_test("tcp_ca_update", NULL);
37206da9f3bSKui-Feng Lee ASSERT_GT(skel->bss->ca1_cnt, 0, "ca1_ca1_cnt");
37306da9f3bSKui-Feng Lee
37406da9f3bSKui-Feng Lee err = bpf_link__update_map(link, skel->maps.ca_no_link);
37506da9f3bSKui-Feng Lee ASSERT_ERR(err, "update_map");
37606da9f3bSKui-Feng Lee
37706da9f3bSKui-Feng Lee bpf_link__destroy(link);
37806da9f3bSKui-Feng Lee bpf_link__destroy(link_nl);
37906da9f3bSKui-Feng Lee tcp_ca_update__destroy(skel);
38006da9f3bSKui-Feng Lee }
38106da9f3bSKui-Feng Lee
test_multi_links(void)38206da9f3bSKui-Feng Lee static void test_multi_links(void)
38306da9f3bSKui-Feng Lee {
38406da9f3bSKui-Feng Lee struct tcp_ca_update *skel;
38506da9f3bSKui-Feng Lee struct bpf_link *link;
38606da9f3bSKui-Feng Lee
38706da9f3bSKui-Feng Lee skel = tcp_ca_update__open_and_load();
38806da9f3bSKui-Feng Lee if (!ASSERT_OK_PTR(skel, "open"))
38906da9f3bSKui-Feng Lee return;
39006da9f3bSKui-Feng Lee
39106da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
39206da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops_1st");
39306da9f3bSKui-Feng Lee bpf_link__destroy(link);
39406da9f3bSKui-Feng Lee
39506da9f3bSKui-Feng Lee /* A map should be able to be used to create links multiple
39606da9f3bSKui-Feng Lee * times.
39706da9f3bSKui-Feng Lee */
39806da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
39906da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops_2nd");
40006da9f3bSKui-Feng Lee bpf_link__destroy(link);
40106da9f3bSKui-Feng Lee
40206da9f3bSKui-Feng Lee tcp_ca_update__destroy(skel);
40306da9f3bSKui-Feng Lee }
40406da9f3bSKui-Feng Lee
test_link_replace(void)40506da9f3bSKui-Feng Lee static void test_link_replace(void)
40606da9f3bSKui-Feng Lee {
40706da9f3bSKui-Feng Lee DECLARE_LIBBPF_OPTS(bpf_link_update_opts, opts);
40806da9f3bSKui-Feng Lee struct tcp_ca_update *skel;
40906da9f3bSKui-Feng Lee struct bpf_link *link;
41006da9f3bSKui-Feng Lee int err;
41106da9f3bSKui-Feng Lee
41206da9f3bSKui-Feng Lee skel = tcp_ca_update__open_and_load();
41306da9f3bSKui-Feng Lee if (!ASSERT_OK_PTR(skel, "open"))
41406da9f3bSKui-Feng Lee return;
41506da9f3bSKui-Feng Lee
41606da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
41706da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops_1st");
41806da9f3bSKui-Feng Lee bpf_link__destroy(link);
41906da9f3bSKui-Feng Lee
42006da9f3bSKui-Feng Lee link = bpf_map__attach_struct_ops(skel->maps.ca_update_2);
42106da9f3bSKui-Feng Lee ASSERT_OK_PTR(link, "attach_struct_ops_2nd");
42206da9f3bSKui-Feng Lee
42306da9f3bSKui-Feng Lee /* BPF_F_REPLACE with a wrong old map Fd. It should fail!
42406da9f3bSKui-Feng Lee *
42506da9f3bSKui-Feng Lee * With BPF_F_REPLACE, the link should be updated only if the
42606da9f3bSKui-Feng Lee * old map fd given here matches the map backing the link.
42706da9f3bSKui-Feng Lee */
42806da9f3bSKui-Feng Lee opts.old_map_fd = bpf_map__fd(skel->maps.ca_update_1);
42906da9f3bSKui-Feng Lee opts.flags = BPF_F_REPLACE;
43006da9f3bSKui-Feng Lee err = bpf_link_update(bpf_link__fd(link),
43106da9f3bSKui-Feng Lee bpf_map__fd(skel->maps.ca_update_1),
43206da9f3bSKui-Feng Lee &opts);
43306da9f3bSKui-Feng Lee ASSERT_ERR(err, "bpf_link_update_fail");
43406da9f3bSKui-Feng Lee
43506da9f3bSKui-Feng Lee /* BPF_F_REPLACE with a correct old map Fd. It should success! */
43606da9f3bSKui-Feng Lee opts.old_map_fd = bpf_map__fd(skel->maps.ca_update_2);
43706da9f3bSKui-Feng Lee err = bpf_link_update(bpf_link__fd(link),
43806da9f3bSKui-Feng Lee bpf_map__fd(skel->maps.ca_update_1),
43906da9f3bSKui-Feng Lee &opts);
44006da9f3bSKui-Feng Lee ASSERT_OK(err, "bpf_link_update_success");
44106da9f3bSKui-Feng Lee
44206da9f3bSKui-Feng Lee bpf_link__destroy(link);
44306da9f3bSKui-Feng Lee
44406da9f3bSKui-Feng Lee tcp_ca_update__destroy(skel);
44506da9f3bSKui-Feng Lee }
44606da9f3bSKui-Feng Lee
test_tcp_ca_kfunc(void)4475da7fb04SMartin KaFai Lau static void test_tcp_ca_kfunc(void)
4485da7fb04SMartin KaFai Lau {
4495da7fb04SMartin KaFai Lau struct tcp_ca_kfunc *skel;
4505da7fb04SMartin KaFai Lau
4515da7fb04SMartin KaFai Lau skel = tcp_ca_kfunc__open_and_load();
4525da7fb04SMartin KaFai Lau ASSERT_OK_PTR(skel, "tcp_ca_kfunc__open_and_load");
4535da7fb04SMartin KaFai Lau tcp_ca_kfunc__destroy(skel);
4545da7fb04SMartin KaFai Lau }
4555da7fb04SMartin KaFai Lau
test_cc_cubic(void)456*96c3490dSMiao Xu static void test_cc_cubic(void)
457*96c3490dSMiao Xu {
458*96c3490dSMiao Xu struct bpf_cc_cubic *cc_cubic_skel;
459*96c3490dSMiao Xu struct bpf_link *link;
460*96c3490dSMiao Xu
461*96c3490dSMiao Xu cc_cubic_skel = bpf_cc_cubic__open_and_load();
462*96c3490dSMiao Xu if (!ASSERT_OK_PTR(cc_cubic_skel, "bpf_cc_cubic__open_and_load"))
463*96c3490dSMiao Xu return;
464*96c3490dSMiao Xu
465*96c3490dSMiao Xu link = bpf_map__attach_struct_ops(cc_cubic_skel->maps.cc_cubic);
466*96c3490dSMiao Xu if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) {
467*96c3490dSMiao Xu bpf_cc_cubic__destroy(cc_cubic_skel);
468*96c3490dSMiao Xu return;
469*96c3490dSMiao Xu }
470*96c3490dSMiao Xu
471*96c3490dSMiao Xu do_test("bpf_cc_cubic", NULL);
472*96c3490dSMiao Xu
473*96c3490dSMiao Xu bpf_link__destroy(link);
474*96c3490dSMiao Xu bpf_cc_cubic__destroy(cc_cubic_skel);
475*96c3490dSMiao Xu }
476*96c3490dSMiao Xu
test_bpf_tcp_ca(void)47709903869SMartin KaFai Lau void test_bpf_tcp_ca(void)
47809903869SMartin KaFai Lau {
47909903869SMartin KaFai Lau if (test__start_subtest("dctcp"))
48009903869SMartin KaFai Lau test_dctcp();
4816de4a9c4SMartin KaFai Lau if (test__start_subtest("cubic"))
4826de4a9c4SMartin KaFai Lau test_cubic();
483d8e8052eSToke Høiland-Jørgensen if (test__start_subtest("invalid_license"))
484d8e8052eSToke Høiland-Jørgensen test_invalid_license();
485574ee209SMartin KaFai Lau if (test__start_subtest("dctcp_fallback"))
486574ee209SMartin KaFai Lau test_dctcp_fallback();
487574ee209SMartin KaFai Lau if (test__start_subtest("rel_setsockopt"))
488574ee209SMartin KaFai Lau test_rel_setsockopt();
4896e945d57SJörn-Thorben Hinz if (test__start_subtest("write_sk_pacing"))
4906e945d57SJörn-Thorben Hinz test_write_sk_pacing();
4910735627dSJörn-Thorben Hinz if (test__start_subtest("incompl_cong_ops"))
4920735627dSJörn-Thorben Hinz test_incompl_cong_ops();
493f14a3f64SJörn-Thorben Hinz if (test__start_subtest("unsupp_cong_op"))
494f14a3f64SJörn-Thorben Hinz test_unsupp_cong_op();
49506da9f3bSKui-Feng Lee if (test__start_subtest("update_ca"))
49606da9f3bSKui-Feng Lee test_update_ca();
49706da9f3bSKui-Feng Lee if (test__start_subtest("update_wrong"))
49806da9f3bSKui-Feng Lee test_update_wrong();
49906da9f3bSKui-Feng Lee if (test__start_subtest("mixed_links"))
50006da9f3bSKui-Feng Lee test_mixed_links();
50106da9f3bSKui-Feng Lee if (test__start_subtest("multi_links"))
50206da9f3bSKui-Feng Lee test_multi_links();
50306da9f3bSKui-Feng Lee if (test__start_subtest("link_replace"))
50406da9f3bSKui-Feng Lee test_link_replace();
5055da7fb04SMartin KaFai Lau if (test__start_subtest("tcp_ca_kfunc"))
5065da7fb04SMartin KaFai Lau test_tcp_ca_kfunc();
507*96c3490dSMiao Xu if (test__start_subtest("cc_cubic"))
508*96c3490dSMiao Xu test_cc_cubic();
50909903869SMartin KaFai Lau }
510