Skip to content

Commit af5624a

Browse files
authored
Fix inbound/outbound classification (#173)
Bring new `kretprobe` and fix socket read.
1 parent bfd03ff commit af5624a

File tree

1 file changed

+65
-8
lines changed

1 file changed

+65
-8
lines changed

kernel/network_viewer_kern.c

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ union netdata_ip {
2929
__u8 addr8[16];
3030
__u16 addr16[8];
3131
__u32 addr32[4];
32+
__u64 addr64[2];
3233
};
3334

3435
/**
@@ -42,7 +43,7 @@ typedef struct netdata_socket {
4243
__u64 first; //First timestamp
4344
__u64 ct; //Current timestamp
4445
__u16 retransmit; //It is never used with UDP
45-
__u8 protocol; //Should this to be in the index?
46+
__u8 protocol;
4647
__u8 removeme;
4748
__u32 reserved;
4849
} netdata_socket_t;
@@ -52,9 +53,9 @@ typedef struct netdata_socket {
5253
*/
5354
typedef struct netdata_socket_idx {
5455
union netdata_ip saddr;
56+
__u16 sport;
5557
union netdata_ip daddr;
5658
__u16 dport;
57-
__u16 sport;
5859
} netdata_socket_idx_t;
5960

6061
/**
@@ -144,6 +145,13 @@ struct bpf_map_def SEC("maps") tbl_sock_total_stats = {
144145
.max_entries = NETDATA_SOCKET_COUNTER
145146
};
146147

148+
struct bpf_map_def SEC("maps") tbl_used_ports = {
149+
.type = BPF_MAP_TYPE_HASH,
150+
.key_size = sizeof(__u16),
151+
.value_size = sizeof(__u8),
152+
.max_entries = 65536
153+
};
154+
147155
/************************************************************************************
148156
*
149157
* Common Section
@@ -183,27 +191,36 @@ static __u16 set_idx_value(netdata_socket_idx_t *nsi, struct inet_sock *is)
183191
{
184192
__u16 family;
185193

186-
//Read Family
194+
// Read Family
187195
bpf_probe_read(&family, sizeof(u16), &is->sk.__sk_common.skc_family);
188-
//Read source and destination IPs
196+
// Read source and destination IPs
189197
if ( family == AF_INET ) { //AF_INET
190-
bpf_probe_read(&nsi->saddr.addr32[0], sizeof(u32), &is->inet_saddr);
198+
bpf_probe_read(&nsi->saddr.addr32[0], sizeof(u32), &is->inet_rcv_saddr);
191199
bpf_probe_read(&nsi->daddr.addr32[0], sizeof(u32), &is->inet_daddr);
200+
201+
if (!nsi->saddr.addr32[0] || !nsi->daddr.addr32[0])
202+
return AF_UNSPEC;
192203
}
193204
// Check necessary according https://elixir.bootlin.com/linux/v5.6.14/source/include/net/sock.h#L199
194205
#if IS_ENABLED(CONFIG_IPV6)
195-
else if ( family == AF_INET6 ){
206+
else if ( family == AF_INET6 ) {
196207
struct in6_addr *addr6 = &is->sk.sk_v6_rcv_saddr;
197208
bpf_probe_read(&nsi->saddr.addr8, sizeof(__u8)*16, &addr6->s6_addr);
198209

199210
addr6 = &is->sk.sk_v6_daddr;
200211
bpf_probe_read(&nsi->daddr.addr8, sizeof(__u8)*16, &addr6->s6_addr);
212+
213+
if ( ((!nsi->saddr.addr64[0]) && (!nsi->saddr.addr64[1])) || ((!nsi->daddr.addr64[0]) && (!nsi->daddr.addr64[1])))
214+
return AF_UNSPEC;
201215
}
202216
#endif
217+
else {
218+
return AF_UNSPEC;
219+
}
203220

204221
//Read destination port
205222
bpf_probe_read(&nsi->dport, sizeof(u16), &is->inet_dport);
206-
bpf_probe_read(&nsi->sport, sizeof(u16), &is->inet_num);
223+
bpf_probe_read(&nsi->sport, sizeof(u16), &is->inet_sport);
207224

208225
return family;
209226
}
@@ -223,7 +240,9 @@ static void update_socket_stats(netdata_socket_t *ptr, __u64 sent, __u64 receive
223240

224241
netdata_update_u64(&ptr->sent_bytes, sent);
225242
netdata_update_u64(&ptr->recv_bytes, received);
226-
netdata_update_u64(&ptr->retransmit, retransmitted);
243+
// We can use update_u64, it was overwritten
244+
// the values
245+
ptr->retransmit += retransmitted;
227246
}
228247

229248
/**
@@ -278,6 +297,26 @@ static void update_pid_stats(__u32 pid, __u32 tgid, __u64 sent, __u64 received)
278297
}
279298
}
280299

300+
SEC("kretprobe/inet_csk_accept")
301+
int netdata_inet_csk_accept(struct pt_regs* ctx)
302+
{
303+
struct sock *sk = (struct sock*)PT_REGS_RC(ctx);
304+
if (!sk)
305+
return 0;
306+
307+
308+
__u16 dport;
309+
bpf_probe_read(&dport, sizeof(u16), &sk->__sk_common.skc_num);
310+
311+
__u8 *value = (__u8 *)bpf_map_lookup_elem(&tbl_used_ports, &dport);
312+
if (!value) {
313+
__u8 value = 1;
314+
bpf_map_update_elem(&tbl_used_ports, &dport, &value, BPF_ANY);
315+
}
316+
317+
return 0;
318+
}
319+
281320
/************************************************************************************
282321
*
283322
* TCP Section
@@ -318,6 +357,9 @@ int netdata_tcp_sendmsg(struct pt_regs* ctx)
318357
netdata_update_global(NETDATA_KEY_CALLS_TCP_SENDMSG, 1);
319358

320359
family = set_idx_value(&idx, is);
360+
if (!family)
361+
return 0;
362+
321363
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
322364

323365
netdata_update_global(NETDATA_KEY_BYTES_TCP_SENDMSG, (__u64)sent);
@@ -336,6 +378,9 @@ int netdata_tcp_retransmit_skb(struct pt_regs* ctx)
336378

337379
struct inet_sock *is = inet_sk((struct sock *)PT_REGS_PARM1(ctx));
338380
family = set_idx_value(&idx, is);
381+
if (!family)
382+
return 0;
383+
339384
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
340385

341386
netdata_update_global(NETDATA_KEY_TCP_RETRANSMIT, 1);
@@ -369,6 +414,9 @@ int netdata_tcp_cleanup_rbuf(struct pt_regs* ctx)
369414
__u64 received = (__u64) PT_REGS_PARM2(ctx);
370415

371416
family = set_idx_value(&idx, is);
417+
if (!family)
418+
return 0;
419+
372420
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
373421

374422
netdata_update_global(NETDATA_KEY_BYTES_TCP_CLEANUP_RBUF, received);
@@ -396,6 +444,9 @@ int netdata_tcp_close(struct pt_regs* ctx)
396444
netdata_update_global(NETDATA_KEY_CALLS_TCP_CLOSE, 1);
397445

398446
family = set_idx_value(&idx, is);
447+
if (!family)
448+
return 0;
449+
399450
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
400451
val = (netdata_socket_t *) bpf_map_lookup_elem(tbl, &idx);
401452
if (val) {
@@ -466,6 +517,9 @@ int trace_udp_ret_recvmsg(struct pt_regs* ctx)
466517
bpf_map_delete_elem(&tbl_nv_udp_conn_stats, &pid_tgid);
467518

468519
family = set_idx_value(&idx, is);
520+
if (!family)
521+
return 0;
522+
469523
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
470524

471525
netdata_update_global(NETDATA_KEY_BYTES_UDP_RECVMSG, received);
@@ -507,6 +561,9 @@ int trace_udp_sendmsg(struct pt_regs* ctx)
507561
netdata_update_global(NETDATA_KEY_CALLS_UDP_SENDMSG, 1);
508562

509563
family = set_idx_value(&idx, is);
564+
if (!family)
565+
return 0;
566+
510567
tbl = (family == AF_INET6)?&tbl_conn_ipv6:&tbl_conn_ipv4;
511568

512569
update_socket_table(tbl, &idx, (__u64) sent, 0, 0, IPPROTO_UDP);

0 commit comments

Comments
 (0)