Skip to content

Commit 4b89e8c

Browse files
ethercflowyonghong-song
authored andcommitted
libbpf-tools: add tcppktlat
Signed-off-by: Wenbo Zhang <[email protected]>
1 parent 6e89a30 commit 4b89e8c

File tree

6 files changed

+475
-0
lines changed

6 files changed

+475
-0
lines changed

libbpf-tools/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
/tcpconnect
5454
/tcpconnlat
5555
/tcplife
56+
/tcppktlat
5657
/tcptracer
5758
/tcprtt
5859
/tcpstates

libbpf-tools/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ APPS = \
8181
tcpconnect \
8282
tcpconnlat \
8383
tcplife \
84+
tcppktlat \
8485
tcprtt \
8586
tcpstates \
8687
tcpsynbl \

libbpf-tools/tcppktlat.bpf.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (c) 2023 Wenbo Zhang
3+
#include <vmlinux.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <bpf/bpf_core_read.h>
6+
#include <bpf/bpf_tracing.h>
7+
8+
#include "compat.bpf.h"
9+
#include "tcppktlat.h"
10+
11+
#define MAX_ENTRIES 10240
12+
#define AF_INET 2
13+
14+
const volatile pid_t targ_pid = 0;
15+
const volatile pid_t targ_tid = 0;
16+
const volatile __u16 targ_sport = 0;
17+
const volatile __u16 targ_dport = 0;
18+
const volatile __u64 targ_min_us = 0;
19+
20+
struct {
21+
__uint(type, BPF_MAP_TYPE_HASH);
22+
__uint(max_entries, MAX_ENTRIES);
23+
__type(key, u64);
24+
__type(value, u64);
25+
} start SEC(".maps");
26+
27+
static int handle_tcp_probe(struct sock *sk, struct sk_buff *skb)
28+
{
29+
const struct inet_sock *inet = (struct inet_sock *)(sk);
30+
u64 sock_cookie, ts, len, doff;
31+
const struct tcphdr *th;
32+
33+
if (targ_sport && targ_sport != BPF_CORE_READ(inet, inet_sport))
34+
return 0;
35+
if (targ_dport && targ_dport != BPF_CORE_READ(sk, __sk_common.skc_dport))
36+
return 0;
37+
th = (const struct tcphdr*)BPF_CORE_READ(skb, data);
38+
doff = BPF_CORE_READ_BITFIELD_PROBED(th, doff);
39+
len = BPF_CORE_READ(skb, len);
40+
/* `doff * 4` means `__tcp_hdrlen` */
41+
if (len <= doff * 4)
42+
return 0;
43+
sock_cookie = bpf_get_socket_cookie(sk);
44+
ts = bpf_ktime_get_ns();
45+
bpf_map_update_elem(&start, &sock_cookie, &ts, 0);
46+
return 0;
47+
}
48+
49+
static int handle_tcp_rcv_space_adjust(void *ctx, struct sock *sk)
50+
{
51+
const struct inet_sock *inet = (struct inet_sock *)(sk);
52+
u64 sock_cookie = bpf_get_socket_cookie(sk);
53+
u64 id = bpf_get_current_pid_tgid(), *tsp;
54+
u32 pid = id >> 32, tid = id;
55+
struct event *eventp;
56+
s64 delta_us;
57+
u16 family;
58+
59+
tsp = bpf_map_lookup_elem(&start, &sock_cookie);
60+
if (!tsp)
61+
return 0;
62+
63+
if (targ_pid && targ_pid != pid)
64+
goto cleanup;
65+
if (targ_tid && targ_tid != tid)
66+
goto cleanup;
67+
68+
delta_us = (bpf_ktime_get_ns() - *tsp) / 1000;
69+
if (delta_us < 0 || delta_us <= targ_min_us)
70+
goto cleanup;
71+
72+
eventp = reserve_buf(sizeof(*eventp));
73+
if (!eventp)
74+
goto cleanup;
75+
76+
eventp->pid = pid;
77+
eventp->tid = tid;
78+
eventp->delta_us = delta_us;
79+
eventp->sport = BPF_CORE_READ(inet, inet_sport);
80+
eventp->dport = BPF_CORE_READ(sk, __sk_common.skc_dport);
81+
bpf_get_current_comm(&eventp->comm, TASK_COMM_LEN);
82+
family = BPF_CORE_READ(sk, __sk_common.skc_family);
83+
if (family == AF_INET) {
84+
eventp->saddr[0] = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
85+
eventp->daddr[0] = BPF_CORE_READ(sk, __sk_common.skc_daddr);
86+
} else { /* family == AF_INET6 */
87+
BPF_CORE_READ_INTO(eventp->saddr, sk, __sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
88+
BPF_CORE_READ_INTO(eventp->daddr, sk, __sk_common.skc_v6_daddr.in6_u.u6_addr32);
89+
}
90+
eventp->family = family;
91+
submit_buf(ctx, eventp, sizeof(*eventp));
92+
93+
cleanup:
94+
bpf_map_delete_elem(&start, &sock_cookie);
95+
return 0;
96+
}
97+
98+
SEC("tp_btf/tcp_probe")
99+
int BPF_PROG(tcp_probe_btf, struct sock *sk, struct sk_buff *skb)
100+
{
101+
return handle_tcp_probe(sk, skb);
102+
}
103+
104+
SEC("tp_btf/tcp_rcv_space_adjust")
105+
int BPF_PROG(tcp_rcv_space_adjust_btf, struct sock *sk)
106+
{
107+
return handle_tcp_rcv_space_adjust(ctx, sk);
108+
}
109+
110+
SEC("raw_tp/tcp_probe")
111+
int BPF_PROG(tcp_probe, struct sock *sk, struct sk_buff *skb) {
112+
return handle_tcp_probe(sk, skb);
113+
}
114+
115+
SEC("raw_tp/tcp_rcv_space_adjust")
116+
int BPF_PROG(tcp_rcv_space_adjust, struct sock *sk)
117+
{
118+
return handle_tcp_rcv_space_adjust(ctx, sk);
119+
}
120+
121+
char LICENSE[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)