1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 #include <vmlinux.h> 4 #include "bpf_tracing_net.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_endian.h> 7 8 #define bpf_tcp_sk(skc) ({ \ 9 struct sock_common *_skc = skc; \ 10 sk = NULL; \ 11 tp = NULL; \ 12 if (_skc) { \ 13 tp = bpf_skc_to_tcp_sock(_skc); \ 14 sk = (struct sock *)tp; \ 15 } \ 16 tp; \ 17 }) 18 19 unsigned short reuse_listen_hport = 0; 20 unsigned short listen_hport = 0; 21 const char cubic_cc[] = "bpf_cubic"; 22 char dctcp_cc[TCP_CA_NAME_MAX] = "bpf_dctcp"; 23 bool random_retry = false; 24 25 26 SEC("iter/tcp") 27 int change_tcp_cc(struct bpf_iter__tcp *ctx) 28 { 29 char cur_cc[TCP_CA_NAME_MAX]; 30 struct tcp_sock *tp; 31 struct sock *sk; 32 33 if (!bpf_tcp_sk(ctx->sk_common)) 34 return 0; 35 36 if (sk->sk_family != AF_INET6 || 37 (sk->sk_state != TCP_LISTEN && 38 sk->sk_state != TCP_ESTABLISHED) || 39 (sk->sk_num != reuse_listen_hport && 40 sk->sk_num != listen_hport && 41 bpf_ntohs(sk->sk_dport) != listen_hport)) 42 return 0; 43 44 if (bpf_getsockopt(tp, SOL_TCP, TCP_CONGESTION, 45 cur_cc, sizeof(cur_cc))) 46 return 0; 47 48 if (bpf_strncmp(cur_cc, TCP_CA_NAME_MAX, cubic_cc)) 49 return 0; 50 51 if (random_retry && bpf_get_prandom_u32() % 4 == 1) 52 return 1; 53 54 bpf_setsockopt(tp, SOL_TCP, TCP_CONGESTION, dctcp_cc, sizeof(dctcp_cc)); 55 return 0; 56 } 57 58 char _license[] SEC("license") = "GPL"; 59