|
|
d29bf8 |
From e661f2a043f8b6548e0bb3e0cc5992d7c0ff3b0f Mon Sep 17 00:00:00 2001
|
|
|
d29bf8 |
From: Rong Tao <rongtao@cestc.cn>
|
|
|
d29bf8 |
Date: Sat, 1 Oct 2022 16:15:27 +0800
|
|
|
d29bf8 |
Subject: [PATCH] tcpdrop: Fix: ERROR: Error attaching probe: 'kprobe:tcp_drop'
|
|
|
d29bf8 |
|
|
|
d29bf8 |
kernel commit 8fbf195798b5('tcp_drop() is no longer needed.') remove
|
|
|
d29bf8 |
the kprobe:tcp_drop, bcc commit 16eab39171eb('Add
|
|
|
d29bf8 |
tracepoint:skb:kfree_skb if no tcp_drop() kprobe.') already fix this
|
|
|
d29bf8 |
problem.
|
|
|
d29bf8 |
|
|
|
d29bf8 |
CI old kernel is too old and not support the 'reason' field, move the
|
|
|
d29bf8 |
old tools/tcpdrop.bt into tools/old/tcpdrop.bt and set the CI to use
|
|
|
d29bf8 |
it.
|
|
|
d29bf8 |
|
|
|
d29bf8 |
Since 5.17 support trace_kfree_skb(skb, ..., reason) 'reason' field.
|
|
|
d29bf8 |
Since 5.19 remove tcp_drop() function.
|
|
|
d29bf8 |
|
|
|
d29bf8 |
ERROR log:
|
|
|
d29bf8 |
|
|
|
d29bf8 |
$ sudo ./tcpdrop.bt
|
|
|
d29bf8 |
./tcpdrop.bt:49-51: WARNING: tcp_drop is not traceable (either non-existing, inlined, or marked as "notrace"); attaching to it will likely fail
|
|
|
d29bf8 |
Attaching 3 probes...
|
|
|
d29bf8 |
cannot attach kprobe, probe entry may not exist
|
|
|
d29bf8 |
ERROR: Error attaching probe: 'kprobe:tcp_drop'
|
|
|
d29bf8 |
|
|
|
d29bf8 |
Link: https://github.com/iovisor/bpftrace/pull/2379
|
|
|
d29bf8 |
Signed-off-by: Rong Tao <rongtao@cestc.cn>
|
|
|
d29bf8 |
---
|
|
|
d29bf8 |
tools/old/tcpdrop.bt | 85 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
d29bf8 |
tools/tcpdrop.bt | 22 ++++++------
|
|
|
d29bf8 |
2 files changed, 97 insertions(+), 10 deletions(-)
|
|
|
d29bf8 |
create mode 100755 tools/old/tcpdrop.bt
|
|
|
d29bf8 |
|
|
|
d29bf8 |
diff --git a/tools/old/tcpdrop.bt b/tools/old/tcpdrop.bt
|
|
|
d29bf8 |
new file mode 100755
|
|
|
d29bf8 |
index 00000000..685a5f6a
|
|
|
d29bf8 |
--- /dev/null
|
|
|
d29bf8 |
+++ b/tools/old/tcpdrop.bt
|
|
|
d29bf8 |
@@ -0,0 +1,85 @@
|
|
|
d29bf8 |
+#!/usr/bin/env bpftrace
|
|
|
d29bf8 |
+/*
|
|
|
d29bf8 |
+ * tcpdrop.bt Trace TCP kernel-dropped packets/segments.
|
|
|
d29bf8 |
+ * For Linux, uses bpftrace and eBPF.
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * USAGE: tcpdrop.bt
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * This is a bpftrace version of the bcc tool of the same name.
|
|
|
d29bf8 |
+ * It is limited to ipv4 addresses, and cannot show tcp flags.
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * This provides information such as packet details, socket state, and kernel
|
|
|
d29bf8 |
+ * stack trace for packets/segments that were dropped via tcp_drop().
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ * WARNING: this script attaches to the tcp_drop kprobe which is likely inlined
|
|
|
d29bf8 |
+ * on newer kernels and not replaced by anything else, therefore
|
|
|
d29bf8 |
+ * the script will stop working
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * For Linux <= 5.18.
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * Copyright (c) 2018 Dale Hamel.
|
|
|
d29bf8 |
+ * Licensed under the Apache License, Version 2.0 (the "License")
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * 23-Nov-2018 Dale Hamel created this.
|
|
|
d29bf8 |
+ */
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+#ifndef BPFTRACE_HAVE_BTF
|
|
|
d29bf8 |
+#include <linux/socket.h>
|
|
|
d29bf8 |
+#include <net/sock.h>
|
|
|
d29bf8 |
+#else
|
|
|
d29bf8 |
+#include <sys/socket.h>
|
|
|
d29bf8 |
+#endif
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+BEGIN
|
|
|
d29bf8 |
+{
|
|
|
d29bf8 |
+ printf("Tracing tcp drops. Hit Ctrl-C to end.\n");
|
|
|
d29bf8 |
+ printf("%-8s %-8s %-16s %-21s %-21s %-8s\n", "TIME", "PID", "COMM", "SADDR:SPORT", "DADDR:DPORT", "STATE");
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ // See https://github.com/torvalds/linux/blob/master/include/net/tcp_states.h
|
|
|
d29bf8 |
+ @tcp_states[1] = "ESTABLISHED";
|
|
|
d29bf8 |
+ @tcp_states[2] = "SYN_SENT";
|
|
|
d29bf8 |
+ @tcp_states[3] = "SYN_RECV";
|
|
|
d29bf8 |
+ @tcp_states[4] = "FIN_WAIT1";
|
|
|
d29bf8 |
+ @tcp_states[5] = "FIN_WAIT2";
|
|
|
d29bf8 |
+ @tcp_states[6] = "TIME_WAIT";
|
|
|
d29bf8 |
+ @tcp_states[7] = "CLOSE";
|
|
|
d29bf8 |
+ @tcp_states[8] = "CLOSE_WAIT";
|
|
|
d29bf8 |
+ @tcp_states[9] = "LAST_ACK";
|
|
|
d29bf8 |
+ @tcp_states[10] = "LISTEN";
|
|
|
d29bf8 |
+ @tcp_states[11] = "CLOSING";
|
|
|
d29bf8 |
+ @tcp_states[12] = "NEW_SYN_RECV";
|
|
|
d29bf8 |
+}
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+kprobe:tcp_drop
|
|
|
d29bf8 |
+{
|
|
|
d29bf8 |
+ $sk = ((struct sock *) arg0);
|
|
|
d29bf8 |
+ $inet_family = $sk->__sk_common.skc_family;
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ if ($inet_family == AF_INET || $inet_family == AF_INET6) {
|
|
|
d29bf8 |
+ if ($inet_family == AF_INET) {
|
|
|
d29bf8 |
+ $daddr = ntop($sk->__sk_common.skc_daddr);
|
|
|
d29bf8 |
+ $saddr = ntop($sk->__sk_common.skc_rcv_saddr);
|
|
|
d29bf8 |
+ } else {
|
|
|
d29bf8 |
+ $daddr = ntop($sk->__sk_common.skc_v6_daddr.in6_u.u6_addr8);
|
|
|
d29bf8 |
+ $saddr = ntop($sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr8);
|
|
|
d29bf8 |
+ }
|
|
|
d29bf8 |
+ $lport = $sk->__sk_common.skc_num;
|
|
|
d29bf8 |
+ $dport = $sk->__sk_common.skc_dport;
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ // Destination port is big endian, it must be flipped
|
|
|
d29bf8 |
+ $dport = bswap($dport);
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ $state = $sk->__sk_common.skc_state;
|
|
|
d29bf8 |
+ $statestr = @tcp_states[$state];
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+ time("%H:%M:%S ");
|
|
|
d29bf8 |
+ printf("%-8d %-16s ", pid, comm);
|
|
|
d29bf8 |
+ printf("%39s:%-6d %39s:%-6d %-10s\n", $saddr, $lport, $daddr, $dport, $statestr);
|
|
|
d29bf8 |
+ printf("%s\n", kstack);
|
|
|
d29bf8 |
+ }
|
|
|
d29bf8 |
+}
|
|
|
d29bf8 |
+
|
|
|
d29bf8 |
+END
|
|
|
d29bf8 |
+{
|
|
|
d29bf8 |
+ clear(@tcp_states);
|
|
|
d29bf8 |
+}
|
|
|
d29bf8 |
diff --git a/tools/tcpdrop.bt b/tools/tcpdrop.bt
|
|
|
d29bf8 |
index 3450a533..bb31107f 100755
|
|
|
d29bf8 |
--- a/tools/tcpdrop.bt
|
|
|
d29bf8 |
+++ b/tools/tcpdrop.bt
|
|
|
d29bf8 |
@@ -9,16 +9,15 @@
|
|
|
d29bf8 |
* It is limited to ipv4 addresses, and cannot show tcp flags.
|
|
|
d29bf8 |
*
|
|
|
d29bf8 |
* This provides information such as packet details, socket state, and kernel
|
|
|
d29bf8 |
- * stack trace for packets/segments that were dropped via tcp_drop().
|
|
|
d29bf8 |
-
|
|
|
d29bf8 |
- * WARNING: this script attaches to the tcp_drop kprobe which is likely inlined
|
|
|
d29bf8 |
- * on newer kernels and not replaced by anything else, therefore
|
|
|
d29bf8 |
- * the script will stop working
|
|
|
d29bf8 |
-
|
|
|
d29bf8 |
+ * stack trace for packets/segments that were dropped via kfree_skb.
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
+ * For Linux 5.17+ (see tools/old for script for lower versions).
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
* Copyright (c) 2018 Dale Hamel.
|
|
|
d29bf8 |
* Licensed under the Apache License, Version 2.0 (the "License")
|
|
|
d29bf8 |
-
|
|
|
d29bf8 |
+ *
|
|
|
d29bf8 |
* 23-Nov-2018 Dale Hamel created this.
|
|
|
d29bf8 |
+ * 01-Oct-2022 Rong Tao use tracepoint:skb:kfree_skb
|
|
|
d29bf8 |
*/
|
|
|
d29bf8 |
|
|
|
d29bf8 |
#ifndef BPFTRACE_HAVE_BTF
|
|
|
d29bf8 |
@@ -48,12 +47,15 @@ BEGIN
|
|
|
d29bf8 |
@tcp_states[12] = "NEW_SYN_RECV";
|
|
|
d29bf8 |
}
|
|
|
d29bf8 |
|
|
|
d29bf8 |
-kprobe:tcp_drop
|
|
|
d29bf8 |
+tracepoint:skb:kfree_skb
|
|
|
d29bf8 |
{
|
|
|
d29bf8 |
- $sk = ((struct sock *) arg0);
|
|
|
d29bf8 |
+ $reason = args->reason;
|
|
|
d29bf8 |
+ $skb = (struct sk_buff *)args->skbaddr;
|
|
|
d29bf8 |
+ $sk = ((struct sock *) $skb->sk);
|
|
|
d29bf8 |
$inet_family = $sk->__sk_common.skc_family;
|
|
|
d29bf8 |
|
|
|
d29bf8 |
- if ($inet_family == AF_INET || $inet_family == AF_INET6) {
|
|
|
d29bf8 |
+ if ($reason > SKB_DROP_REASON_NOT_SPECIFIED &&
|
|
|
d29bf8 |
+ ($inet_family == AF_INET || $inet_family == AF_INET6)) {
|
|
|
d29bf8 |
if ($inet_family == AF_INET) {
|
|
|
d29bf8 |
$daddr = ntop($sk->__sk_common.skc_daddr);
|
|
|
d29bf8 |
$saddr = ntop($sk->__sk_common.skc_rcv_saddr);
|
|
|
d29bf8 |
--
|
|
|
d29bf8 |
2.38.1
|
|
|
d29bf8 |
|