@cryptotaxi247 / netdata-1 / commits / 68684b59f

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