1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun #include <linux/bpf.h> 3*4882a593Smuzhiyun #include <bpf/bpf_helpers.h> 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun char _license[] SEC("license") = "GPL"; 6*4882a593Smuzhiyun __u32 _version SEC("version") = 1; 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun struct tcp_rtt_storage { 9*4882a593Smuzhiyun __u32 invoked; 10*4882a593Smuzhiyun __u32 dsack_dups; 11*4882a593Smuzhiyun __u32 delivered; 12*4882a593Smuzhiyun __u32 delivered_ce; 13*4882a593Smuzhiyun __u32 icsk_retransmits; 14*4882a593Smuzhiyun }; 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun struct { 17*4882a593Smuzhiyun __uint(type, BPF_MAP_TYPE_SK_STORAGE); 18*4882a593Smuzhiyun __uint(map_flags, BPF_F_NO_PREALLOC); 19*4882a593Smuzhiyun __type(key, int); 20*4882a593Smuzhiyun __type(value, struct tcp_rtt_storage); 21*4882a593Smuzhiyun } socket_storage_map SEC(".maps"); 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun SEC("sockops") _sockops(struct bpf_sock_ops * ctx)24*4882a593Smuzhiyunint _sockops(struct bpf_sock_ops *ctx) 25*4882a593Smuzhiyun { 26*4882a593Smuzhiyun struct tcp_rtt_storage *storage; 27*4882a593Smuzhiyun struct bpf_tcp_sock *tcp_sk; 28*4882a593Smuzhiyun int op = (int) ctx->op; 29*4882a593Smuzhiyun struct bpf_sock *sk; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun sk = ctx->sk; 32*4882a593Smuzhiyun if (!sk) 33*4882a593Smuzhiyun return 1; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun storage = bpf_sk_storage_get(&socket_storage_map, sk, 0, 36*4882a593Smuzhiyun BPF_SK_STORAGE_GET_F_CREATE); 37*4882a593Smuzhiyun if (!storage) 38*4882a593Smuzhiyun return 1; 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun if (op == BPF_SOCK_OPS_TCP_CONNECT_CB) { 41*4882a593Smuzhiyun bpf_sock_ops_cb_flags_set(ctx, BPF_SOCK_OPS_RTT_CB_FLAG); 42*4882a593Smuzhiyun return 1; 43*4882a593Smuzhiyun } 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun if (op != BPF_SOCK_OPS_RTT_CB) 46*4882a593Smuzhiyun return 1; 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun tcp_sk = bpf_tcp_sock(sk); 49*4882a593Smuzhiyun if (!tcp_sk) 50*4882a593Smuzhiyun return 1; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun storage->invoked++; 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun storage->dsack_dups = tcp_sk->dsack_dups; 55*4882a593Smuzhiyun storage->delivered = tcp_sk->delivered; 56*4882a593Smuzhiyun storage->delivered_ce = tcp_sk->delivered_ce; 57*4882a593Smuzhiyun storage->icsk_retransmits = tcp_sk->icsk_retransmits; 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun return 1; 60*4882a593Smuzhiyun } 61