Skip to content

Commit

Permalink
Discard completely necessity to parse /proc (#370)
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagoftsm authored Mar 4, 2024
1 parent 821aceb commit 49a9815
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 29 deletions.
16 changes: 14 additions & 2 deletions includes/netdata_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef _NETDATA_NETWORK_H_
#define _NETDATA_NETWORK_H_ 1

#include <linux/in6.h>

/**
* SOCKET
*/
Expand Down Expand Up @@ -138,9 +140,18 @@ enum socket_functions {
* NETWORK VIEWER
*/

typedef enum __attribute__((packed)) {
NETDATA_SOCKET_DIRECTION_NONE = 0,
NETDATA_SOCKET_DIRECTION_LISTEN = (1 << 0), // a listening socket
NETDATA_SOCKET_DIRECTION_INBOUND = (1 << 1), // an inbound socket connecting a remote system to a local listening socket
NETDATA_SOCKET_DIRECTION_OUTBOUND = (1 << 2), // a socket initiated by this system, connecting to another system
NETDATA_SOCKET_DIRECTION_LOCAL_INBOUND = (1 << 3), // the socket connecting 2 localhost applications
NETDATA_SOCKET_DIRECTION_LOCAL_OUTBOUND = (1 << 4), // the socket connecting 2 localhost applications
} NETDATA_SOCKET_DIRECTION;

union ipv46 {
uint32_t ipv4;
union netdata_ip ipv6;
struct in6_addr ipv6;
};

typedef struct netdata_nv_idx {
Expand All @@ -159,13 +170,14 @@ typedef struct netdata_nv_data {

__u8 timer;
__u8 retransmits;
__u16 closed;
__u32 expires;
__u32 rqueue;
__u32 wqueue;

char name[TASK_COMM_LEN];

__u32 direction;
NETDATA_SOCKET_DIRECTION direction;

__u16 family;
__u16 protocol;
Expand Down
92 changes: 65 additions & 27 deletions kernel/network_viewer_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,16 @@ static __always_inline __u16 set_nv_idx_value(netdata_nv_idx_t *nvi, struct sock
bpf_probe_read(&nvi->saddr.ipv4, sizeof(u32), &is->inet_saddr);
bpf_probe_read(&nvi->daddr.ipv4, sizeof(u32), &is->inet_daddr);
if (nvi->saddr.ipv4 == 0 || nvi->daddr.ipv4 == 0) // Zero
return AF_UNSPEC;
return AF_INET;
}
// Check necessary according https://elixir.bootlin.com/linux/v5.6.14/source/include/net/sock.h#L199
else if ( family == AF_INET6 ) {
// struct in6_addr *addr6 = &is->sk.sk_v6_rcv_saddr; // bind to local address
struct in6_addr *addr6 = (struct in6_addr *)&is->sk.__sk_common.skc_v6_rcv_saddr.s6_addr;
bpf_probe_read(&nvi->saddr.ipv6.addr8, sizeof(__u8)*16, &addr6->s6_addr);
bpf_probe_read(&nvi->saddr.ipv6.in6_u.u6_addr8, sizeof(__u8)*16, &addr6->s6_addr);

addr6 = (struct in6_addr *)&is->sk.__sk_common.skc_v6_daddr.s6_addr;
bpf_probe_read(&nvi->daddr.ipv6.addr8, sizeof(__u8)*16, &addr6->s6_addr);

if (((nvi->saddr.ipv6.addr64[0] == 0) && (nvi->saddr.ipv6.addr64[1] == 0)) ||
((nvi->daddr.ipv6.addr64[0] == 0) && (nvi->daddr.ipv6.addr64[1] == 0))) // Zero addr
return AF_UNSPEC;
bpf_probe_read(&nvi->daddr.ipv6.in6_u.u6_addr8, sizeof(__u8)*16, &addr6->s6_addr);
}
else {
return AF_UNSPEC;
Expand Down Expand Up @@ -151,7 +147,8 @@ static __always_inline __s32 am_i_monitoring_protocol(struct sock *sk)
static __always_inline void set_common_tcp_nv_data(netdata_nv_data_t *data,
struct sock *sk,
__u16 family,
int state)
int state,
NETDATA_SOCKET_DIRECTION direction)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
const struct tcp_sock *tp = tcp_sk(sk);
Expand Down Expand Up @@ -203,13 +200,17 @@ static __always_inline void set_common_tcp_nv_data(netdata_nv_data_t *data,
data->expires = 0;
data->rqueue = rx_queue;

if (data->direction == NETDATA_SOCKET_DIRECTION_NONE)
data->direction = direction;

data->family = family;
data->protocol = IPPROTO_TCP;
}

static __always_inline void set_common_udp_nv_data(netdata_nv_data_t *data,
struct sock *sk,
__u16 family) {
__u16 family,
NETDATA_SOCKET_DIRECTION direction) {
data->pid = bpf_get_current_pid_tgid() >> 32;
data->uid = bpf_get_current_uid_gid();
// Only update this data when it is a new value
Expand All @@ -226,6 +227,9 @@ static __always_inline void set_common_udp_nv_data(netdata_nv_data_t *data,
#else
data->name[0] = '\0';
#endif

if (data->direction == NETDATA_SOCKET_DIRECTION_NONE)
data->direction = direction;
}

/************************************************************************************
Expand All @@ -243,17 +247,18 @@ int netdata_inet_csk_accept(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = (idx.sport == idx.dport) ? NETDATA_SOCKET_DIRECTION_LISTEN : NETDATA_SOCKET_DIRECTION_INBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -275,17 +280,18 @@ int netdata_tcp_sendmsg(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = (idx.sport == idx.dport) ? NETDATA_SOCKET_DIRECTION_LISTEN : NETDATA_SOCKET_DIRECTION_OUTBOUND | NETDATA_SOCKET_DIRECTION_INBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -301,17 +307,18 @@ int netdata_tcp_retransmit_skb(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = (idx.sport == idx.dport) ? NETDATA_SOCKET_DIRECTION_LISTEN : NETDATA_SOCKET_DIRECTION_OUTBOUND | NETDATA_SOCKET_DIRECTION_INBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -328,9 +335,10 @@ int netdata_tcp_set_state(struct pt_regs* ctx)
int state = (int)PT_REGS_PARM2(ctx);
netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = (idx.sport == idx.dport) ? NETDATA_SOCKET_DIRECTION_LISTEN : NETDATA_SOCKET_DIRECTION_OUTBOUND | NETDATA_SOCKET_DIRECTION_INBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, state);
set_common_tcp_nv_data(val, sk, family, state, direction);
val->state = state;
return 0;
}
Expand All @@ -339,7 +347,7 @@ int netdata_tcp_set_state(struct pt_regs* ctx)
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, state);
set_common_tcp_nv_data(&data, sk, family, state, direction);
data.state = state;

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);
Expand All @@ -357,17 +365,18 @@ int netdata_tcp_cleanup_rbuf(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = (idx.sport == idx.dport) ? NETDATA_SOCKET_DIRECTION_LISTEN : NETDATA_SOCKET_DIRECTION_OUTBOUND | NETDATA_SOCKET_DIRECTION_INBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -383,17 +392,18 @@ int netdata_tcp_v4_connect(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = NETDATA_SOCKET_DIRECTION_OUTBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -409,23 +419,43 @@ int netdata_tcp_v6_connect(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = NETDATA_SOCKET_DIRECTION_OUTBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_tcp_nv_data(val, sk, family, 0);
set_common_tcp_nv_data(val, sk, family, 0, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_tcp_nv_data(&data, sk, family, 0);
set_common_tcp_nv_data(&data, sk, family, 0, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

return 0;
}

SEC("kprobe/tcp_close")
int netdata_tcp_close(struct pt_regs* ctx)
{
struct sock *sk = (struct sock *)PT_REGS_PARM1(ctx);
if (!sk || sk == (void *)1)
return 0;

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = NETDATA_SOCKET_DIRECTION_OUTBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (!val)
return 0;

val->closed = 1;

return 0;
}

/************************************************************************************
*
* UDP Section
Expand All @@ -442,17 +472,24 @@ int trace_udp_recvmsg(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_udp_nv_data(val, sk, family);
direction = NETDATA_SOCKET_DIRECTION_OUTBOUND;
set_common_udp_nv_data(val, sk, family, direction);
if (direction != NETDATA_SOCKET_DIRECTION_LISTEN)
val->closed = 1;

return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_udp_nv_data(&data, sk, family);
direction = NETDATA_SOCKET_DIRECTION_OUTBOUND | NETDATA_SOCKET_DIRECTION_INBOUND;
set_common_udp_nv_data(&data, sk, family, direction);


bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand All @@ -468,17 +505,18 @@ int trace_udp_sendmsg(struct pt_regs* ctx)

netdata_nv_idx_t idx = {};
__u16 family = set_nv_idx_value(&idx, sk);
NETDATA_SOCKET_DIRECTION direction = NETDATA_SOCKET_DIRECTION_OUTBOUND;
netdata_nv_data_t *val = (netdata_nv_data_t *) bpf_map_lookup_elem(&tbl_nv_socket, &idx);
if (val) {
set_common_udp_nv_data(val, sk, family);
set_common_udp_nv_data(val, sk, family, direction);
return 0;
}

if (!monitor_apps(&nv_ctrl))
return 0;

netdata_nv_data_t data = { };
set_common_udp_nv_data(&data, sk, family);
set_common_udp_nv_data(&data, sk, family, direction);

bpf_map_update_elem(&tbl_nv_socket, &idx, &data, BPF_ANY);

Expand Down

0 comments on commit 49a9815

Please sign in to comment.