0001
0002
0003
0004
0005 #include <linux/bpf.h>
0006 #include <bpf/bpf_helpers.h>
0007 #include "bpf_tcp_helpers.h"
0008
0009 char _license[] SEC("license") = "GPL";
0010 __u32 token = 0;
0011
0012 struct mptcp_storage {
0013 __u32 invoked;
0014 __u32 is_mptcp;
0015 struct sock *sk;
0016 __u32 token;
0017 struct sock *first;
0018 char ca_name[TCP_CA_NAME_MAX];
0019 };
0020
0021 struct {
0022 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
0023 __uint(map_flags, BPF_F_NO_PREALLOC);
0024 __type(key, int);
0025 __type(value, struct mptcp_storage);
0026 } socket_storage_map SEC(".maps");
0027
0028 SEC("sockops")
0029 int _sockops(struct bpf_sock_ops *ctx)
0030 {
0031 struct mptcp_storage *storage;
0032 struct mptcp_sock *msk;
0033 int op = (int)ctx->op;
0034 struct tcp_sock *tsk;
0035 struct bpf_sock *sk;
0036 bool is_mptcp;
0037
0038 if (op != BPF_SOCK_OPS_TCP_CONNECT_CB)
0039 return 1;
0040
0041 sk = ctx->sk;
0042 if (!sk)
0043 return 1;
0044
0045 tsk = bpf_skc_to_tcp_sock(sk);
0046 if (!tsk)
0047 return 1;
0048
0049 is_mptcp = bpf_core_field_exists(tsk->is_mptcp) ? tsk->is_mptcp : 0;
0050 if (!is_mptcp) {
0051 storage = bpf_sk_storage_get(&socket_storage_map, sk, 0,
0052 BPF_SK_STORAGE_GET_F_CREATE);
0053 if (!storage)
0054 return 1;
0055
0056 storage->token = 0;
0057 __builtin_memset(storage->ca_name, 0, TCP_CA_NAME_MAX);
0058 storage->first = NULL;
0059 } else {
0060 msk = bpf_skc_to_mptcp_sock(sk);
0061 if (!msk)
0062 return 1;
0063
0064 storage = bpf_sk_storage_get(&socket_storage_map, msk, 0,
0065 BPF_SK_STORAGE_GET_F_CREATE);
0066 if (!storage)
0067 return 1;
0068
0069 storage->token = msk->token;
0070 __builtin_memcpy(storage->ca_name, msk->ca_name, TCP_CA_NAME_MAX);
0071 storage->first = msk->first;
0072 }
0073 storage->invoked++;
0074 storage->is_mptcp = is_mptcp;
0075 storage->sk = (struct sock *)sk;
0076
0077 return 1;
0078 }
0079
0080 SEC("fentry/mptcp_pm_new_connection")
0081 int BPF_PROG(trace_mptcp_pm_new_connection, struct mptcp_sock *msk,
0082 const struct sock *ssk, int server_side)
0083 {
0084 if (!server_side)
0085 token = msk->token;
0086
0087 return 0;
0088 }