Added IPv4/IPv6 filter support for tcp trace tools (#3565)
authorHariharan Ananthakrishnan <5103173+hariharan-a@users.noreply.github.com>
Thu, 12 Aug 2021 12:55:21 +0000 (05:55 -0700)
committerGitHub <noreply@github.com>
Thu, 12 Aug 2021 12:55:21 +0000 (05:55 -0700)
* Added IPv4/IPv6 filter support for tcp trace tools

* Fixed a typo

* Added usage for TCP syn backlog

* Fixed a typo

* Fixed a typo

* Added man support for IPv4/IPv6 family filters

32 files changed:
man/man8/tcpaccept.8
man/man8/tcpconnect.8
man/man8/tcpconnlat.8
man/man8/tcpdrop.8
man/man8/tcplife.8
man/man8/tcpretrans.8
man/man8/tcprtt.8
man/man8/tcpstates.8
man/man8/tcpsynbl.8
man/man8/tcptop.8
man/man8/tcptracer.8
tools/tcpaccept.py
tools/tcpaccept_example.txt
tools/tcpconnect.py
tools/tcpconnect_example.txt
tools/tcpconnlat.py
tools/tcpconnlat_example.txt
tools/tcpdrop.py
tools/tcpdrop_example.txt
tools/tcplife.py
tools/tcplife_example.txt
tools/tcpretrans.py
tools/tcpretrans_example.txt
tools/tcprtt.py
tools/tcprtt_example.txt
tools/tcpstates.py
tools/tcpstates_example.txt
tools/tcpsynbl.py
tools/tcpsynbl_example.txt
tools/tcptop.py
tools/tcptop_example.txt
tools/tcptracer.py

index 603a5ca433f5c2b4d692783b9172dc4298227553..05b79693de62edca912012f10119b081bdcca5ab 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpaccept \- Trace TCP passive connections (accept()). Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpaccept [\-h] [\-T] [\-t] [\-p PID] [\-P PORTS] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH]
+.B tcpaccept [\-h] [\-T] [\-t] [\-p PID] [\-P PORTS] [\-4 | \-6] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH]
 .SH DESCRIPTION
 This tool traces passive TCP connections (eg, via an accept() syscall;
 connect() are active connections). This can be useful for general
@@ -34,6 +34,12 @@ Trace this process ID only (filtered in-kernel).
 \-P PORTS
 Comma-separated list of local ports to trace (filtered in-kernel).
 .TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
+.TP
 \-\-cgroupmap MAPPATH
 Trace cgroups in this BPF map only (filtered in-kernel).
 .TP
@@ -57,6 +63,14 @@ Trace PID 181 only:
 #
 .B tcpaccept \-p 181
 .TP
+Trace IPv4 family only:
+#
+.B tcpaccept \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcpaccept \-6
+.TP
 Trace a set of cgroups only (see special_filtering.md from bcc sources for more details):
 #
 .B tcpaccept \-\-cgroupmap /sys/fs/bpf/test01
index 55105709e41befc39780391844c6f509846d27b3..0ea84686e9b42bb200afba91571e0c0cbeac5148 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpconnect \- Trace TCP active connections (connect()). Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpconnect [\-h] [\-c] [\-t] [\-p PID] [-P PORT] [\-L] [-u UID] [-U] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH] [\-d]
+.B tcpconnect [\-h] [\-c] [\-t] [\-p PID] [-P PORT] [\-4 | \-6] [\-L] [-u UID] [-U] [\-\-cgroupmap MAPPATH] [\-\-mntnsmap MAPPATH] [\-d]
 .SH DESCRIPTION
 This tool traces active TCP connections (eg, via a connect() syscall;
 accept() are passive connections). This can be useful for general
@@ -43,6 +43,12 @@ Trace this process ID only (filtered in-kernel).
 \-P PORT
 Comma-separated list of destination ports to trace (filtered in-kernel).
 .TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
+.TP
 \-L
 Include a LPORT column.
 .TP
@@ -99,6 +105,14 @@ Trace ports 80 and 81 only:
 #
 .B tcpconnect \-P 80,81
 .TP
+Trace IPv4 family only:
+#
+.B tcpconnect -4
+.TP
+Trace IPv6 family only:
+#
+.B tcpconnect -6
+.TP
 Trace all TCP connects, and include LPORT:
 #
 .B tcpconnect \-L
index 9c810071adc9668d23daec4ec2ba7064899056e3..84762b4584e5851415aea30bab28340fb52e05d9 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpconnlat \- Trace TCP active connection latency. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpconnlat [\-h] [\-t] [\-p PID] [\-L] [-v] [min_ms]
+.B tcpconnlat [\-h] [\-t] [\-p PID] [\-L] [\-4 | \-6] [-v] [min_ms]
 .SH DESCRIPTION
 This tool traces active TCP connections
 (eg, via a connect() syscall), and shows the latency (time) for the connection
@@ -34,6 +34,12 @@ Trace this process ID only (filtered in-kernel).
 \-L
 Include a LPORT column.
 .TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
+.TP
 \-v
 Print the resulting BPF program, for debugging purposes.
 .TP
@@ -57,6 +63,14 @@ Trace connects, and include LPORT:
 #
 .B tcpconnlat \-L
 .TP
+Trace IPv4 family only:
+#
+.B tcpconnlat \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcpconnlat \-6
+.TP
 Trace connects with latency longer than 10 ms:
 #
 .B tcpconnlat 10
index 12806472e7f508ae471c82832c4e66451d0cab0e..c9b777b3010b70c2198db62d9624976159fa6978 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpdrop \- Trace kernel-based TCP packet drops with details. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpdrop [\-h]
+.B tcpdrop [\-4 | \-6] [\-h]
 .SH DESCRIPTION
 This tool traces TCP packets or segments that were dropped by the kernel, and
 shows details from the IP and TCP headers, the socket state, and the
@@ -17,9 +17,27 @@ Since this uses BPF, only the root user can use this tool.
 CONFIG_BPF and bcc.
 .SH OPTIONS
 .TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
+.TP
 \-h
 Print usage message.
+.SH EXAMPLES
+.TP
+Trace kernel-based TCP packet drops with details:
+#
 .B tcpdrop
+.TP
+Trace IPv4 family only:
+#
+.B tcpdrop \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcpdrop \-6
 .SH FIELDS
 .TP
 TIME
index a2419c61b8c341cf9adbc159a570066babec3cee..5fb4c28309607a5ac6b1e0e0b0e7eae770b08079 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcplife \- Trace TCP sessions and summarize lifespan. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcplife [\-h] [\-T] [\-t] [\-w] [\-s] [\-p PID] [\-D PORTS] [\-L PORTS]
+.B tcplife [\-h] [\-T] [\-t] [\-w] [\-s] [\-p PID] [\-D PORTS] [\-L PORTS] [\-4 | \-6]
 .SH DESCRIPTION
 This tool traces TCP sessions that open and close while tracing, and prints
 a line of output to summarize each one. This includes the IP addresses, ports,
@@ -43,6 +43,12 @@ Comma-separated list of local ports to trace (filtered in-kernel).
 .TP
 \-D PORTS
 Comma-separated list of destination ports to trace (filtered in-kernel).
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Trace all TCP sessions, and summarize lifespan and throughput:
@@ -64,6 +70,14 @@ Trace connections to local ports 80 and 81 only:
 Trace connections to remote port 80 only:
 #
 .B tcplife \-D 80
+.TP
+Trace IPv4 family only:
+#
+.B tcplife \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcplife \-6
 .SH FIELDS
 .TP
 TIME
index 0ac82afa85e7e21e25e052ac3322ed222e86d015..ea00ac7fa4839881290548e8663f8fc7b75c68a4 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpretrans \- Trace or count TCP retransmits and TLPs. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpretrans [\-h] [\-l] [\-c]
+.B tcpretrans [\-h] [\-l] [\-c] [\-4 | \-6]
 .SH DESCRIPTION
 This traces TCP retransmits, showing address, port, and TCP state information,
 and sometimes the PID (although usually not, since retransmits are usually
@@ -29,7 +29,13 @@ Include tail loss probe attempts (in some cases the kernel may not
 complete the TLP send).
 .TP
 \-c
-Count occurring retransmits per flow. 
+Count occurring retransmits per flow.
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Trace TCP retransmits:
@@ -39,6 +45,14 @@ Trace TCP retransmits:
 Trace TCP retransmits and TLP attempts:
 #
 .B tcpretrans \-l
+.TP
+Trace IPv4 family only:
+#
+.B tcpretrans \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcpretrans \-6
 .SH FIELDS
 .TP
 TIME
index f82ba6cc96d6f7c7c546e2a6a25e2712566d6544..1ed32d6e65266236f7147a1e7bf075f488ec675c 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcprtt \- Trace TCP RTT of established connections. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcprtt [\-h] [\-T] [\-D] [\-m] [\-i INTERVAL] [\-d DURATION] [\-b] [\-B] [\-e]
+.B tcprtt [\-h] [\-T] [\-D] [\-m] [\-i INTERVAL] [\-d DURATION] [\-b] [\-B] [\-e] [\-4 | \-6]
 .SH DESCRIPTION
 This tool traces established connections RTT(round-trip time) to analyze the
 quality of network. This can be useful for general troubleshooting to
@@ -51,6 +51,12 @@ Show sockets histogram by remote address.
 .TP
 \-e
 Show extension summary(average).
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Trace TCP RTT and print 1 second summaries, 10 times:
@@ -68,6 +74,14 @@ Only trace TCP RTT for remote address 192.168.1.100 and remote port 80:
 Trace local port and show a breakdown of remote hosts RTT:
 #
 .B tcprtt \-i 3 --lport 80 --byraddr
+.TP
+Trace IPv4 family only:
+#
+.B tcprtt \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcprtt \-6
 .SH OVERHEAD
 This traces the kernel tcp_rcv_established function and collects TCP RTT. The
 rate of this depends on your server application. If it is a web or proxy server
index 26c7a8a1a20dfabe43bf647c59b0c01aaaa9955a..57c40a83dbf51ff88ca2a7c2b9cceaf9e0d551c0 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpstates \- Trace TCP session state changes with durations. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcpstates [\-h] [\-T] [\-t] [\-w] [\-s] [\-D PORTS] [\-L PORTS] [\-Y]
+.B tcpstates [\-h] [\-T] [\-t] [\-w] [\-s] [\-D PORTS] [\-L PORTS] [\-Y] [\-4 | \-6]
 .SH DESCRIPTION
 This tool traces TCP session state changes while tracing, and prints details
 including the duration in each state. This can help explain the latency of
@@ -44,6 +44,12 @@ Comma-separated list of destination ports to trace (filtered in-kernel).
 .TP
 \-Y
 Log session state changes to the systemd journal.
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Trace all TCP sessions, and show all state changes:
@@ -61,6 +67,14 @@ Trace connections to local ports 80 and 81 only:
 Trace connections to remote port 80 only:
 #
 .B tcpstates \-D 80
+.TP
+Trace IPv4 family only:
+#
+.B tcpstates -4
+.TP
+Trace IPv6 family only:
+#
+.B tcpstates -6
 .SH FIELDS
 .TP
 TIME
index 4dd38c8a0e349f61180ca134ba4aaa723221a55f..8557af2b5dfa94c0af7686df789f8facfcd91a93 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcpsynbl \- Show the TCP SYN backlog as a histogram. Uses BCC/eBPF.
 .SH SYNOPSIS
-.B tcpsynbl
+.B tcpsynbl [\-4 | \-6]
 .SH DESCRIPTION
 This tool shows the TCP SYN backlog size during SYN arrival as a histogram.
 This lets you see how close your applications are to hitting the backlog limit
@@ -17,11 +17,29 @@ change in future kernels, this tool may need maintenance to keep working.
 Since this uses BPF, only the root user can use this tool.
 .SH REQUIREMENTS
 CONFIG_BPF and BCC.
+.SH OPTIONS
+.TP
+\-h
+Print usage message.
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Show the TCP SYN backlog as a histogram.
 #
 .B tcpsynbl
+.TP
+Trace IPv4 family only:
+#
+.B tcpsynbl -4
+.TP
+Trace IPv6 family only:
+#
+.B tcpsynbl -6
 .SH FIELDS
 .TP
 backlog
index e636f45696538b5325715de8d702d834ec71c303..f4f1c3d748f66594c9041a96fb582e65f5722d90 100644 (file)
@@ -3,7 +3,7 @@
 tcptop \- Summarize TCP send/recv throughput by host. Top for TCP.
 .SH SYNOPSIS
 .B tcptop [\-h] [\-C] [\-S] [\-p PID] [\-\-cgroupmap MAPPATH]
-          [--mntnsmap MAPPATH] [interval] [count]
+          [--mntnsmap MAPPATH] [interval] [count] [\-4 | \-6]
 .SH DESCRIPTION
 This is top for TCP sessions.
 
@@ -47,6 +47,12 @@ Interval between updates, seconds (default 1).
 .TP
 count
 Number of interval summaries (default is many).
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Summarize TCP throughput by active sessions, 1 second refresh:
@@ -64,6 +70,14 @@ Trace PID 181 only, and don't clear the screen:
 Trace a set of cgroups only (see special_filtering.md from bcc sources for more details):
 #
 .B tcptop \-\-cgroupmap /sys/fs/bpf/test01
+.TP
+Trace IPv4 family only:
+#
+.B tcptop \-4
+.TP
+Trace IPv6 family only:
+#
+.B tcptop \-6
 .SH FIELDS
 .TP
 loadavg:
index d2346c776d32b1dca6a96698168e3fc9e2bd4aa9..59240f4b076f3522e75978a3f96e1e53c1ff1924 100644 (file)
@@ -2,7 +2,7 @@
 .SH NAME
 tcptracer \- Trace TCP established connections. Uses Linux eBPF/bcc.
 .SH SYNOPSIS
-.B tcptracer [\-h] [\-v] [\-p PID] [\-N NETNS] [\-\-cgroupmap MAPPATH] [--mntnsmap MAPPATH]
+.B tcptracer [\-h] [\-v] [\-p PID] [\-N NETNS] [\-\-cgroupmap MAPPATH] [--mntnsmap MAPPATH] [\-4 | \-6]
 .SH DESCRIPTION
 This tool traces established TCP connections that open and close while tracing,
 and prints a line of output per connect, accept and close events. This includes
@@ -34,6 +34,12 @@ Trace cgroups in this BPF map only (filtered in-kernel).
 .TP
 \-\-mntnsmap  MAPPATH
 Trace mount namespaces in the map (filtered in-kernel).
+.TP
+\-4
+Trace IPv4 family only.
+.TP
+\-6
+Trace IPv6 family only.
 .SH EXAMPLES
 .TP
 Trace all TCP established connections:
@@ -55,6 +61,14 @@ Trace connections in network namespace 4026531969 only:
 Trace a set of cgroups only (see special_filtering.md from bcc sources for more details):
 #
 .B tcptracer \-\-cgroupmap /sys/fs/bpf/test01
+.TP
+Trace IPv4 family only:
+#
+.B tcptracer -4
+.TP
+Trace IPv6 family only:
+#
+.B tcptracer -6
 .SH FIELDS
 .TP
 TYPE
index 1a5f1c7b527113e417fc8cf307ca9a4a55c04fb4..d3e44143d8b1334e9feae9e20bc23e92d4828e9a 100755 (executable)
@@ -4,7 +4,7 @@
 # tcpaccept Trace TCP accept()s.
 #           For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcpaccept [-h] [-T] [-t] [-p PID] [-P PORTS]
+# USAGE: tcpaccept [-h] [-T] [-t] [-p PID] [-P PORTS] [-4 | -6]
 #
 # This uses dynamic tracing of the kernel inet_csk_accept() socket function
 # (from tcp_prot.accept), and will need to be modified to match kernel changes.
@@ -32,6 +32,8 @@ examples = """examples:
     ./tcpaccept -p 181    # only trace PID 181
     ./tcpaccept --cgroupmap mappath  # only trace cgroups in this BPF map
     ./tcpaccept --mntnsmap mappath   # only trace mount namespaces in the map
+    ./tcpaccept -4        # trace IPv4 family
+    ./tcpaccept -6        # trace IPv6 family
 """
 parser = argparse.ArgumentParser(
     description="Trace TCP accepts",
@@ -45,6 +47,11 @@ parser.add_argument("-p", "--pid",
     help="trace this PID only")
 parser.add_argument("-P", "--port",
     help="comma-separated list of local ports to trace")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--cgroupmap",
     help="trace cgroups in this BPF map only")
 parser.add_argument("--mntnsmap",
@@ -152,6 +159,8 @@ int kretprobe__inet_csk_accept(struct pt_regs *ctx)
     dport = newsk->__sk_common.skc_dport;
     dport = ntohs(dport);
 
+    ##FILTER_FAMILY##
+
     ##FILTER_PORT##
 
     if (family == AF_INET) {
@@ -195,6 +204,13 @@ if args.port:
     lports_if = ' && '.join(['lport != %d' % lport for lport in lports])
     bpf_text = bpf_text.replace('##FILTER_PORT##',
         'if (%s) { return 0; }' % lports_if)
+if args.ipv4:
+    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
+        'if (family != AF_INET6) { return 0; }')
+
 bpf_text = filter_by_containers(args) + bpf_text
 if debug or args.ebpf:
     print(bpf_text)
@@ -202,6 +218,7 @@ if debug or args.ebpf:
         exit()
 
 bpf_text = bpf_text.replace('##FILTER_PORT##', '')
+bpf_text = bpf_text.replace('##FILTER_FAMILY##', '')
 
 # process event
 def print_ipv4_event(cpu, data, size):
index 9381565568a56df5c1ff0399060fd2e3e2f7eab8..245679049747c920ef148b8314abe520925f3b43 100644 (file)
@@ -44,7 +44,7 @@ For more details, see docs/special_filtering.md
 USAGE message:
 
 # ./tcpaccept -h
-usage: tcpaccept.py [-h] [-T] [-t] [-p PID] [-P PORT] [--cgroupmap CGROUPMAP]
+usage: tcpaccept.py [-h] [-T] [-t] [-p PID] [-P PORT] [-4 | -6] [--cgroupmap CGROUPMAP]
 
 Trace TCP accepts
 
@@ -54,6 +54,8 @@ optional arguments:
   -t, --timestamp       include timestamp on output
   -p PID, --pid PID     trace this PID only
   -P PORT, --port PORT  comma-separated list of local ports to trace
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
   --cgroupmap CGROUPMAP
                         trace cgroups in this BPF map only
 
@@ -63,4 +65,6 @@ examples:
     ./tcpaccept -P 80,81  # only trace port 80 and 81
     ./tcpaccept -p 181    # only trace PID 181
     ./tcpaccept --cgroupmap mappath  # only trace cgroups in this BPF map
-    ./tcpaccept --mntnsmap mappath   # only trace mount namespaces in the map
\ No newline at end of file
+    ./tcpaccept --mntnsmap mappath   # only trace mount namespaces in the map
+    ./tcpaccept -4        # trace IPv4 family only
+    ./tcpaccept -6        # trace IPv6 family only
\ No newline at end of file
index 0d204ea5c69fc95151d08fbc488c9301dedc9ed6..8b49c70a2abd49ef79403ca81d0767d1ec2a08b9 100755 (executable)
@@ -4,7 +4,7 @@
 # tcpconnect    Trace TCP connect()s.
 #               For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcpconnect [-h] [-c] [-t] [-p PID] [-P PORT [PORT ...]]
+# USAGE: tcpconnect [-h] [-c] [-t] [-p PID] [-P PORT [PORT ...]] [-4 | -6]
 #
 # All connection attempts are traced, even if they ultimately fail.
 #
@@ -39,6 +39,8 @@ examples = """examples:
     ./tcpconnect -p 181    # only trace PID 181
     ./tcpconnect -P 80     # only trace port 80
     ./tcpconnect -P 80,81  # only trace port 80 and 81
+    ./tcpconnect -4        # only trace IPv4 family
+    ./tcpconnect -6        # only trace IPv6 family
     ./tcpconnect -U        # include UID
     ./tcpconnect -u 1000   # only trace UID 1000
     ./tcpconnect -c        # count connects per src ip and dest ip/port
@@ -56,6 +58,11 @@ parser.add_argument("-p", "--pid",
     help="trace this PID only")
 parser.add_argument("-P", "--port",
     help="comma-separated list of destination ports to trace.")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("-L", "--lport", action="store_true",
     help="include LPORT on output")
 parser.add_argument("-U", "--print-uid", action="store_true",
@@ -171,6 +178,8 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver)
     u16 dport = skp->__sk_common.skc_dport;
 
     FILTER_PORT
+    
+    FILTER_FAMILY
 
     if (ipver == 4) {
         IPV4_CODE
@@ -335,6 +344,12 @@ if args.port:
     dports_if = ' && '.join(['dport != %d' % ntohs(dport) for dport in dports])
     bpf_text = bpf_text.replace('FILTER_PORT',
         'if (%s) { currsock.delete(&tid); return 0; }' % dports_if)
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (ipver != 4) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (ipver != 6) { return 0; }')
 if args.uid:
     bpf_text = bpf_text.replace('FILTER_UID',
         'if (uid != %s) { return 0; }' % args.uid)
@@ -342,6 +357,7 @@ bpf_text = filter_by_containers(args) + bpf_text
 
 bpf_text = bpf_text.replace('FILTER_PID', '')
 bpf_text = bpf_text.replace('FILTER_PORT', '')
+bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 bpf_text = bpf_text.replace('FILTER_UID', '')
 
 if args.dns:
index f2e6d72f3e502d1bd300b269f26041e8121da0d0..3f720c422a6e9b623b6fbf640b9b5b56c7eb5b3f 100644 (file)
@@ -106,8 +106,8 @@ USAGE message:
 
 # ./tcpconnect -h
 
-usage: tcpconnect.py [-h] [-t] [-p PID] [-P PORT] [-L] [-U] [-u UID] [-c]
-                     [--cgroupmap CGROUPMAP] [--mntnsmap MNTNSMAP] [-d]
+usage: tcpconnect.py [-h] [-t] [-p PID] [-P PORT] [-4 | -6] [-L] [-U] [-u UID]
+                     [-c] [--cgroupmap CGROUPMAP] [--mntnsmap MNTNSMAP] [-d]
 
 Trace TCP connects
 
@@ -116,6 +116,8 @@ optional arguments:
   -t, --timestamp       include timestamp on output
   -p PID, --pid PID     trace this PID only
   -P PORT, --port PORT  comma-separated list of destination ports to trace.
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
   -L, --lport           include LPORT on output
   -U, --print-uid       include UID on output
   -u UID, --uid UID     trace this UID only
@@ -132,6 +134,8 @@ examples:
     ./tcpconnect -p 181    # only trace PID 181
     ./tcpconnect -P 80     # only trace port 80
     ./tcpconnect -P 80,81  # only trace port 80 and 81
+    ./tcpconnect -4        # only trace IPv4 family
+    ./tcpconnect -6        # only trace IPv6 family
     ./tcpconnect -U        # include UID
     ./tcpconnect -u 1000   # only trace UID 1000
     ./tcpconnect -c        # count connects per src ip and dest ip/port
index f30b71d280a4348f2da92276477569689a7cbeb9..093f2676e4f087e76f8eba577a7596a4fc570c0c 100755 (executable)
@@ -4,7 +4,7 @@
 # tcpconnlat    Trace TCP active connection latency (connect).
 #               For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcpconnlat [-h] [-t] [-p PID]
+# USAGE: tcpconnlat [-h] [-t] [-p PID] [-4 | -6]
 #
 # This uses dynamic tracing of kernel functions, and will need to be updated
 # to match kernel changes.
@@ -40,6 +40,8 @@ examples = """examples:
     ./tcpconnlat -t        # include timestamps
     ./tcpconnlat -p 181    # only trace PID 181
     ./tcpconnlat -L        # include LPORT while printing outputs
+    ./tcpconnlat -4        # trace IPv4 family only
+    ./tcpconnlat -6        # trace IPv6 family only
 """
 parser = argparse.ArgumentParser(
     description="Trace TCP connects and show connection latency",
@@ -51,6 +53,11 @@ parser.add_argument("-p", "--pid",
     help="trace this PID only")
 parser.add_argument("-L", "--lport", action="store_true",
     help="include LPORT on output")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("duration_ms", nargs="?", default=0,
     type=positive_float,
     help="minimum duration to trace (ms)")
@@ -202,8 +209,14 @@ if debug or args.verbose or args.ebpf:
 
 # initialize BPF
 b = BPF(text=bpf_text)
-b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect")
-b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect")
+if args.ipv4:
+    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect")
+elif args.ipv6:
+    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect")
+else:
+    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect")
+    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect")
+
 b.attach_kprobe(event="tcp_rcv_state_process",
     fn_name="trace_tcp_rcv_state_process")
 
@@ -260,8 +273,14 @@ else:
         "SADDR", "DADDR", "DPORT", "LAT(ms)"))
 
 # read events
-b["ipv4_events"].open_perf_buffer(print_ipv4_event)
-b["ipv6_events"].open_perf_buffer(print_ipv6_event)
+if args.ipv4:
+    b["ipv4_events"].open_perf_buffer(print_ipv4_event)
+elif args.ipv6:
+    b["ipv6_events"].open_perf_buffer(print_ipv6_event)
+else:
+    b["ipv4_events"].open_perf_buffer(print_ipv4_event)
+    b["ipv6_events"].open_perf_buffer(print_ipv6_event)
+
 while 1:
     try:
         b.perf_buffer_poll()
index 8ca2821b268a1eb07d37fc17cee1374b337faef1..fe05ca5ce90137684928fba9b405e9617f08f8e8 100644 (file)
@@ -34,7 +34,7 @@ if the response is a RST (port closed).
 USAGE message:
 
 # ./tcpconnlat -h
-usage: tcpconnlat [-h] [-t] [-p PID] [-L] [-v] [duration_ms]
+usage: tcpconnlat [-h] [-t] [-p PID] [-L] [-4 | -6] [-v] [duration_ms]
 
 Trace TCP connects and show connection latency
 
@@ -46,6 +46,8 @@ optional arguments:
   -t, --timestamp    include timestamp on output
   -p PID, --pid PID  trace this PID only
   -L, --lport        include LPORT on output
+  -4, --ipv4         trace IPv4 family only
+  -6  --ipv6         trace IPv6 family only
   -v, --verbose      print the BPF program for debugging purposes
 
 examples:
@@ -55,3 +57,5 @@ examples:
     ./tcpconnlat -t        # include timestamps
     ./tcpconnlat -p 181    # only trace PID 181
     ./tcpconnlat -L        # include LPORT while printing outputs
+    ./tcpconnlat -4        # trace IPv4 family only
+    ./tcpconnlat -6        # trace IPv6 family only
index 59dbf66c04c8efbcaddf632402ff49cd83290a3e..4853f6ab54a97d9a83d78d942f5d07fc744b91c4 100755 (executable)
@@ -7,7 +7,7 @@
 # This provides information such as packet details, socket state, and kernel
 # stack trace for packets/segments that were dropped via tcp_drop().
 #
-# USAGE: tcpdrop [-h]
+# USAGE: tcpdrop [-4 | -6] [-h]
 #
 # This uses dynamic tracing of kernel functions, and will need to be updated
 # to match kernel changes.
@@ -29,11 +29,18 @@ from bcc import tcp
 # arguments
 examples = """examples:
     ./tcpdrop           # trace kernel TCP drops
+    ./tcpdrop -4        # trace IPv4 family only
+    ./tcpdrop -6        # trace IPv6 family only
 """
 parser = argparse.ArgumentParser(
     description="Trace TCP drops by the kernel",
     formatter_class=argparse.RawDescriptionHelpFormatter,
     epilog=examples)
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 args = parser.parse_args()
@@ -111,6 +118,8 @@ int trace_tcp_drop(struct pt_regs *ctx, struct sock *sk, struct sk_buff *skb)
     sport = ntohs(sport);
     dport = ntohs(dport);
 
+    FILTER_FAMILY
+    
     if (family == AF_INET) {
         struct ipv4_data_t data4 = {};
         data4.pid = pid;
@@ -151,6 +160,14 @@ if debug or args.ebpf:
     print(bpf_text)
     if args.ebpf:
         exit()
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET6) { return 0; }')
+else:
+    bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 
 # process event
 def print_ipv4_event(cpu, data, size):
index 752ec4bf6a9a9eb0de443163a0eeb6cf2211d1f1..2adbb6c0eab3565522e19129786e6d99cedbc1c6 100644 (file)
@@ -61,12 +61,16 @@ remote end to do timer-based retransmits, hurting performance.
 USAGE:
 
 # ./tcpdrop.py -h
-usage: tcpdrop.py [-h]
+usage: tcpdrop.py [4 | -6] [-h]
 
 Trace TCP drops by the kernel
 
 optional arguments:
+  -4, --ipv4  trace IPv4 family only
+  -6, --ipv6  trace IPv6 family only
   -h, --help  show this help message and exit
 
 examples:
     ./tcpdrop           # trace kernel TCP drops
+    ./tcpdrop -4        # trace IPv4 family only
+    ./tcpdrop -6        # trace IPv6 family only
index 9fe9804b9283e2e2337bebd04f86d61520dbdfd7..780385b4513b241e04e2ab09208aabd23da93e4e 100755 (executable)
@@ -4,7 +4,7 @@
 # tcplife   Trace the lifespan of TCP sessions and summarize.
 #           For Linux, uses BCC, BPF. Embedded C.
 #
-# USAGE: tcplife [-h] [-C] [-S] [-p PID] [interval [count]]
+# USAGE: tcplife [-h] [-C] [-S] [-p PID] [-4 | -6] [interval [count]]
 #
 # This uses the sock:inet_sock_set_state tracepoint if it exists (added to
 # Linux 4.16, and replacing the earlier tcp:tcp_set_state), else it uses
@@ -39,6 +39,8 @@ examples = """examples:
     ./tcplife -L 80     # only trace local port 80
     ./tcplife -L 80,81  # only trace local ports 80 and 81
     ./tcplife -D 80     # only trace remote port 80
+    ./tcplife -4        # only trace IPv4 family
+    ./tcplife -6        # only trace IPv6 family
 """
 parser = argparse.ArgumentParser(
     description="Trace the lifespan of TCP sessions and summarize",
@@ -58,6 +60,11 @@ parser.add_argument("-L", "--localport",
     help="comma-separated list of local ports to trace.")
 parser.add_argument("-D", "--remoteport",
     help="comma-separated list of remote ports to trace.")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 args = parser.parse_args()
@@ -190,6 +197,8 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state)
     tx_b = tp->bytes_acked;
 
     u16 family = sk->__sk_common.skc_family;
+    
+    FILTER_FAMILY
 
     if (family == AF_INET) {
         struct ipv4_data_t data4 = {};
@@ -309,6 +318,9 @@ TRACEPOINT_PROBE(sock, inet_sock_set_state)
     if (mep != 0)
         pid = mep->pid;
     FILTER_PID
+    
+    u16 family = args->family;
+    FILTER_FAMILY
 
     // get throughput stats. see tcp_get_info().
     u64 rx_b = 0, tx_b = 0, sport = 0;
@@ -380,9 +392,16 @@ if args.localport:
     lports_if = ' && '.join(['lport != %d' % lport for lport in lports])
     bpf_text = bpf_text.replace('FILTER_LPORT',
         'if (%s) { birth.delete(&sk); return 0; }' % lports_if)
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET6) { return 0; }')
 bpf_text = bpf_text.replace('FILTER_PID', '')
 bpf_text = bpf_text.replace('FILTER_DPORT', '')
 bpf_text = bpf_text.replace('FILTER_LPORT', '')
+bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 
 if debug or args.ebpf:
     print(bpf_text)
index cbf44796f22e4f437f6e2fa592e2ff53da236d64..88c40df7628ab18ceb9c362d0223b647f1b21b60 100644 (file)
@@ -108,7 +108,7 @@ USAGE:
 
 # ./tcplife.py -h
 usage: tcplife.py [-h] [-T] [-t] [-w] [-s] [-p PID] [-L LOCALPORT]
-                  [-D REMOTEPORT]
+                  [-D REMOTEPORT] [-4 | -6]
 
 Trace the lifespan of TCP sessions and summarize
 
@@ -123,6 +123,8 @@ optional arguments:
                         comma-separated list of local ports to trace.
   -D REMOTEPORT, --remoteport REMOTEPORT
                         comma-separated list of remote ports to trace.
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
 
 examples:
     ./tcplife           # trace all TCP connect()s
@@ -133,3 +135,5 @@ examples:
     ./tcplife -L 80     # only trace local port 80
     ./tcplife -L 80,81  # only trace local ports 80 and 81
     ./tcplife -D 80     # only trace remote port 80
+    ./tcplife -4        # only trace IPv4 family
+    ./tcplife -6        # only trace IPv6 family
index 7785d9b343f280cb144a5ba2f192c38cc9636531..8e6247f7bc8d7b54c39dcca706398f8fa382bf6b 100755 (executable)
@@ -4,7 +4,7 @@
 # tcpretrans    Trace or count TCP retransmits and TLPs.
 #               For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcpretrans [-c] [-h] [-l]
+# USAGE: tcpretrans [-c] [-h] [-l] [-4 | -6]
 #
 # This uses dynamic tracing of kernel functions, and will need to be updated
 # to match kernel changes.
@@ -27,6 +27,8 @@ from time import sleep
 examples = """examples:
     ./tcpretrans           # trace TCP retransmits
     ./tcpretrans -l        # include TLP attempts
+    ./tcpretrans -4        # trace IPv4 family only
+    ./tcpretrans -6        # trace IPv6 family only
 """
 parser = argparse.ArgumentParser(
     description="Trace TCP retransmits",
@@ -36,6 +38,11 @@ parser.add_argument("-l", "--lossprobe", action="store_true",
     help="include tail loss probe attempts")
 parser.add_argument("-c", "--count", action="store_true",
     help="count occurred retransmits per flow")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 args = parser.parse_args()
@@ -106,6 +113,8 @@ static int trace_event(struct pt_regs *ctx, struct sock *skp, int type)
     u16 dport = skp->__sk_common.skc_dport;
     char state = skp->__sk_common.skc_state;
 
+    FILTER_FAMILY
+    
     if (family == AF_INET) {
         IPV4_INIT
         IPV4_CORE
@@ -145,6 +154,8 @@ TRACEPOINT_PROBE(tcp, tcp_retransmit_skb)
     char state = skp->__sk_common.skc_state;
     u16 family = skp->__sk_common.skc_family;
 
+    FILTER_FAMILY 
+    
     if (family == AF_INET) {
         IPV4_CODE
     } else if (family == AF_INET6) {
@@ -278,7 +289,14 @@ if args.lossprobe or not BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
         bpf_text += bpf_text_kprobe_tlp
     if not BPF.tracepoint_exists("tcp", "tcp_retransmit_skb"):
         bpf_text += bpf_text_kprobe_retransmit
-
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET6) { return 0; }')
+else:
+    bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 if debug or args.ebpf:
     print(bpf_text)
     if args.ebpf:
index db63477589c8d69aab9a8d6c1fca603df488ef9e..77fc12f8d2a7ba08f6b4b0f1a3c9b19537fdb309 100644 (file)
@@ -62,7 +62,7 @@ responsible for clamping tcp performance.
 USAGE message:
 
 # ./tcpretrans -h
-usage: tcpretrans [-h] [-l]
+usage: tcpretrans [-h] [-l] [-4 | -6]
 
 Trace TCP retransmits
 
@@ -70,7 +70,11 @@ optional arguments:
   -h, --help       show this help message and exit
   -l, --lossprobe  include tail loss probe attempts
   -c, --count      count occurred retransmits per flow
+  -4, --ipv4       trace IPv4 family only
+  -6, --ipv6       trace IPv6 family only
 
 examples:
     ./tcpretrans           # trace TCP retransmits
     ./tcpretrans -l        # include TLP attempts
+    ./tcpretrans -4        # trace IPv4 family only
+    ./tcpretrans -6        # trace IPv6 family only
index ac1b27d470ffd0a689f6ef2c0a0197b20a7be06d..c5c3905a1b995c7b00365dbcec081ff3646a4e00 100755 (executable)
@@ -5,6 +5,7 @@
 #
 # USAGE: tcprtt [-h] [-T] [-D] [-m] [-i INTERVAL] [-d DURATION]
 #           [-p LPORT] [-P RPORT] [-a LADDR] [-A RADDR] [-b] [-B] [-e]
+#           [-4 | -6]
 #
 # Copyright (c) 2020 zhenwei pi
 # Licensed under the Apache License, Version 2.0 (the "License")
@@ -32,6 +33,8 @@ examples = """examples:
     ./tcprtt -B         # show sockets histogram by remote address
     ./tcprtt -D         # show debug bpf text
     ./tcprtt -e         # show extension summary(average)
+    ./tcprtt -4         # trace only IPv4 family
+    ./tcprtt -6         # trace only IPv6 family
 """
 parser = argparse.ArgumentParser(
     description="Summarize TCP RTT as a histogram",
@@ -61,6 +64,11 @@ parser.add_argument("-e", "--extension", action="store_true",
     help="show extension summary(average)")
 parser.add_argument("-D", "--debug", action="store_true",
     help="print BPF program before starting (for debugging purposes)")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 args = parser.parse_args()
@@ -102,6 +110,7 @@ int trace_tcp_rcv(struct pt_regs *ctx, struct sock *sk, struct sk_buff *skb)
     u16 dport = 0;
     u32 saddr = 0;
     u32 daddr = 0;
+    u16 family = 0;
 
     /* for histogram */
     sock_key_t key;
@@ -113,11 +122,13 @@ int trace_tcp_rcv(struct pt_regs *ctx, struct sock *sk, struct sk_buff *skb)
     bpf_probe_read_kernel(&dport, sizeof(dport), (void *)&inet->inet_dport);
     bpf_probe_read_kernel(&saddr, sizeof(saddr), (void *)&inet->inet_saddr);
     bpf_probe_read_kernel(&daddr, sizeof(daddr), (void *)&inet->inet_daddr);
+    bpf_probe_read_kernel(&family, sizeof(family), (void *)&sk->__sk_common.skc_family);
 
     LPORTFILTER
     RPORTFILTER
     LADDRFILTER
     RADDRFILTER
+    FAMILYFILTER
 
     FACTOR
 
@@ -162,7 +173,14 @@ if args.raddr:
         return 0;""" % struct.unpack("=I", socket.inet_aton(args.raddr))[0])
 else:
     bpf_text = bpf_text.replace('RADDRFILTER', '')
-
+if args.ipv4:
+    bpf_text = bpf_text.replace('FAMILYFILTER',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FAMILYFILTER',
+        'if (family != AF_INET6) { return 0; }')
+else:
+    bpf_text = bpf_text.replace('FAMILYFILTER', '')
 # show msecs or usecs[default]
 if args.milliseconds:
     bpf_text = bpf_text.replace('FACTOR', 'srtt /= 1000;')
index fbfe18f69e4a93299c225c077bfb2142370b1efc..afc1293ca70c19f5652734e13cfbe078bb9397bb 100644 (file)
@@ -144,6 +144,7 @@ Full USAGE:
 # ./tcprtt -h
 usage: tcprtt [-h] [-i INTERVAL] [-d DURATION] [-T] [-m] [-p LPORT]
               [-P RPORT] [-a LADDR] [-A RADDR] [-b] [-B] [-e] [-D]
+              [-4 | -6]
 
 Summarize TCP RTT as a histogram
 
@@ -168,6 +169,8 @@ optional arguments:
   -e, --extension       show extension summary(average)
   -D, --debug           print BPF program before starting (for debugging
                         purposes)
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
 
 examples:
     ./tcprtt            # summarize TCP RTT
@@ -181,3 +184,5 @@ examples:
     ./tcprtt -B         # show sockets histogram by remote address
     ./tcprtt -D         # show debug bpf text
     ./tcprtt -e         # show extension summary(average)
+    ./tcprtt -4         # trace IPv4 family only
+    ./tcprtt -6         # trace IPv6 family only
index ec5bb7b356975d6264da14db9d2b28cda2ba070d..cb38c591d8f30311b0a49c7e796f9492ebd2f2d8 100755 (executable)
@@ -5,7 +5,7 @@
 # tcpstates   Trace the TCP session state changes with durations.
 #             For Linux, uses BCC, BPF. Embedded C.
 #
-# USAGE: tcpstates [-h] [-C] [-S] [interval [count]]
+# USAGE: tcpstates [-h] [-C] [-S] [interval [count]] [-4 | -6]
 #
 # This uses the sock:inet_sock_set_state tracepoint, added to Linux 4.16.
 # Linux 4.16 also adds more state transitions so that they can be traced.
@@ -34,6 +34,8 @@ examples = """examples:
     ./tcpstates -L 80     # only trace local port 80
     ./tcpstates -L 80,81  # only trace local ports 80 and 81
     ./tcpstates -D 80     # only trace remote port 80
+    ./tcpstates -4        # trace IPv4 family only
+    ./tcpstates -6        # trace IPv6 family only
 """
 parser = argparse.ArgumentParser(
     description="Trace TCP session state changes and durations",
@@ -55,6 +57,11 @@ parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 parser.add_argument("-Y", "--journal", action="store_true",
     help="log session state changes to the systemd journal")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 args = parser.parse_args()
 debug = 0
 
@@ -126,7 +133,9 @@ TRACEPOINT_PROBE(sock, inet_sock_set_state)
         delta_us = 0;
     else
         delta_us = (bpf_ktime_get_ns() - *tsp) / 1000;
-
+    u16 family = args->family;
+    FILTER_FAMILY
+    
     if (args->family == AF_INET) {
         struct ipv4_data_t data4 = {
             .span_us = delta_us,
@@ -194,7 +203,8 @@ int kprobe__tcp_set_state(struct pt_regs *ctx, struct sock *sk, int state)
         delta_us = (bpf_ktime_get_ns() - *tsp) / 1000;
 
     u16 family = sk->__sk_common.skc_family;
-
+    FILTER_FAMILY
+    
     if (family == AF_INET) {
         struct ipv4_data_t data4 = {
             .span_us = delta_us,
@@ -258,6 +268,13 @@ if args.localport:
     lports_if = ' && '.join(['lport != %d' % lport for lport in lports])
     bpf_text = bpf_text.replace('FILTER_LPORT',
         'if (%s) { last.delete(&sk); return 0; }' % lports_if)
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET6) { return 0; }')
+bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 bpf_text = bpf_text.replace('FILTER_DPORT', '')
 bpf_text = bpf_text.replace('FILTER_LPORT', '')
 
index e50012e7d8a45a5e8a83042740c57d848f86fe62..5a7d543a52d11b447c8fc91fff7d946e1f430802 100644 (file)
@@ -27,7 +27,7 @@ USAGE:
 
 # tcpstates -h
 usage: tcpstates.py [-h] [-T] [-t] [-w] [-s] [-L LOCALPORT] [-D REMOTEPORT]
-                    [-Y]
+                    [-Y] [-4 | -6]
 
 Trace TCP session state changes and durations
 
@@ -42,6 +42,8 @@ optional arguments:
   -D REMOTEPORT, --remoteport REMOTEPORT
                         comma-separated list of remote ports to trace.
   -Y, --journal         log session state changes to the systemd journal
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
 
 examples:
     ./tcpstates           # trace all TCP state changes
@@ -53,3 +55,5 @@ examples:
     ./tcpstates -L 80     # only trace local port 80
     ./tcpstates -L 80,81  # only trace local ports 80 and 81
     ./tcpstates -D 80     # only trace remote port 80
+    ./tcpstates -4        # trace IPv4 family only
+    ./tcpstates -6        # trace IPv6 family only
index 93cef4b71e69953622089d94f70754c12c667b1c..dc85abe73b68373c26710eca8b8331f30e3302aa 100755 (executable)
@@ -4,6 +4,8 @@
 # tcpsynbl      Show TCP SYN backlog.
 #               For Linux, uses BCC, eBPF. Embedded C.
 #
+# USAGE: tcpsynbl [-4 | -6] [-h]
+#
 # Copyright (c) 2019 Brendan Gregg.
 # Licensed under the Apache License, Version 2.0 (the "License").
 # This was originally created for the BPF Performance Tools book
 # 03-Jul-2019   Brendan Gregg   Ported from bpftrace to BCC.
 
 from __future__ import print_function
+import argparse
 from bcc import BPF
 from time import sleep
 
 # load BPF program
-b = BPF(text="""
+bpf_text = """
 #include <net/sock.h>
 
 typedef struct backlog_key {
@@ -29,7 +32,7 @@ BPF_HISTOGRAM(dist, backlog_key_t);
 
 int do_entry(struct pt_regs *ctx) {
     struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
-
+    
     backlog_key_t key = {};
     key.backlog = sk->sk_max_ack_backlog;
     key.slot = bpf_log2l(sk->sk_ack_backlog);
@@ -37,9 +40,32 @@ int do_entry(struct pt_regs *ctx) {
 
     return 0;
 };
-""")
-b.attach_kprobe(event="tcp_v4_syn_recv_sock", fn_name="do_entry")
-b.attach_kprobe(event="tcp_v6_syn_recv_sock", fn_name="do_entry")
+"""
+examples = """examples:
+    ./tcpsynbl          # trace syn backlog
+    ./tcpsynbl -4       # trace IPv4 family only
+    ./tcpsynbl -6       # trace IPv6 family only
+"""
+parser = argparse.ArgumentParser(
+    description="Show TCP SYN backlog.",
+    formatter_class=argparse.RawDescriptionHelpFormatter,
+    epilog=examples)
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
+args = parser.parse_args()
+
+b = BPF(text=bpf_text)
+
+if args.ipv4:
+    b.attach_kprobe(event="tcp_v4_syn_recv_sock", fn_name="do_entry")
+elif args.ipv6:
+    b.attach_kprobe(event="tcp_v6_syn_recv_sock", fn_name="do_entry")
+else:
+    b.attach_kprobe(event="tcp_v4_syn_recv_sock", fn_name="do_entry")
+    b.attach_kprobe(event="tcp_v6_syn_recv_sock", fn_name="do_entry")
 
 print("Tracing SYN backlog size. Ctrl-C to end.");
 
index 1ac167df38316e96249a4d94a754e9a5f5e92ea8..716b55c10cdf4028606bbb8d4892247ccc7b8080 100644 (file)
@@ -18,3 +18,20 @@ backlog_max = 500L
 This output shows that for the backlog limit of 500, there were 961 SYN
 arrival where the backlog was zero or one, and one accept where the backlog was
 two or three. This indicates that we are nowhere near this limit.
+
+USAGE:
+
+# ./tcpsynbl -h
+usage: tcpsynbl.py [-h] [-4 | -6]
+
+Show TCP SYN backlog.
+
+optional arguments:
+  -h, --help  show this help message and exit
+  -4, --ipv4  trace IPv4 family only
+  -6, --ipv6  trace IPv6 family only
+
+examples:
+    ./tcpsynbl          # trace syn backlog
+    ./tcpsynbl -4       # trace IPv4 family only
+    ./tcpsynbl -6       # trace IPv6 family only
\ No newline at end of file
index e9d0d1a28b8856560ebd4d198fbd129d10dc4833..76c91affd8955c9174bc99b7ef8619f1bc2de212 100755 (executable)
@@ -4,7 +4,7 @@
 # tcptop    Summarize TCP send/recv throughput by host.
 #           For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcptop [-h] [-C] [-S] [-p PID] [interval [count]]
+# USAGE: tcptop [-h] [-C] [-S] [-p PID] [interval [count]] [-4 | -6]
 #
 # This uses dynamic tracing of kernel functions, and will need to be updated
 # to match kernel changes.
@@ -48,6 +48,8 @@ examples = """examples:
     ./tcptop -p 181    # only trace PID 181
     ./tcptop --cgroupmap mappath  # only trace cgroups in this BPF map
     ./tcptop --mntnsmap mappath   # only trace mount namespaces in the map
+    ./tcptop -4        # trace IPv4 family only
+    ./tcptop -6        # trace IPv6 family only
 """
 parser = argparse.ArgumentParser(
     description="Summarize TCP send/recv throughput by host",
@@ -67,6 +69,11 @@ parser.add_argument("--cgroupmap",
     help="trace cgroups in this BPF map only")
 parser.add_argument("--mntnsmap",
     help="trace mount namespaces in this BPF map only")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+    help="trace IPv6 family only")
 parser.add_argument("--ebpf", action="store_true",
     help=argparse.SUPPRESS)
 args = parser.parse_args()
@@ -114,6 +121,8 @@ int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk,
 
     u16 dport = 0, family = sk->__sk_common.skc_family;
 
+    FILTER_FAMILY
+    
     if (family == AF_INET) {
         struct ipv4_key_t ipv4_key = {.pid = pid};
         ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr;
@@ -160,6 +169,8 @@ int kprobe__tcp_cleanup_rbuf(struct pt_regs *ctx, struct sock *sk, int copied)
     if (copied <= 0)
         return 0;
 
+    FILTER_FAMILY
+    
     if (family == AF_INET) {
         struct ipv4_key_t ipv4_key = {.pid = pid};
         ipv4_key.saddr = sk->__sk_common.skc_rcv_saddr;
@@ -192,6 +203,13 @@ if args.pid:
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '')
+if args.ipv4:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('FILTER_FAMILY',
+        'if (family != AF_INET6) { return 0; }')
+bpf_text = bpf_text.replace('FILTER_FAMILY', '')
 bpf_text = filter_by_containers(args) + bpf_text
 if debug or args.ebpf:
     print(bpf_text)
index e29e2fa2e03119cfafa844bfc31649394f640e78..98064a9b646bb66e05f2beac4e2066b5c6b7912d 100644 (file)
@@ -105,7 +105,7 @@ USAGE:
 # tcptop -h
 usage: tcptop.py [-h] [-C] [-S] [-p PID] [--cgroupmap CGROUPMAP]
                  [--mntnsmap MNTNSMAP]
-                 [interval] [count]
+                 [interval] [count] [-4 | -6]
 
 Summarize TCP send/recv throughput by host
 
@@ -120,6 +120,8 @@ optional arguments:
   -p PID, --pid PID     trace this PID only
   --cgroupmap CGROUPMAP
                         trace cgroups in this BPF map only
+  -4, --ipv4            trace IPv4 family only
+  -6, --ipv6            trace IPv6 family only
 
 examples:
     ./tcptop           # trace TCP send/recv by host
@@ -127,3 +129,5 @@ examples:
     ./tcptop -p 181    # only trace PID 181
     ./tcptop --cgroupmap ./mappath  # only trace cgroups in this BPF map
     ./tcptop --mntnsmap mappath   # only trace mount namespaces in the map
+    ./tcptop -4        # trace IPv4 family only
+    ./tcptop -6        # trace IPv6 family only
index 3220105eb7b8eb184518497796f04a32442d854b..25c6fd78dc7ce43b2e841b76b5b01225ba598ee2 100755 (executable)
@@ -3,7 +3,7 @@
 # tcpv4tracer   Trace TCP connections.
 #               For Linux, uses BCC, eBPF. Embedded C.
 #
-# USAGE: tcpv4tracer [-h] [-v] [-p PID] [-N NETNS]
+# USAGE: tcpv4tracer [-h] [-v] [-p PID] [-N NETNS] [-4 | -6]
 #
 # You should generally try to avoid writing long scripts that measure multiple
 # functions and walk multiple kernel structures, as they will be a burden to
@@ -34,6 +34,11 @@ parser.add_argument("--cgroupmap",
                     help="trace cgroups in this BPF map only")
 parser.add_argument("--mntnsmap",
                     help="trace mount namespaces in this BPF map only")
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-4", "--ipv4", action="store_true",
+                    help="trace IPv4 family only")
+group.add_argument("-6", "--ipv6", action="store_true",
+                   help="trace IPv6 family only")
 parser.add_argument("-v", "--verbose", action="store_true",
                     help="include Network Namespace in the output")
 parser.add_argument("--ebpf", action="store_true",
@@ -185,6 +190,10 @@ int trace_connect_v4_entry(struct pt_regs *ctx, struct sock *sk)
   u64 pid = bpf_get_current_pid_tgid();
 
   ##FILTER_PID##
+  
+  u16 family = sk->__sk_common.skc_family;
+  ##FILTER_FAMILY##
+
 
   // stash the sock ptr for lookup on return
   connectsock.update(&pid, &sk);
@@ -235,6 +244,8 @@ int trace_connect_v6_entry(struct pt_regs *ctx, struct sock *sk)
   u64 pid = bpf_get_current_pid_tgid();
 
   ##FILTER_PID##
+  u16 family = sk->__sk_common.skc_family;
+  ##FILTER_FAMILY##
 
   // stash the sock ptr for lookup on return
   connectsock.update(&pid, &sk);
@@ -283,6 +294,9 @@ int trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *skp, int state)
       return 0;
   }
 
+  u16 family = skp->__sk_common.skc_family;
+  ##FILTER_FAMILY##
+  
   u8 ipver = 0;
   if (check_family(skp, AF_INET)) {
       ipver = 4;
@@ -371,6 +385,9 @@ int trace_close_entry(struct pt_regs *ctx, struct sock *skp)
   u64 pid = bpf_get_current_pid_tgid();
 
   ##FILTER_PID##
+  
+  u16 family = skp->__sk_common.skc_family;
+  ##FILTER_FAMILY##
 
   u8 oldstate = skp->sk_state;
   // Don't generate close events for connections that were never
@@ -456,6 +473,9 @@ int trace_accept_return(struct pt_regs *ctx)
 #endif
 
   ##FILTER_NETNS##
+  
+  u16 family = newsk->__sk_common.skc_family;
+  ##FILTER_FAMILY##
 
   if (check_family(newsk, AF_INET)) {
       ipver = 4;
@@ -598,7 +618,13 @@ if args.pid:
     pid_filter = 'if (pid >> 32 != %d) { return 0; }' % args.pid
 if args.netns:
     netns_filter = 'if (net_ns_inum != %d) { return 0; }' % args.netns
-
+if args.ipv4:
+    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
+        'if (family != AF_INET) { return 0; }')
+elif args.ipv6:
+    bpf_text = bpf_text.replace('##FILTER_FAMILY##',
+        'if (family != AF_INET6) { return 0; }')
+bpf_text = bpf_text.replace('##FILTER_FAMILY##', '')
 bpf_text = bpf_text.replace('##FILTER_PID##', pid_filter)
 bpf_text = bpf_text.replace('##FILTER_NETNS##', netns_filter)
 bpf_text = filter_by_containers(args) + bpf_text
@@ -609,10 +635,17 @@ if args.ebpf:
 
 # initialize BPF
 b = BPF(text=bpf_text)
-b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
-b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return")
-b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry")
-b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return")
+if args.ipv4:
+    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
+    b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return")
+elif args.ipv6:
+    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry")
+    b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return")
+else:
+    b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
+    b.attach_kretprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_return")
+    b.attach_kprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_entry")
+    b.attach_kretprobe(event="tcp_v6_connect", fn_name="trace_connect_v6_return")
 b.attach_kprobe(event="tcp_set_state", fn_name="trace_tcp_set_state_entry")
 b.attach_kprobe(event="tcp_close", fn_name="trace_close_entry")
 b.attach_kretprobe(event="inet_csk_accept", fn_name="trace_accept_return")