Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Test an incomplete BPF CC

Test whether a TCP CC implemented in BPF providing neither cong_avoid()
nor cong_control() is correctly rejected. This check solely depends on
tcp_register_congestion_control() now, which is invoked during
bpf_map__attach_struct_ops().

Signed-off-by: Jörn-Thorben Hinz <jthinz@mailbox.tu-berlin.de>
Link: https://lore.kernel.org/r/20220622191227.898118-5-jthinz@mailbox.tu-berlin.de
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Jörn-Thorben Hinz and committed by
Alexei Starovoitov
0735627d 6e945d57

+57
+22
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
··· 10 10 #include "bpf_tcp_nogpl.skel.h" 11 11 #include "bpf_dctcp_release.skel.h" 12 12 #include "tcp_ca_write_sk_pacing.skel.h" 13 + #include "tcp_ca_incompl_cong_ops.skel.h" 13 14 14 15 #ifndef ENOTSUPP 15 16 #define ENOTSUPP 524 ··· 340 339 tcp_ca_write_sk_pacing__destroy(skel); 341 340 } 342 341 342 + static void test_incompl_cong_ops(void) 343 + { 344 + struct tcp_ca_incompl_cong_ops *skel; 345 + struct bpf_link *link; 346 + 347 + skel = tcp_ca_incompl_cong_ops__open_and_load(); 348 + if (!ASSERT_OK_PTR(skel, "open_and_load")) 349 + return; 350 + 351 + /* That cong_avoid() and cong_control() are missing is only reported at 352 + * this point: 353 + */ 354 + link = bpf_map__attach_struct_ops(skel->maps.incompl_cong_ops); 355 + ASSERT_ERR_PTR(link, "attach_struct_ops"); 356 + 357 + bpf_link__destroy(link); 358 + tcp_ca_incompl_cong_ops__destroy(skel); 359 + } 360 + 343 361 void test_bpf_tcp_ca(void) 344 362 { 345 363 if (test__start_subtest("dctcp")) ··· 373 353 test_rel_setsockopt(); 374 354 if (test__start_subtest("write_sk_pacing")) 375 355 test_write_sk_pacing(); 356 + if (test__start_subtest("incompl_cong_ops")) 357 + test_incompl_cong_ops(); 376 358 }
+35
tools/testing/selftests/bpf/progs/tcp_ca_incompl_cong_ops.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "vmlinux.h" 4 + 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + 8 + char _license[] SEC("license") = "GPL"; 9 + 10 + static inline struct tcp_sock *tcp_sk(const struct sock *sk) 11 + { 12 + return (struct tcp_sock *)sk; 13 + } 14 + 15 + SEC("struct_ops/incompl_cong_ops_ssthresh") 16 + __u32 BPF_PROG(incompl_cong_ops_ssthresh, struct sock *sk) 17 + { 18 + return tcp_sk(sk)->snd_ssthresh; 19 + } 20 + 21 + SEC("struct_ops/incompl_cong_ops_undo_cwnd") 22 + __u32 BPF_PROG(incompl_cong_ops_undo_cwnd, struct sock *sk) 23 + { 24 + return tcp_sk(sk)->snd_cwnd; 25 + } 26 + 27 + SEC(".struct_ops") 28 + struct tcp_congestion_ops incompl_cong_ops = { 29 + /* Intentionally leaving out any of the required cong_avoid() and 30 + * cong_control() here. 31 + */ 32 + .ssthresh = (void *)incompl_cong_ops_ssthresh, 33 + .undo_cwnd = (void *)incompl_cong_ops_undo_cwnd, 34 + .name = "bpf_incompl_ops", 35 + };