Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2020, Tessares SA. */
0003 /* Copyright (c) 2022, SUSE. */
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 }