Socket connections (eBPF) and bug fix (#12532)
thiagoftsm committed
Mar 29, 2022 at 18:21 UTC
68684b59f704cdd1b4190f4be8b3bce95d60da75
12 files changed
+812
-98
collectors/ebpf.plugin/ebpf.c
+3
-2
@@ -51,7 +51,7 @@ ebpf_module_t ebpf_modules[] = {
51
.pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &socket_config,
52
.config_file = NETDATA_NETWORK_CONFIG_FILE,
53
.kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
54
- .load = EBPF_LOAD_LEGACY, .targets = NULL},
54
+ .load = EBPF_LOAD_LEGACY, .targets = socket_targets},
55
{ .thread_name = "cachestat", .config_name = "cachestat", .enabled = 0, .start_routine = ebpf_cachestat_thread,
56
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
57
.cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
@@ -972,6 +972,7 @@ static void read_local_ports(char *filename, uint8_t proto)
972
return;
973
974
size_t lines = procfile_lines(ff), l;
975
+ netdata_passive_connection_t values = {.counter = 0, .tgid = 0, .pid = 0};
976
for(l = 0; l < lines ;l++) {
977
size_t words = procfile_linewords(ff, l);
978
// This is header or end of file
@@ -985,7 +986,7 @@ static void read_local_ports(char *filename, uint8_t proto)
986
987
// Read local port
988
uint16_t port = (uint16_t)strtol(procfile_lineword(ff, l, 2), NULL, 16);
988
- update_listen_table(htons(port), proto);
989
+ update_listen_table(htons(port), proto, &values);
990
}
991
992
procfile_close(ff);
collectors/ebpf.plugin/ebpf.d/network.conf
+12
@@ -14,6 +14,16 @@
14
# `ipv6 connection table size`: Maximum number of IPV6 connections monitored
15
# `udp connection table size`: Maximum number of UDP connections monitored
16
#
17
+# The `ebpf type format` option accepts the following values :
18
+# `auto` : The eBPF collector will investigate hardware and select between the two next options.
19
+# `legacy`: The eBPF collector will load the legacy code. Note: This has a bigger overload.
20
+# `co-re` : The eBPF collector will use latest tracing method. Note: This is not available on all platforms.
21
+#
22
+# The `ebpf co-re tracing` option accepts the following values:
23
+# `trampoline`: This is the default mode used by the eBPF collector, due the small overhead added to host.
24
+# `tracepoint`: When available, the eBPF collector will use kernel tracepoint to monitor syscall.
25
+# `probe` : This is the same as legacy code.
26
+#
27
[global]
28
# ebpf load mode = entry
29
# apps = yes
@@ -23,6 +33,8 @@
33
ipv4 connection table size = 16384
34
ipv6 connection table size = 16384
35
udp connection table size = 4096
36
+ ebpf type format = auto
37
+ ebpf co-re tracing = trampoline
38
39
#
40
# Network Connection
collectors/ebpf.plugin/ebpf.h
+1
@@ -244,6 +244,7 @@ extern void ebpf_pid_file(char *filename, size_t length);
244
245
#define EBPF_COMMON_DIMENSION_PERCENTAGE "%"
246
#define EBPF_COMMON_DIMENSION_CALL "calls/s"
247
+#define EBPF_COMMON_DIMENSION_CONNECTIONS "connections/s"
248
#define EBPF_COMMON_DIMENSION_BITS "kilobits/s"
249
#define EBPF_COMMON_DIMENSION_BYTES "bytes/s"
250
#define EBPF_COMMON_DIMENSION_DIFFERENCE "difference"
collectors/ebpf.plugin/ebpf_apps.h
+3
@@ -380,6 +380,9 @@ typedef struct ebpf_bandwidth {
380
uint64_t call_udp_sent; // Number of times udp_sendmsg was called
381
uint64_t call_udp_received; // Number of times udp_recvmsg was called
382
uint64_t close; // Number of times tcp_close was called
383
+ uint64_t drop; // THIS IS NOT USED FOR WHILE, we are in groom section
384
+ uint32_t tcp_v4_connection; // Number of times tcp_v4_connection was called.
385
+ uint32_t tcp_v6_connection; // Number of times tcp_v6_connection was called.
386
} ebpf_bandwidth_t;
387
388
/**
collectors/ebpf.plugin/ebpf_socket.c
+654
-59
@@ -12,9 +12,13 @@
12
*****************************************************************/
13
14
static char *socket_dimension_names[NETDATA_MAX_SOCKET_VECTOR] = { "received", "sent", "close",
15
- "received", "sent", "retransmitted" };
15
+ "received", "sent", "retransmitted",
16
+ "connected_V4", "connected_V6", "connected_tcp",
17
+ "connected_udp"};
18
static char *socket_id_names[NETDATA_MAX_SOCKET_VECTOR] = { "tcp_cleanup_rbuf", "tcp_sendmsg", "tcp_close",
17
- "udp_recvmsg", "udp_sendmsg", "tcp_retransmit_skb" };
19
+ "udp_recvmsg", "udp_sendmsg", "tcp_retransmit_skb",
20
+ "tcp_connect_v4", "tcp_connect_v6", "inet_csk_accept_tcp",
21
+ "inet_csk_accept_udp" };
22
23
static ebpf_local_maps_t socket_maps[] = {{.name = "tbl_bandwidth",
24
.internal_input = NETDATA_COMPILED_CONNECTIONS_ALLOWED,
@@ -77,6 +81,349 @@ struct config socket_config = { .first_section = NULL,
81
.index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare },
82
.rwlock = AVL_LOCK_INITIALIZER } };
83
84
+netdata_ebpf_targets_t socket_targets[] = { {.name = "inet_csk_accept", .mode = EBPF_LOAD_TRAMPOLINE},
85
+ {.name = "tcp_retransmit_skb", .mode = EBPF_LOAD_TRAMPOLINE},
86
+ {.name = "tcp_cleanup_rbuf", .mode = EBPF_LOAD_TRAMPOLINE},
87
+ {.name = "tcp_close", .mode = EBPF_LOAD_TRAMPOLINE},
88
+ {.name = "udp_recvmsg", .mode = EBPF_LOAD_TRAMPOLINE},
89
+ {.name = "tcp_sendmsg", .mode = EBPF_LOAD_TRAMPOLINE},
90
+ {.name = "udp_sendmsg", .mode = EBPF_LOAD_TRAMPOLINE},
91
+ {.name = "tcp_v4_connect", .mode = EBPF_LOAD_TRAMPOLINE},
92
+ {.name = "tcp_v6_connect", .mode = EBPF_LOAD_TRAMPOLINE},
93
+ {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
94
+
95
+#ifdef LIBBPF_MAJOR_VERSION
96
+#include "includes/socket.skel.h" // BTF code
97
+
98
+static struct socket_bpf *bpf_obj = NULL;
99
+
100
+/**
101
+ * Disable Probe
102
+ *
103
+ * Disable probes to use trampoline.
104
+ *
105
+ * @param obj is the main structure for bpf objects.
106
+ */
107
+static void ebpf_socket_disable_probes(struct socket_bpf *obj)
108
+{
109
+ bpf_program__set_autoload(obj->progs.netdata_inet_csk_accept_kretprobe, false);
110
+ bpf_program__set_autoload(obj->progs.netdata_tcp_v4_connect_kretprobe, false);
111
+ bpf_program__set_autoload(obj->progs.netdata_tcp_v6_connect_kretprobe, false);
112
+ bpf_program__set_autoload(obj->progs.netdata_tcp_retransmit_skb_kprobe, false);
113
+ bpf_program__set_autoload(obj->progs.netdata_tcp_cleanup_rbuf_kprobe, false);
114
+ bpf_program__set_autoload(obj->progs.netdata_tcp_close_kprobe, false);
115
+ bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_kprobe, false);
116
+ bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_kretprobe, false);
117
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kretprobe, false);
118
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kprobe, false);
119
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kretprobe, false);
120
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kprobe, false);
121
+ bpf_program__set_autoload(obj->progs.netdata_socket_release_task_kprobe, false);
122
+}
123
+
124
+/**
125
+ * Disable Trampoline
126
+ *
127
+ * Disable trampoline to use probes.
128
+ *
129
+ * @param obj is the main structure for bpf objects.
130
+ */
131
+static void ebpf_socket_disable_trampoline(struct socket_bpf *obj)
132
+{
133
+ bpf_program__set_autoload(obj->progs.netdata_inet_csk_accept_fentry, false);
134
+ bpf_program__set_autoload(obj->progs.netdata_tcp_v4_connect_fexit, false);
135
+ bpf_program__set_autoload(obj->progs.netdata_tcp_v6_connect_fexit, false);
136
+ bpf_program__set_autoload(obj->progs.netdata_tcp_retransmit_skb_fentry, false);
137
+ bpf_program__set_autoload(obj->progs.netdata_tcp_cleanup_rbuf_fentry, false);
138
+ bpf_program__set_autoload(obj->progs.netdata_tcp_close_fentry, false);
139
+ bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_fentry, false);
140
+ bpf_program__set_autoload(obj->progs.netdata_udp_recvmsg_fexit, false);
141
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fentry, false);
142
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fexit, false);
143
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fentry, false);
144
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fexit, false);
145
+ bpf_program__set_autoload(obj->progs.netdata_socket_release_task_fentry, false);
146
+}
147
+
148
+/**
149
+ * Set trampoline target.
150
+ *
151
+ * @param obj is the main structure for bpf objects.
152
+ */
153
+static void ebpf_set_trampoline_target(struct socket_bpf *obj)
154
+{
155
+ bpf_program__set_attach_target(obj->progs.netdata_inet_csk_accept_fentry, 0,
156
+ socket_targets[NETDATA_FCNT_INET_CSK_ACCEPT].name);
157
+
158
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_v4_connect_fexit, 0,
159
+ socket_targets[NETDATA_FCNT_TCP_V4_CONNECT].name);
160
+
161
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_v6_connect_fexit, 0,
162
+ socket_targets[NETDATA_FCNT_TCP_V6_CONNECT].name);
163
+
164
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_retransmit_skb_fentry, 0,
165
+ socket_targets[NETDATA_FCNT_TCP_RETRANSMIT].name);
166
+
167
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_cleanup_rbuf_fentry, 0,
168
+ socket_targets[NETDATA_FCNT_CLEANUP_RBUF].name);
169
+
170
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_close_fentry, 0, socket_targets[NETDATA_FCNT_TCP_CLOSE].name);
171
+
172
+ bpf_program__set_attach_target(obj->progs.netdata_udp_recvmsg_fentry, 0,
173
+ socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name);
174
+
175
+ bpf_program__set_attach_target(obj->progs.netdata_udp_recvmsg_fexit, 0,
176
+ socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name);
177
+
178
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_sendmsg_fentry, 0,
179
+ socket_targets[NETDATA_FCNT_TCP_SENDMSG].name);
180
+
181
+ bpf_program__set_attach_target(obj->progs.netdata_tcp_sendmsg_fexit, 0,
182
+ socket_targets[NETDATA_FCNT_TCP_SENDMSG].name);
183
+
184
+ bpf_program__set_attach_target(obj->progs.netdata_udp_sendmsg_fentry, 0,
185
+ socket_targets[NETDATA_FCNT_UDP_SENDMSG].name);
186
+
187
+ bpf_program__set_attach_target(obj->progs.netdata_udp_sendmsg_fexit, 0,
188
+ socket_targets[NETDATA_FCNT_UDP_SENDMSG].name);
189
+
190
+ bpf_program__set_attach_target(obj->progs.netdata_socket_release_task_fentry, 0, EBPF_COMMON_FNCT_CLEAN_UP);
191
+}
192
+
193
+
194
+/**
195
+ * Disable specific trampoline
196
+ *
197
+ * Disable specific trampoline to match user selection.
198
+ *
199
+ * @param obj is the main structure for bpf objects.
200
+ * @param sel option selected by user.
201
+ */
202
+static inline void ebpf_socket_disable_specific_trampoline(struct socket_bpf *obj, netdata_run_mode_t sel)
203
+{
204
+ if (sel == MODE_RETURN) {
205
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fentry, false);
206
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fentry, false);
207
+ } else {
208
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_fexit, false);
209
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_fexit, false);
210
+ }
211
+}
212
+
213
+/**
214
+ * Disable specific trampoline
215
+ *
216
+ * Disable specific trampoline to match user selection.
217
+ *
218
+ * @param obj is the main structure for bpf objects.
219
+ * @param sel option selected by user.
220
+ */
221
+static inline void ebpf_socket_disable_specific_probe(struct socket_bpf *obj, netdata_run_mode_t sel)
222
+{
223
+ if (sel == MODE_RETURN) {
224
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kprobe, false);
225
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kprobe, false);
226
+ } else {
227
+ bpf_program__set_autoload(obj->progs.netdata_tcp_sendmsg_kretprobe, false);
228
+ bpf_program__set_autoload(obj->progs.netdata_udp_sendmsg_kretprobe, false);
229
+ }
230
+}
231
+
232
+/**
233
+ * Attach probes
234
+ *
235
+ * Attach probes to targets.
236
+ *
237
+ * @param obj is the main structure for bpf objects.
238
+ * @param sel option selected by user.
239
+ */
240
+static int ebpf_socket_attach_probes(struct socket_bpf *obj, netdata_run_mode_t sel)
241
+{
242
+ obj->links.netdata_inet_csk_accept_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_inet_csk_accept_kretprobe,
243
+ true,
244
+ socket_targets[NETDATA_FCNT_INET_CSK_ACCEPT].name);
245
+ int ret = libbpf_get_error(obj->links.netdata_inet_csk_accept_kretprobe);
246
+ if (ret)
247
+ return -1;
248
+
249
+ obj->links.netdata_tcp_v4_connect_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_v4_connect_kretprobe,
250
+ true,
251
+ socket_targets[NETDATA_FCNT_TCP_V4_CONNECT].name);
252
+ ret = libbpf_get_error(obj->links.netdata_tcp_v4_connect_kretprobe);
253
+ if (ret)
254
+ return -1;
255
+
256
+ obj->links.netdata_tcp_v6_connect_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_v6_connect_kretprobe,
257
+ true,
258
+ socket_targets[NETDATA_FCNT_TCP_V6_CONNECT].name);
259
+ ret = libbpf_get_error(obj->links.netdata_tcp_v6_connect_kretprobe);
260
+ if (ret)
261
+ return -1;
262
+
263
+ obj->links.netdata_tcp_retransmit_skb_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_retransmit_skb_kprobe,
264
+ false,
265
+ socket_targets[NETDATA_FCNT_TCP_RETRANSMIT].name);
266
+ ret = libbpf_get_error(obj->links.netdata_tcp_retransmit_skb_kprobe);
267
+ if (ret)
268
+ return -1;
269
+
270
+ obj->links.netdata_tcp_cleanup_rbuf_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_cleanup_rbuf_kprobe,
271
+ false,
272
+ socket_targets[NETDATA_FCNT_CLEANUP_RBUF].name);
273
+ ret = libbpf_get_error(obj->links.netdata_tcp_cleanup_rbuf_kprobe);
274
+ if (ret)
275
+ return -1;
276
+
277
+ obj->links.netdata_tcp_close_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_close_kprobe,
278
+ false,
279
+ socket_targets[NETDATA_FCNT_TCP_CLOSE].name);
280
+ ret = libbpf_get_error(obj->links.netdata_tcp_close_kprobe);
281
+ if (ret)
282
+ return -1;
283
+
284
+ obj->links.netdata_udp_recvmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_recvmsg_kprobe,
285
+ false,
286
+ socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name);
287
+ ret = libbpf_get_error(obj->links.netdata_udp_recvmsg_kprobe);
288
+ if (ret)
289
+ return -1;
290
+
291
+ obj->links.netdata_udp_recvmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_recvmsg_kretprobe,
292
+ true,
293
+ socket_targets[NETDATA_FCNT_UDP_RECEVMSG].name);
294
+ ret = libbpf_get_error(obj->links.netdata_udp_recvmsg_kretprobe);
295
+ if (ret)
296
+ return -1;
297
+
298
+ if (sel == MODE_RETURN) {
299
+ obj->links.netdata_tcp_sendmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_sendmsg_kretprobe,
300
+ true,
301
+ socket_targets[NETDATA_FCNT_TCP_SENDMSG].name);
302
+ ret = libbpf_get_error(obj->links.netdata_tcp_sendmsg_kretprobe);
303
+ if (ret)
304
+ return -1;
305
+
306
+ obj->links.netdata_udp_sendmsg_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_sendmsg_kretprobe,
307
+ true,
308
+ socket_targets[NETDATA_FCNT_UDP_SENDMSG].name);
309
+ ret = libbpf_get_error(obj->links.netdata_udp_sendmsg_kretprobe);
310
+ if (ret)
311
+ return -1;
312
+ } else {
313
+ obj->links.netdata_tcp_sendmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_tcp_sendmsg_kprobe,
314
+ false,
315
+ socket_targets[NETDATA_FCNT_TCP_SENDMSG].name);
316
+ ret = libbpf_get_error(obj->links.netdata_tcp_sendmsg_kprobe);
317
+ if (ret)
318
+ return -1;
319
+
320
+ obj->links.netdata_udp_sendmsg_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_udp_sendmsg_kprobe,
321
+ false,
322
+ socket_targets[NETDATA_FCNT_UDP_SENDMSG].name);
323
+ ret = libbpf_get_error(obj->links.netdata_udp_sendmsg_kprobe);
324
+ if (ret)
325
+ return -1;
326
+ }
327
+
328
+ obj->links.netdata_socket_release_task_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_socket_release_task_kprobe,
329
+ false, EBPF_COMMON_FNCT_CLEAN_UP);
330
+ ret = libbpf_get_error(obj->links.netdata_socket_release_task_kprobe);
331
+ if (ret)
332
+ return -1;
333
+
334
+ return 0;
335
+}
336
+
337
+/**
338
+ * Set hash tables
339
+ *
340
+ * Set the values for maps according the value given by kernel.
341
+ *
342
+ * @param obj is the main structure for bpf objects.
343
+ */
344
+static void ebpf_socket_set_hash_tables(struct socket_bpf *obj)
345
+{
346
+ socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH].map_fd = bpf_map__fd(obj->maps.tbl_bandwidth);
347
+ socket_maps[NETDATA_SOCKET_GLOBAL].map_fd = bpf_map__fd(obj->maps.tbl_global_sock);
348
+ socket_maps[NETDATA_SOCKET_LPORTS].map_fd = bpf_map__fd(obj->maps.tbl_lports);
349
+ socket_maps[NETDATA_SOCKET_TABLE_IPV4].map_fd = bpf_map__fd(obj->maps.tbl_conn_ipv4);
350
+ socket_maps[NETDATA_SOCKET_TABLE_IPV6].map_fd = bpf_map__fd(obj->maps.tbl_conn_ipv6);
351
+ socket_maps[NETDATA_SOCKET_TABLE_UDP].map_fd = bpf_map__fd(obj->maps.tbl_nv_udp);
352
+ socket_maps[NETDATA_SOCKET_TABLE_CTRL].map_fd = bpf_map__fd(obj->maps.socket_ctrl);
353
+}
354
+
355
+/**
356
+ * Adjust Map Size
357
+ *
358
+ * Resize maps according input from users.
359
+ *
360
+ * @param obj is the main structure for bpf objects.
361
+ * @param em structure with configuration
362
+ */
363
+static void ebpf_socket_adjust_map_size(struct socket_bpf *obj, ebpf_module_t *em)
364
+{
365
+ ebpf_update_map_size(obj->maps.tbl_bandwidth, &socket_maps[NETDATA_SOCKET_TABLE_BANDWIDTH],
366
+ em, bpf_map__name(obj->maps.tbl_bandwidth));
367
+
368
+ ebpf_update_map_size(obj->maps.tbl_conn_ipv4, &socket_maps[NETDATA_SOCKET_TABLE_IPV4],
369
+ em, bpf_map__name(obj->maps.tbl_conn_ipv4));
370
+
371
+ ebpf_update_map_size(obj->maps.tbl_conn_ipv6, &socket_maps[NETDATA_SOCKET_TABLE_IPV6],
372
+ em, bpf_map__name(obj->maps.tbl_conn_ipv6));
373
+
374
+ ebpf_update_map_size(obj->maps.tbl_nv_udp, &socket_maps[NETDATA_SOCKET_TABLE_UDP],
375
+ em, bpf_map__name(obj->maps.tbl_nv_udp));
376
+}
377
+
378
+/**
379
+ * Load and attach
380
+ *
381
+ * Load and attach the eBPF code in kernel.
382
+ *
383
+ * @param obj is the main structure for bpf objects.
384
+ * @param em structure with configuration
385
+ *
386
+ * @return it returns 0 on succes and -1 otherwise
387
+ */
388
+static inline int ebpf_socket_load_and_attach(struct socket_bpf *obj, ebpf_module_t *em)
389
+{
390
+ netdata_ebpf_targets_t *mt = em->targets;
391
+ netdata_ebpf_program_loaded_t test = mt[NETDATA_FCNT_INET_CSK_ACCEPT].mode;
392
+
393
+ if (test == EBPF_LOAD_TRAMPOLINE) {
394
+ ebpf_socket_disable_probes(obj);
395
+
396
+ ebpf_set_trampoline_target(obj);
397
+ ebpf_socket_disable_specific_trampoline(obj, em->mode);
398
+ } else { // We are not using tracepoints for this thread.
399
+ ebpf_socket_disable_trampoline(obj);
400
+
401
+ ebpf_socket_disable_specific_probe(obj, em->mode);
402
+ }
403
+
404
+ int ret = socket_bpf__load(obj);
405
+ if (ret) {
406
+ fprintf(stderr, "failed to load BPF object: %d\n", ret);
407
+ return ret;
408
+ }
409
+
410
+ ebpf_socket_adjust_map_size(obj, em);
411
+
412
+ if (test == EBPF_LOAD_TRAMPOLINE) {
413
+ ret = socket_bpf__attach(obj);
414
+ } else {
415
+ ret = ebpf_socket_attach_probes(obj, em->mode);
416
+ }
417
+
418
+ if (!ret) {
419
+ ebpf_socket_set_hash_tables(obj);
420
+
421
+ ebpf_update_controller(socket_maps[NETDATA_SOCKET_TABLE_CTRL].map_fd, em);
422
+ }
423
+
424
+ return ret;
425
+}
426
+#endif
427
/*****************************************************************
428
*
429
* PROCESS DATA AND SEND TO NETDATA
@@ -293,6 +640,31 @@ static void ebpf_socket_send_nv_data(netdata_vector_plot_t *ptr)
640
}
641
}
642
643
+/**
644
+ * Send Global Inbound connection
645
+ *
646
+ * Send number of connections read per protocol.
647
+ */
648
+static void ebpf_socket_send_global_inbound_conn()
649
+{
650
+ uint64_t udp_conn = 0;
651
+ uint64_t tcp_conn = 0;
652
+ ebpf_network_viewer_port_list_t *move = listen_ports;
653
+ while (move) {
654
+ if (move->protocol == IPPROTO_TCP)
655
+ tcp_conn += move->connections;
656
+ else
657
+ udp_conn += move->connections;
658
+
659
+ move = move->next;
660
+ }
661
+
662
+ write_begin_chart(NETDATA_EBPF_IP_FAMILY, NETDATA_INBOUND_CONNECTIONS);
663
+ write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_TCP].name, (long long) tcp_conn);
664
+ write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_UDP].name, (long long) udp_conn);
665
+ write_end_chart();
666
+}
667
+
668
/**
669
* Send data to Netdata calling auxiliary functions.
670
*
@@ -304,6 +676,10 @@ static void ebpf_socket_send_data(ebpf_module_t *em)
676
netdata_publish_vfs_common_t common_udp;
677
ebpf_update_global_publish(socket_publish_aggregated, &common_tcp, &common_udp, socket_aggregated_data);
678
679
+ ebpf_socket_send_global_inbound_conn();
680
+ write_count_chart(NETDATA_TCP_OUTBOUND_CONNECTIONS, NETDATA_EBPF_IP_FAMILY,
681
+ &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4], 2);
682
+
683
// We read bytes from function arguments, but bandwidth is given in bits,
684
// so we need to multiply by 8 to convert for the final value.
685
write_count_chart(NETDATA_TCP_FUNCTION_COUNT, NETDATA_EBPF_IP_FAMILY, socket_publish_aggregated, 3);
@@ -367,6 +743,26 @@ void ebpf_socket_send_apps_data(ebpf_module_t *em, struct target *root)
743
struct target *w;
744
collected_number value;
745
746
+ write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V4);
747
+ for (w = root; w; w = w->next) {
748
+ if (unlikely(w->exposed && w->processes)) {
749
+ value = ebpf_socket_sum_values_for_pids(w->root_pid, offsetof(ebpf_socket_publish_apps_t,
750
+ call_tcp_v4_connection));
751
+ write_chart_dimension(w->name, value);
752
+ }
753
+ }
754
+ write_end_chart();
755
+
756
+ write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V6);
757
+ for (w = root; w; w = w->next) {
758
+ if (unlikely(w->exposed && w->processes)) {
759
+ value = ebpf_socket_sum_values_for_pids(w->root_pid, offsetof(ebpf_socket_publish_apps_t,
760
+ call_tcp_v6_connection));
761
+ write_chart_dimension(w->name, value);
762
+ }
763
+ }
764
+ write_end_chart();
765
+
766
write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_NET_APPS_BANDWIDTH_SENT);
767
for (w = root; w; w = w->next) {
768
if (unlikely(w->exposed && w->processes)) {
@@ -456,6 +852,32 @@ void ebpf_socket_send_apps_data(ebpf_module_t *em, struct target *root)
852
*/
853
static void ebpf_create_global_charts(ebpf_module_t *em)
854
{
855
+ int order = 21070;
856
+ ebpf_create_chart(NETDATA_EBPF_IP_FAMILY,
857
+ NETDATA_INBOUND_CONNECTIONS,
858
+ "Inbound connections.",
859
+ EBPF_COMMON_DIMENSION_CONNECTIONS,
860
+ NETDATA_SOCKET_KERNEL_FUNCTIONS,
861
+ NULL,
862
+ NETDATA_EBPF_CHART_TYPE_LINE,
863
+ order++,
864
+ ebpf_create_global_dimension,
865
+ &socket_publish_aggregated[NETDATA_IDX_INCOMING_CONNECTION_TCP],
866
+ 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
867
+
868
+ ebpf_create_chart(NETDATA_EBPF_IP_FAMILY,
869
+ NETDATA_TCP_OUTBOUND_CONNECTIONS,
870
+ "TCP outbound connections.",
871
+ EBPF_COMMON_DIMENSION_CONNECTIONS,
872
+ NETDATA_SOCKET_KERNEL_FUNCTIONS,
873
+ NULL,
874
+ NETDATA_EBPF_CHART_TYPE_LINE,
875
+ order++,
876
+ ebpf_create_global_dimension,
877
+ &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4],
878
+ 2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
879
+
880
+
881
ebpf_create_chart(NETDATA_EBPF_IP_FAMILY,
882
NETDATA_TCP_FUNCTION_COUNT,
883
"Calls to internal functions",
@@ -463,7 +885,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
885
NETDATA_SOCKET_KERNEL_FUNCTIONS,
886
NULL,
887
NETDATA_EBPF_CHART_TYPE_LINE,
466
- 21070,
888
+ order++,
889
ebpf_create_global_dimension,
890
socket_publish_aggregated,
891
3, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -473,7 +895,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
895
NETDATA_SOCKET_KERNEL_FUNCTIONS,
896
NULL,
897
NETDATA_EBPF_CHART_TYPE_LINE,
476
- 21071,
898
+ order++,
899
ebpf_create_global_dimension,
900
socket_publish_aggregated,
901
2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -486,7 +908,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
908
NETDATA_SOCKET_KERNEL_FUNCTIONS,
909
NULL,
910
NETDATA_EBPF_CHART_TYPE_LINE,
489
- 21072,
911
+ order++,
912
ebpf_create_global_dimension,
913
socket_publish_aggregated,
914
2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -499,7 +921,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
921
NETDATA_SOCKET_KERNEL_FUNCTIONS,
922
NULL,
923
NETDATA_EBPF_CHART_TYPE_LINE,
502
- 21073,
924
+ order++,
925
ebpf_create_global_dimension,
926
&socket_publish_aggregated[NETDATA_IDX_TCP_RETRANSMIT],
927
1, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -511,7 +933,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
933
NETDATA_SOCKET_KERNEL_FUNCTIONS,
934
NULL,
935
NETDATA_EBPF_CHART_TYPE_LINE,
514
- 21074,
936
+ order++,
937
ebpf_create_global_dimension,
938
&socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF],
939
2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -521,7 +943,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
943
NETDATA_SOCKET_KERNEL_FUNCTIONS,
944
NULL,
945
NETDATA_EBPF_CHART_TYPE_LINE,
524
- 21075,
946
+ order++,
947
ebpf_create_global_dimension,
948
&socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF],
949
2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -534,7 +956,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
956
NETDATA_SOCKET_KERNEL_FUNCTIONS,
957
NULL,
958
NETDATA_EBPF_CHART_TYPE_LINE,
537
- 21076,
959
+ order++,
960
ebpf_create_global_dimension,
961
&socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF],
962
2, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
@@ -551,12 +973,29 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
973
*/
974
void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
975
{
554
- struct target *root = ptr;;
976
+ struct target *root = ptr;
977
+ int order = 20080;
978
+ ebpf_create_charts_on_apps(NETDATA_NET_APPS_CONNECTION_TCP_V4,
979
+ "Calls to tcp_v4_connection", EBPF_COMMON_DIMENSION_CONNECTIONS,
980
+ NETDATA_APPS_NET_GROUP,
981
+ NETDATA_EBPF_CHART_TYPE_STACKED,
982
+ order++,
983
+ ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
984
+ root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
985
+
986
+ ebpf_create_charts_on_apps(NETDATA_NET_APPS_CONNECTION_TCP_V6,
987
+ "Calls to tcp_v6_connection", EBPF_COMMON_DIMENSION_CONNECTIONS,
988
+ NETDATA_APPS_NET_GROUP,
989
+ NETDATA_EBPF_CHART_TYPE_STACKED,
990
+ order++,
991
+ ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
992
+ root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
993
+
994
ebpf_create_charts_on_apps(NETDATA_NET_APPS_BANDWIDTH_SENT,
995
"Bytes sent", EBPF_COMMON_DIMENSION_BITS,
996
NETDATA_APPS_NET_GROUP,
997
NETDATA_EBPF_CHART_TYPE_STACKED,
559
- 20080,
998
+ order++,
999
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1000
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1001
@@ -564,7 +1003,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1003
"bytes received", EBPF_COMMON_DIMENSION_BITS,
1004
NETDATA_APPS_NET_GROUP,
1005
NETDATA_EBPF_CHART_TYPE_STACKED,
567
- 20081,
1006
+ order++,
1007
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1008
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1009
@@ -573,7 +1012,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1012
EBPF_COMMON_DIMENSION_CALL,
1013
NETDATA_APPS_NET_GROUP,
1014
NETDATA_EBPF_CHART_TYPE_STACKED,
576
- 20082,
1015
+ order++,
1016
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1017
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1018
@@ -582,7 +1021,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1021
EBPF_COMMON_DIMENSION_CALL,
1022
NETDATA_APPS_NET_GROUP,
1023
NETDATA_EBPF_CHART_TYPE_STACKED,
585
- 20083,
1024
+ order++,
1025
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1026
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1027
@@ -591,7 +1030,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1030
EBPF_COMMON_DIMENSION_CALL,
1031
NETDATA_APPS_NET_GROUP,
1032
NETDATA_EBPF_CHART_TYPE_STACKED,
594
- 20084,
1033
+ order++,
1034
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1035
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1036
@@ -600,7 +1039,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1039
EBPF_COMMON_DIMENSION_CALL,
1040
NETDATA_APPS_NET_GROUP,
1041
NETDATA_EBPF_CHART_TYPE_STACKED,
603
- 20085,
1042
+ order++,
1043
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1044
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1045
@@ -609,7 +1048,7 @@ void ebpf_socket_create_apps_charts(struct ebpf_module *em, void *ptr)
1048
EBPF_COMMON_DIMENSION_CALL,
1049
NETDATA_APPS_NET_GROUP,
1050
NETDATA_EBPF_CHART_TYPE_STACKED,
612
- 20086,
1051
+ order++,
1052
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
1053
root, em->update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
1054
@@ -1386,6 +1825,26 @@ static void read_socket_hash_table(int fd, int family, int network_connection)
1825
}
1826
}
1827
1828
+/**
1829
+ * Fill Network Viewer Port list
1830
+ *
1831
+ * Fill the strcture with values read from /proc or hash table.
1832
+ *
1833
+ * @param out the structure where we will store data.
1834
+ * @param value the ports we are listen to.
1835
+ * @param proto the protocol used for this connection.
1836
+ * @param in the strcuture with values read form different sources.
1837
+ */
1838
+static inline void fill_nv_port_list(ebpf_network_viewer_port_list_t *out, uint16_t value, uint16_t proto,
1839
+ netdata_passive_connection_t *in)
1840
+{
1841
+ out->first = value;
1842
+ out->protocol = proto;
1843
+ out->pid = in->pid;
1844
+ out->tgid = in->tgid;
1845
+ out->connections = in->counter;
1846
+}
1847
+
1848
/**
1849
* Update listen table
1850
*
@@ -1393,31 +1852,33 @@ static void read_socket_hash_table(int fd, int family, int network_connection)
1852
*
1853
* @param value the ports we are listen to.
1854
* @param proto the protocol used with port connection.
1855
+ * @param in the strcuture with values read form different sources.
1856
*/
1397
-void update_listen_table(uint16_t value, uint8_t proto)
1857
+void update_listen_table(uint16_t value, uint16_t proto, netdata_passive_connection_t *in)
1858
{
1859
ebpf_network_viewer_port_list_t *w;
1860
if (likely(listen_ports)) {
1861
ebpf_network_viewer_port_list_t *move = listen_ports, *store = listen_ports;
1862
while (move) {
1403
- if (move->protocol == proto && move->first == value)
1863
+ if (move->protocol == proto && move->first == value) {
1864
+ move->pid = in->pid;
1865
+ move->tgid = in->tgid;
1866
+ move->connections = in->counter;
1867
return;
1868
+ }
1869
1870
store = move;
1871
move = move->next;
1872
}
1873
1874
w = callocz(1, sizeof(ebpf_network_viewer_port_list_t));
1411
- w->first = value;
1412
- w->protocol = proto;
1875
store->next = w;
1876
} else {
1877
w = callocz(1, sizeof(ebpf_network_viewer_port_list_t));
1416
- w->first = value;
1417
- w->protocol = proto;
1878
1879
listen_ports = w;
1880
}
1881
+ fill_nv_port_list(w, value, proto, in);
1882
1883
#ifdef NETDATA_INTERNAL_CHECKS
1884
info("The network viewer is monitoring inbound connections for port %u", ntohs(value));
@@ -1431,11 +1892,11 @@ void update_listen_table(uint16_t value, uint8_t proto)
1892
*/
1893
static void read_listen_table()
1894
{
1434
- uint16_t key = 0;
1435
- uint16_t next_key = 0;
1895
+ netdata_passive_connection_idx_t key = {};
1896
+ netdata_passive_connection_idx_t next_key = {};
1897
1898
int fd = socket_maps[NETDATA_SOCKET_LPORTS].map_fd;
1438
- uint8_t value;
1899
+ netdata_passive_connection_t value = {};
1900
while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
1901
int test = bpf_map_lookup_elem(fd, &key, &value);
1902
if (test < 0) {
@@ -1444,14 +1905,15 @@ static void read_listen_table()
1905
}
1906
1907
// The correct protocol must come from kernel
1447
- update_listen_table(htons(key), (key == 53)?IPPROTO_UDP:IPPROTO_TCP);
1908
+ update_listen_table(key.port, key.protocol, &value);
1909
1910
key = next_key;
1911
+ memset(&value, 0, sizeof(value));
1912
}
1913
1452
- if (next_key) {
1914
+ if (next_key.port && value.pid) {
1915
// The correct protocol must come from kernel
1454
- update_listen_table(htons(next_key), (key == 53)?IPPROTO_UDP:IPPROTO_TCP);
1916
+ update_listen_table(next_key.port, next_key.protocol, &value);
1917
}
1918
}
1919
@@ -1522,11 +1984,15 @@ static void read_hash_global_tables()
1984
socket_aggregated_data[NETDATA_IDX_UDP_RECVBUF].call = res[NETDATA_KEY_CALLS_UDP_RECVMSG];
1985
socket_aggregated_data[NETDATA_IDX_UDP_SENDMSG].call = res[NETDATA_KEY_CALLS_UDP_SENDMSG];
1986
socket_aggregated_data[NETDATA_IDX_TCP_RETRANSMIT].call = res[NETDATA_KEY_TCP_RETRANSMIT];
1987
+ socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V4].call = res[NETDATA_KEY_CALLS_TCP_CONNECT_IPV4];
1988
+ socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V6].call = res[NETDATA_KEY_CALLS_TCP_CONNECT_IPV6];
1989
1990
socket_aggregated_data[NETDATA_IDX_TCP_SENDMSG].ecall = res[NETDATA_KEY_ERROR_TCP_SENDMSG];
1991
socket_aggregated_data[NETDATA_IDX_TCP_CLEANUP_RBUF].ecall = res[NETDATA_KEY_ERROR_TCP_CLEANUP_RBUF];
1992
socket_aggregated_data[NETDATA_IDX_UDP_RECVBUF].ecall = res[NETDATA_KEY_ERROR_UDP_RECVMSG];
1993
socket_aggregated_data[NETDATA_IDX_UDP_SENDMSG].ecall = res[NETDATA_KEY_ERROR_UDP_SENDMSG];
1994
+ socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V4].ecall = res[NETDATA_KEY_ERROR_TCP_CONNECT_IPV4];
1995
+ socket_aggregated_data[NETDATA_IDX_TCP_CONNECTION_V6].ecall = res[NETDATA_KEY_ERROR_TCP_CONNECT_IPV6];
1996
1997
socket_aggregated_data[NETDATA_IDX_TCP_SENDMSG].bytes = res[NETDATA_KEY_BYTES_TCP_SENDMSG];
1998
socket_aggregated_data[NETDATA_IDX_TCP_CLEANUP_RBUF].bytes = res[NETDATA_KEY_BYTES_TCP_CLEANUP_RBUF];
@@ -1556,6 +2022,8 @@ void ebpf_socket_fill_publish_apps(uint32_t current_pid, ebpf_bandwidth_t *eb)
2022
curr->call_udp_sent = eb->call_udp_sent;
2023
curr->call_udp_received = eb->call_udp_received;
2024
curr->call_close = eb->close;
2025
+ curr->call_tcp_v4_connection = eb->tcp_v4_connection;
2026
+ curr->call_tcp_v6_connection = eb->tcp_v6_connection;
2027
}
2028
2029
/**
@@ -1577,6 +2045,8 @@ void ebpf_socket_bandwidth_accumulator(ebpf_bandwidth_t *out)
2045
total->call_udp_sent += move->call_udp_sent;
2046
total->call_udp_received += move->call_udp_received;
2047
total->close += move->close;
2048
+ total->tcp_v4_connection += move->tcp_v4_connection;
2049
+ total->tcp_v6_connection += move->tcp_v6_connection;
2050
}
2051
}
2052
@@ -1635,6 +2105,8 @@ static void ebpf_update_socket_cgroup()
2105
publish->call_udp_sent = in->call_udp_sent;
2106
publish->call_udp_received = in->call_udp_received;
2107
publish->call_close = in->call_close;
2108
+ publish->call_tcp_v4_connection = in->call_tcp_v4_connection;
2109
+ publish->call_tcp_v6_connection = in->call_tcp_v6_connection;
2110
} else {
2111
if (!bpf_map_lookup_elem(fd, &pid, eb)) {
2112
ebpf_socket_bandwidth_accumulator(eb);
@@ -1649,6 +2121,8 @@ static void ebpf_update_socket_cgroup()
2121
publish->call_udp_sent = out->call_udp_sent;
2122
publish->call_udp_received = out->call_udp_received;
2123
publish->call_close = out->close;
2124
+ publish->call_tcp_v4_connection = out->tcp_v4_connection;
2125
+ publish->call_tcp_v6_connection = out->tcp_v6_connection;
2126
}
2127
}
2128
}
@@ -1680,6 +2154,8 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru
2154
accumulator.call_udp_received += w->call_udp_received;
2155
accumulator.call_udp_sent += w->call_udp_sent;
2156
accumulator.call_close += w->close;
2157
+ accumulator.call_tcp_v4_connection += w->tcp_v4_connection;
2158
+ accumulator.call_tcp_v6_connection += w->tcp_v6_connection;
2159
2160
pids = pids->next;
2161
}
@@ -1692,6 +2168,10 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru
2168
socket->call_udp_sent = (accumulator.call_udp_sent >= socket->call_udp_sent) ? accumulator.call_udp_sent : socket->call_udp_sent;
2169
socket->call_udp_received = (accumulator.call_udp_received >= socket->call_udp_received) ? accumulator.call_udp_received : socket->call_udp_received;
2170
socket->call_close = (accumulator.call_close >= socket->call_close) ? accumulator.call_close : socket->call_close;
2171
+ socket->call_tcp_v4_connection = (accumulator.call_tcp_v4_connection >= socket->call_tcp_v4_connection) ?
2172
+ accumulator.call_tcp_v4_connection : socket->call_tcp_v4_connection;
2173
+ socket->call_tcp_v6_connection = (accumulator.call_tcp_v6_connection >= socket->call_tcp_v6_connection) ?
2174
+ accumulator.call_tcp_v6_connection : socket->call_tcp_v6_connection;
2175
}
2176
2177
/**
@@ -1704,75 +2184,96 @@ static void ebpf_socket_sum_cgroup_pids(ebpf_socket_publish_apps_t *socket, stru
2184
*/
2185
static void ebpf_create_specific_socket_charts(char *type, int update_every)
2186
{
2187
+ int order_basis = 5300;
2188
+ ebpf_create_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V4,
2189
+ "Calls to tcp_v4_connection",
2190
+ EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_CGROUP_NET_GROUP,
2191
+ NETDATA_CGROUP_TCP_V4_CONN_CONTEXT,
2192
+ NETDATA_EBPF_CHART_TYPE_LINE,
2193
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2194
+ ebpf_create_global_dimension,
2195
+ &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4], 1,
2196
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2197
+
2198
+ ebpf_create_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V6,
2199
+ "Calls to tcp_v6_connection",
2200
+ EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_CGROUP_NET_GROUP,
2201
+ NETDATA_CGROUP_TCP_V6_CONN_CONTEXT,
2202
+ NETDATA_EBPF_CHART_TYPE_LINE,
2203
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2204
+ ebpf_create_global_dimension,
2205
+ &socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V6], 1,
2206
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2207
+
2208
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_RECV,
2209
"Bytes received",
2210
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2211
NETDATA_CGROUP_SOCKET_BYTES_RECV_CONTEXT,
2212
NETDATA_EBPF_CHART_TYPE_LINE,
1712
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5300,
2213
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2214
ebpf_create_global_dimension,
2215
&socket_publish_aggregated[NETDATA_IDX_TCP_CLEANUP_RBUF], 1,
1715
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2216
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2217
2218
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_SENT,
2219
"Bytes sent",
2220
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2221
NETDATA_CGROUP_SOCKET_BYTES_SEND_CONTEXT,
2222
NETDATA_EBPF_CHART_TYPE_LINE,
1722
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5301,
2223
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2224
ebpf_create_global_dimension,
2225
socket_publish_aggregated, 1,
1725
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2226
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2227
2228
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RECV_CALLS,
2229
"Calls to tcp_cleanup_rbuf.",
2230
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2231
NETDATA_CGROUP_SOCKET_TCP_RECV_CONTEXT,
2232
NETDATA_EBPF_CHART_TYPE_LINE,
1732
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5302,
2233
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2234
ebpf_create_global_dimension,
2235
&socket_publish_aggregated[NETDATA_IDX_TCP_CLEANUP_RBUF], 1,
1735
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2236
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2237
2238
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS,
2239
"Calls to tcp_sendmsg.",
2240
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2241
NETDATA_CGROUP_SOCKET_TCP_SEND_CONTEXT,
2242
NETDATA_EBPF_CHART_TYPE_LINE,
1742
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5303,
2243
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2244
ebpf_create_global_dimension,
2245
socket_publish_aggregated, 1,
1745
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2246
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2247
2248
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RETRANSMIT,
2249
"Calls to tcp_retransmit.",
2250
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2251
NETDATA_CGROUP_SOCKET_TCP_RETRANSMIT_CONTEXT,
2252
NETDATA_EBPF_CHART_TYPE_LINE,
1752
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5304,
2253
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2254
ebpf_create_global_dimension,
2255
&socket_publish_aggregated[NETDATA_IDX_TCP_RETRANSMIT], 1,
1755
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2256
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2257
2258
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_UDP_SEND_CALLS,
2259
"Calls to udp_sendmsg",
2260
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2261
NETDATA_CGROUP_SOCKET_UDP_SEND_CONTEXT,
2262
NETDATA_EBPF_CHART_TYPE_LINE,
1762
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5305,
2263
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2264
ebpf_create_global_dimension,
2265
&socket_publish_aggregated[NETDATA_IDX_UDP_SENDMSG], 1,
1765
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2266
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2267
2268
ebpf_create_chart(type, NETDATA_NET_APPS_BANDWIDTH_UDP_RECV_CALLS,
2269
"Calls to udp_recvmsg",
2270
EBPF_COMMON_DIMENSION_CALL, NETDATA_CGROUP_NET_GROUP,
2271
NETDATA_CGROUP_SOCKET_UDP_RECV_CONTEXT,
2272
NETDATA_EBPF_CHART_TYPE_LINE,
1772
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5306,
2273
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++,
2274
ebpf_create_global_dimension,
2275
&socket_publish_aggregated[NETDATA_IDX_UDP_RECVBUF], 1,
1775
- update_every, NETDATA_EBPF_MODULE_NAME_SWAP);
2276
+ update_every, NETDATA_EBPF_MODULE_NAME_SOCKET);
2277
}
2278
2279
/**
@@ -1785,40 +2286,51 @@ static void ebpf_create_specific_socket_charts(char *type, int update_every)
2286
*/
2287
static void ebpf_obsolete_specific_socket_charts(char *type, int update_every)
2288
{
2289
+ int order_basis = 5300;
2290
+ ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_CONNECTION_TCP_V4, "Calls to tcp_v4_connection",
2291
+ EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_APPS_NET_GROUP,
2292
+ NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT,
2293
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2294
+
2295
+ ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_CONNECTION_TCP_V6,"Calls to tcp_v6_connection",
2296
+ EBPF_COMMON_DIMENSION_CONNECTIONS, NETDATA_APPS_NET_GROUP,
2297
+ NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT,
2298
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2299
+
2300
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_RECV, "Bytes received",
2301
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2302
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT,
1791
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5300, update_every);
2303
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2304
2305
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_SENT,"Bytes sent",
2306
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2307
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT,
1796
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5301, update_every);
2308
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2309
2310
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RECV_CALLS, "Calls to tcp_cleanup_rbuf.",
2311
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2312
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT,
1801
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5302, update_every);
2313
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2314
2315
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS, "Calls to tcp_sendmsg.",
2316
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2317
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_SEND_CONTEXT,
1806
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5303, update_every);
2318
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2319
2320
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_TCP_RETRANSMIT, "Calls to tcp_retransmit.",
2321
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2322
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_TCP_RETRANSMIT_CONTEXT,
1811
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5304, update_every);
2323
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2324
2325
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_UDP_SEND_CALLS, "Calls to udp_sendmsg",
2326
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP,
2327
NETDATA_EBPF_CHART_TYPE_LINE, NETDATA_SERVICES_SOCKET_UDP_SEND_CONTEXT,
1816
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5305, update_every);
2328
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2329
2330
ebpf_write_chart_obsolete(type, NETDATA_NET_APPS_BANDWIDTH_UDP_RECV_CALLS, "Calls to udp_recvmsg",
2331
EBPF_COMMON_DIMENSION_CALL, NETDATA_APPS_NET_GROUP, NETDATA_EBPF_CHART_TYPE_LINE,
2332
NETDATA_SERVICES_SOCKET_UDP_RECV_CONTEXT,
1821
- NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + 5306, update_every);
2333
+ NETDATA_CHART_PRIO_CGROUPS_CONTAINERS + order_basis++, update_every);
2334
}
2335
2336
/*
@@ -1831,6 +2343,16 @@ static void ebpf_obsolete_specific_socket_charts(char *type, int update_every)
2343
*/
2344
static void ebpf_send_specific_socket_data(char *type, ebpf_socket_publish_apps_t *values)
2345
{
2346
+ write_begin_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V4);
2347
+ write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V4].name,
2348
+ (long long) values->call_tcp_v4_connection);
2349
+ write_end_chart();
2350
+
2351
+ write_begin_chart(type, NETDATA_NET_APPS_CONNECTION_TCP_V6);
2352
+ write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_CONNECTION_V6].name,
2353
+ (long long) values->call_tcp_v6_connection);
2354
+ write_end_chart();
2355
+
2356
write_begin_chart(type, NETDATA_NET_APPS_BANDWIDTH_SENT);
2357
write_chart_dimension(socket_publish_aggregated[NETDATA_IDX_TCP_SENDMSG].name,
2358
(long long) values->bytes_sent);
@@ -1876,11 +2398,30 @@ static void ebpf_send_specific_socket_data(char *type, ebpf_socket_publish_apps_
2398
**/
2399
static void ebpf_create_systemd_socket_charts(int update_every)
2400
{
2401
+ int order = 20080;
2402
+ ebpf_create_charts_on_systemd(NETDATA_NET_APPS_CONNECTION_TCP_V4,
2403
+ "Calls to tcp_v4_connection", EBPF_COMMON_DIMENSION_CONNECTIONS,
2404
+ NETDATA_APPS_NET_GROUP,
2405
+ NETDATA_EBPF_CHART_TYPE_STACKED,
2406
+ order++,
2407
+ ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2408
+ NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2409
+ update_every);
2410
+
2411
+ ebpf_create_charts_on_systemd(NETDATA_NET_APPS_CONNECTION_TCP_V6,
2412
+ "Calls to tcp_v6_connection", EBPF_COMMON_DIMENSION_CONNECTIONS,
2413
+ NETDATA_APPS_NET_GROUP,
2414
+ NETDATA_EBPF_CHART_TYPE_STACKED,
2415
+ order++,
2416
+ ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2417
+ NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2418
+ update_every);
2419
+
2420
ebpf_create_charts_on_systemd(NETDATA_NET_APPS_BANDWIDTH_RECV,
2421
"Bytes received", EBPF_COMMON_DIMENSION_BITS,
2422
NETDATA_APPS_NET_GROUP,
2423
NETDATA_EBPF_CHART_TYPE_STACKED,
1883
- 20080,
2424
+ order++,
2425
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2426
NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2427
update_every);
@@ -1889,7 +2430,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2430
"Bytes sent", EBPF_COMMON_DIMENSION_BITS,
2431
NETDATA_APPS_NET_GROUP,
2432
NETDATA_EBPF_CHART_TYPE_STACKED,
1892
- 20081,
2433
+ order++,
2434
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2435
NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2436
update_every);
@@ -1899,7 +2440,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2440
EBPF_COMMON_DIMENSION_CALL,
2441
NETDATA_APPS_NET_GROUP,
2442
NETDATA_EBPF_CHART_TYPE_STACKED,
1902
- 20082,
2443
+ order++,
2444
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2445
NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2446
update_every);
@@ -1909,7 +2450,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2450
EBPF_COMMON_DIMENSION_CALL,
2451
NETDATA_APPS_NET_GROUP,
2452
NETDATA_EBPF_CHART_TYPE_STACKED,
1912
- 20083,
2453
+ order++,
2454
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2455
NETDATA_SERVICES_SOCKET_TCP_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2456
update_every);
@@ -1919,7 +2460,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2460
EBPF_COMMON_DIMENSION_CALL,
2461
NETDATA_APPS_NET_GROUP,
2462
NETDATA_EBPF_CHART_TYPE_STACKED,
1922
- 20084,
2463
+ order++,
2464
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2465
NETDATA_SERVICES_SOCKET_TCP_RETRANSMIT_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2466
update_every);
@@ -1929,7 +2470,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2470
EBPF_COMMON_DIMENSION_CALL,
2471
NETDATA_APPS_NET_GROUP,
2472
NETDATA_EBPF_CHART_TYPE_STACKED,
1932
- 20085,
2473
+ order++,
2474
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2475
NETDATA_SERVICES_SOCKET_UDP_SEND_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2476
update_every);
@@ -1939,7 +2480,7 @@ static void ebpf_create_systemd_socket_charts(int update_every)
2480
EBPF_COMMON_DIMENSION_CALL,
2481
NETDATA_APPS_NET_GROUP,
2482
NETDATA_EBPF_CHART_TYPE_STACKED,
1942
- 20086,
2483
+ order++,
2484
ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
2485
NETDATA_SERVICES_SOCKET_UDP_RECV_CONTEXT, NETDATA_EBPF_MODULE_NAME_SOCKET,
2486
update_every);
@@ -1957,6 +2498,24 @@ static int ebpf_send_systemd_socket_charts()
2498
{
2499
int ret = 1;
2500
ebpf_cgroup_target_t *ect;
2501
+ write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V4);
2502
+ for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) {
2503
+ if (unlikely(ect->systemd) && unlikely(ect->updated)) {
2504
+ write_chart_dimension(ect->name, (long long)ect->publish_socket.call_tcp_v4_connection);
2505
+ } else
2506
+ ret = 0;
2507
+ }
2508
+ write_end_chart();
2509
+
2510
+ write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_CONNECTION_TCP_V6);
2511
+ for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) {
2512
+ if (unlikely(ect->systemd) && unlikely(ect->updated)) {
2513
+ write_chart_dimension(ect->name, (long long)ect->publish_socket.call_tcp_v6_connection);
2514
+ } else
2515
+ ret = 0;
2516
+ }
2517
+ write_end_chart();
2518
+
2519
write_begin_chart(NETDATA_SERVICE_FAMILY, NETDATA_NET_APPS_BANDWIDTH_SENT);
2520
for (ect = ebpf_cgroup_pids; ect ; ect = ect->next) {
2521
if (unlikely(ect->systemd) && unlikely(ect->updated)) {
@@ -3320,6 +3879,40 @@ void parse_table_size_options(struct config *cfg)
3879
EBPF_CONFIG_UDP_SIZE, NETDATA_MAXIMUM_UDP_CONNECTIONS_ALLOWED);
3880
}
3881
3882
+/*
3883
+ * Load BPF
3884
+ *
3885
+ * Load BPF files.
3886
+ *
3887
+ * @param em the structure with configuration
3888
+ */
3889
+static int ebpf_socket_load_bpf(ebpf_module_t *em)
3890
+{
3891
+ int ret = 0;
3892
+
3893
+ if (em->load == EBPF_LOAD_LEGACY) {
3894
+ probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
3895
+ if (!probe_links) {
3896
+ ret = -1;
3897
+ }
3898
+ }
3899
+#ifdef LIBBPF_MAJOR_VERSION
3900
+ else {
3901
+ bpf_obj = socket_bpf__open();
3902
+ if (!bpf_obj)
3903
+ ret = -1;
3904
+ else
3905
+ ret = ebpf_socket_load_and_attach(bpf_obj, em);
3906
+ }
3907
+#endif
3908
+
3909
+ if (ret) {
3910
+ error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name);
3911
+ }
3912
+
3913
+ return ret;
3914
+}
3915
+
3916
/**
3917
* Socket thread
3918
*
@@ -3361,8 +3954,10 @@ void *ebpf_socket_thread(void *ptr)
3954
if (running_on_kernel < NETDATA_EBPF_KERNEL_5_0)
3955
em->mode = MODE_ENTRY;
3956
3364
- probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
3365
- if (!probe_links) {
3957
+#ifdef LIBBPF_MAJOR_VERSION
3958
+ ebpf_adjust_thread_load(em, default_btf);
3959
+#endif
3960
+ if (ebpf_socket_load_bpf(em)) {
3961
em->enabled = CONFIG_BOOLEAN_NO;
3962
pthread_mutex_unlock(&lock);
3963
goto endsocket;
collectors/ebpf.plugin/ebpf_socket.h
+58
-12
@@ -43,11 +43,27 @@ enum ebpf_socket_publish_index {
43
NETDATA_IDX_UDP_RECVBUF,
44
NETDATA_IDX_UDP_SENDMSG,
45
NETDATA_IDX_TCP_RETRANSMIT,
46
+ NETDATA_IDX_TCP_CONNECTION_V4,
47
+ NETDATA_IDX_TCP_CONNECTION_V6,
48
+ NETDATA_IDX_INCOMING_CONNECTION_TCP,
49
+ NETDATA_IDX_INCOMING_CONNECTION_UDP,
50
51
// Keep this as last and don't skip numbers as it is used as element counter
52
NETDATA_MAX_SOCKET_VECTOR
53
};
54
55
+enum socket_functions {
56
+ NETDATA_FCNT_INET_CSK_ACCEPT,
57
+ NETDATA_FCNT_TCP_RETRANSMIT,
58
+ NETDATA_FCNT_CLEANUP_RBUF,
59
+ NETDATA_FCNT_TCP_CLOSE,
60
+ NETDATA_FCNT_UDP_RECEVMSG,
61
+ NETDATA_FCNT_TCP_SENDMSG,
62
+ NETDATA_FCNT_UDP_SENDMSG,
63
+ NETDATA_FCNT_TCP_V4_CONNECT,
64
+ NETDATA_FCNT_TCP_V6_CONNECT
65
+};
66
+
67
typedef enum ebpf_socket_idx {
68
NETDATA_KEY_CALLS_TCP_SENDMSG,
69
NETDATA_KEY_ERROR_TCP_SENDMSG,
@@ -69,6 +85,12 @@ typedef enum ebpf_socket_idx {
85
86
NETDATA_KEY_TCP_RETRANSMIT,
87
88
+ NETDATA_KEY_CALLS_TCP_CONNECT_IPV4,
89
+ NETDATA_KEY_ERROR_TCP_CONNECT_IPV4,
90
+
91
+ NETDATA_KEY_CALLS_TCP_CONNECT_IPV6,
92
+ NETDATA_KEY_ERROR_TCP_CONNECT_IPV6,
93
+
94
// Keep this as last and don't skip numbers as it is used as element counter
95
NETDATA_SOCKET_COUNTER
96
} ebpf_socket_index_t;
@@ -78,6 +100,8 @@ typedef enum ebpf_socket_idx {
100
#define NETDATA_CGROUP_NET_GROUP "network (eBPF)"
101
102
// Global chart name
103
+#define NETDATA_TCP_OUTBOUND_CONNECTIONS "tcp_outbound_conn"
104
+#define NETDATA_INBOUND_CONNECTIONS "inbound_conn"
105
#define NETDATA_TCP_FUNCTION_COUNT "tcp_functions"
106
#define NETDATA_TCP_FUNCTION_BITS "total_tcp_bandwidth"
107
#define NETDATA_TCP_FUNCTION_ERROR "tcp_error"
@@ -87,6 +111,8 @@ typedef enum ebpf_socket_idx {
111
#define NETDATA_UDP_FUNCTION_ERROR "udp_error"
112
113
// Charts created on Apps submenu
114
+#define NETDATA_NET_APPS_CONNECTION_TCP_V4 "outbound_conn_v4"
115
+#define NETDATA_NET_APPS_CONNECTION_TCP_V6 "outbound_conn_v6"
116
#define NETDATA_NET_APPS_BANDWIDTH_SENT "total_bandwidth_sent"
117
#define NETDATA_NET_APPS_BANDWIDTH_RECV "total_bandwidth_recv"
118
#define NETDATA_NET_APPS_BANDWIDTH_TCP_SEND_CALLS "bandwidth_tcp_send"
@@ -114,6 +140,8 @@ typedef enum ebpf_socket_idx {
140
#define NETDATA_MAXIMUM_IPV4_CIDR 32
141
142
// Contexts
143
+#define NETDATA_CGROUP_TCP_V4_CONN_CONTEXT "cgroup.net_conn_ipv4"
144
+#define NETDATA_CGROUP_TCP_V6_CONN_CONTEXT "cgroup.net_conn_ipv6"
145
#define NETDATA_CGROUP_SOCKET_BYTES_RECV_CONTEXT "cgroup.net_bytes_recv"
146
#define NETDATA_CGROUP_SOCKET_BYTES_SEND_CONTEXT "cgroup.net_bytes_send"
147
#define NETDATA_CGROUP_SOCKET_TCP_RECV_CONTEXT "cgroup.net_tcp_recv"
@@ -122,6 +150,8 @@ typedef enum ebpf_socket_idx {
150
#define NETDATA_CGROUP_SOCKET_UDP_RECV_CONTEXT "cgroup.net_udp_recv"
151
#define NETDATA_CGROUP_SOCKET_UDP_SEND_CONTEXT "cgroup.net_udp_send"
152
153
+#define NETDATA_SERVICES_SOCKET_TCP_V4_CONN_CONTEXT "services.net_conn_ipv4"
154
+#define NETDATA_SERVICES_SOCKET_TCP_V6_CONN_CONTEXT "services.net_conn_ipv6"
155
#define NETDATA_SERVICES_SOCKET_BYTES_RECV_CONTEXT "services.net_bytes_recv"
156
#define NETDATA_SERVICES_SOCKET_BYTES_SEND_CONTEXT "services.net_bytes_send"
157
#define NETDATA_SERVICES_SOCKET_TCP_RECV_CONTEXT "services.net_tcp_recv"
@@ -132,14 +162,16 @@ typedef enum ebpf_socket_idx {
162
163
typedef struct ebpf_socket_publish_apps {
164
// Data read
135
- uint64_t bytes_sent; // Bytes sent
136
- uint64_t bytes_received; // Bytes received
137
- uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called
138
- uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called
139
- uint64_t retransmit; // Number of times tcp_retransmit was called
140
- uint64_t call_udp_sent; // Number of times udp_sendmsg was called
141
- uint64_t call_udp_received; // Number of times udp_recvmsg was called
142
- uint64_t call_close; // Number of times tcp_close was called
165
+ uint64_t bytes_sent; // Bytes sent
166
+ uint64_t bytes_received; // Bytes received
167
+ uint64_t call_tcp_sent; // Number of times tcp_sendmsg was called
168
+ uint64_t call_tcp_received; // Number of times tcp_cleanup_rbuf was called
169
+ uint64_t retransmit; // Number of times tcp_retransmit was called
170
+ uint64_t call_udp_sent; // Number of times udp_sendmsg was called
171
+ uint64_t call_udp_received; // Number of times udp_recvmsg was called
172
+ uint64_t call_close; // Number of times tcp_close was called
173
+ uint64_t call_tcp_v4_connection;// Number of times tcp_v4_connect was called
174
+ uint64_t call_tcp_v6_connection;// Number of times tcp_v6_connect was called
175
} ebpf_socket_publish_apps_t;
176
177
typedef struct ebpf_network_viewer_dimension_names {
@@ -161,10 +193,24 @@ typedef struct ebpf_network_viewer_port_list {
193
uint16_t cmp_first;
194
uint16_t cmp_last;
195
164
- uint8_t protocol;
196
+ uint16_t protocol;
197
+ uint32_t pid;
198
+ uint32_t tgid;
199
+ uint64_t connections;
200
struct ebpf_network_viewer_port_list *next;
201
} ebpf_network_viewer_port_list_t;
202
203
+typedef struct netdata_passive_connection {
204
+ uint32_t tgid;
205
+ uint32_t pid;
206
+ uint64_t counter;
207
+} netdata_passive_connection_t;
208
+
209
+typedef struct netdata_passive_connection_idx {
210
+ uint16_t protocol;
211
+ uint16_t port;
212
+} netdata_passive_connection_idx_t;
213
+
214
/**
215
* Union used to store ip addresses
216
*/
@@ -235,14 +281,13 @@ typedef struct netdata_socket {
281
uint16_t reserved;
282
} netdata_socket_t __attribute__((__aligned__(8)));
283
238
-
284
typedef struct netdata_plot_values {
285
// Values used in the previous iteration
286
uint64_t recv_packets;
287
uint64_t sent_packets;
288
uint64_t recv_bytes;
289
uint64_t sent_bytes;
245
- uint16_t retransmit;
290
+ uint32_t retransmit;
291
292
uint64_t last_time;
293
@@ -313,7 +358,7 @@ typedef struct netdata_vector_plot {
358
359
extern void clean_port_structure(ebpf_network_viewer_port_list_t **clean);
360
extern ebpf_network_viewer_port_list_t *listen_ports;
316
-extern void update_listen_table(uint16_t value, uint8_t proto);
361
+extern void update_listen_table(uint16_t value, uint16_t proto, netdata_passive_connection_t *values);
362
extern void parse_network_viewer_section(struct config *cfg);
363
extern void fill_ip_list(ebpf_network_viewer_ip_list_t **out, ebpf_network_viewer_ip_list_t *in, char *table);
364
extern void parse_service_name_section(struct config *cfg);
@@ -321,5 +366,6 @@ extern void clean_socket_apps_structures();
366
367
extern ebpf_socket_publish_apps_t **socket_bandwidth_curr;
368
extern struct config socket_config;
369
+extern netdata_ebpf_targets_t socket_targets[];
370
371
#endif
libnetdata/ebpf/ebpf.c
+71
-19
@@ -453,14 +453,53 @@ void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em)
453
pid->user_input = em->pid_map_size;
454
}
455
456
-void ebpf_update_map_sizes(struct bpf_object *program, ebpf_module_t *em)
456
+/**
457
+ * Update map size
458
+ *
459
+ * Update map size with information read from configuration files.
460
+ *
461
+ * @param map the structure with file descriptor to update.
462
+ * @param lmap the structure with information from configuration files.
463
+ * @param em the structure with information about how the module/thread is working.
464
+ * @param map_name the name of the file used to log.
465
+ */
466
+void ebpf_update_map_size(struct bpf_map *map, ebpf_local_maps_t *lmap, ebpf_module_t *em, const char *map_name)
467
+{
468
+ uint32_t apps_type = NETDATA_EBPF_MAP_PID | NETDATA_EBPF_MAP_RESIZABLE;
469
+ if (lmap->user_input && lmap->user_input != lmap->internal_input) {
470
+#ifdef NETDATA_INTERNAL_CHECKS
471
+ info("Changing map %s from size %u to %u ", map_name, lmap->internal_input, lmap->user_input);
472
+#endif
473
+#ifdef LIBBPF_MAJOR_VERSION
474
+ bpf_map__set_max_entries(map, lmap->user_input);
475
+#else
476
+ bpf_map__resize(map, lmap->user_input);
477
+#endif
478
+ } else if (((lmap->type & apps_type) == apps_type) && (!em->apps_charts) && (!em->cgroup_charts)) {
479
+ lmap->user_input = ND_EBPF_DEFAULT_MIN_PID;
480
+#ifdef LIBBPF_MAJOR_VERSION
481
+ bpf_map__set_max_entries(map, lmap->user_input);
482
+#else
483
+ bpf_map__resize(map, lmap->user_input);
484
+#endif
485
+ }
486
+}
487
+
488
+/**
489
+ * Update Legacy map sizes
490
+ *
491
+ * Update map size for eBPF legacy code.
492
+ *
493
+ * @param program the structure with values read from binary.
494
+ * @param em the structure with information about how the module/thread is working.
495
+ */
496
+static void ebpf_update_legacy_map_sizes(struct bpf_object *program, ebpf_module_t *em)
497
{
498
struct bpf_map *map;
499
ebpf_local_maps_t *maps = em->maps;
500
if (!maps)
501
return;
502
463
- uint32_t apps_type = NETDATA_EBPF_MAP_PID | NETDATA_EBPF_MAP_RESIZABLE;
503
bpf_map__for_each(map, program)
504
{
505
const char *map_name = bpf_map__name(map);
@@ -469,15 +508,7 @@ void ebpf_update_map_sizes(struct bpf_object *program, ebpf_module_t *em)
508
ebpf_local_maps_t *w = &maps[i];
509
if (w->type & NETDATA_EBPF_MAP_RESIZABLE) {
510
if (!strcmp(w->name, map_name)) {
472
- if (w->user_input && w->user_input != w->internal_input) {
473
-#ifdef NETDATA_INTERNAL_CHECKS
474
- info("Changing map %s from size %u to %u ", map_name, w->internal_input, w->user_input);
475
-#endif
476
- bpf_map__resize(map, w->user_input);
477
- } else if (((w->type & apps_type) == apps_type) && (!em->apps_charts) && (!em->cgroup_charts)) {
478
- w->user_input = ND_EBPF_DEFAULT_MIN_PID;
479
- bpf_map__resize(map, w->user_input);
480
- }
511
+ ebpf_update_map_size(map, w, em, map_name);
512
}
513
}
514
@@ -566,7 +597,32 @@ static void ebpf_update_maps(ebpf_module_t *em, struct bpf_object *obj)
597
}
598
}
599
569
-static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj)
600
+/**
601
+ * Update Controller
602
+ *
603
+ * Update controller value with user input.
604
+ *
605
+ * @param fd the table file descriptor
606
+ * @param em structure with information about eBPF program we will load.
607
+ */
608
+void ebpf_update_controller(int fd, ebpf_module_t *em)
609
+{
610
+ uint32_t key = NETDATA_CONTROLLER_APPS_ENABLED;
611
+ uint32_t value = em->apps_charts | em->cgroup_charts;
612
+ int ret = bpf_map_update_elem(fd, &key, &value, 0);
613
+ if (ret)
614
+ error("Add key(%u) for controller table failed.", key);
615
+}
616
+
617
+/**
618
+ * Update Legacy controller
619
+ *
620
+ * Update legacy controller table when eBPF program has it.
621
+ *
622
+ * @param em structure with information about eBPF program we will load.
623
+ * @param obj bpf object with tables.
624
+ */
625
+static void ebpf_update_legacy_controller(ebpf_module_t *em, struct bpf_object *obj)
626
{
627
ebpf_local_maps_t *maps = em->maps;
628
if (!maps)
@@ -582,11 +638,7 @@ static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj)
638
w->type &= ~NETDATA_EBPF_MAP_CONTROLLER;
639
w->type |= NETDATA_EBPF_MAP_CONTROLLER_UPDATED;
640
585
- uint32_t key = NETDATA_CONTROLLER_APPS_ENABLED;
586
- int value = em->apps_charts | em->cgroup_charts;
587
- int ret = bpf_map_update_elem(w->map_fd, &key, &value, 0);
588
- if (ret)
589
- error("Add key(%u) for controller table failed.", key);
641
+ ebpf_update_controller(w->map_fd, em);
642
}
643
i++;
644
}
@@ -622,7 +674,7 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kv
674
return NULL;
675
}
676
625
- ebpf_update_map_sizes(*obj, em);
677
+ ebpf_update_legacy_map_sizes(*obj, em);
678
679
if (bpf_object__load(*obj)) {
680
error("ERROR: loading BPF object file failed %s\n", lpath);
@@ -631,7 +683,7 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kv
683
}
684
685
ebpf_update_maps(em, *obj);
634
- ebpf_update_controller(em, *obj);
686
+ ebpf_update_legacy_controller(em, *obj);
687
688
size_t count_programs = ebpf_count_programs(*obj);
689
libnetdata/ebpf/ebpf.h
+4
@@ -38,6 +38,8 @@
38
#define EBPF_CFG_APPLICATION "apps"
39
#define EBPF_CFG_CGROUP "cgroups"
40
41
+#define EBPF_COMMON_FNCT_CLEAN_UP "release_task"
42
+
43
/**
44
* The RedHat magic number was got doing:
45
*
@@ -249,6 +251,8 @@ extern void ebpf_load_addresses(ebpf_addresses_t *fa, int fd);
251
extern void ebpf_fill_algorithms(int *algorithms, size_t length, int algorithm);
252
extern char **ebpf_fill_histogram_dimension(size_t maximum);
253
extern void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em);
254
+extern void ebpf_update_controller(int fd, ebpf_module_t *em);
255
+extern void ebpf_update_map_size(struct bpf_map *map, ebpf_local_maps_t *lmap, ebpf_module_t *em, const char *map_name);
256
257
// Histogram
258
#define NETDATA_EBPF_HIST_MAX_BINS 24UL
packaging/ebpf-co-re.checksums
+1
-1
@@ -1 +1 @@
1
-da6929bc3a432240369bcb84c86e607d1ed255cd9530620d2f355e105ce376d6 netdata-ebpf-co-re-glibc-v0.9.2.tar.xz
1
+0e3a6928a9b69a1a1e7911635b6d6fda44e78b67a3e38daad9d8cc3babfcdfee netdata-ebpf-co-re-glibc-v0.9.3.2.tar.xz
packaging/ebpf-co-re.version
+1
-1
@@ -1 +1 @@
1
-v0.9.2
1
+v0.9.3.2
packaging/ebpf.checksums
+3
-3
@@ -1,3 +1,3 @@
1
-380103099c16a1703aca6d3aef5ea36142f6ecc621af79e0ecf248f768a8502f netdata-kernel-collector-glibc-v0.9.2.tar.xz
2
-23700cd83035d7f3b61e826c5b957e99ff67afcf11c59df3d096a9372115b2b0 netdata-kernel-collector-musl-v0.9.2.tar.xz
3
-a96d9f05a11208dcd58eb9e781f383ca88530abc407b24c7eaa0059d823892ed netdata-kernel-collector-static-v0.9.2.tar.xz
1
+cee483b29e1fd3125d635d03f9266d267eab1ba13e02c99afcf6a84bdcb729f4 ./netdata-kernel-collector-glibc-v0.9.3.tar.xz
2
+33aeae2cf7e9c0967c62f262bf6c6c44db49dc5dbb6d3a16e8bfde4433779069 ./netdata-kernel-collector-musl-v0.9.3.tar.xz
3
+9eba23184be7c9b29d22271e439e3fac517d32d500bd796c4e21f653b6f4d337 ./netdata-kernel-collector-static-v0.9.3.tar.xz
packaging/ebpf.version
+1
-1
@@ -1 +1 @@
1
-v0.9.2
1
+v0.9.3