@cryptotaxi247 / netdata-1 / commits / ac62dedef

Self-cleaning obsolete network interfaces in FreeBSD plugin

Vladimir Kobal committed Mar 30, 2017 at 15:13 UTC ac62dedef23d6fafd3f45843434d269c32eff1c7
5 files changed +497 -418
CMakeLists.txt
+2
@@ -29,6 +29,8 @@ set(NETDATA_SOURCE_FILES
29 src/eval.c
30 src/eval.h
31 src/freebsd_sysctl.c
32 + src/freebsd_getmntinfo.c
33 + src/freebsd_getifaddrs.c
34 src/global_statistics.c
35 src/global_statistics.h
36 src/health.c
src/Makefile.am
+1
@@ -147,6 +147,7 @@ netdata_SOURCES += \
147 plugin_freebsd.h \
148 freebsd_sysctl.c \
149 freebsd_getmntinfo.c \
150 + freebsd_getifaddrs.c \
151 $(NULL)
152 else
153 if MACOS
src/freebsd_getifaddrs.c new
+494
@@ -0,0 +1,494 @@
1 +#include "common.h"
2 +
3 +#include <ifaddrs.h>
4 +
5 +struct network_interface {
6 + char *name;
7 + uint32_t hash;
8 + size_t len;
9 +
10 + // flags
11 + int configured;
12 + int enabled;
13 + int updated;
14 +
15 + int do_bandwidth;
16 + int do_packets;
17 + int do_errors;
18 + int do_drops;
19 + int do_events;
20 +
21 + // charts and dimensions
22 +
23 + RRDSET *st_bandwidth;
24 + RRDDIM *rd_bandwidth_in;
25 + RRDDIM *rd_bandwidth_out;
26 +
27 + RRDSET *st_packets;
28 + RRDDIM *rd_packets_in;
29 + RRDDIM *rd_packets_out;
30 + RRDDIM *rd_packets_m_in;
31 + RRDDIM *rd_packets_m_out;
32 +
33 + RRDSET *st_errors;
34 + RRDDIM *rd_errors_in;
35 + RRDDIM *rd_errors_out;
36 +
37 + RRDSET *st_drops;
38 + RRDDIM *rd_drops_in;
39 + RRDDIM *rd_drops_out;
40 +
41 + RRDSET *st_events;
42 + RRDDIM *rd_events_coll;
43 +
44 + struct network_interface *next;
45 +};
46 +
47 +static struct network_interface *network_interfaces_root = NULL, *network_interfaces_last_used = NULL;
48 +
49 +static size_t network_interfaces_added = 0, network_interfaces_found = 0;
50 +
51 +static void network_interface_free(struct network_interface *ifm) {
52 + if (likely(ifm->st_bandwidth))
53 + rrdset_flag_set(ifm->st_bandwidth, RRDSET_FLAG_OBSOLETE);
54 + if (likely(ifm->st_packets))
55 + rrdset_flag_set(ifm->st_packets, RRDSET_FLAG_OBSOLETE);
56 + if (likely(ifm->st_errors))
57 + rrdset_flag_set(ifm->st_errors, RRDSET_FLAG_OBSOLETE);
58 + if (likely(ifm->st_drops))
59 + rrdset_flag_set(ifm->st_drops, RRDSET_FLAG_OBSOLETE);
60 + if (likely(ifm->st_events))
61 + rrdset_flag_set(ifm->st_events, RRDSET_FLAG_OBSOLETE);
62 +
63 + network_interfaces_added--;
64 + freez(ifm->name);
65 + freez(ifm);
66 +}
67 +
68 +static void network_interfaces_cleanup() {
69 + if (likely(network_interfaces_found == network_interfaces_added)) return;
70 +
71 + struct network_interface *ifm = network_interfaces_root, *last = NULL;
72 + while(ifm) {
73 + if (unlikely(!ifm->updated)) {
74 + // info("Removing network interface '%s', linked after '%s'", ifm->name, last?last->name:"ROOT");
75 +
76 + if (network_interfaces_last_used == ifm)
77 + network_interfaces_last_used = last;
78 +
79 + struct network_interface *t = ifm;
80 +
81 + if (ifm == network_interfaces_root || !last)
82 + network_interfaces_root = ifm = ifm->next;
83 +
84 + else
85 + last->next = ifm = ifm->next;
86 +
87 + t->next = NULL;
88 + network_interface_free(t);
89 + }
90 + else {
91 + last = ifm;
92 + ifm->updated = 0;
93 + ifm = ifm->next;
94 + }
95 + }
96 +}
97 +
98 +static struct network_interface *get_network_interface(const char *name) {
99 + struct network_interface *ifm;
100 +
101 + uint32_t hash = simple_hash(name);
102 +
103 + // search it, from the last position to the end
104 + for(ifm = network_interfaces_last_used ; ifm ; ifm = ifm->next) {
105 + if (unlikely(hash == ifm->hash && !strcmp(name, ifm->name))) {
106 + network_interfaces_last_used = ifm->next;
107 + return ifm;
108 + }
109 + }
110 +
111 + // search it from the beginning to the last position we used
112 + for(ifm = network_interfaces_root ; ifm != network_interfaces_last_used ; ifm = ifm->next) {
113 + if (unlikely(hash == ifm->hash && !strcmp(name, ifm->name))) {
114 + network_interfaces_last_used = ifm->next;
115 + return ifm;
116 + }
117 + }
118 +
119 + // create a new one
120 + ifm = callocz(1, sizeof(struct network_interface));
121 + ifm->name = strdupz(name);
122 + ifm->hash = simple_hash(ifm->name);
123 + ifm->len = strlen(ifm->name);
124 + network_interfaces_added++;
125 +
126 + // link it to the end
127 + if (network_interfaces_root) {
128 + struct network_interface *e;
129 + for(e = network_interfaces_root; e->next ; e = e->next) ;
130 + e->next = ifm;
131 + }
132 + else
133 + network_interfaces_root = ifm;
134 +
135 + return ifm;
136 +}
137 +
138 +// --------------------------------------------------------------------------------------------------------------------
139 +// getifaddrs
140 +
141 +int do_getifaddrs(int update_every, usec_t dt) {
142 + (void)dt;
143 +
144 +#define DELAULT_EXLUDED_INTERFACES "lo*"
145 +#define CONFIG_SECTION_GETIFADDRS "plugin:freebsd:getifaddrs"
146 +
147 + static int enable_new_interfaces = -1;
148 + static int do_bandwidth_ipv4 = -1, do_bandwidth_ipv6 = -1, do_bandwidth = -1, do_packets = -1,
149 + do_errors = -1, do_drops = -1, do_events = -1;
150 + static SIMPLE_PATTERN *excluded_interfaces = NULL;
151 +
152 + if (unlikely(enable_new_interfaces == -1)) {
153 + enable_new_interfaces = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS,
154 + "enable new interfaces detected at runtime",
155 + CONFIG_BOOLEAN_AUTO);
156 +
157 + do_bandwidth_ipv4 = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "total bandwidth for ipv4 interfaces",
158 + CONFIG_BOOLEAN_AUTO);
159 + do_bandwidth_ipv6 = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "total bandwidth for ipv6 interfaces",
160 + CONFIG_BOOLEAN_AUTO);
161 + do_bandwidth = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "bandwidth for all interfaces",
162 + CONFIG_BOOLEAN_AUTO);
163 + do_packets = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "packets for all interfaces",
164 + CONFIG_BOOLEAN_AUTO);
165 + do_errors = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "errors for all interfaces",
166 + CONFIG_BOOLEAN_AUTO);
167 + do_drops = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "drops for all interfaces",
168 + CONFIG_BOOLEAN_AUTO);
169 + do_events = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "collisions for all interfaces",
170 + CONFIG_BOOLEAN_AUTO);
171 +
172 + excluded_interfaces = simple_pattern_create(
173 + config_get(CONFIG_SECTION_GETIFADDRS, "disable by default interfaces matching",
174 + DELAULT_EXLUDED_INTERFACES)
175 + , SIMPLE_PATTERN_EXACT
176 + );
177 + }
178 +
179 + if (likely(do_bandwidth_ipv4 || do_bandwidth_ipv6 || do_bandwidth || do_packets || do_errors ||
180 + do_drops || do_events)) {
181 + struct ifaddrs *ifap;
182 +
183 + if (unlikely(getifaddrs(&ifap))) {
184 + error("FREEBSD: getifaddrs() failed");
185 + do_bandwidth_ipv4 = 0;
186 + error("DISABLED: system.ipv4 chart");
187 + do_bandwidth_ipv6 = 0;
188 + error("DISABLED: system.ipv6 chart");
189 + do_bandwidth = 0;
190 + error("DISABLED: net.* charts");
191 + do_packets = 0;
192 + error("DISABLED: net_packets.* charts");
193 + do_errors = 0;
194 + error("DISABLED: net_errors.* charts");
195 + do_drops = 0;
196 + error("DISABLED: net_drops.* charts");
197 + do_events = 0;
198 + error("DISABLED: net_events.* charts");
199 + error("DISABLED: getifaddrs module");
200 + return 1;
201 + } else {
202 +#define IFA_DATA(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
203 + struct ifaddrs *ifa;
204 + struct iftot {
205 + u_long ift_ibytes;
206 + u_long ift_obytes;
207 + } iftot = {0, 0};
208 +
209 + // --------------------------------------------------------------------
210 +
211 + if (likely(do_bandwidth_ipv4)) {
212 + iftot.ift_ibytes = iftot.ift_obytes = 0;
213 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
214 + if (ifa->ifa_addr->sa_family != AF_INET)
215 + continue;
216 + iftot.ift_ibytes += IFA_DATA(ibytes);
217 + iftot.ift_obytes += IFA_DATA(obytes);
218 + }
219 +
220 + static RRDSET *st = NULL;
221 + static RRDDIM *rd_in = NULL, *rd_out = NULL;
222 +
223 + if (unlikely(!st)) {
224 + st = rrdset_create_localhost("system",
225 + "ipv4",
226 + NULL,
227 + "network",
228 + NULL,
229 + "IPv4 Bandwidth",
230 + "kilobits/s",
231 + 500,
232 + update_every,
233 + RRDSET_TYPE_AREA
234 + );
235 +
236 + rd_in = rrddim_add(st, "InOctets", "received", 8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
237 + rd_out = rrddim_add(st, "OutOctets", "sent", -8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
238 + } else
239 + rrdset_next(st);
240 +
241 + rrddim_set_by_pointer(st, rd_in, iftot.ift_ibytes);
242 + rrddim_set_by_pointer(st, rd_out, iftot.ift_obytes);
243 + rrdset_done(st);
244 + }
245 +
246 + // --------------------------------------------------------------------
247 +
248 + if (likely(do_bandwidth_ipv6)) {
249 + iftot.ift_ibytes = iftot.ift_obytes = 0;
250 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
251 + if (ifa->ifa_addr->sa_family != AF_INET6)
252 + continue;
253 + iftot.ift_ibytes += IFA_DATA(ibytes);
254 + iftot.ift_obytes += IFA_DATA(obytes);
255 + }
256 +
257 + static RRDSET *st = NULL;
258 + static RRDDIM *rd_in = NULL, *rd_out = NULL;
259 +
260 + if (unlikely(!st)) {
261 + st = rrdset_create_localhost("system",
262 + "ipv6",
263 + NULL,
264 + "network",
265 + NULL,
266 + "IPv6 Bandwidth",
267 + "kilobits/s",
268 + 500,
269 + update_every,
270 + RRDSET_TYPE_AREA
271 + );
272 +
273 + rd_in = rrddim_add(st, "received", NULL, 8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
274 + rd_out = rrddim_add(st, "sent", NULL, -8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
275 + } else
276 + rrdset_next(st);
277 +
278 + rrddim_set_by_pointer(st, rd_in, iftot.ift_ibytes);
279 + rrddim_set_by_pointer(st, rd_out, iftot.ift_obytes);
280 + rrdset_done(st);
281 + }
282 +
283 + // --------------------------------------------------------------------
284 +
285 + network_interfaces_found = 0;
286 +
287 + for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
288 + if (ifa->ifa_addr->sa_family != AF_LINK)
289 + continue;
290 +
291 + struct network_interface *ifm = get_network_interface(ifa->ifa_name);
292 + ifm->updated = 1;
293 + network_interfaces_found++;
294 +
295 + if (unlikely(!ifm->configured)) {
296 + char var_name[4096 + 1];
297 +
298 + // this is the first time we see this network interface
299 +
300 + // remember we configured it
301 + ifm->configured = 1;
302 +
303 + ifm->enabled = enable_new_interfaces;
304 +
305 + if (likely(ifm->enabled))
306 + ifm->enabled = !simple_pattern_matches(excluded_interfaces, ifa->ifa_name);
307 +
308 + snprintfz(var_name, 4096, "%s:%s", CONFIG_SECTION_GETIFADDRS, ifa->ifa_name);
309 + ifm->enabled = config_get_boolean_ondemand(var_name, "enabled", ifm->enabled);
310 +
311 + if (unlikely(ifm->enabled == CONFIG_BOOLEAN_NO))
312 + continue;
313 +
314 + ifm->do_bandwidth = config_get_boolean_ondemand(var_name, "bandwidth", do_bandwidth);
315 + ifm->do_packets = config_get_boolean_ondemand(var_name, "packets", do_packets);
316 + ifm->do_errors = config_get_boolean_ondemand(var_name, "errors", do_errors);
317 + ifm->do_drops = config_get_boolean_ondemand(var_name, "drops", do_drops);
318 + ifm->do_events = config_get_boolean_ondemand(var_name, "events", do_events);
319 + }
320 +
321 + if (unlikely(!ifm->enabled))
322 + continue;
323 +
324 + // --------------------------------------------------------------------
325 +
326 + if (ifm->do_bandwidth == CONFIG_BOOLEAN_YES || (ifm->do_bandwidth == CONFIG_BOOLEAN_AUTO &&
327 + (IFA_DATA(ibytes) || IFA_DATA(obytes)))) {
328 + if (unlikely(!ifm->st_bandwidth)) {
329 + ifm->st_bandwidth = rrdset_create_localhost("net",
330 + ifa->ifa_name,
331 + NULL,
332 + ifa->ifa_name,
333 + "net.net",
334 + "Bandwidth",
335 + "kilobits/s",
336 + 7000,
337 + update_every,
338 + RRDSET_TYPE_AREA
339 + );
340 +
341 + ifm->rd_bandwidth_in = rrddim_add(ifm->st_bandwidth, "received", NULL, 8, KILO_FACTOR,
342 + RRD_ALGORITHM_INCREMENTAL);
343 + ifm->rd_bandwidth_out = rrddim_add(ifm->st_bandwidth, "sent", NULL, -8, KILO_FACTOR,
344 + RRD_ALGORITHM_INCREMENTAL);
345 + } else
346 + rrdset_next(ifm->st_bandwidth);
347 +
348 + rrddim_set_by_pointer(ifm->st_bandwidth, ifm->rd_bandwidth_in, IFA_DATA(ibytes));
349 + rrddim_set_by_pointer(ifm->st_bandwidth, ifm->rd_bandwidth_out, IFA_DATA(obytes));
350 + rrdset_done(ifm->st_bandwidth);
351 + }
352 +
353 + // --------------------------------------------------------------------
354 +
355 + if (ifm->do_packets == CONFIG_BOOLEAN_YES || (ifm->do_packets == CONFIG_BOOLEAN_AUTO &&
356 + (IFA_DATA(ipackets) || IFA_DATA(opackets) || IFA_DATA(imcasts) || IFA_DATA(omcasts)))) {
357 + if (unlikely(!ifm->st_packets)) {
358 + ifm->st_packets = rrdset_create_localhost("net_packets",
359 + ifa->ifa_name,
360 + NULL,
361 + ifa->ifa_name,
362 + "net.packets",
363 + "Packets",
364 + "packets/s",
365 + 7001,
366 + update_every,
367 + RRDSET_TYPE_LINE
368 + );
369 +
370 + rrdset_flag_set(ifm->st_packets, RRDSET_FLAG_DETAIL);
371 +
372 + ifm->rd_packets_in = rrddim_add(ifm->st_packets, "received", NULL, 1, 1,
373 + RRD_ALGORITHM_INCREMENTAL);
374 + ifm->rd_packets_out = rrddim_add(ifm->st_packets, "sent", NULL, -1, 1,
375 + RRD_ALGORITHM_INCREMENTAL);
376 + ifm->rd_packets_m_in = rrddim_add(ifm->st_packets, "multicast_received", NULL, 1, 1,
377 + RRD_ALGORITHM_INCREMENTAL);
378 + ifm->rd_packets_m_out = rrddim_add(ifm->st_packets, "multicast_sent", NULL, -1, 1,
379 + RRD_ALGORITHM_INCREMENTAL);
380 + } else
381 + rrdset_next(ifm->st_packets);
382 +
383 + rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_in, IFA_DATA(ipackets));
384 + rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_out, IFA_DATA(opackets));
385 + rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_m_in, IFA_DATA(imcasts));
386 + rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_m_out, IFA_DATA(omcasts));
387 + rrdset_done(ifm->st_packets);
388 + }
389 +
390 + // --------------------------------------------------------------------
391 +
392 + if (ifm->do_errors == CONFIG_BOOLEAN_YES || (ifm->do_errors == CONFIG_BOOLEAN_AUTO &&
393 + (IFA_DATA(ierrors) || IFA_DATA(oerrors)))) {
394 + if (unlikely(!ifm->st_errors)) {
395 + ifm->st_errors = rrdset_create_localhost("net_errors",
396 + ifa->ifa_name,
397 + NULL,
398 + ifa->ifa_name,
399 + "net.errors",
400 + "Interface Errors",
401 + "errors/s",
402 + 7002,
403 + update_every,
404 + RRDSET_TYPE_LINE
405 + );
406 +
407 + rrdset_flag_set(ifm->st_errors, RRDSET_FLAG_DETAIL);
408 +
409 + ifm->rd_errors_in = rrddim_add(ifm->st_errors, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
410 + ifm->rd_errors_out = rrddim_add(ifm->st_errors, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
411 + } else
412 + rrdset_next(ifm->st_errors);
413 +
414 + rrddim_set_by_pointer(ifm->st_errors, ifm->rd_errors_in, IFA_DATA(ierrors));
415 + rrddim_set_by_pointer(ifm->st_errors, ifm->rd_errors_out, IFA_DATA(oerrors));
416 + rrdset_done(ifm->st_errors);
417 + }
418 + // --------------------------------------------------------------------
419 +
420 + if (ifm->do_drops == CONFIG_BOOLEAN_YES || (ifm->do_drops == CONFIG_BOOLEAN_AUTO &&
421 + (IFA_DATA(iqdrops)
422 + #if __FreeBSD__ >= 11
423 + || IFA_DATA(oqdrops)
424 +#endif
425 + ))) {
426 + if (unlikely(!ifm->st_drops)) {
427 + ifm->st_drops = rrdset_create_localhost("net_drops",
428 + ifa->ifa_name,
429 + NULL,
430 + ifa->ifa_name,
431 + "net.drops",
432 + "Interface Drops",
433 + "drops/s",
434 + 7003,
435 + update_every,
436 + RRDSET_TYPE_LINE
437 + );
438 +
439 + rrdset_flag_set(ifm->st_drops, RRDSET_FLAG_DETAIL);
440 +
441 + ifm->rd_drops_in = rrddim_add(ifm->st_drops, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
442 +#if __FreeBSD__ >= 11
443 + ifm->rd_drops_out = rrddim_add(ifm->st_drops, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
444 +#endif
445 + } else
446 + rrdset_next(ifm->st_drops);
447 +
448 + rrddim_set_by_pointer(ifm->st_drops, ifm->rd_drops_in, IFA_DATA(iqdrops));
449 +#if __FreeBSD__ >= 11
450 + rrddim_set_by_pointer(ifm->st_drops, ifm->rd_drops_out, IFA_DATA(oqdrops));
451 +#endif
452 + rrdset_done(ifm->st_drops);
453 + }
454 +
455 + // --------------------------------------------------------------------
456 +
457 + if (ifm->do_events == CONFIG_BOOLEAN_YES || (ifm->do_events == CONFIG_BOOLEAN_AUTO &&
458 + IFA_DATA(collisions))) {
459 + if (unlikely(!ifm->st_events)) {
460 + ifm->st_events = rrdset_create_localhost("net_events",
461 + ifa->ifa_name,
462 + NULL,
463 + ifa->ifa_name,
464 + "net.events",
465 + "Network Interface Events",
466 + "events/s",
467 + 7006,
468 + update_every,
469 + RRDSET_TYPE_LINE
470 + );
471 +
472 + rrdset_flag_set(ifm->st_events, RRDSET_FLAG_DETAIL);
473 +
474 + ifm->rd_events_coll = rrddim_add(ifm->st_events, "collisions", NULL, -1, 1,
475 + RRD_ALGORITHM_INCREMENTAL);
476 + } else
477 + rrdset_next(ifm->st_events);
478 +
479 + rrddim_set_by_pointer(ifm->st_events, ifm->rd_events_coll, IFA_DATA(collisions));
480 + rrdset_done(ifm->st_events);
481 + }
482 + }
483 +
484 + freeifaddrs(ifap);
485 + }
486 + } else {
487 + error("DISABLED: getifaddrs module");
488 + return 1;
489 + }
490 +
491 + network_interfaces_cleanup();
492 +
493 + return 0;
494 +}
src/freebsd_getmntinfo.c
-1
@@ -291,4 +291,3 @@ int do_getmntinfo(int update_every, usec_t dt) {
291
292 return 0;
293 }
294 -
src/freebsd_sysctl.c
-417
@@ -2,7 +2,6 @@
2
3 #include <sys/vmmeter.h>
4 #include <sys/devicestat.h>
5 -#include <sys/mount.h>
5 #include <vm/vm_param.h>
6
7 #define _KERNEL
@@ -13,7 +12,6 @@
12
13 #include <net/netisr.h>
14 #include <net/if.h>
16 -#include <ifaddrs.h>
15
16 #include <netinet/ip.h>
17 #include <netinet/ip_var.h>
@@ -2778,421 +2776,6 @@ int do_net_inet6_icmp6_stats(int update_every, usec_t dt) {
2776 return 0;
2777 }
2778
2781 -// --------------------------------------------------------------------------------------------------------------------
2782 -// getifaddrs
2783 -
2784 -int do_getifaddrs(int update_every, usec_t dt) {
2785 - (void)dt;
2786 -
2787 -#define DELAULT_EXLUDED_INTERFACES "lo*"
2788 -#define CONFIG_SECTION_GETIFADDRS "plugin:freebsd:getifaddrs"
2789 -
2790 - static int do_bandwidth_ipv4 = -1, do_bandwidth_ipv6 = -1, do_bandwidth = -1, do_packets = -1,
2791 - do_errors = -1, do_drops = -1, do_events = -1;
2792 -
2793 - if (unlikely(do_bandwidth_ipv4 == -1)) {
2794 - do_bandwidth_ipv4 = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "total bandwidth for ipv4 interfaces",
2795 - CONFIG_BOOLEAN_AUTO);
2796 - do_bandwidth_ipv6 = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "total bandwidth for ipv6 interfaces",
2797 - CONFIG_BOOLEAN_AUTO);
2798 - do_bandwidth = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "bandwidth for all interfaces",
2799 - CONFIG_BOOLEAN_AUTO);
2800 - do_packets = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "packets for all interfaces",
2801 - CONFIG_BOOLEAN_AUTO);
2802 - do_errors = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "errors for all interfaces",
2803 - CONFIG_BOOLEAN_AUTO);
2804 - do_drops = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "drops for all interfaces",
2805 - CONFIG_BOOLEAN_AUTO);
2806 - do_events = config_get_boolean_ondemand(CONFIG_SECTION_GETIFADDRS, "collisions for all interfaces",
2807 - CONFIG_BOOLEAN_AUTO);
2808 - }
2809 -
2810 - if (likely(do_bandwidth_ipv4 || do_bandwidth_ipv6 || do_bandwidth || do_packets || do_errors ||
2811 - do_drops || do_events)) {
2812 - struct ifaddrs *ifap;
2813 -
2814 - if (unlikely(getifaddrs(&ifap))) {
2815 - error("FREEBSD: getifaddrs() failed");
2816 - do_bandwidth_ipv4 = 0;
2817 - error("DISABLED: system.ipv4 chart");
2818 - do_bandwidth_ipv6 = 0;
2819 - error("DISABLED: system.ipv6 chart");
2820 - do_bandwidth = 0;
2821 - error("DISABLED: net.* charts");
2822 - do_packets = 0;
2823 - error("DISABLED: net_packets.* charts");
2824 - do_errors = 0;
2825 - error("DISABLED: net_errors.* charts");
2826 - do_drops = 0;
2827 - error("DISABLED: net_drops.* charts");
2828 - do_events = 0;
2829 - error("DISABLED: net_events.* charts");
2830 - error("DISABLED: getifaddrs module");
2831 - return 1;
2832 - } else {
2833 - #define IFA_DATA(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
2834 - struct ifaddrs *ifa;
2835 - struct iftot {
2836 - u_long ift_ibytes;
2837 - u_long ift_obytes;
2838 - } iftot = {0, 0};
2839 -
2840 - // --------------------------------------------------------------------
2841 -
2842 - if (likely(do_bandwidth_ipv4)) {
2843 - iftot.ift_ibytes = iftot.ift_obytes = 0;
2844 - for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
2845 - if (ifa->ifa_addr->sa_family != AF_INET)
2846 - continue;
2847 - iftot.ift_ibytes += IFA_DATA(ibytes);
2848 - iftot.ift_obytes += IFA_DATA(obytes);
2849 - }
2850 -
2851 - static RRDSET *st = NULL;
2852 - static RRDDIM *rd_in = NULL, *rd_out = NULL;
2853 -
2854 - if (unlikely(!st)) {
2855 - st = rrdset_create_localhost("system",
2856 - "ipv4",
2857 - NULL,
2858 - "network",
2859 - NULL,
2860 - "IPv4 Bandwidth",
2861 - "kilobits/s",
2862 - 500,
2863 - update_every,
2864 - RRDSET_TYPE_AREA
2865 - );
2866 -
2867 - rd_in = rrddim_add(st, "InOctets", "received", 8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
2868 - rd_out = rrddim_add(st, "OutOctets", "sent", -8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
2869 - } else
2870 - rrdset_next(st);
2871 -
2872 - rrddim_set_by_pointer(st, rd_in, iftot.ift_ibytes);
2873 - rrddim_set_by_pointer(st, rd_out, iftot.ift_obytes);
2874 - rrdset_done(st);
2875 - }
2876 -
2877 - // --------------------------------------------------------------------
2878 -
2879 - if (likely(do_bandwidth_ipv6)) {
2880 - iftot.ift_ibytes = iftot.ift_obytes = 0;
2881 - for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
2882 - if (ifa->ifa_addr->sa_family != AF_INET6)
2883 - continue;
2884 - iftot.ift_ibytes += IFA_DATA(ibytes);
2885 - iftot.ift_obytes += IFA_DATA(obytes);
2886 - }
2887 -
2888 - static RRDSET *st = NULL;
2889 - static RRDDIM *rd_in = NULL, *rd_out = NULL;
2890 -
2891 - if (unlikely(!st)) {
2892 - st = rrdset_create_localhost("system",
2893 - "ipv6",
2894 - NULL,
2895 - "network",
2896 - NULL,
2897 - "IPv6 Bandwidth",
2898 - "kilobits/s",
2899 - 500,
2900 - update_every,
2901 - RRDSET_TYPE_AREA
2902 - );
2903 -
2904 - rd_in = rrddim_add(st, "received", NULL, 8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
2905 - rd_out = rrddim_add(st, "sent", NULL, -8, KILO_FACTOR, RRD_ALGORITHM_INCREMENTAL);
2906 - } else
2907 - rrdset_next(st);
2908 -
2909 - rrddim_set_by_pointer(st, rd_in, iftot.ift_ibytes);
2910 - rrddim_set_by_pointer(st, rd_out, iftot.ift_obytes);
2911 - rrdset_done(st);
2912 - }
2913 -
2914 - // --------------------------------------------------------------------
2915 -
2916 - // Data to be stored in DICTIONARY interfaces.
2917 - // This DICTIONARY is used to lookup the settings of the interfaces on each iteration.
2918 - struct interfaces_metadata {
2919 - int do_bandwidth;
2920 - int do_packets;
2921 - int do_errors;
2922 - int do_drops;
2923 - int do_events;
2924 -
2925 - // charts and dimensions
2926 -
2927 - RRDSET *st_bandwidth;
2928 - RRDDIM *rd_bandwidth_in;
2929 - RRDDIM *rd_bandwidth_out;
2930 -
2931 - RRDSET *st_packets;
2932 - RRDDIM *rd_packets_in;
2933 - RRDDIM *rd_packets_out;
2934 - RRDDIM *rd_packets_m_in;
2935 - RRDDIM *rd_packets_m_out;
2936 -
2937 - RRDSET *st_errors;
2938 - RRDDIM *rd_errors_in;
2939 - RRDDIM *rd_errors_out;
2940 -
2941 - RRDSET *st_drops;
2942 - RRDDIM *rd_drops_in;
2943 - RRDDIM *rd_drops_out;
2944 -
2945 - RRDSET *st_events;
2946 - RRDDIM *rd_events_coll;
2947 - };
2948 - static DICTIONARY *interfaces = NULL;
2949 - static SIMPLE_PATTERN *excluded_interfaces = NULL;
2950 -
2951 - if(unlikely(!interfaces)) {
2952 -
2953 - excluded_interfaces = simple_pattern_create(
2954 - config_get(CONFIG_SECTION_GETIFADDRS, "disable by default interfaces matching",
2955 - DELAULT_EXLUDED_INTERFACES)
2956 - , SIMPLE_PATTERN_EXACT
2957 - );
2958 -
2959 - interfaces = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
2960 - }
2961 -
2962 - for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
2963 - if (ifa->ifa_addr->sa_family != AF_LINK)
2964 - continue;
2965 -
2966 - int def_bandwidth, def_packets, def_errors, def_drops, def_events,
2967 - iter_bandwidth, iter_packets, iter_errors, iter_drops, iter_events;
2968 -
2969 - struct interfaces_metadata *ifm = dictionary_get(interfaces, ifa->ifa_name);
2970 - if(unlikely(!ifm)) {
2971 - char var_name[4096 + 1];
2972 - snprintfz(var_name, 4096, "%s:%s", CONFIG_SECTION_GETIFADDRS, ifa->ifa_name);
2973 -
2974 - def_bandwidth = do_bandwidth;
2975 - def_packets = do_packets;
2976 - def_errors = do_errors;
2977 - def_drops = do_drops;
2978 - def_events = do_events;
2979 -
2980 - if(unlikely(simple_pattern_matches(excluded_interfaces, ifa->ifa_name))) {
2981 - def_bandwidth = CONFIG_BOOLEAN_NO;
2982 - def_packets = CONFIG_BOOLEAN_NO;
2983 - def_errors = CONFIG_BOOLEAN_NO;
2984 - def_drops = CONFIG_BOOLEAN_NO;
2985 - def_events = CONFIG_BOOLEAN_NO;
2986 - }
2987 -
2988 - iter_bandwidth = config_get_boolean_ondemand(var_name, "bandwidth", def_bandwidth);
2989 - iter_packets = config_get_boolean_ondemand(var_name, "packets", def_packets);
2990 - iter_errors = config_get_boolean_ondemand(var_name, "errors", def_errors);
2991 - iter_drops = config_get_boolean_ondemand(var_name, "drops", def_drops);
2992 - iter_events = config_get_boolean_ondemand(var_name, "events", def_events);
2993 -
2994 - struct interfaces_metadata ifmp = {
2995 - .do_bandwidth = iter_bandwidth,
2996 - .do_packets = iter_packets,
2997 - .do_errors = iter_errors,
2998 - .do_drops = iter_drops,
2999 - .do_events = iter_events,
3000 -
3001 - .st_bandwidth = NULL,
3002 - .rd_bandwidth_in = NULL,
3003 - .rd_bandwidth_out = NULL,
3004 -
3005 - .st_packets = NULL,
3006 - .rd_packets_in = NULL,
3007 - .rd_packets_out = NULL,
3008 - .rd_packets_m_in = NULL,
3009 - .rd_packets_m_out = NULL,
3010 -
3011 - .st_errors = NULL,
3012 - .rd_errors_in = NULL,
3013 - .rd_errors_out = NULL,
3014 -
3015 - .st_drops = NULL,
3016 - .rd_drops_in = NULL,
3017 - .rd_drops_out = NULL,
3018 -
3019 - .st_events = NULL,
3020 - .rd_events_coll = NULL,
3021 - };
3022 -
3023 - ifm = dictionary_set(interfaces, ifa->ifa_name, &ifmp, sizeof(struct interfaces_metadata));
3024 - }
3025 -
3026 - // --------------------------------------------------------------------
3027 -
3028 - if (ifm->do_bandwidth == CONFIG_BOOLEAN_YES || (ifm->do_bandwidth == CONFIG_BOOLEAN_AUTO &&
3029 - (IFA_DATA(ibytes) || IFA_DATA(obytes)))) {
3030 - if (unlikely(!ifm->st_bandwidth)) {
3031 - ifm->st_bandwidth = rrdset_create_localhost("net",
3032 - ifa->ifa_name,
3033 - NULL,
3034 - ifa->ifa_name,
3035 - "net.net",
3036 - "Bandwidth",
3037 - "kilobits/s",
3038 - 7000,
3039 - update_every,
3040 - RRDSET_TYPE_AREA
3041 - );
3042 -
3043 - ifm->rd_bandwidth_in = rrddim_add(ifm->st_bandwidth, "received", NULL, 8, KILO_FACTOR,
3044 - RRD_ALGORITHM_INCREMENTAL);
3045 - ifm->rd_bandwidth_out = rrddim_add(ifm->st_bandwidth, "sent", NULL, -8, KILO_FACTOR,
3046 - RRD_ALGORITHM_INCREMENTAL);
3047 - } else
3048 - rrdset_next(ifm->st_bandwidth);
3049 -
3050 - rrddim_set_by_pointer(ifm->st_bandwidth, ifm->rd_bandwidth_in, IFA_DATA(ibytes));
3051 - rrddim_set_by_pointer(ifm->st_bandwidth, ifm->rd_bandwidth_out, IFA_DATA(obytes));
3052 - rrdset_done(ifm->st_bandwidth);
3053 - }
3054 -
3055 - // --------------------------------------------------------------------
3056 -
3057 - if (ifm->do_packets == CONFIG_BOOLEAN_YES || (ifm->do_packets == CONFIG_BOOLEAN_AUTO &&
3058 - (IFA_DATA(ipackets) || IFA_DATA(opackets) || IFA_DATA(imcasts) || IFA_DATA(omcasts)))) {
3059 - if (unlikely(!ifm->st_packets)) {
3060 - ifm->st_packets = rrdset_create_localhost("net_packets",
3061 - ifa->ifa_name,
3062 - NULL,
3063 - ifa->ifa_name,
3064 - "net.packets",
3065 - "Packets",
3066 - "packets/s",
3067 - 7001,
3068 - update_every,
3069 - RRDSET_TYPE_LINE
3070 - );
3071 -
3072 - rrdset_flag_set(ifm->st_packets, RRDSET_FLAG_DETAIL);
3073 -
3074 - ifm->rd_packets_in = rrddim_add(ifm->st_packets, "received", NULL, 1, 1,
3075 - RRD_ALGORITHM_INCREMENTAL);
3076 - ifm->rd_packets_out = rrddim_add(ifm->st_packets, "sent", NULL, -1, 1,
3077 - RRD_ALGORITHM_INCREMENTAL);
3078 - ifm->rd_packets_m_in = rrddim_add(ifm->st_packets, "multicast_received", NULL, 1, 1,
3079 - RRD_ALGORITHM_INCREMENTAL);
3080 - ifm->rd_packets_m_out = rrddim_add(ifm->st_packets, "multicast_sent", NULL, -1, 1,
3081 - RRD_ALGORITHM_INCREMENTAL);
3082 - } else
3083 - rrdset_next(ifm->st_packets);
3084 -
3085 - rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_in, IFA_DATA(ipackets));
3086 - rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_out, IFA_DATA(opackets));
3087 - rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_m_in, IFA_DATA(imcasts));
3088 - rrddim_set_by_pointer(ifm->st_packets, ifm->rd_packets_m_out, IFA_DATA(omcasts));
3089 - rrdset_done(ifm->st_packets);
3090 - }
3091 -
3092 - // --------------------------------------------------------------------
3093 -
3094 - if (ifm->do_errors == CONFIG_BOOLEAN_YES || (ifm->do_errors == CONFIG_BOOLEAN_AUTO &&
3095 - (IFA_DATA(ierrors) || IFA_DATA(oerrors)))) {
3096 - if (unlikely(!ifm->st_errors)) {
3097 - ifm->st_errors = rrdset_create_localhost("net_errors",
3098 - ifa->ifa_name,
3099 - NULL,
3100 - ifa->ifa_name,
3101 - "net.errors",
3102 - "Interface Errors",
3103 - "errors/s",
3104 - 7002,
3105 - update_every,
3106 - RRDSET_TYPE_LINE
3107 - );
3108 -
3109 - rrdset_flag_set(ifm->st_errors, RRDSET_FLAG_DETAIL);
3110 -
3111 - ifm->rd_errors_in = rrddim_add(ifm->st_errors, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3112 - ifm->rd_errors_out = rrddim_add(ifm->st_errors, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3113 - } else
3114 - rrdset_next(ifm->st_errors);
3115 -
3116 - rrddim_set_by_pointer(ifm->st_errors, ifm->rd_errors_in, IFA_DATA(ierrors));
3117 - rrddim_set_by_pointer(ifm->st_errors, ifm->rd_errors_out, IFA_DATA(oerrors));
3118 - rrdset_done(ifm->st_errors);
3119 - }
3120 - // --------------------------------------------------------------------
3121 -
3122 - if (ifm->do_drops == CONFIG_BOOLEAN_YES || (ifm->do_drops == CONFIG_BOOLEAN_AUTO &&
3123 - (IFA_DATA(iqdrops)
3124 -#if __FreeBSD__ >= 11
3125 - || IFA_DATA(oqdrops)
3126 -#endif
3127 - ))) {
3128 - if (unlikely(!ifm->st_drops)) {
3129 - ifm->st_drops = rrdset_create_localhost("net_drops",
3130 - ifa->ifa_name,
3131 - NULL,
3132 - ifa->ifa_name,
3133 - "net.drops",
3134 - "Interface Drops",
3135 - "drops/s",
3136 - 7003,
3137 - update_every,
3138 - RRDSET_TYPE_LINE
3139 - );
3140 -
3141 - rrdset_flag_set(ifm->st_drops, RRDSET_FLAG_DETAIL);
3142 -
3143 - ifm->rd_drops_in = rrddim_add(ifm->st_drops, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
3144 -#if __FreeBSD__ >= 11
3145 - ifm->rd_drops_out = rrddim_add(ifm->st_drops, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
3146 -#endif
3147 - } else
3148 - rrdset_next(ifm->st_drops);
3149 -
3150 - rrddim_set_by_pointer(ifm->st_drops, ifm->rd_drops_in, IFA_DATA(iqdrops));
3151 -#if __FreeBSD__ >= 11
3152 - rrddim_set_by_pointer(ifm->st_drops, ifm->rd_drops_out, IFA_DATA(oqdrops));
3153 -#endif
3154 - rrdset_done(ifm->st_drops);
3155 - }
3156 -
3157 - // --------------------------------------------------------------------
3158 -
3159 - if (ifm->do_events == CONFIG_BOOLEAN_YES || (ifm->do_events == CONFIG_BOOLEAN_AUTO &&
3160 - IFA_DATA(collisions))) {
3161 - if (unlikely(!ifm->st_events)) {
3162 - ifm->st_events = rrdset_create_localhost("net_events",
3163 - ifa->ifa_name,
3164 - NULL,
3165 - ifa->ifa_name,
3166 - "net.events",
3167 - "Network Interface Events",
3168 - "events/s",
3169 - 7006,
3170 - update_every,
3171 - RRDSET_TYPE_LINE
3172 - );
3173 -
3174 - rrdset_flag_set(ifm->st_events, RRDSET_FLAG_DETAIL);
3175 -
3176 - ifm->rd_events_coll = rrddim_add(ifm->st_events, "collisions", NULL, -1, 1,
3177 - RRD_ALGORITHM_INCREMENTAL);
3178 - } else
3179 - rrdset_next(ifm->st_events);
3180 -
3181 - rrddim_set_by_pointer(ifm->st_events, ifm->rd_events_coll, IFA_DATA(collisions));
3182 - rrdset_done(ifm->st_events);
3183 - }
3184 - }
3185 -
3186 - freeifaddrs(ifap);
3187 - }
3188 - } else {
3189 - error("DISABLED: getifaddrs module");
3190 - return 1;
3191 - }
3192 -
3193 - return 0;
3194 -}
3195 -
2779 // --------------------------------------------------------------------------------------------------------------------
2780 // kern.devstat
2781