Skip to content

Commit

Permalink
tools: add option --cgroupmap to tcp tools
Browse files Browse the repository at this point in the history
List of tcp tools updated: tcpaccept, tcpconnect, tcptracer
  • Loading branch information
alban authored and yonghong-song committed Feb 21, 2020
1 parent 9422274 commit 1ce868f
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 10 deletions.
3 changes: 3 additions & 0 deletions docs/filtering_by_cgroups.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Examples of commands:
```
# ./opensnoop --cgroupmap /sys/fs/bpf/test01
# ./execsnoop --cgroupmap /sys/fs/bpf/test01
# ./tcpconnect --cgroupmap /sys/fs/bpf/test01
# ./tcpaccept --cgroupmap /sys/fs/bpf/test01
# ./tcptracer --cgroupmap /sys/fs/bpf/test01
```

The commands above will only display results from processes that belong to one
Expand Down
20 changes: 20 additions & 0 deletions tools/tcpaccept.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
./tcpaccept -t # include timestamps
./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
"""
parser = argparse.ArgumentParser(
description="Trace TCP accepts",
Expand All @@ -42,6 +43,8 @@
help="trace this PID only")
parser.add_argument("-P", "--port",
help="comma-separated list of local ports to trace")
parser.add_argument("--cgroupmap",
help="trace cgroups in this BPF map only")
parser.add_argument("--ebpf", action="store_true",
help=argparse.SUPPRESS)
args = parser.parse_args()
Expand Down Expand Up @@ -77,6 +80,11 @@
char task[TASK_COMM_LEN];
};
BPF_PERF_OUTPUT(ipv6_events);
#if CGROUPSET
BPF_TABLE_PINNED("hash", u64, u64, cgroupset, 1024, "CGROUPPATH");
#endif
"""

#
Expand All @@ -89,6 +97,13 @@
bpf_text_kprobe = """
int kretprobe__inet_csk_accept(struct pt_regs *ctx)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
struct sock *newsk = (struct sock *)PT_REGS_RC(ctx);
u32 pid = bpf_get_current_pid_tgid() >> 32;
Expand Down Expand Up @@ -184,6 +199,11 @@
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.cgroupmap:
bpf_text = bpf_text.replace('CGROUPSET', '1')
bpf_text = bpf_text.replace('CGROUPPATH', args.cgroupmap)
else:
bpf_text = bpf_text.replace('CGROUPSET', '0')
if debug or args.ebpf:
print(bpf_text)
if args.ebpf:
Expand Down
23 changes: 17 additions & 6 deletions tools/tcpaccept_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,33 @@ TIME(s) PID COMM IP RADDR RPORT LADDR LPORT
1.984 907 sshd 4 127.0.0.1 51250 127.0.0.1 22


The --cgroupmap option filters based on a cgroup set. It is meant to be used
with an externally created map.

# ./tcpaccept --cgroupmap /sys/fs/bpf/test01

For more details, see docs/filtering_by_cgroups.md


USAGE message:

# ./tcpaccept -h
usage: tcpaccept [-h] [-T] [-t] [-p PID] [-P PORTS]
usage: tcpaccept.py [-h] [-T] [-t] [-p PID] [-P PORT] [--cgroupmap CGROUPMAP]

Trace TCP accepts

optional arguments:
-h, --help show this help message and exit
-T, --time include time column on output (HH:MM:SS)
-t, --timestamp include timestamp on output
-p PID, --pid PID trace this PID only
-P PORTS, --port PORTS comma-separated list of local ports to trace
-h, --help show this help message and exit
-T, --time include time column on output (HH:MM:SS)
-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
--cgroupmap CGROUPMAP
trace cgroups in this BPF map only

examples:
./tcpaccept # trace all TCP accept()s
./tcpaccept -t # include timestamps
./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
19 changes: 19 additions & 0 deletions tools/tcpconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
./tcpconnect -U # include UID
./tcpconnect -u 1000 # only trace UID 1000
./tcpconnect -c # count connects per src ip and dest ip/port
./tcpconnect --cgroupmap ./mappath # only trace cgroups in this BPF map
"""
parser = argparse.ArgumentParser(
description="Trace TCP connects",
Expand All @@ -54,6 +55,8 @@
help="trace this UID only")
parser.add_argument("-c", "--count", action="store_true",
help="count connects per src ip and dest ip/port")
parser.add_argument("--cgroupmap",
help="trace cgroups in this BPF map only")
parser.add_argument("--ebpf", action="store_true",
help=argparse.SUPPRESS)
args = parser.parse_args()
Expand All @@ -67,6 +70,10 @@
BPF_HASH(currsock, u32, struct sock *);
#if CGROUPSET
BPF_TABLE_PINNED("hash", u64, u64, cgroupset, 1024, "CGROUPPATH");
#endif
// separate data structs for ipv4 and ipv6
struct ipv4_data_t {
u64 ts_us;
Expand Down Expand Up @@ -109,6 +116,13 @@
int trace_connect_entry(struct pt_regs *ctx, struct sock *sk)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = pid_tgid;
Expand Down Expand Up @@ -234,6 +248,11 @@
if args.uid:
bpf_text = bpf_text.replace('FILTER_UID',
'if (uid != %s) { return 0; }' % args.uid)
if args.cgroupmap:
bpf_text = bpf_text.replace('CGROUPSET', '1')
bpf_text = bpf_text.replace('CGROUPPATH', args.cgroupmap)
else:
bpf_text = bpf_text.replace('CGROUPSET', '0')

bpf_text = bpf_text.replace('FILTER_PID', '')
bpf_text = bpf_text.replace('FILTER_PORT', '')
Expand Down
17 changes: 14 additions & 3 deletions tools/tcpconnect_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,32 @@ LADDR RADDR RPORT CONNECTS
[...]


The --cgroupmap option filters based on a cgroup set. It is meant to be used
with an externally created map.

# ./tcpconnect --cgroupmap /sys/fs/bpf/test01

For more details, see docs/filtering_by_cgroups.md


USAGE message:

# ./tcpconnect -h
usage: tcpconnect [-h] [-c] [-t] [-p PID] [-P PORT]
usage: tcpconnect.py [-h] [-t] [-p PID] [-P PORT] [-U] [-u UID] [-c]
[--cgroupmap CGROUPMAP]

Trace TCP connects

optional arguments:
-h, --help show this help message and exit
-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.
-P PORT, --port PORT comma-separated list of destination ports to trace.
-U, --print-uid include UID on output
-u UID, --uid UID trace this UID only
-c, --count count connects per src ip and dest ip/port
--cgroupmap CGROUPMAP
trace cgroups in this BPF map only

examples:
./tcpconnect # trace all TCP connect()s
Expand All @@ -94,3 +104,4 @@ examples:
./tcpconnect -U # include UID
./tcpconnect -u 1000 # only trace UID 1000
./tcpconnect -c # count connects per src ip and dest ip/port
./tcpconnect --cgroupmap ./mappath # only trace cgroups in this BPF map
40 changes: 39 additions & 1 deletion tools/tcptracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# The following code should be replaced, and simplified, when static TCP probes
# exist.
#
# Copyright 2017 Kinvolk GmbH
# Copyright 2017-2020 Kinvolk GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License")
from __future__ import print_function
Expand All @@ -29,6 +29,8 @@
help="trace this PID only")
parser.add_argument("-N", "--netns", default=0, type=int,
help="trace this Network Namespace only")
parser.add_argument("--cgroupmap",
help="trace cgroups in this BPF map only")
parser.add_argument("-v", "--verbose", action="store_true",
help="include Network Namespace in the output")
parser.add_argument("--ebpf", action="store_true",
Expand Down Expand Up @@ -77,6 +79,10 @@
};
BPF_PERF_OUTPUT(tcp_ipv6_event);
#if CGROUPSET
BPF_TABLE_PINNED("hash", u64, u64, cgroupset, 1024, "CGROUPPATH");
#endif
// tcp_set_state doesn't run in the context of the process that initiated the
// connection so we need to store a map TUPLE -> PID to send the right PID on
// the event
Expand Down Expand Up @@ -173,6 +179,13 @@
int trace_connect_v4_entry(struct pt_regs *ctx, struct sock *sk)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
u64 pid = bpf_get_current_pid_tgid();
##FILTER_PID##
Expand Down Expand Up @@ -220,6 +233,12 @@
int trace_connect_v6_entry(struct pt_regs *ctx, struct sock *sk)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
u64 pid = bpf_get_current_pid_tgid();
##FILTER_PID##
Expand Down Expand Up @@ -352,6 +371,13 @@
int trace_close_entry(struct pt_regs *ctx, struct sock *skp)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
u64 pid = bpf_get_current_pid_tgid();
##FILTER_PID##
Expand Down Expand Up @@ -413,6 +439,13 @@
int trace_accept_return(struct pt_regs *ctx)
{
#if CGROUPSET
u64 cgroupid = bpf_get_current_cgroup_id();
if (cgroupset.lookup(&cgroupid) == NULL) {
return 0;
}
#endif
struct sock *newsk = (struct sock *)PT_REGS_RC(ctx);
u64 pid = bpf_get_current_pid_tgid();
Expand Down Expand Up @@ -581,6 +614,11 @@ def print_ipv6_event(cpu, data, size):

bpf_text = bpf_text.replace('##FILTER_PID##', pid_filter)
bpf_text = bpf_text.replace('##FILTER_NETNS##', netns_filter)
if args.cgroupmap:
bpf_text = bpf_text.replace('CGROUPSET', '1')
bpf_text = bpf_text.replace('CGROUPPATH', args.cgroupmap)
else:
bpf_text = bpf_text.replace('CGROUPSET', '0')

if args.ebpf:
print(bpf_text)
Expand Down
8 changes: 8 additions & 0 deletions tools/tcptracer_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ TIME(s) T PID COMM IP SADDR DADDR SPORT
3.546 C 748 curl 6 [::1] [::1] 42592 80
4.294 X 31002 telnet 4 192.168.1.2 192.168.1.1 42590 23
```


The --cgroupmap option filters based on a cgroup set. It is meant to be used
with an externally created map.

# ./tcptracer --cgroupmap /sys/fs/bpf/test01

For more details, see docs/filtering_by_cgroups.md

0 comments on commit 1ce868f

Please sign in to comment.