Skip to content

Commit

Permalink
Merge pull request iovisor#4135 from aspsk/aspsk/tcpconnect-add-an-op…
Browse files Browse the repository at this point in the history
…tion

libbpf-tools: tcpconnect: take source port into consideration
  • Loading branch information
davemarchevsky committed Aug 1, 2022
2 parents 58fe075 + 4c2d123 commit f6c4b4c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 22 deletions.
25 changes: 17 additions & 8 deletions libbpf-tools/tcpconnect.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const volatile int filter_ports_len = 0;
const volatile uid_t filter_uid = -1;
const volatile pid_t filter_pid = 0;
const volatile bool do_count = 0;
const volatile bool source_port = 0;

/* Define here, because there are conflicts with include files */
#define AF_INET 2
Expand Down Expand Up @@ -81,21 +82,22 @@ enter_tcp_connect(struct pt_regs *ctx, struct sock *sk)
return 0;
}

static __always_inline void count_v4(struct sock *sk, __u16 dport)
static __always_inline void count_v4(struct sock *sk, __u16 sport, __u16 dport)
{
struct ipv4_flow_key key = {};
static __u64 zero;
__u64 *val;

BPF_CORE_READ_INTO(&key.saddr, sk, __sk_common.skc_rcv_saddr);
BPF_CORE_READ_INTO(&key.daddr, sk, __sk_common.skc_daddr);
key.sport = sport;
key.dport = dport;
val = bpf_map_lookup_or_try_init(&ipv4_count, &key, &zero);
if (val)
__atomic_add_fetch(val, 1, __ATOMIC_RELAXED);
}

static __always_inline void count_v6(struct sock *sk, __u16 dport)
static __always_inline void count_v6(struct sock *sk, __u16 sport, __u16 dport)
{
struct ipv6_flow_key key = {};
static const __u64 zero;
Expand All @@ -105,6 +107,7 @@ static __always_inline void count_v6(struct sock *sk, __u16 dport)
__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
BPF_CORE_READ_INTO(&key.daddr, sk,
__sk_common.skc_v6_daddr.in6_u.u6_addr32);
key.sport = sport;
key.dport = dport;

val = bpf_map_lookup_or_try_init(&ipv6_count, &key, &zero);
Expand All @@ -113,7 +116,7 @@ static __always_inline void count_v6(struct sock *sk, __u16 dport)
}

static __always_inline void
trace_v4(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 dport)
trace_v4(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 sport, __u16 dport)
{
struct event event = {};

Expand All @@ -123,6 +126,7 @@ trace_v4(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 dport)
event.ts_us = bpf_ktime_get_ns() / 1000;
BPF_CORE_READ_INTO(&event.saddr_v4, sk, __sk_common.skc_rcv_saddr);
BPF_CORE_READ_INTO(&event.daddr_v4, sk, __sk_common.skc_daddr);
event.sport = sport;
event.dport = dport;
bpf_get_current_comm(event.task, sizeof(event.task));

Expand All @@ -131,7 +135,7 @@ trace_v4(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 dport)
}

static __always_inline void
trace_v6(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 dport)
trace_v6(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 sport, __u16 dport)
{
struct event event = {};

Expand All @@ -143,6 +147,7 @@ trace_v6(struct pt_regs *ctx, pid_t pid, struct sock *sk, __u16 dport)
__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
BPF_CORE_READ_INTO(&event.daddr_v6, sk,
__sk_common.skc_v6_daddr.in6_u.u6_addr32);
event.sport = sport;
event.dport = dport;
bpf_get_current_comm(event.task, sizeof(event.task));

Expand All @@ -158,6 +163,7 @@ exit_tcp_connect(struct pt_regs *ctx, int ret, int ip_ver)
__u32 tid = pid_tgid;
struct sock **skpp;
struct sock *sk;
__u16 sport = 0;
__u16 dport;

skpp = bpf_map_lookup_elem(&sockets, &tid);
Expand All @@ -169,20 +175,23 @@ exit_tcp_connect(struct pt_regs *ctx, int ret, int ip_ver)

sk = *skpp;

if (source_port)
BPF_CORE_READ_INTO(&sport, sk, __sk_common.skc_num);
BPF_CORE_READ_INTO(&dport, sk, __sk_common.skc_dport);

if (filter_port(dport))
goto end;

if (do_count) {
if (ip_ver == 4)
count_v4(sk, dport);
count_v4(sk, sport, dport);
else
count_v6(sk, dport);
count_v6(sk, sport, dport);
} else {
if (ip_ver == 4)
trace_v4(ctx, pid, sk, dport);
trace_v4(ctx, pid, sk, sport, dport);
else
trace_v6(ctx, pid, sk, dport);
trace_v6(ctx, pid, sk, sport, dport);
}

end:
Expand Down
60 changes: 46 additions & 14 deletions libbpf-tools/tcpconnect.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ static const struct argp_option opts[] = {
{ "print-uid", 'U', NULL, 0, "Include UID on output" },
{ "pid", 'p', "PID", 0, "Process PID to trace" },
{ "uid", 'u', "UID", 0, "Process UID to trace" },
{ "source-port", 's', NULL, 0, "Consider source port when counting" },
{ "port", 'P', "PORTS", 0,
"Comma-separated list of destination ports to trace" },
{ "cgroupmap", 'C', "PATH", 0, "trace cgroups in this map" },
Expand All @@ -127,6 +128,7 @@ static struct env {
uid_t uid;
int nports;
int ports[MAX_PORTS];
bool source_port;
} env = {
.uid = (uid_t) -1,
};
Expand All @@ -146,6 +148,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
case 'c':
env.count = true;
break;
case 's':
env.source_port = true;
break;
case 't':
env.print_timestamp = true;
break;
Expand Down Expand Up @@ -221,10 +226,14 @@ static void print_count_ipv4(int map_fd)
src.s_addr = keys[i].saddr;
dst.s_addr = keys[i].daddr;

printf("%-25s %-25s %-20d %-10llu\n",
printf("%-25s %-25s",
inet_ntop(AF_INET, &src, s, sizeof(s)),
inet_ntop(AF_INET, &dst, d, sizeof(d)),
ntohs(keys[i].dport), counts[i]);
inet_ntop(AF_INET, &dst, d, sizeof(d)));
if (env.source_port)
printf(" %-20d", keys[i].sport);
printf(" %-20d", ntohs(keys[i].dport));
printf(" %-10llu", counts[i]);
printf("\n");
}
}

Expand All @@ -250,21 +259,33 @@ static void print_count_ipv6(int map_fd)
memcpy(src.s6_addr, keys[i].saddr, sizeof(src.s6_addr));
memcpy(dst.s6_addr, keys[i].daddr, sizeof(src.s6_addr));

printf("%-25s %-25s %-20d %-10llu\n",
printf("%-25s %-25s",
inet_ntop(AF_INET6, &src, s, sizeof(s)),
inet_ntop(AF_INET6, &dst, d, sizeof(d)),
ntohs(keys[i].dport), counts[i]);
inet_ntop(AF_INET6, &dst, d, sizeof(d)));
if (env.source_port)
printf(" %-20d", keys[i].sport);
printf(" %-20d", ntohs(keys[i].dport));
printf(" %-10llu", counts[i]);
printf("\n");
}
}

static void print_count(int map_fd_ipv4, int map_fd_ipv6)
static void print_count_header()
{
static const char *header_fmt = "\n%-25s %-25s %-20s %-10s\n";
printf("\n%-25s %-25s", "LADDR", "RADDR");
if (env.source_port)
printf(" %-20s", "LPORT");
printf(" %-20s", "RPORT");
printf(" %-10s", "CONNECTS");
printf("\n");
}

static void print_count(int map_fd_ipv4, int map_fd_ipv6)
{
while (!exiting)
pause();

printf(header_fmt, "LADDR", "RADDR", "RPORT", "CONNECTS");
print_count_header();
print_count_ipv4(map_fd_ipv4);
print_count_ipv6(map_fd_ipv6);
}
Expand All @@ -275,8 +296,11 @@ static void print_events_header()
printf("%-9s", "TIME(s)");
if (env.print_uid)
printf("%-6s", "UID");
printf("%-6s %-12s %-2s %-16s %-16s %-4s\n",
"PID", "COMM", "IP", "SADDR", "DADDR", "DPORT");
printf("%-6s %-12s %-2s %-16s %-16s",
"PID", "COMM", "IP", "SADDR", "DADDR");
if (env.source_port)
printf(" %-5s", "SPORT");
printf(" %-5s\n", "DPORT");
}

static void handle_event(void *ctx, int cpu, void *data, __u32 data_sz)
Expand Down Expand Up @@ -310,12 +334,18 @@ static void handle_event(void *ctx, int cpu, void *data, __u32 data_sz)
if (env.print_uid)
printf("%-6d", event->uid);

printf("%-6d %-12.12s %-2d %-16s %-16s %-4d\n",
printf("%-6d %-12.12s %-2d %-16s %-16s",
event->pid, event->task,
event->af == AF_INET ? 4 : 6,
inet_ntop(event->af, &s, src, sizeof(src)),
inet_ntop(event->af, &d, dst, sizeof(dst)),
ntohs(event->dport));
inet_ntop(event->af, &d, dst, sizeof(dst)));

if (env.source_port)
printf(" %-5d", event->sport);

printf(" %-5d", ntohs(event->dport));

printf("\n");
}

static void handle_lost_events(void *ctx, int cpu, __u64 lost_cnt)
Expand Down Expand Up @@ -394,6 +424,8 @@ int main(int argc, char **argv)
obj->rodata->filter_ports[i] = htons(env.ports[i]);
}
}
if (env.source_port)
obj->rodata->source_port = true;

err = tcpconnect_bpf__load(obj);
if (err) {
Expand Down
3 changes: 3 additions & 0 deletions libbpf-tools/tcpconnect.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
struct ipv4_flow_key {
__u32 saddr;
__u32 daddr;
__u16 sport;
__u16 dport;
};

struct ipv6_flow_key {
__u8 saddr[16];
__u8 daddr[16];
__u16 sport;
__u16 dport;
};

Expand All @@ -37,6 +39,7 @@ struct event {
__u32 af; // AF_INET or AF_INET6
__u32 pid;
__u32 uid;
__u16 sport;
__u16 dport;
};

Expand Down

0 comments on commit f6c4b4c

Please sign in to comment.