blob: 79ff1cad3bda5aa78a3e49e9528e719992ba9b44 [file] [log] [blame]
Alexey Ivanovcc01a9c2019-01-16 09:50:46 -08001#!/usr/bin/python
Brendan Gregg553f2aa2016-02-14 18:15:24 -08002# @lint-avoid-python-3-compatibility-imports
3#
Brendan Gregg73b54012017-12-18 20:37:11 -08004# tcpretrans Trace or count TCP retransmits and TLPs.
Brendan Gregg553f2aa2016-02-14 18:15:24 -08005# For Linux, uses BCC, eBPF. Embedded C.
6#
Hariharan Ananthakrishnan04893e32021-08-12 05:55:21 -07007# USAGE: tcpretrans [-c] [-h] [-l] [-4 | -6]
Brendan Gregg553f2aa2016-02-14 18:15:24 -08008#
9# This uses dynamic tracing of kernel functions, and will need to be updated
10# to match kernel changes.
11#
Brendan Gregg553f2aa2016-02-14 18:15:24 -080012# Copyright 2016 Netflix, Inc.
13# Licensed under the Apache License, Version 2.0 (the "License")
14#
15# 14-Feb-2016 Brendan Gregg Created this.
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +010016# 03-Nov-2017 Matthias Tafelmeier Extended this.
Brendan Gregg553f2aa2016-02-14 18:15:24 -080017
18from __future__ import print_function
19from bcc import BPF
20import argparse
21from time import strftime
Mark Drayton11de2982016-06-26 21:14:44 +010022from socket import inet_ntop, AF_INET, AF_INET6
23from struct import pack
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +010024from time import sleep
Brendan Gregg553f2aa2016-02-14 18:15:24 -080025
26# arguments
27examples = """examples:
28 ./tcpretrans # trace TCP retransmits
29 ./tcpretrans -l # include TLP attempts
Hariharan Ananthakrishnan04893e32021-08-12 05:55:21 -070030 ./tcpretrans -4 # trace IPv4 family only
31 ./tcpretrans -6 # trace IPv6 family only
Brendan Gregg553f2aa2016-02-14 18:15:24 -080032"""
33parser = argparse.ArgumentParser(
34 description="Trace TCP retransmits",
35 formatter_class=argparse.RawDescriptionHelpFormatter,
36 epilog=examples)
Michael Gugino7abd77a2021-09-01 18:07:33 -040037parser.add_argument("-s", "--sequence", action="store_true",
38 help="display TCP sequence numbers")
Brendan Gregg553f2aa2016-02-14 18:15:24 -080039parser.add_argument("-l", "--lossprobe", action="store_true",
40 help="include tail loss probe attempts")
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +010041parser.add_argument("-c", "--count", action="store_true",
42 help="count occurred retransmits per flow")
Hariharan Ananthakrishnan04893e32021-08-12 05:55:21 -070043group = parser.add_mutually_exclusive_group()
44group.add_argument("-4", "--ipv4", action="store_true",
45 help="trace IPv4 family only")
46group.add_argument("-6", "--ipv6", action="store_true",
47 help="trace IPv6 family only")
Nathan Scottcf0792f2018-02-02 16:56:50 +110048parser.add_argument("--ebpf", action="store_true",
49 help=argparse.SUPPRESS)
Brendan Gregg553f2aa2016-02-14 18:15:24 -080050args = parser.parse_args()
Brendan Gregg73b54012017-12-18 20:37:11 -080051debug = 0
Brendan Gregg553f2aa2016-02-14 18:15:24 -080052
53# define BPF program
54bpf_text = """
55#include <uapi/linux/ptrace.h>
56#include <net/sock.h>
Michael Gugino7abd77a2021-09-01 18:07:33 -040057#include <net/tcp.h>
Brendan Gregg553f2aa2016-02-14 18:15:24 -080058#include <bcc/proto.h>
59
60#define RETRANSMIT 1
61#define TLP 2
62
63// separate data structs for ipv4 and ipv6
64struct ipv4_data_t {
Joe Yin36ce1122018-08-17 06:04:00 +080065 u32 pid;
Brendan Gregg553f2aa2016-02-14 18:15:24 -080066 u64 ip;
Michael Gugino7abd77a2021-09-01 18:07:33 -040067 u32 seq;
Joe Yin36ce1122018-08-17 06:04:00 +080068 u32 saddr;
69 u32 daddr;
70 u16 lport;
71 u16 dport;
Brendan Gregg553f2aa2016-02-14 18:15:24 -080072 u64 state;
73 u64 type;
74};
75BPF_PERF_OUTPUT(ipv4_events);
76
77struct ipv6_data_t {
Joe Yin36ce1122018-08-17 06:04:00 +080078 u32 pid;
Michael Gugino7abd77a2021-09-01 18:07:33 -040079 u32 seq;
Brendan Gregg553f2aa2016-02-14 18:15:24 -080080 u64 ip;
Mark Drayton11de2982016-06-26 21:14:44 +010081 unsigned __int128 saddr;
82 unsigned __int128 daddr;
Joe Yin36ce1122018-08-17 06:04:00 +080083 u16 lport;
84 u16 dport;
Brendan Gregg553f2aa2016-02-14 18:15:24 -080085 u64 state;
86 u64 type;
87};
88BPF_PERF_OUTPUT(ipv6_events);
89
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +010090// separate flow keys per address family
91struct ipv4_flow_key_t {
92 u32 saddr;
93 u32 daddr;
94 u16 lport;
95 u16 dport;
96};
97BPF_HASH(ipv4_count, struct ipv4_flow_key_t);
98
99struct ipv6_flow_key_t {
100 unsigned __int128 saddr;
101 unsigned __int128 daddr;
102 u16 lport;
103 u16 dport;
104};
105BPF_HASH(ipv6_count, struct ipv6_flow_key_t);
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800106"""
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100107
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800108bpf_text_kprobe = """
Michael Gugino7abd77a2021-09-01 18:07:33 -0400109static int trace_event(struct pt_regs *ctx, struct sock *skp, struct sk_buff *skb, int type)
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800110{
Michael Gugino7abd77a2021-09-01 18:07:33 -0400111 struct tcp_skb_cb *tcb;
112 u32 seq;
113
Paul Chaignon25212ee2017-08-06 11:15:11 +0200114 if (skp == NULL)
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800115 return 0;
Marko Myllynena77a2542018-09-10 20:44:55 +0300116 u32 pid = bpf_get_current_pid_tgid() >> 32;
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800117
118 // pull in details
Paul Chaignon25212ee2017-08-06 11:15:11 +0200119 u16 family = skp->__sk_common.skc_family;
120 u16 lport = skp->__sk_common.skc_num;
121 u16 dport = skp->__sk_common.skc_dport;
122 char state = skp->__sk_common.skc_state;
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800123
Michael Gugino7abd77a2021-09-01 18:07:33 -0400124 seq = 0;
125 if (skb) {
126 /* macro TCP_SKB_CB from net/tcp.h */
127 tcb = ((struct tcp_skb_cb *)&((skb)->cb[0]));
128 seq = tcb->seq;
129 }
130
Hariharan Ananthakrishnan04893e32021-08-12 05:55:21 -0700131 FILTER_FAMILY
Michael Gugino7abd77a2021-09-01 18:07:33 -0400132
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800133 if (family == AF_INET) {
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100134 IPV4_INIT
135 IPV4_CORE
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800136 } else if (family == AF_INET6) {
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100137 IPV6_INIT
138 IPV6_CORE
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800139 }
140 // else drop
141
142 return 0;
143}
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800144"""
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800145
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800146bpf_text_kprobe_retransmit = """
Michael Gugino7abd77a2021-09-01 18:07:33 -0400147int trace_retransmit(struct pt_regs *ctx, struct sock *sk, struct sk_buff *skb)
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800148{
Michael Gugino7abd77a2021-09-01 18:07:33 -0400149 trace_event(ctx, sk, skb, RETRANSMIT);
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800150 return 0;
151}
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800152"""
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800153
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800154bpf_text_kprobe_tlp = """
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800155int trace_tlp(struct pt_regs *ctx, struct sock *sk)
156{
Michael Gugino7abd77a2021-09-01 18:07:33 -0400157 trace_event(ctx, sk, NULL, TLP);
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800158 return 0;
159}
160"""
161
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800162bpf_text_tracepoint = """
163TRACEPOINT_PROBE(tcp, tcp_retransmit_skb)
164{
Michael Gugino7abd77a2021-09-01 18:07:33 -0400165 struct tcp_skb_cb *tcb;
166 u32 seq;
167
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800168 u32 pid = bpf_get_current_pid_tgid() >> 32;
169 const struct sock *skp = (const struct sock *)args->skaddr;
Michael Gugino7abd77a2021-09-01 18:07:33 -0400170 const struct sk_buff *skb = (const struct sk_buff *)args->skbaddr;
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800171 u16 lport = args->sport;
172 u16 dport = args->dport;
173 char state = skp->__sk_common.skc_state;
174 u16 family = skp->__sk_common.skc_family;
175
Michael Gugino7abd77a2021-09-01 18:07:33 -0400176 seq = 0;
177 if (skb) {
178 /* macro TCP_SKB_CB from net/tcp.h */
179 tcb = ((struct tcp_skb_cb *)&((skb)->cb[0]));
180 seq = tcb->seq;
181 }
182
183 FILTER_FAMILY
184
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800185 if (family == AF_INET) {
186 IPV4_CODE
187 } else if (family == AF_INET6) {
188 IPV6_CODE
189 }
190 return 0;
191}
192"""
193
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200194struct_init = { 'ipv4':
195 { 'count' :
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100196 """
197 struct ipv4_flow_key_t flow_key = {};
198 flow_key.saddr = skp->__sk_common.skc_rcv_saddr;
199 flow_key.daddr = skp->__sk_common.skc_daddr;
200 // lport is host order
201 flow_key.lport = lport;
202 flow_key.dport = ntohs(dport);""",
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200203 'trace' :
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100204 """
Joe Yin36ce1122018-08-17 06:04:00 +0800205 struct ipv4_data_t data4 = {};
206 data4.pid = pid;
207 data4.ip = 4;
Michael Gugino7abd77a2021-09-01 18:07:33 -0400208 data4.seq = seq;
Joe Yin36ce1122018-08-17 06:04:00 +0800209 data4.type = type;
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100210 data4.saddr = skp->__sk_common.skc_rcv_saddr;
211 data4.daddr = skp->__sk_common.skc_daddr;
212 // lport is host order
213 data4.lport = lport;
214 data4.dport = ntohs(dport);
215 data4.state = state; """
216 },
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200217 'ipv6':
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100218 { 'count' :
219 """
220 struct ipv6_flow_key_t flow_key = {};
Sumanth Korikkar7f6066d2020-05-20 10:49:56 -0500221 bpf_probe_read_kernel(&flow_key.saddr, sizeof(flow_key.saddr),
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100222 skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
Sumanth Korikkar7f6066d2020-05-20 10:49:56 -0500223 bpf_probe_read_kernel(&flow_key.daddr, sizeof(flow_key.daddr),
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100224 skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
225 // lport is host order
226 flow_key.lport = lport;
227 flow_key.dport = ntohs(dport);""",
228 'trace' : """
Marko Myllynenbfbf17e2018-09-11 21:49:58 +0300229 struct ipv6_data_t data6 = {};
230 data6.pid = pid;
231 data6.ip = 6;
Michael Gugino7abd77a2021-09-01 18:07:33 -0400232 data6.seq = seq;
Marko Myllynenbfbf17e2018-09-11 21:49:58 +0300233 data6.type = type;
Sumanth Korikkar7f6066d2020-05-20 10:49:56 -0500234 bpf_probe_read_kernel(&data6.saddr, sizeof(data6.saddr),
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100235 skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
Sumanth Korikkar7f6066d2020-05-20 10:49:56 -0500236 bpf_probe_read_kernel(&data6.daddr, sizeof(data6.daddr),
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100237 skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
238 // lport is host order
239 data6.lport = lport;
240 data6.dport = ntohs(dport);
241 data6.state = state;"""
242 }
243 }
244
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800245struct_init_tracepoint = { 'ipv4':
246 { 'count' : """
247 struct ipv4_flow_key_t flow_key = {};
248 __builtin_memcpy(&flow_key.saddr, args->saddr, sizeof(flow_key.saddr));
249 __builtin_memcpy(&flow_key.daddr, args->daddr, sizeof(flow_key.daddr));
250 flow_key.lport = lport;
251 flow_key.dport = dport;
252 ipv4_count.increment(flow_key);
253 """,
254 'trace' : """
255 struct ipv4_data_t data4 = {};
256 data4.pid = pid;
257 data4.lport = lport;
258 data4.dport = dport;
259 data4.type = RETRANSMIT;
260 data4.ip = 4;
Michael Gugino7abd77a2021-09-01 18:07:33 -0400261 data4.seq = seq;
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800262 data4.state = state;
263 __builtin_memcpy(&data4.saddr, args->saddr, sizeof(data4.saddr));
264 __builtin_memcpy(&data4.daddr, args->daddr, sizeof(data4.daddr));
265 ipv4_events.perf_submit(args, &data4, sizeof(data4));
266 """
267 },
268 'ipv6':
269 { 'count' : """
270 struct ipv6_flow_key_t flow_key = {};
271 __builtin_memcpy(&flow_key.saddr, args->saddr_v6, sizeof(flow_key.saddr));
272 __builtin_memcpy(&flow_key.daddr, args->daddr_v6, sizeof(flow_key.daddr));
273 flow_key.lport = lport;
274 flow_key.dport = dport;
275 ipv6_count.increment(flow_key);
276 """,
277 'trace' : """
278 struct ipv6_data_t data6 = {};
279 data6.pid = pid;
280 data6.lport = lport;
281 data6.dport = dport;
282 data6.type = RETRANSMIT;
283 data6.ip = 6;
Michael Gugino7abd77a2021-09-01 18:07:33 -0400284 data6.seq = seq;
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800285 data6.state = state;
286 __builtin_memcpy(&data6.saddr, args->saddr_v6, sizeof(data6.saddr));
287 __builtin_memcpy(&data6.daddr, args->daddr_v6, sizeof(data6.daddr));
288 ipv6_events.perf_submit(args, &data6, sizeof(data6));
289 """
290 }
291 }
292
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100293count_core_base = """
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200294 COUNT_STRUCT.increment(flow_key);
295"""
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100296
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800297if BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
298 if args.count:
299 bpf_text_tracepoint = bpf_text_tracepoint.replace("IPV4_CODE", struct_init_tracepoint['ipv4']['count'])
300 bpf_text_tracepoint = bpf_text_tracepoint.replace("IPV6_CODE", struct_init_tracepoint['ipv6']['count'])
301 else:
302 bpf_text_tracepoint = bpf_text_tracepoint.replace("IPV4_CODE", struct_init_tracepoint['ipv4']['trace'])
303 bpf_text_tracepoint = bpf_text_tracepoint.replace("IPV6_CODE", struct_init_tracepoint['ipv6']['trace'])
304 bpf_text += bpf_text_tracepoint
305
306if args.lossprobe or not BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
307 bpf_text += bpf_text_kprobe
308 if args.count:
309 bpf_text = bpf_text.replace("IPV4_INIT", struct_init['ipv4']['count'])
310 bpf_text = bpf_text.replace("IPV6_INIT", struct_init['ipv6']['count'])
311 bpf_text = bpf_text.replace("IPV4_CORE", count_core_base.replace("COUNT_STRUCT", 'ipv4_count'))
312 bpf_text = bpf_text.replace("IPV6_CORE", count_core_base.replace("COUNT_STRUCT", 'ipv6_count'))
313 else:
314 bpf_text = bpf_text.replace("IPV4_INIT", struct_init['ipv4']['trace'])
315 bpf_text = bpf_text.replace("IPV6_INIT", struct_init['ipv6']['trace'])
316 bpf_text = bpf_text.replace("IPV4_CORE", "ipv4_events.perf_submit(ctx, &data4, sizeof(data4));")
317 bpf_text = bpf_text.replace("IPV6_CORE", "ipv6_events.perf_submit(ctx, &data6, sizeof(data6));")
318 if args.lossprobe:
319 bpf_text += bpf_text_kprobe_tlp
320 if not BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
321 bpf_text += bpf_text_kprobe_retransmit
Hariharan Ananthakrishnan04893e32021-08-12 05:55:21 -0700322if args.ipv4:
323 bpf_text = bpf_text.replace('FILTER_FAMILY',
324 'if (family != AF_INET) { return 0; }')
325elif args.ipv6:
326 bpf_text = bpf_text.replace('FILTER_FAMILY',
327 'if (family != AF_INET6) { return 0; }')
328else:
329 bpf_text = bpf_text.replace('FILTER_FAMILY', '')
Nathan Scottcf0792f2018-02-02 16:56:50 +1100330if debug or args.ebpf:
Brendan Gregg73b54012017-12-18 20:37:11 -0800331 print(bpf_text)
Nathan Scottcf0792f2018-02-02 16:56:50 +1100332 if args.ebpf:
333 exit()
Brendan Gregg73b54012017-12-18 20:37:11 -0800334
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800335# from bpf_text:
336type = {}
337type[1] = 'R'
338type[2] = 'L'
339
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800340# from include/net/tcp_states.h:
341tcpstate = {}
342tcpstate[1] = 'ESTABLISHED'
343tcpstate[2] = 'SYN_SENT'
344tcpstate[3] = 'SYN_RECV'
345tcpstate[4] = 'FIN_WAIT1'
346tcpstate[5] = 'FIN_WAIT2'
347tcpstate[6] = 'TIME_WAIT'
348tcpstate[7] = 'CLOSE'
349tcpstate[8] = 'CLOSE_WAIT'
350tcpstate[9] = 'LAST_ACK'
351tcpstate[10] = 'LISTEN'
352tcpstate[11] = 'CLOSING'
353tcpstate[12] = 'NEW_SYN_RECV'
354
355# process event
356def print_ipv4_event(cpu, data, size):
Xiaozhou Liu51d62d32019-02-15 13:03:05 +0800357 event = b["ipv4_events"].event(data)
xingfeng251003e49482022-03-17 13:07:16 +0800358 print("%-8s %-7d %-2d %-20s %1s> %-20s" % (
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800359 strftime("%H:%M:%S"), event.pid, event.ip,
Mark Drayton11de2982016-06-26 21:14:44 +0100360 "%s:%d" % (inet_ntop(AF_INET, pack('I', event.saddr)), event.lport),
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800361 type[event.type],
Michael Gugino7abd77a2021-09-01 18:07:33 -0400362 "%s:%s" % (inet_ntop(AF_INET, pack('I', event.daddr)), event.dport)),
363 end='')
364 if args.sequence:
365 print(" %-12s %s" % (tcpstate[event.state], event.seq))
366 else:
367 print(" %s" % (tcpstate[event.state]))
Mark Drayton11de2982016-06-26 21:14:44 +0100368
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800369def print_ipv6_event(cpu, data, size):
Xiaozhou Liu51d62d32019-02-15 13:03:05 +0800370 event = b["ipv6_events"].event(data)
xingfeng251003e49482022-03-17 13:07:16 +0800371 print("%-8s %-7d %-2d %-20s %1s> %-20s" % (
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800372 strftime("%H:%M:%S"), event.pid, event.ip,
Mark Drayton11de2982016-06-26 21:14:44 +0100373 "%s:%d" % (inet_ntop(AF_INET6, event.saddr), event.lport),
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800374 type[event.type],
Michael Gugino7abd77a2021-09-01 18:07:33 -0400375 "%s:%d" % (inet_ntop(AF_INET6, event.daddr), event.dport)),
376 end='')
377 if args.sequence:
378 print(" %-12s %s" % (tcpstate[event.state], event.seq))
379 else:
380 print(" %s" % (tcpstate[event.state]))
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800381
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100382def depict_cnt(counts_tab, l3prot='ipv4'):
383 for k, v in sorted(counts_tab.items(), key=lambda counts: counts[1].value):
384 depict_key = ""
385 ep_fmt = "[%s]#%d"
386 if l3prot == 'ipv4':
387 depict_key = "%-20s <-> %-20s" % (ep_fmt % (inet_ntop(AF_INET, pack('I', k.saddr)), k.lport),
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200388 ep_fmt % (inet_ntop(AF_INET, pack('I', k.daddr)), k.dport))
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100389 else:
390 depict_key = "%-20s <-> %-20s" % (ep_fmt % (inet_ntop(AF_INET6, k.saddr), k.lport),
391 ep_fmt % (inet_ntop(AF_INET6, k.daddr), k.dport))
392
393 print ("%s %10d" % (depict_key, v.value))
394
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800395# initialize BPF
396b = BPF(text=bpf_text)
Xiaozhou Liu9cede202019-11-09 08:34:45 +0800397if not BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
398 b.attach_kprobe(event="tcp_retransmit_skb", fn_name="trace_retransmit")
Mark Drayton11de2982016-06-26 21:14:44 +0100399if args.lossprobe:
400 b.attach_kprobe(event="tcp_send_loss_probe", fn_name="trace_tlp")
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800401
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100402print("Tracing retransmits ... Hit Ctrl-C to end")
403if args.count:
404 try:
405 while 1:
406 sleep(99999999)
407 except BaseException:
408 pass
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800409
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100410 # header
411 print("\n%-25s %-25s %-10s" % (
412 "LADDR:LPORT", "RADDR:RPORT", "RETRANSMITS"))
Javier Honduvilla Coto64bf9652018-08-01 06:50:19 +0200413 depict_cnt(b.get_table("ipv4_count"))
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100414 depict_cnt(b.get_table("ipv6_count"), l3prot='ipv6')
Brendan Gregg553f2aa2016-02-14 18:15:24 -0800415# read events
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100416else:
417 # header
xingfeng251003e49482022-03-17 13:07:16 +0800418 print("%-8s %-7s %-2s %-20s %1s> %-20s" % ("TIME", "PID", "IP",
Michael Gugino7abd77a2021-09-01 18:07:33 -0400419 "LADDR:LPORT", "T", "RADDR:RPORT"), end='')
420 if args.sequence:
421 print(" %-12s %-10s" % ("STATE", "SEQ"))
422 else:
423 print(" %-4s" % ("STATE"))
Matthias Tafelmeier1e9467f2017-12-13 18:50:22 +0100424 b["ipv4_events"].open_perf_buffer(print_ipv4_event)
425 b["ipv6_events"].open_perf_buffer(print_ipv6_event)
426 while 1:
Jerome Marchand51671272018-12-19 01:57:24 +0100427 try:
428 b.perf_buffer_poll()
429 except KeyboardInterrupt:
430 exit()