Fix ebpf source port, add event validation and simpify tcp monitoring

This commit is contained in:
Vladimir Stoilov
2023-06-14 17:35:09 +03:00
parent f754555979
commit cecce3ffcb
6 changed files with 73 additions and 102 deletions

View File

@@ -11,6 +11,9 @@
#define UDP 17
#define UDPLite 136
#define OUTBOUND 0
#define INBOUND 1
char __license[] SEC("license") = "GPL";
// Ring buffer for all connection events
@@ -28,24 +31,14 @@ struct Event {
u32 pid;
u8 ipVersion;
u8 protocol;
u8 direction;
};
struct Event *unused __attribute__((unused));
// Fexit of tcp_v4_connect will be executed when equivalent kernel function returns.
// In the kernel function all IPs and ports are set and then tcp_connect is called. tcp_v4_connect -> tcp_connect -> [this-function]
SEC("fexit/tcp_v4_connect")
int BPF_PROG(tcp_v4_connect, struct sock *sk) {
// Ignore everything else then IPv4
if (sk->__sk_common.skc_family != AF_INET) {
return 0;
}
// Make sure it's tcp sock
struct tcp_sock *ts = bpf_skc_to_tcp_sock(sk);
if (!ts) {
return 0;
}
// Fentry of tcp_connect will be executed when equivalent kernel function is called.
// In the kernel all IP address and ports should be set before tcp_connect is called. [this-function] -> tcp_connect
SEC("fentry/tcp_connect")
int BPF_PROG(tcp_connect, struct sock *sk) {
// Alloc space for the event
struct Event *tcp_info;
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
@@ -56,67 +49,32 @@ int BPF_PROG(tcp_v4_connect, struct sock *sk) {
// Read PID
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
// Set src and dist ports
tcp_info->sport = sk->__sk_common.skc_num;
tcp_info->dport = sk->__sk_common.skc_dport;
// Set src and dist IPs
tcp_info->saddr[0] = __builtin_bswap32(sk->__sk_common.skc_rcv_saddr);
tcp_info->daddr[0] = __builtin_bswap32(sk->__sk_common.skc_daddr);
// Set IP version
tcp_info->ipVersion = 4;
// Set protocol
tcp_info->protocol = TCP;
// Send event
bpf_ringbuf_submit(tcp_info, 0);
return 0;
};
// Fexit(function exit) of tcp_v6_connect will be executed when equivalent kernel function returns.
// In the kernel function all IPs and ports are set and then tcp_connect is called. tcp_v6_connect -> tcp_connect -> [this-function]
SEC("fexit/tcp_v6_connect")
int BPF_PROG(tcp_v6_connect, struct sock *sk) {
// Ignore everything else then IPv6
if (sk->__sk_common.skc_family != AF_INET6) {
return 0;
}
// Make sure its a tcp6 sock
struct tcp6_sock *ts = bpf_skc_to_tcp6_sock(sk);
if (!ts) {
return 0;
}
// Alloc space for the event
struct Event *tcp_info;
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
if (!tcp_info) {
return 0;
}
// Read PID
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
// Set direction
tcp_info->direction = OUTBOUND;
// Set src and dist ports
tcp_info->sport = sk->__sk_common.skc_num;
tcp_info->sport = __builtin_bswap16(sk->__sk_common.skc_num);
tcp_info->dport = sk->__sk_common.skc_dport;
// Set src and dist IPs
for(int i = 0; i < 4; i++) {
tcp_info->saddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[i]);
if (sk->__sk_common.skc_family == AF_INET) {
tcp_info->saddr[0] = __builtin_bswap32(sk->__sk_common.skc_rcv_saddr);
tcp_info->daddr[0] = __builtin_bswap32(sk->__sk_common.skc_daddr);
// Set IP version
tcp_info->ipVersion = 4;
} else if (sk->__sk_common.skc_family == AF_INET6) {
for(int i = 0; i < 4; i++) {
tcp_info->saddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[i]);
}
for(int i = 0; i < 4; i++) {
tcp_info->daddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[i]);
}
// Set IP version
tcp_info->ipVersion = 6;
}
for(int i = 0; i < 4; i++) {
tcp_info->daddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[i]);
}
// Set IP version
tcp_info->ipVersion = 6;
// Set protocol
tcp_info->protocol = TCP;
// Send event
bpf_ringbuf_submit(tcp_info, 0);
@@ -143,7 +101,7 @@ int BPF_PROG(udp_v4_connect, struct sock *sk) {
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
// Set src and dist ports
udp_info->sport = sk->__sk_common.skc_num;
udp_info->sport = __builtin_bswap16(sk->__sk_common.skc_num);
udp_info->dport = sk->__sk_common.skc_dport;
// Set src and dist IPs
@@ -187,7 +145,7 @@ int BPF_PROG(udp_v6_connect, struct sock *sk) {
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
// Set src and dist ports
udp_info->sport = sk->__sk_common.skc_num;
udp_info->sport = __builtin_bswap16(sk->__sk_common.skc_num);
udp_info->dport = sk->__sk_common.skc_dport;
// Set src and dist IPs