1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2020, Tessares SA. */ 3 /* Copyright (c) 2022, SUSE. */ 4 5 #include <linux/bpf.h> 6 #include <bpf/bpf_helpers.h> 7 #include "bpf_tcp_helpers.h" 8 9 char _license[] SEC("license") = "GPL"; 10 __u32 token = 0; 11 12 struct mptcp_storage { 13 __u32 invoked; 14 __u32 is_mptcp; 15 __u32 token; 16 }; 17 18 struct { 19 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 20 __uint(map_flags, BPF_F_NO_PREALLOC); 21 __type(key, int); 22 __type(value, struct mptcp_storage); 23 } socket_storage_map SEC(".maps"); 24 25 SEC("sockops") 26 int _sockops(struct bpf_sock_ops *ctx) 27 { 28 struct mptcp_storage *storage; 29 struct mptcp_sock *msk; 30 int op = (int)ctx->op; 31 struct tcp_sock *tsk; 32 struct bpf_sock *sk; 33 bool is_mptcp; 34 35 if (op != BPF_SOCK_OPS_TCP_CONNECT_CB) 36 return 1; 37 38 sk = ctx->sk; 39 if (!sk) 40 return 1; 41 42 tsk = bpf_skc_to_tcp_sock(sk); 43 if (!tsk) 44 return 1; 45 46 is_mptcp = bpf_core_field_exists(tsk->is_mptcp) ? tsk->is_mptcp : 0; 47 if (!is_mptcp) { 48 storage = bpf_sk_storage_get(&socket_storage_map, sk, 0, 49 BPF_SK_STORAGE_GET_F_CREATE); 50 if (!storage) 51 return 1; 52 53 storage->token = 0; 54 } else { 55 msk = bpf_skc_to_mptcp_sock(sk); 56 if (!msk) 57 return 1; 58 59 storage = bpf_sk_storage_get(&socket_storage_map, msk, 0, 60 BPF_SK_STORAGE_GET_F_CREATE); 61 if (!storage) 62 return 1; 63 64 storage->token = msk->token; 65 } 66 storage->invoked++; 67 storage->is_mptcp = is_mptcp; 68 69 return 1; 70 } 71 72 SEC("fentry/mptcp_pm_new_connection") 73 int BPF_PROG(trace_mptcp_pm_new_connection, struct mptcp_sock *msk, 74 const struct sock *ssk, int server_side) 75 { 76 if (!server_side) 77 token = msk->token; 78 79 return 0; 80 } 81