xref: /aosp_15_r20/external/bcc/libbpf-tools/tcpconnlat.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0
2*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) 2020 Wenbo Zhang
3*387f9dfdSAndroid Build Coastguard Worker #include <vmlinux.h>
4*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_helpers.h>
5*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_core_read.h>
6*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_tracing.h>
7*387f9dfdSAndroid Build Coastguard Worker #include "tcpconnlat.h"
8*387f9dfdSAndroid Build Coastguard Worker 
9*387f9dfdSAndroid Build Coastguard Worker #define AF_INET    2
10*387f9dfdSAndroid Build Coastguard Worker #define AF_INET6   10
11*387f9dfdSAndroid Build Coastguard Worker 
12*387f9dfdSAndroid Build Coastguard Worker const volatile __u64 targ_min_us = 0;
13*387f9dfdSAndroid Build Coastguard Worker const volatile pid_t targ_tgid = 0;
14*387f9dfdSAndroid Build Coastguard Worker 
15*387f9dfdSAndroid Build Coastguard Worker struct piddata {
16*387f9dfdSAndroid Build Coastguard Worker 	char comm[TASK_COMM_LEN];
17*387f9dfdSAndroid Build Coastguard Worker 	u64 ts;
18*387f9dfdSAndroid Build Coastguard Worker 	u32 tgid;
19*387f9dfdSAndroid Build Coastguard Worker };
20*387f9dfdSAndroid Build Coastguard Worker 
21*387f9dfdSAndroid Build Coastguard Worker struct {
22*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
23*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, 4096);
24*387f9dfdSAndroid Build Coastguard Worker 	__type(key, struct sock *);
25*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct piddata);
26*387f9dfdSAndroid Build Coastguard Worker } start SEC(".maps");
27*387f9dfdSAndroid Build Coastguard Worker 
28*387f9dfdSAndroid Build Coastguard Worker struct {
29*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
30*387f9dfdSAndroid Build Coastguard Worker 	__uint(key_size, sizeof(u32));
31*387f9dfdSAndroid Build Coastguard Worker 	__uint(value_size, sizeof(u32));
32*387f9dfdSAndroid Build Coastguard Worker } events SEC(".maps");
33*387f9dfdSAndroid Build Coastguard Worker 
trace_connect(struct sock * sk)34*387f9dfdSAndroid Build Coastguard Worker static int trace_connect(struct sock *sk)
35*387f9dfdSAndroid Build Coastguard Worker {
36*387f9dfdSAndroid Build Coastguard Worker 	u32 tgid = bpf_get_current_pid_tgid() >> 32;
37*387f9dfdSAndroid Build Coastguard Worker 	struct piddata piddata = {};
38*387f9dfdSAndroid Build Coastguard Worker 
39*387f9dfdSAndroid Build Coastguard Worker 	if (targ_tgid && targ_tgid != tgid)
40*387f9dfdSAndroid Build Coastguard Worker 		return 0;
41*387f9dfdSAndroid Build Coastguard Worker 
42*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&piddata.comm, sizeof(piddata.comm));
43*387f9dfdSAndroid Build Coastguard Worker 	piddata.ts = bpf_ktime_get_ns();
44*387f9dfdSAndroid Build Coastguard Worker 	piddata.tgid = tgid;
45*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&start, &sk, &piddata, 0);
46*387f9dfdSAndroid Build Coastguard Worker 	return 0;
47*387f9dfdSAndroid Build Coastguard Worker }
48*387f9dfdSAndroid Build Coastguard Worker 
handle_tcp_rcv_state_process(void * ctx,struct sock * sk)49*387f9dfdSAndroid Build Coastguard Worker static int handle_tcp_rcv_state_process(void *ctx, struct sock *sk)
50*387f9dfdSAndroid Build Coastguard Worker {
51*387f9dfdSAndroid Build Coastguard Worker 	struct piddata *piddatap;
52*387f9dfdSAndroid Build Coastguard Worker 	struct event event = {};
53*387f9dfdSAndroid Build Coastguard Worker 	s64 delta;
54*387f9dfdSAndroid Build Coastguard Worker 	u64 ts;
55*387f9dfdSAndroid Build Coastguard Worker 
56*387f9dfdSAndroid Build Coastguard Worker 	if (BPF_CORE_READ(sk, __sk_common.skc_state) != TCP_SYN_SENT)
57*387f9dfdSAndroid Build Coastguard Worker 		return 0;
58*387f9dfdSAndroid Build Coastguard Worker 
59*387f9dfdSAndroid Build Coastguard Worker 	piddatap = bpf_map_lookup_elem(&start, &sk);
60*387f9dfdSAndroid Build Coastguard Worker 	if (!piddatap)
61*387f9dfdSAndroid Build Coastguard Worker 		return 0;
62*387f9dfdSAndroid Build Coastguard Worker 
63*387f9dfdSAndroid Build Coastguard Worker 	ts = bpf_ktime_get_ns();
64*387f9dfdSAndroid Build Coastguard Worker 	delta = (s64)(ts - piddatap->ts);
65*387f9dfdSAndroid Build Coastguard Worker 	if (delta < 0)
66*387f9dfdSAndroid Build Coastguard Worker 		goto cleanup;
67*387f9dfdSAndroid Build Coastguard Worker 
68*387f9dfdSAndroid Build Coastguard Worker 	event.delta_us = delta / 1000U;
69*387f9dfdSAndroid Build Coastguard Worker 	if (targ_min_us && event.delta_us < targ_min_us)
70*387f9dfdSAndroid Build Coastguard Worker 		goto cleanup;
71*387f9dfdSAndroid Build Coastguard Worker 	__builtin_memcpy(&event.comm, piddatap->comm,
72*387f9dfdSAndroid Build Coastguard Worker 			sizeof(event.comm));
73*387f9dfdSAndroid Build Coastguard Worker 	event.ts_us = ts / 1000;
74*387f9dfdSAndroid Build Coastguard Worker 	event.tgid = piddatap->tgid;
75*387f9dfdSAndroid Build Coastguard Worker 	event.lport = BPF_CORE_READ(sk, __sk_common.skc_num);
76*387f9dfdSAndroid Build Coastguard Worker 	event.dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
77*387f9dfdSAndroid Build Coastguard Worker 	event.af = BPF_CORE_READ(sk, __sk_common.skc_family);
78*387f9dfdSAndroid Build Coastguard Worker 	if (event.af == AF_INET) {
79*387f9dfdSAndroid Build Coastguard Worker 		event.saddr_v4 = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
80*387f9dfdSAndroid Build Coastguard Worker 		event.daddr_v4 = BPF_CORE_READ(sk, __sk_common.skc_daddr);
81*387f9dfdSAndroid Build Coastguard Worker 	} else {
82*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&event.saddr_v6, sk,
83*387f9dfdSAndroid Build Coastguard Worker 				__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
84*387f9dfdSAndroid Build Coastguard Worker 		BPF_CORE_READ_INTO(&event.daddr_v6, sk,
85*387f9dfdSAndroid Build Coastguard Worker 				__sk_common.skc_v6_daddr.in6_u.u6_addr32);
86*387f9dfdSAndroid Build Coastguard Worker 	}
87*387f9dfdSAndroid Build Coastguard Worker 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
88*387f9dfdSAndroid Build Coastguard Worker 			&event, sizeof(event));
89*387f9dfdSAndroid Build Coastguard Worker 
90*387f9dfdSAndroid Build Coastguard Worker cleanup:
91*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&start, &sk);
92*387f9dfdSAndroid Build Coastguard Worker 	return 0;
93*387f9dfdSAndroid Build Coastguard Worker }
94*387f9dfdSAndroid Build Coastguard Worker 
95*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_v4_connect")
BPF_KPROBE(tcp_v4_connect,struct sock * sk)96*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(tcp_v4_connect, struct sock *sk)
97*387f9dfdSAndroid Build Coastguard Worker {
98*387f9dfdSAndroid Build Coastguard Worker 	return trace_connect(sk);
99*387f9dfdSAndroid Build Coastguard Worker }
100*387f9dfdSAndroid Build Coastguard Worker 
101*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_v6_connect")
BPF_KPROBE(tcp_v6_connect,struct sock * sk)102*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(tcp_v6_connect, struct sock *sk)
103*387f9dfdSAndroid Build Coastguard Worker {
104*387f9dfdSAndroid Build Coastguard Worker 	return trace_connect(sk);
105*387f9dfdSAndroid Build Coastguard Worker }
106*387f9dfdSAndroid Build Coastguard Worker 
107*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/tcp_rcv_state_process")
BPF_KPROBE(tcp_rcv_state_process,struct sock * sk)108*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(tcp_rcv_state_process, struct sock *sk)
109*387f9dfdSAndroid Build Coastguard Worker {
110*387f9dfdSAndroid Build Coastguard Worker 	return handle_tcp_rcv_state_process(ctx, sk);
111*387f9dfdSAndroid Build Coastguard Worker }
112*387f9dfdSAndroid Build Coastguard Worker 
113*387f9dfdSAndroid Build Coastguard Worker SEC("tracepoint/tcp/tcp_destroy_sock")
tcp_destroy_sock(struct trace_event_raw_tcp_event_sk * ctx)114*387f9dfdSAndroid Build Coastguard Worker int tcp_destroy_sock(struct trace_event_raw_tcp_event_sk *ctx)
115*387f9dfdSAndroid Build Coastguard Worker {
116*387f9dfdSAndroid Build Coastguard Worker 	const struct sock *sk = ctx->skaddr;
117*387f9dfdSAndroid Build Coastguard Worker 
118*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&start, &sk);
119*387f9dfdSAndroid Build Coastguard Worker 	return 0;
120*387f9dfdSAndroid Build Coastguard Worker }
121*387f9dfdSAndroid Build Coastguard Worker 
122*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/tcp_v4_connect")
BPF_PROG(fentry_tcp_v4_connect,struct sock * sk)123*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(fentry_tcp_v4_connect, struct sock *sk)
124*387f9dfdSAndroid Build Coastguard Worker {
125*387f9dfdSAndroid Build Coastguard Worker 	return trace_connect(sk);
126*387f9dfdSAndroid Build Coastguard Worker }
127*387f9dfdSAndroid Build Coastguard Worker 
128*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/tcp_v6_connect")
BPF_PROG(fentry_tcp_v6_connect,struct sock * sk)129*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(fentry_tcp_v6_connect, struct sock *sk)
130*387f9dfdSAndroid Build Coastguard Worker {
131*387f9dfdSAndroid Build Coastguard Worker 	return trace_connect(sk);
132*387f9dfdSAndroid Build Coastguard Worker }
133*387f9dfdSAndroid Build Coastguard Worker 
134*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/tcp_rcv_state_process")
BPF_PROG(fentry_tcp_rcv_state_process,struct sock * sk)135*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(fentry_tcp_rcv_state_process, struct sock *sk)
136*387f9dfdSAndroid Build Coastguard Worker {
137*387f9dfdSAndroid Build Coastguard Worker 	return handle_tcp_rcv_state_process(ctx, sk);
138*387f9dfdSAndroid Build Coastguard Worker }
139*387f9dfdSAndroid Build Coastguard Worker 
140*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
141