Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2021 Facebook */
0003 #include "bpf_iter.h"
0004 #include "bpf_tracing_net.h"
0005 #include <bpf/bpf_helpers.h>
0006 #include <bpf/bpf_endian.h>
0007 
0008 #define bpf_tcp_sk(skc) ({              \
0009     struct sock_common *_skc = skc;         \
0010     sk = NULL;                  \
0011     tp = NULL;                  \
0012     if (_skc) {                 \
0013         tp = bpf_skc_to_tcp_sock(_skc);     \
0014         sk = (struct sock *)tp;         \
0015     }                       \
0016     tp;                     \
0017 })
0018 
0019 unsigned short reuse_listen_hport = 0;
0020 unsigned short listen_hport = 0;
0021 char cubic_cc[TCP_CA_NAME_MAX] = "bpf_cubic";
0022 char dctcp_cc[TCP_CA_NAME_MAX] = "bpf_dctcp";
0023 bool random_retry = false;
0024 
0025 static bool tcp_cc_eq(const char *a, const char *b)
0026 {
0027     int i;
0028 
0029     for (i = 0; i < TCP_CA_NAME_MAX; i++) {
0030         if (a[i] != b[i])
0031             return false;
0032         if (!a[i])
0033             break;
0034     }
0035 
0036     return true;
0037 }
0038 
0039 SEC("iter/tcp")
0040 int change_tcp_cc(struct bpf_iter__tcp *ctx)
0041 {
0042     char cur_cc[TCP_CA_NAME_MAX];
0043     struct tcp_sock *tp;
0044     struct sock *sk;
0045     int ret;
0046 
0047     if (!bpf_tcp_sk(ctx->sk_common))
0048         return 0;
0049 
0050     if (sk->sk_family != AF_INET6 ||
0051         (sk->sk_state != TCP_LISTEN &&
0052          sk->sk_state != TCP_ESTABLISHED) ||
0053         (sk->sk_num != reuse_listen_hport &&
0054          sk->sk_num != listen_hport &&
0055          bpf_ntohs(sk->sk_dport) != listen_hport))
0056         return 0;
0057 
0058     if (bpf_getsockopt(tp, SOL_TCP, TCP_CONGESTION,
0059                cur_cc, sizeof(cur_cc)))
0060         return 0;
0061 
0062     if (!tcp_cc_eq(cur_cc, cubic_cc))
0063         return 0;
0064 
0065     if (random_retry && bpf_get_prandom_u32() % 4 == 1)
0066         return 1;
0067 
0068     bpf_setsockopt(tp, SOL_TCP, TCP_CONGESTION, dctcp_cc, sizeof(dctcp_cc));
0069     return 0;
0070 }
0071 
0072 char _license[] SEC("license") = "GPL";