]> arthur.barton.de Git - netdata.git/blob - src/freebsd_sysctl.c
New sysctl helpers. Separate load average function
[netdata.git] / src / freebsd_sysctl.c
1 #include "common.h"
2
3 #include <sys/vmmeter.h>
4 #include <sys/devicestat.h>
5 #include <sys/mount.h>
6 #include <vm/vm_param.h>
7
8 #define _KERNEL
9 #include <sys/sem.h>
10 #include <sys/shm.h>
11 #include <sys/msg.h>
12 #undef _KERNEL
13
14 #include <net/netisr.h>
15 #include <net/if.h>
16 #include <ifaddrs.h>
17
18 #include <netinet/ip.h>
19 #include <netinet/ip_var.h>
20 #include <netinet/ip_icmp.h>
21 #include <netinet/icmp_var.h>
22 #include <netinet6/ip6_var.h>
23 #include <netinet/icmp6.h>
24 #include <netinet/tcp_var.h>
25 #include <netinet/tcp_fsm.h>
26 #include <netinet/udp.h>
27 #include <netinet/udp_var.h>
28
29 #define KILO_FACTOR 1024
30 #define MEGA_FACTOR 1048576     // 1024 * 1024
31 #define GIGA_FACTOR 1073741824  // 1024 * 1024 * 1024
32
33 #define MAX_INT_DIGITS 10 // maximum number of digits for int
34
35 int system_pagesize = PAGE_SIZE;
36
37 // FreeBSD plugin initialization
38 int freebsd_plugin_init()
39 {
40     system_pagesize = getpagesize();
41     if (system_pagesize <= 0) {
42         error("FREEBSD: can't get system page size");
43         return 1;
44     }
45
46     return 0;
47 }
48
49 // FreeBSD calculates load averages once every 5 seconds
50 #define MIN_LOADAVG_UPDATE_EVERY 5
51
52 int do_vm_loadavg(int update_every, usec_t dt){
53     static usec_t next_loadavg_dt = 0;
54     static int mib[2] = {0,0};
55     struct loadavg sysload;
56     static RRDSET *st = NULL;
57     static RRDDIM *rdload1 = NULL, *rdload2 = NULL, *rdload3 = NULL;
58
59     if (next_loadavg_dt <= dt) {
60         if (unlikely(GETSYSCTL_SIMPLE("vm.loadavg", mib, sysload))) {
61             error("DISABLED: system.load");
62             return 1;
63         } else if (unlikely(!st)) {
64             st = rrdset_create_localhost("system",
65                                          "load",
66                                          NULL,
67                                          "load",
68                                          NULL,
69                                          "System Load Average",
70                                          "load",
71                                          100,
72                                          (update_every < MIN_LOADAVG_UPDATE_EVERY) ?
73                                          MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE
74             );
75             rdload1 = rrddim_add(st, "load1", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
76             rdload2 = rrddim_add(st, "load5", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
77             rdload3 = rrddim_add(st, "load15", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
78         }
79         else rrdset_next(st);
80
81         rrddim_set_by_pointer(st, rdload1, (collected_number) ((double)sysload.ldavg[0] / sysload.fscale * 1000));
82         rrddim_set_by_pointer(st, rdload2, (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
83         rrddim_set_by_pointer(st, rdload3, (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
84         rrdset_done(st);
85
86         next_loadavg_dt = st->update_every * USEC_PER_SEC;
87     }
88     else next_loadavg_dt -= dt;
89
90     return 0;
91 }
92
93 // NEEDED BY: do_disk_io
94 #define RRD_TYPE_DISK "disk"
95
96 // NEEDED BY: do_bandwidth
97 #define IFA_DATA(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
98
99 int do_freebsd_sysctl_old(int update_every, usec_t dt) {
100     static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1,
101         do_all_processes = -1, do_disk_io = -1, do_swap = -1, do_ram = -1, do_swapio = -1,
102         do_pgfaults = -1, do_committed = -1, do_ipc_semaphores = -1, do_ipc_shared_mem = -1, do_ipc_msg_queues = -1,
103         do_dev_intr = -1, do_soft_intr = -1, do_netisr = -1, do_netisr_per_core = -1, do_bandwidth = -1,
104         do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
105         do_ecn = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1,
106         do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1,
107         do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
108         do_ip6_packets = -1, do_ip6_fragsout = -1, do_ip6_fragsin = -1, do_ip6_errors = -1,
109         do_icmp6 = -1, do_icmp6_redir = -1, do_icmp6_errors = -1, do_icmp6_echos = -1, do_icmp6_router = -1,
110         do_icmp6_neighbor = -1, do_icmp6_types = -1, do_space = -1, do_inodes = -1, do_uptime = -1;
111
112     if (unlikely(do_cpu == -1)) {
113         do_cpu                  = config_get_boolean("plugin:freebsd:sysctl", "cpu utilization", 1);
114         do_cpu_cores            = config_get_boolean("plugin:freebsd:sysctl", "per cpu core utilization", 1);
115         do_interrupts           = config_get_boolean("plugin:freebsd:sysctl", "cpu interrupts", 1);
116         do_dev_intr             = config_get_boolean("plugin:freebsd:sysctl", "device interrupts", 1);
117         do_soft_intr            = config_get_boolean("plugin:freebsd:sysctl", "software interrupts", 1);
118         do_context              = config_get_boolean("plugin:freebsd:sysctl", "context switches", 1);
119         do_forks                = config_get_boolean("plugin:freebsd:sysctl", "processes started", 1);
120         do_processes            = config_get_boolean("plugin:freebsd:sysctl", "processes running", 1);
121         do_all_processes        = config_get_boolean("plugin:freebsd:sysctl", "enable total processes", 1);
122         do_disk_io              = config_get_boolean("plugin:freebsd:sysctl", "stats for all disks", 1);
123         do_swap                 = config_get_boolean("plugin:freebsd:sysctl", "system swap", 1);
124         do_ram                  = config_get_boolean("plugin:freebsd:sysctl", "system ram", 1);
125         do_swapio               = config_get_boolean("plugin:freebsd:sysctl", "swap i/o", 1);
126         do_pgfaults             = config_get_boolean("plugin:freebsd:sysctl", "memory page faults", 1);
127         do_committed            = config_get_boolean("plugin:freebsd:sysctl", "committed memory", 1);
128         do_ipc_semaphores       = config_get_boolean("plugin:freebsd:sysctl", "ipc semaphores", 1);
129         do_ipc_shared_mem       = config_get_boolean("plugin:freebsd:sysctl", "ipc shared memory", 1);
130         do_ipc_msg_queues       = config_get_boolean("plugin:freebsd:sysctl", "ipc message queues", 1);
131         do_netisr               = config_get_boolean("plugin:freebsd:sysctl", "netisr", 1);
132         do_netisr_per_core      = config_get_boolean("plugin:freebsd:sysctl", "netisr per core", 1);
133         do_bandwidth            = config_get_boolean("plugin:freebsd:sysctl", "bandwidth", 1);
134         do_tcp_sockets          = config_get_boolean("plugin:freebsd:sysctl", "ipv4 TCP connections", 1);
135         do_tcp_packets          = config_get_boolean("plugin:freebsd:sysctl", "ipv4 TCP packets", 1);
136         do_tcp_errors           = config_get_boolean("plugin:freebsd:sysctl", "ipv4 TCP errors", 1);
137         do_tcp_handshake        = config_get_boolean("plugin:freebsd:sysctl", "ipv4 TCP handshake issues", 1);
138         do_ecn                  = config_get_boolean_ondemand("plugin:freebsd:sysctl", "ECN packets", CONFIG_BOOLEAN_AUTO);
139         do_tcpext_syscookies    = config_get_boolean_ondemand("plugin:freebsd:sysctl", "TCP SYN cookies", CONFIG_BOOLEAN_AUTO);
140         do_tcpext_ofo           = config_get_boolean_ondemand("plugin:freebsd:sysctl", "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO);
141         do_tcpext_connaborts    = config_get_boolean_ondemand("plugin:freebsd:sysctl", "TCP connection aborts", CONFIG_BOOLEAN_AUTO);
142         do_udp_packets          = config_get_boolean("plugin:freebsd:sysctl", "ipv4 UDP packets", 1);
143         do_udp_errors           = config_get_boolean("plugin:freebsd:sysctl", "ipv4 UDP errors", 1);
144         do_icmp_packets         = config_get_boolean("plugin:freebsd:sysctl", "ipv4 ICMP packets", 1);
145         do_icmpmsg              = config_get_boolean("plugin:freebsd:sysctl", "ipv4 ICMP messages", 1);
146         do_ip_packets           = config_get_boolean("plugin:freebsd:sysctl", "ipv4 packets", 1);
147         do_ip_fragsout          = config_get_boolean("plugin:freebsd:sysctl", "ipv4 fragments sent", 1);
148         do_ip_fragsin           = config_get_boolean("plugin:freebsd:sysctl", "ipv4 fragments assembly", 1);
149         do_ip_errors            = config_get_boolean("plugin:freebsd:sysctl", "ipv4 errors", 1);
150         do_ip6_packets          = config_get_boolean_ondemand("plugin:freebsd:sysctl", "ipv6 packets", CONFIG_BOOLEAN_AUTO);
151         do_ip6_fragsout         = config_get_boolean_ondemand("plugin:freebsd:sysctl", "ipv6 fragments sent", CONFIG_BOOLEAN_AUTO);
152         do_ip6_fragsin          = config_get_boolean_ondemand("plugin:freebsd:sysctl", "ipv6 fragments assembly", CONFIG_BOOLEAN_AUTO);
153         do_ip6_errors           = config_get_boolean_ondemand("plugin:freebsd:sysctl", "ipv6 errors", CONFIG_BOOLEAN_AUTO);
154         do_icmp6                = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp", CONFIG_BOOLEAN_AUTO);
155         do_icmp6_redir          = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp redirects", CONFIG_BOOLEAN_AUTO);
156         do_icmp6_errors         = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp errors", CONFIG_BOOLEAN_AUTO);
157         do_icmp6_echos          = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp echos", CONFIG_BOOLEAN_AUTO);
158         do_icmp6_router         = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp router", CONFIG_BOOLEAN_AUTO);
159         do_icmp6_neighbor       = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp neighbor", CONFIG_BOOLEAN_AUTO);
160         do_icmp6_types          = config_get_boolean_ondemand("plugin:freebsd:sysctl", "icmp types", CONFIG_BOOLEAN_AUTO);
161         do_space                = config_get_boolean("plugin:freebsd:sysctl", "space usage for all disks", 1);
162         do_inodes               = config_get_boolean("plugin:freebsd:sysctl", "inodes usage for all disks", 1);
163         do_uptime               = config_get_boolean("plugin:freebsd:sysctl", "system uptime", 1);
164     }
165
166     RRDSET *st;
167     RRDDIM *rd;
168
169     int i, n;
170     void *p;
171     int common_error = 0;
172     size_t size;
173     char title[4096 + 1];
174
175     // NEEDED BY: do_cpu, do_cpu_cores
176     long cp_time[CPUSTATES];
177
178     // NEEDED BY: du_cpu_cores, do_netisr, do_netisr_per_core
179     int ncpus;
180
181     // NEEDED BY: do_cpu_cores
182     static long *pcpu_cp_time = NULL;
183     char cpuid[MAX_INT_DIGITS + 1];
184
185     // NEEDED BY: do_all_processes, do_processes
186     struct vmtotal vmtotal_data;
187
188     // NEEDED BY: do_context, do_forks
189     u_int u_int_data;
190
191     // NEEDED BY: do_interrupts
192     size_t intrcnt_size;
193     unsigned long nintr = 0;
194     static unsigned long *intrcnt = NULL;
195     static char *intrnames = NULL;
196     unsigned long long totalintr = 0;
197
198     // NEEDED BY: do_disk_io
199     #define BINTIME_SCALE 5.42101086242752217003726400434970855712890625e-17 // this is 1000/2^64
200     int numdevs;
201     static void *devstat_data = NULL;
202     struct devstat *dstat;
203     char disk[DEVSTAT_NAME_LEN + MAX_INT_DIGITS + 1];
204     struct cur_dstat {
205         collected_number duration_read_ms;
206         collected_number duration_write_ms;
207         collected_number busy_time_ms;
208     } cur_dstat;
209     struct prev_dstat {
210         collected_number bytes_read;
211         collected_number bytes_write;
212         collected_number operations_read;
213         collected_number operations_write;
214         collected_number duration_read_ms;
215         collected_number duration_write_ms;
216         collected_number busy_time_ms;
217     } prev_dstat;
218
219     // NEEDED BY: do_swap
220     size_t mibsize;
221     int mib[3]; // CTL_MAXNAME = 24 maximum mib components (sysctl.h)
222     struct xswdev xsw;
223     struct total_xsw {
224         collected_number bytes_used;
225         collected_number bytes_total;
226     } total_xsw = {0, 0};
227
228     // NEEDED BY: do_swapio, do_ram
229     struct vmmeter vmmeter_data;
230
231     // NEEDED BY: do_ram
232     int vfs_bufspace_count;
233
234     // NEEDED BY: do_ipc_semaphores
235     struct ipc_sem {
236         int semmni;
237         collected_number sets;
238         collected_number semaphores;
239     } ipc_sem = {0, 0, 0};
240     static struct semid_kernel *ipc_sem_data = NULL;
241
242     // NEEDED BY: do_ipc_shared_mem
243     struct ipc_shm {
244         u_long shmmni;
245         collected_number segs;
246         collected_number segsize;
247     } ipc_shm = {0, 0, 0};
248     static struct shmid_kernel *ipc_shm_data = NULL;
249
250     // NEEDED BY: do_ipc_msg_queues
251     struct ipc_msq {
252         int msgmni;
253         collected_number queues;
254         collected_number messages;
255         collected_number usedsize;
256         collected_number allocsize;
257     } ipc_msq = {0, 0, 0, 0, 0};
258     static struct msqid_kernel *ipc_msq_data = NULL;
259
260     // NEEDED BY: do_netisr, do_netisr_per_core
261     size_t netisr_workstream_size;
262     size_t netisr_work_size;
263     unsigned long num_netisr_workstreams = 0, num_netisr_works = 0;
264     static struct sysctl_netisr_workstream *netisr_workstream = NULL;
265     static struct sysctl_netisr_work *netisr_work = NULL;
266     static struct netisr_stats {
267         collected_number dispatched;
268         collected_number hybrid_dispatched;
269         collected_number qdrops;
270         collected_number queued;
271     } *netisr_stats = NULL;
272     char netstat_cpuid[21]; // no more than 4 digits expected
273
274     // NEEDED BY: do_bandwidth
275     struct ifaddrs *ifa, *ifap;
276     struct iftot {
277         u_long  ift_ibytes;
278         u_long  ift_obytes;
279     } iftot = {0, 0};
280
281     // NEEDED BY: do_tcp...
282     struct tcpstat tcpstat;
283     uint64_t tcps_states[TCP_NSTATES];
284
285     // NEEDED BY: do_udp...
286     struct udpstat udpstat;
287
288     // NEEDED BY: do_icmp...
289     struct icmpstat icmpstat;
290     struct icmp_total {
291         u_long  msgs_in;
292         u_long  msgs_out;
293     } icmp_total = {0, 0};
294
295     // NEEDED BY: do_ip...
296     struct ipstat ipstat;
297
298     // NEEDED BY: do_ip6...
299     struct ip6stat ip6stat;
300
301     // NEEDED BY: do_icmp6...
302     struct icmp6stat icmp6stat;
303     struct icmp6_total {
304         u_long  msgs_in;
305         u_long  msgs_out;
306     } icmp6_total = {0, 0};
307
308     // NEEDED BY: do_space, do_inodes
309     struct statfs *mntbuf;
310     int mntsize;
311     char mntonname[MNAMELEN + 1];
312
313     // NEEDED BY: do_uptime
314     struct timespec up_time;
315
316     // --------------------------------------------------------------------
317
318     if (likely(do_all_processes | do_processes | do_committed)) {
319         if (unlikely(GETSYSCTL_BY_NAME("vm.vmtotal", vmtotal_data))) {
320             do_all_processes = 0;
321             error("DISABLED: system.active_processes");
322             do_processes = 0;
323             error("DISABLED: system.processes");
324             do_committed = 0;
325             error("DISABLED: mem.committed");
326         } else {
327             if (likely(do_all_processes)) {
328
329                 st = rrdset_find_bytype_localhost("system", "active_processes");
330                 if (unlikely(!st)) {
331                     st = rrdset_create_localhost("system", "active_processes", NULL, "processes", NULL, "System Active Processes", "processes", 750, update_every, RRDSET_TYPE_LINE);
332                     rrddim_add(st, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
333                 }
334                 else rrdset_next(st);
335
336                 rrddim_set(st, "active", (vmtotal_data.t_rq + vmtotal_data.t_dw + vmtotal_data.t_pw + vmtotal_data.t_sl + vmtotal_data.t_sw));
337                 rrdset_done(st);
338             }
339
340             // --------------------------------------------------------------------
341
342             if (likely(do_processes)) {
343
344                 st = rrdset_find_bytype_localhost("system", "processes");
345                 if (unlikely(!st)) {
346                     st = rrdset_create_localhost("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
347
348                     rrddim_add(st, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
349                     rrddim_add(st, "blocked", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
350                 }
351                 else rrdset_next(st);
352
353                 rrddim_set(st, "running", vmtotal_data.t_rq);
354                 rrddim_set(st, "blocked", (vmtotal_data.t_dw + vmtotal_data.t_pw));
355                 rrdset_done(st);
356             }
357
358             // --------------------------------------------------------------------
359
360             if (likely(do_committed)) {
361                 st = rrdset_find_localhost("mem.committed");
362                 if (unlikely(!st)) {
363                     st = rrdset_create_localhost("mem", "committed", NULL, "system", NULL, "Committed (Allocated) Memory", "MB", 5000, update_every, RRDSET_TYPE_AREA);
364                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
365
366                     rrddim_add(st, "Committed_AS", NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
367                 }
368                 else rrdset_next(st);
369
370                 rrddim_set(st, "Committed_AS", vmtotal_data.t_rm);
371                 rrdset_done(st);
372             }
373         }
374     }
375
376     // --------------------------------------------------------------------
377
378     if (likely(do_cpu)) {
379         if (unlikely(CPUSTATES != 5)) {
380             error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
381             do_cpu = 0;
382             error("DISABLED: system.cpu");
383         } else {
384             if (unlikely(GETSYSCTL_BY_NAME("kern.cp_time", cp_time))) {
385                 do_cpu = 0;
386                 error("DISABLED: system.cpu");
387             } else {
388
389                 st = rrdset_find_bytype_localhost("system", "cpu");
390                 if (unlikely(!st)) {
391                     st = rrdset_create_localhost("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED);
392
393                     rrddim_add(st, "nice", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
394                     rrddim_add(st, "system", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
395                     rrddim_add(st, "user", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
396                     rrddim_add(st, "interrupt", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
397                     rrddim_add(st, "idle", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
398                     rrddim_hide(st, "idle");
399                 }
400                 else rrdset_next(st);
401
402                 rrddim_set(st, "nice", cp_time[1]);
403                 rrddim_set(st, "system", cp_time[2]);
404                 rrddim_set(st, "user", cp_time[0]);
405                 rrddim_set(st, "interrupt", cp_time[3]);
406                 rrddim_set(st, "idle", cp_time[4]);
407                 rrdset_done(st);
408             }
409         }
410     }
411
412     // --------------------------------------------------------------------
413
414     if (likely(do_cpu_cores)) {
415         if (unlikely(CPUSTATES != 5)) {
416             error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
417             do_cpu_cores = 0;
418             error("DISABLED: cpu.cpuXX");
419         } else {
420             if (unlikely(GETSYSCTL_BY_NAME("kern.smp.cpus", ncpus))) {
421                 do_cpu_cores = 0;
422                 error("DISABLED: cpu.cpuXX");
423             } else {
424                 pcpu_cp_time = reallocz(pcpu_cp_time, sizeof(cp_time) * ncpus);
425                 if (unlikely(getsysctl_by_name("kern.cp_times", pcpu_cp_time, sizeof(cp_time) * ncpus))) {
426                     do_cpu_cores = 0;
427                     error("DISABLED: cpu.cpuXX");
428                 } else {
429                     for (i = 0; i < ncpus; i++) {
430                         snprintfz(cpuid, MAX_INT_DIGITS, "cpu%d", i);
431                         st = rrdset_find_bytype_localhost("cpu", cpuid);
432                         if (unlikely(!st)) {
433                             st = rrdset_create_localhost("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization",
434                                                "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
435
436                             rrddim_add(st, "nice", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
437                             rrddim_add(st, "system", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
438                             rrddim_add(st, "user", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
439                             rrddim_add(st, "interrupt", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
440                             rrddim_add(st, "idle", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
441                             rrddim_hide(st, "idle");
442                         } else
443                             rrdset_next(st);
444
445                         rrddim_set(st, "nice", pcpu_cp_time[i * 5 + 1]);
446                         rrddim_set(st, "system", pcpu_cp_time[i * 5 + 2]);
447                         rrddim_set(st, "user", pcpu_cp_time[i * 5 + 0]);
448                         rrddim_set(st, "interrupt", pcpu_cp_time[i * 5 + 3]);
449                         rrddim_set(st, "idle", pcpu_cp_time[i * 5 + 4]);
450                         rrdset_done(st);
451                 }
452                 }
453             }
454         }
455     }
456
457     // --------------------------------------------------------------------
458
459     if (likely(do_interrupts)) {
460         if (unlikely(sysctlbyname("hw.intrcnt", NULL, &intrcnt_size, NULL, 0) == -1)) {
461             error("FREEBSD: sysctl(hw.intrcnt...) failed: %s", strerror(errno));
462             do_interrupts = 0;
463             error("DISABLED: system.intr");
464         } else {
465             nintr = intrcnt_size / sizeof(u_long);
466             intrcnt = reallocz(intrcnt, nintr * sizeof(u_long));
467             if (unlikely(getsysctl_by_name("hw.intrcnt", intrcnt, nintr * sizeof(u_long)))){
468                 do_interrupts = 0;
469                 error("DISABLED: system.intr");
470             } else {
471                 for (i = 0; i < nintr; i++)
472                     totalintr += intrcnt[i];
473
474                 st = rrdset_find_bytype_localhost("system", "intr");
475                 if (unlikely(!st)) {
476                     st = rrdset_create_localhost("system", "intr", NULL, "interrupts", NULL, "Total Hardware Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
477                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
478
479                     rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
480                 }
481                 else rrdset_next(st);
482
483                 rrddim_set(st, "interrupts", totalintr);
484                 rrdset_done(st);
485
486                 // --------------------------------------------------------------------
487
488                 size = nintr * (MAXCOMLEN +1);
489                 intrnames = reallocz(intrnames, size);
490                 if (unlikely(getsysctl_by_name("hw.intrnames", intrnames, size))) {
491                     do_interrupts = 0;
492                     error("DISABLED: system.intr");
493                 } else {
494                     st = rrdset_find_bytype_localhost("system", "interrupts");
495                     if (unlikely(!st))
496                         st = rrdset_create_localhost("system", "interrupts", NULL, "interrupts", NULL, "System interrupts", "interrupts/s",
497                                            1000, update_every, RRDSET_TYPE_STACKED);
498                     else
499                         rrdset_next(st);
500
501                     for (i = 0; i < nintr; i++) {
502                         p = intrnames + i * (MAXCOMLEN + 1);
503                         if (unlikely((intrcnt[i] != 0) && (*(char*)p != 0))) {
504                             rd = rrddim_find(st, p);
505                             if (unlikely(!rd))
506                                 rd = rrddim_add(st, p, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
507                             rrddim_set_by_pointer(st, rd, intrcnt[i]);
508                         }
509                     }
510                     rrdset_done(st);
511                 }
512             }
513         }
514     }
515
516     // --------------------------------------------------------------------
517
518     if (likely(do_dev_intr)) {
519         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.sys.v_intr", u_int_data))) {
520             do_dev_intr = 0;
521             error("DISABLED: system.dev_intr");
522         } else {
523
524             st = rrdset_find_bytype_localhost("system", "dev_intr");
525             if (unlikely(!st)) {
526                 st = rrdset_create_localhost("system", "dev_intr", NULL, "interrupts", NULL, "Device Interrupts", "interrupts/s", 1000, update_every, RRDSET_TYPE_LINE);
527
528                 rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
529             }
530             else rrdset_next(st);
531
532             rrddim_set(st, "interrupts", u_int_data);
533             rrdset_done(st);
534         }
535     }
536
537     // --------------------------------------------------------------------
538
539     if (likely(do_soft_intr)) {
540         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.sys.v_soft", u_int_data))) {
541             do_soft_intr = 0;
542             error("DISABLED: system.dev_intr");
543         } else {
544
545             st = rrdset_find_bytype_localhost("system", "soft_intr");
546             if (unlikely(!st)) {
547                 st = rrdset_create_localhost("system", "soft_intr", NULL, "interrupts", NULL, "Software Interrupts", "interrupts/s", 1100, update_every, RRDSET_TYPE_LINE);
548
549                 rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
550             }
551             else rrdset_next(st);
552
553             rrddim_set(st, "interrupts", u_int_data);
554             rrdset_done(st);
555         }
556     }
557
558     // --------------------------------------------------------------------
559
560     if (likely(do_context)) {
561         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.sys.v_swtch", u_int_data))) {
562             do_context = 0;
563             error("DISABLED: system.ctxt");
564         } else {
565
566             st = rrdset_find_bytype_localhost("system", "ctxt");
567             if (unlikely(!st)) {
568                 st = rrdset_create_localhost("system", "ctxt", NULL, "processes", NULL, "CPU Context Switches", "context switches/s", 800, update_every, RRDSET_TYPE_LINE);
569
570                 rrddim_add(st, "switches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
571             }
572             else rrdset_next(st);
573
574             rrddim_set(st, "switches", u_int_data);
575             rrdset_done(st);
576         }
577     }
578
579     // --------------------------------------------------------------------
580
581     if (likely(do_forks)) {
582         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.vm.v_forks", u_int_data))) {
583             do_forks = 0;
584             error("DISABLED: system.forks");
585         } else {
586
587             st = rrdset_find_bytype_localhost("system", "forks");
588             if (unlikely(!st)) {
589                 st = rrdset_create_localhost("system", "forks", NULL, "processes", NULL, "Started Processes", "processes/s", 700, update_every, RRDSET_TYPE_LINE);
590                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
591
592                 rrddim_add(st, "started", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
593             }
594             else rrdset_next(st);
595
596             rrddim_set(st, "started", u_int_data);
597             rrdset_done(st);
598         }
599     }
600
601     // --------------------------------------------------------------------
602
603     if (likely(do_disk_io)) {
604         if (unlikely(GETSYSCTL_BY_NAME("kern.devstat.numdevs", numdevs))) {
605             do_disk_io = 0;
606             error("DISABLED: disk.io");
607         } else {
608             devstat_data = reallocz(devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs); // there is generation number before devstat structures
609             if (unlikely(
610                     getsysctl_by_name("kern.devstat.all", devstat_data, sizeof(long) + sizeof(struct devstat) * numdevs))) {
611                 do_disk_io = 0;
612                 error("DISABLED: disk.io");
613             } else {
614                 dstat = devstat_data + sizeof(long); // skip generation number
615                 collected_number total_disk_kbytes_read = 0;
616                 collected_number total_disk_kbytes_write = 0;
617
618                 for (i = 0; i < numdevs; i++) {
619                     if (((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_DIRECT) || ((dstat[i].device_type & DEVSTAT_TYPE_MASK) == DEVSTAT_TYPE_STORARRAY)) {
620                         sprintf(disk, "%s%d", dstat[i].device_name, dstat[i].unit_number);
621
622                         // --------------------------------------------------------------------
623
624                         st = rrdset_find_bytype_localhost(RRD_TYPE_DISK, disk);
625                         if (unlikely(!st)) {
626                             st = rrdset_create_localhost(RRD_TYPE_DISK, disk, NULL, disk, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
627
628                             rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
629                             rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
630                         }
631                         else rrdset_next(st);
632
633                         total_disk_kbytes_read += dstat[i].bytes[DEVSTAT_READ]/KILO_FACTOR;
634                         total_disk_kbytes_write += dstat[i].bytes[DEVSTAT_WRITE]/KILO_FACTOR;
635                         prev_dstat.bytes_read = rrddim_set(st, "reads", dstat[i].bytes[DEVSTAT_READ]);
636                         prev_dstat.bytes_write = rrddim_set(st, "writes", dstat[i].bytes[DEVSTAT_WRITE]);
637                         rrdset_done(st);
638
639                         // --------------------------------------------------------------------
640
641                         st = rrdset_find_bytype_localhost("disk_ops", disk);
642                         if (unlikely(!st)) {
643                             st = rrdset_create_localhost("disk_ops", disk, NULL, disk, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
644                             rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
645
646                             rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
647                             rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
648                         }
649                         else rrdset_next(st);
650
651                         prev_dstat.operations_read = rrddim_set(st, "reads", dstat[i].operations[DEVSTAT_READ]);
652                         prev_dstat.operations_write = rrddim_set(st, "writes", dstat[i].operations[DEVSTAT_WRITE]);
653                         rrdset_done(st);
654
655                         // --------------------------------------------------------------------
656
657                         st = rrdset_find_bytype_localhost("disk_qops", disk);
658                         if (unlikely(!st)) {
659                             st = rrdset_create_localhost("disk_qops", disk, NULL, disk, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
660                             rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
661
662                             rrddim_add(st, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
663                         }
664                         else rrdset_next(st);
665
666                         rrddim_set(st, "operations", dstat[i].start_count - dstat[i].end_count);
667                         rrdset_done(st);
668
669                         // --------------------------------------------------------------------
670
671                         st = rrdset_find_bytype_localhost("disk_util", disk);
672                         if (unlikely(!st)) {
673                             st = rrdset_create_localhost("disk_util", disk, NULL, disk, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
674                             rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
675
676                             rrddim_add(st, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
677                         }
678                         else rrdset_next(st);
679
680                         cur_dstat.busy_time_ms = dstat[i].busy_time.sec * 1000 + dstat[i].busy_time.frac * BINTIME_SCALE;
681                         prev_dstat.busy_time_ms = rrddim_set(st, "utilization", cur_dstat.busy_time_ms);
682                         rrdset_done(st);
683
684                         // --------------------------------------------------------------------
685
686                         st = rrdset_find_bytype_localhost("disk_iotime", disk);
687                         if (unlikely(!st)) {
688                             st = rrdset_create_localhost("disk_iotime", disk, NULL, disk, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
689                             rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
690
691                             rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
692                             rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
693                         }
694                         else rrdset_next(st);
695
696                         cur_dstat.duration_read_ms = dstat[i].duration[DEVSTAT_READ].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
697                         cur_dstat.duration_write_ms = dstat[i].duration[DEVSTAT_WRITE].sec * 1000 + dstat[i].duration[DEVSTAT_READ].frac * BINTIME_SCALE;
698                         prev_dstat.duration_read_ms = rrddim_set(st, "reads", cur_dstat.duration_read_ms);
699                         prev_dstat.duration_write_ms = rrddim_set(st, "writes", cur_dstat.duration_write_ms);
700                         rrdset_done(st);
701
702                         // --------------------------------------------------------------------
703                         // calculate differential charts
704                         // only if this is not the first time we run
705
706                         if (likely(dt)) {
707
708                             // --------------------------------------------------------------------
709
710                             st = rrdset_find_bytype_localhost("disk_await", disk);
711                             if (unlikely(!st)) {
712                                 st = rrdset_create_localhost("disk_await", disk, NULL, disk, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
713                                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
714
715                                 rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
716                                 rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
717                             }
718                             else rrdset_next(st);
719
720                             rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
721                                 (cur_dstat.duration_read_ms - prev_dstat.duration_read_ms) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
722                             rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
723                                 (cur_dstat.duration_write_ms - prev_dstat.duration_write_ms) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
724                             rrdset_done(st);
725
726                             // --------------------------------------------------------------------
727
728                             st = rrdset_find_bytype_localhost("disk_avgsz", disk);
729                             if (unlikely(!st)) {
730                                 st = rrdset_create_localhost("disk_avgsz", disk, NULL, disk, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
731                                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
732
733                                 rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
734                                 rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_ABSOLUTE);
735                             }
736                             else rrdset_next(st);
737
738                             rrddim_set(st, "reads", (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) ?
739                                 (dstat[i].bytes[DEVSTAT_READ] - prev_dstat.bytes_read) / (dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) : 0);
740                             rrddim_set(st, "writes", (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) ?
741                                 (dstat[i].bytes[DEVSTAT_WRITE] - prev_dstat.bytes_write) / (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write) : 0);
742                             rrdset_done(st);
743
744                             // --------------------------------------------------------------------
745
746                             st = rrdset_find_bytype_localhost("disk_svctm", disk);
747                             if (unlikely(!st)) {
748                                 st = rrdset_create_localhost("disk_svctm", disk, NULL, disk, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
749                                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
750
751                                 rrddim_add(st, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
752                             }
753                             else rrdset_next(st);
754
755                             rrddim_set(st, "svctm", ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) ?
756                                 (cur_dstat.busy_time_ms - prev_dstat.busy_time_ms) / ((dstat[i].operations[DEVSTAT_READ] - prev_dstat.operations_read) + (dstat[i].operations[DEVSTAT_WRITE] - prev_dstat.operations_write)) : 0);
757                             rrdset_done(st);
758                         }
759                     }
760                 }
761
762                 // --------------------------------------------------------------------
763
764                 st = rrdset_find_bytype_localhost("system", "io");
765                 if (unlikely(!st)) {
766                     st = rrdset_create_localhost("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
767                     rrddim_add(st, "in",  NULL,  1, 1, RRD_ALGORITHM_INCREMENTAL);
768                     rrddim_add(st, "out", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
769                 }
770                 else rrdset_next(st);
771
772                 rrddim_set(st, "in", total_disk_kbytes_read);
773                 rrddim_set(st, "out", total_disk_kbytes_write);
774                 rrdset_done(st);
775             }
776         }
777     }
778
779     // --------------------------------------------------------------------
780
781
782     if (likely(do_swap)) {
783         mibsize = sizeof mib / sizeof mib[0];
784         if (unlikely(sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)) {
785             error("FREEBSD: sysctl(%s...) failed: %s", "vm.swap_info", strerror(errno));
786             do_swap = 0;
787             error("DISABLED: system.swap");
788         } else {
789             for (i = 0; ; i++) {
790                 mib[mibsize] = i;
791                 size = sizeof(xsw);
792                 if (unlikely(sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1 )) {
793                     if (unlikely(errno != ENOENT)) {
794                         error("FREEBSD: sysctl(%s...) failed: %s", "vm.swap_info", strerror(errno));
795                         do_swap = 0;
796                         error("DISABLED: system.swap");
797                     } else {
798                         if (unlikely(size != sizeof(xsw))) {
799                             error("FREEBSD: sysctl(%s...) expected %lu, got %lu", "vm.swap_info", (unsigned long)sizeof(xsw), (unsigned long)size);
800                             do_swap = 0;
801                             error("DISABLED: system.swap");
802                         } else break;
803                     }
804                 }
805                 total_xsw.bytes_used += xsw.xsw_used;
806                 total_xsw.bytes_total += xsw.xsw_nblks;
807             }
808
809             if (likely(do_swap)) {
810                 st = rrdset_find_localhost("system.swap");
811                 if (unlikely(!st)) {
812                     st = rrdset_create_localhost("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201, update_every, RRDSET_TYPE_STACKED);
813                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
814
815                     rrddim_add(st, "free",    NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
816                     rrddim_add(st, "used",    NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
817                 }
818                 else rrdset_next(st);
819
820                 rrddim_set(st, "used", total_xsw.bytes_used);
821                 rrddim_set(st, "free", total_xsw.bytes_total - total_xsw.bytes_used);
822                 rrdset_done(st);
823             }
824         }
825     }
826
827     // --------------------------------------------------------------------
828
829     if (likely(do_ram)) {
830         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.vm.v_active_count",    vmmeter_data.v_active_count) ||
831                      GETSYSCTL_BY_NAME("vm.stats.vm.v_inactive_count",  vmmeter_data.v_inactive_count) ||
832                      GETSYSCTL_BY_NAME("vm.stats.vm.v_wire_count",      vmmeter_data.v_wire_count) ||
833 #if __FreeBSD_version < 1200016
834                      GETSYSCTL_BY_NAME("vm.stats.vm.v_cache_count",     vmmeter_data.v_cache_count) ||
835 #endif
836                      GETSYSCTL_BY_NAME("vfs.bufspace",                  vfs_bufspace_count) ||
837                      GETSYSCTL_BY_NAME("vm.stats.vm.v_free_count",      vmmeter_data.v_free_count))) {
838             do_ram = 0;
839             error("DISABLED: system.ram");
840         } else {
841             st = rrdset_find_localhost("system.ram");
842             if (unlikely(!st)) {
843                 st = rrdset_create_localhost("system", "ram", NULL, "ram", NULL, "System RAM", "MB", 200, update_every, RRDSET_TYPE_STACKED);
844
845                 rrddim_add(st, "active",    NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
846                 rrddim_add(st, "inactive",  NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
847                 rrddim_add(st, "wired",     NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
848 #if __FreeBSD_version < 1200016
849                 rrddim_add(st, "cache",     NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
850 #endif
851                 rrddim_add(st, "buffers",   NULL, 1, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
852                 rrddim_add(st, "free",      NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
853             }
854             else rrdset_next(st);
855
856             rrddim_set(st, "active",    vmmeter_data.v_active_count);
857             rrddim_set(st, "inactive",  vmmeter_data.v_inactive_count);
858             rrddim_set(st, "wired",     vmmeter_data.v_wire_count);
859 #if __FreeBSD_version < 1200016
860             rrddim_set(st, "cache",     vmmeter_data.v_cache_count);
861 #endif
862             rrddim_set(st, "buffers",   vfs_bufspace_count);
863             rrddim_set(st, "free",      vmmeter_data.v_free_count);
864             rrdset_done(st);
865         }
866     }
867
868     // --------------------------------------------------------------------
869
870     if (likely(do_swapio)) {
871         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.vm.v_swappgsin", vmmeter_data.v_swappgsin) || GETSYSCTL_BY_NAME("vm.stats.vm.v_swappgsout", vmmeter_data.v_swappgsout))) {
872             do_swapio = 0;
873             error("DISABLED: system.swapio");
874         } else {
875             st = rrdset_find_localhost("system.swapio");
876             if (unlikely(!st)) {
877                 st = rrdset_create_localhost("system", "swapio", NULL, "swap", NULL, "Swap I/O", "kilobytes/s", 250, update_every, RRDSET_TYPE_AREA);
878
879                 rrddim_add(st, "in",  NULL, system_pagesize, 1024, RRD_ALGORITHM_INCREMENTAL);
880                 rrddim_add(st, "out", NULL, -system_pagesize, 1024, RRD_ALGORITHM_INCREMENTAL);
881             }
882             else rrdset_next(st);
883
884             rrddim_set(st, "in", vmmeter_data.v_swappgsin);
885             rrddim_set(st, "out", vmmeter_data.v_swappgsout);
886             rrdset_done(st);
887         }
888     }
889
890     // --------------------------------------------------------------------
891
892     if (likely(do_pgfaults)) {
893         if (unlikely(GETSYSCTL_BY_NAME("vm.stats.vm.v_vm_faults",   vmmeter_data.v_vm_faults) ||
894                      GETSYSCTL_BY_NAME("vm.stats.vm.v_io_faults",   vmmeter_data.v_io_faults) ||
895                      GETSYSCTL_BY_NAME("vm.stats.vm.v_cow_faults",  vmmeter_data.v_cow_faults) ||
896                      GETSYSCTL_BY_NAME("vm.stats.vm.v_cow_optim",   vmmeter_data.v_cow_optim) ||
897                      GETSYSCTL_BY_NAME("vm.stats.vm.v_intrans",     vmmeter_data.v_intrans))) {
898             do_pgfaults = 0;
899             error("DISABLED: mem.pgfaults");
900         } else {
901             st = rrdset_find_localhost("mem.pgfaults");
902             if (unlikely(!st)) {
903                 st = rrdset_create_localhost("mem", "pgfaults", NULL, "system", NULL, "Memory Page Faults", "page faults/s", 500, update_every, RRDSET_TYPE_LINE);
904                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
905
906                 rrddim_add(st, "memory", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
907                 rrddim_add(st, "io_requiring", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
908                 rrddim_add(st, "cow", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
909                 rrddim_add(st, "cow_optimized", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
910                 rrddim_add(st, "in_transit", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
911             }
912             else rrdset_next(st);
913
914             rrddim_set(st, "memory", vmmeter_data.v_vm_faults);
915             rrddim_set(st, "io_requiring", vmmeter_data.v_io_faults);
916             rrddim_set(st, "cow", vmmeter_data.v_cow_faults);
917             rrddim_set(st, "cow_optimized", vmmeter_data.v_cow_optim);
918             rrddim_set(st, "in_transit", vmmeter_data.v_intrans);
919             rrdset_done(st);
920         }
921     }
922
923     // --------------------------------------------------------------------
924
925     if (likely(do_ipc_semaphores)) {
926         if (unlikely(GETSYSCTL_BY_NAME("kern.ipc.semmni", ipc_sem.semmni))) {
927             do_ipc_semaphores = 0;
928             error("DISABLED: system.ipc_semaphores");
929             error("DISABLED: system.ipc_semaphore_arrays");
930         } else {
931             ipc_sem_data = reallocz(ipc_sem_data, sizeof(struct semid_kernel) * ipc_sem.semmni);
932             if (unlikely(getsysctl_by_name("kern.ipc.sema", ipc_sem_data, sizeof(struct semid_kernel) * ipc_sem.semmni))) {
933                 do_ipc_semaphores = 0;
934                 error("DISABLED: system.ipc_semaphores");
935                 error("DISABLED: system.ipc_semaphore_arrays");
936             } else {
937                 for (i = 0; i < ipc_sem.semmni; i++) {
938                     if (unlikely(ipc_sem_data[i].u.sem_perm.mode & SEM_ALLOC)) {
939                         ipc_sem.sets += 1;
940                         ipc_sem.semaphores += ipc_sem_data[i].u.sem_nsems;
941                     }
942                 }
943
944                 // --------------------------------------------------------------------
945
946                 st = rrdset_find_localhost("system.ipc_semaphores");
947                 if (unlikely(!st)) {
948                     st = rrdset_create_localhost("system", "ipc_semaphores", NULL, "ipc semaphores", NULL, "IPC Semaphores", "semaphores", 1000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
949                     rrddim_add(st, "semaphores", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
950                 }
951                 else rrdset_next(st);
952
953                 rrddim_set(st, "semaphores", ipc_sem.semaphores);
954                 rrdset_done(st);
955
956                 // --------------------------------------------------------------------
957
958                 st = rrdset_find_localhost("system.ipc_semaphore_arrays");
959                 if (unlikely(!st)) {
960                     st = rrdset_create_localhost("system", "ipc_semaphore_arrays", NULL, "ipc semaphores", NULL, "IPC Semaphore Arrays", "arrays", 1000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
961                     rrddim_add(st, "arrays", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
962                 }
963                 else rrdset_next(st);
964
965                 rrddim_set(st, "arrays", ipc_sem.sets);
966                 rrdset_done(st);
967             }
968         }
969     }
970
971     // --------------------------------------------------------------------
972
973     if (likely(do_ipc_shared_mem)) {
974         if (unlikely(GETSYSCTL_BY_NAME("kern.ipc.shmmni", ipc_shm.shmmni))) {
975             do_ipc_shared_mem = 0;
976             error("DISABLED: system.ipc_shared_mem_segs");
977             error("DISABLED: system.ipc_shared_mem_size");
978         } else {
979             ipc_shm_data = reallocz(ipc_shm_data, sizeof(struct shmid_kernel) * ipc_shm.shmmni);
980             if (unlikely(
981                     getsysctl_by_name("kern.ipc.shmsegs", ipc_shm_data, sizeof(struct shmid_kernel) * ipc_shm.shmmni))) {
982                 do_ipc_shared_mem = 0;
983                 error("DISABLED: system.ipc_shared_mem_segs");
984                 error("DISABLED: system.ipc_shared_mem_size");
985             } else {
986                 for (i = 0; i < ipc_shm.shmmni; i++) {
987                     if (unlikely(ipc_shm_data[i].u.shm_perm.mode & 0x0800)) {
988                         ipc_shm.segs += 1;
989                         ipc_shm.segsize += ipc_shm_data[i].u.shm_segsz;
990                     }
991                 }
992
993                 // --------------------------------------------------------------------
994
995                 st = rrdset_find_localhost("system.ipc_shared_mem_segs");
996                 if (unlikely(!st)) {
997                     st = rrdset_create_localhost("system", "ipc_shared_mem_segs", NULL, "ipc shared memory", NULL, "IPC Shared Memory Segments", "segments", 1000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
998                     rrddim_add(st, "segments", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
999                 }
1000                 else rrdset_next(st);
1001
1002                 rrddim_set(st, "segments", ipc_shm.segs);
1003                 rrdset_done(st);
1004
1005                 // --------------------------------------------------------------------
1006
1007                 st = rrdset_find_localhost("system.ipc_shared_mem_size");
1008                 if (unlikely(!st)) {
1009                     st = rrdset_create_localhost("system", "ipc_shared_mem_size", NULL, "ipc shared memory", NULL, "IPC Shared Memory Segments Size", "kilobytes", 1000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
1010                     rrddim_add(st, "allocated", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
1011                 }
1012                 else rrdset_next(st);
1013
1014                 rrddim_set(st, "allocated", ipc_shm.segsize);
1015                 rrdset_done(st);
1016             }
1017         }
1018     }
1019
1020     // --------------------------------------------------------------------
1021
1022     if (likely(do_ipc_msg_queues)) {
1023         if (unlikely(GETSYSCTL_BY_NAME("kern.ipc.msgmni", ipc_msq.msgmni))) {
1024             do_ipc_msg_queues = 0;
1025             error("DISABLED: system.ipc_msq_queues");
1026             error("DISABLED: system.ipc_msq_messages");
1027             error("DISABLED: system.ipc_msq_size");
1028         } else {
1029             ipc_msq_data = reallocz(ipc_msq_data, sizeof(struct msqid_kernel) * ipc_msq.msgmni);
1030             if (unlikely(
1031                     getsysctl_by_name("kern.ipc.msqids", ipc_msq_data, sizeof(struct msqid_kernel) * ipc_msq.msgmni))) {
1032                 do_ipc_msg_queues = 0;
1033                 error("DISABLED: system.ipc_msq_queues");
1034                 error("DISABLED: system.ipc_msq_messages");
1035                 error("DISABLED: system.ipc_msq_size");
1036             } else {
1037                 for (i = 0; i < ipc_msq.msgmni; i++) {
1038                     if (unlikely(ipc_msq_data[i].u.msg_qbytes != 0)) {
1039                         ipc_msq.queues += 1;
1040                         ipc_msq.messages += ipc_msq_data[i].u.msg_qnum;
1041                         ipc_msq.usedsize += ipc_msq_data[i].u.msg_cbytes;
1042                         ipc_msq.allocsize += ipc_msq_data[i].u.msg_qbytes;
1043                     }
1044                 }
1045
1046                 // --------------------------------------------------------------------
1047
1048                 st = rrdset_find_localhost("system.ipc_msq_queues");
1049                 if (unlikely(!st)) {
1050                     st = rrdset_create_localhost("system", "ipc_msq_queues", NULL, "ipc message queues", NULL, "Number of IPC Message Queues", "queues", 990, localhost->rrd_update_every, RRDSET_TYPE_AREA);
1051                     rrddim_add(st, "queues", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1052                 }
1053                 else rrdset_next(st);
1054
1055                 rrddim_set(st, "queues", ipc_msq.queues);
1056                 rrdset_done(st);
1057
1058                 // --------------------------------------------------------------------
1059
1060                 st = rrdset_find_localhost("system.ipc_msq_messages");
1061                 if (unlikely(!st)) {
1062                     st = rrdset_create_localhost("system", "ipc_msq_messages", NULL, "ipc message queues", NULL, "Number of Messages in IPC Message Queues", "messages", 1000, localhost->rrd_update_every, RRDSET_TYPE_AREA);
1063                     rrddim_add(st, "messages", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1064                 }
1065                 else rrdset_next(st);
1066
1067                 rrddim_set(st, "messages", ipc_msq.messages);
1068                 rrdset_done(st);
1069
1070                 // --------------------------------------------------------------------
1071
1072                 st = rrdset_find_localhost("system.ipc_msq_size");
1073                 if (unlikely(!st)) {
1074                     st = rrdset_create_localhost("system", "ipc_msq_size", NULL, "ipc message queues", NULL, "Size of IPC Message Queues", "bytes", 1100, localhost->rrd_update_every, RRDSET_TYPE_LINE);
1075                     rrddim_add(st, "allocated", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1076                     rrddim_add(st, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1077                 }
1078                 else rrdset_next(st);
1079
1080                 rrddim_set(st, "allocated", ipc_msq.allocsize);
1081                 rrddim_set(st, "used", ipc_msq.usedsize);
1082                 rrdset_done(st);
1083
1084             }
1085         }
1086     }
1087
1088     // --------------------------------------------------------------------
1089
1090     if (likely(do_netisr || do_netisr_per_core)) {
1091         if (unlikely(GETSYSCTL_BY_NAME("kern.smp.cpus", ncpus))) {
1092             common_error = 1;
1093         } else if (unlikely(sysctlbyname("net.isr.workstream", NULL, &netisr_workstream_size, NULL, 0) == -1)) {
1094             error("FREEBSD: sysctl(net.isr.workstream...) failed: %s", strerror(errno));
1095             common_error = 1;
1096         } else if (unlikely(sysctlbyname("net.isr.work", NULL, &netisr_work_size, NULL, 0) == -1)) {
1097             error("FREEBSD: sysctl(net.isr.work...) failed: %s", strerror(errno));
1098             common_error = 1;
1099         } else {
1100             num_netisr_workstreams = netisr_workstream_size / sizeof(struct sysctl_netisr_workstream);
1101             netisr_workstream = reallocz(netisr_workstream, num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream));
1102             if (unlikely(getsysctl_by_name("net.isr.workstream", netisr_workstream,
1103                                            num_netisr_workstreams * sizeof(struct sysctl_netisr_workstream)))){
1104                 common_error = 1;
1105             } else {
1106                 num_netisr_works = netisr_work_size / sizeof(struct sysctl_netisr_work);
1107                 netisr_work = reallocz(netisr_work, num_netisr_works * sizeof(struct sysctl_netisr_work));
1108                 if (unlikely(getsysctl_by_name("net.isr.work", netisr_work,
1109                                                num_netisr_works * sizeof(struct sysctl_netisr_work)))){
1110                     common_error = 1;
1111                 }
1112             }
1113         }
1114         if (unlikely(common_error)) {
1115             do_netisr = 0;
1116             error("DISABLED: system.softnet_stat");
1117             do_netisr_per_core = 0;
1118             error("DISABLED: system.cpuX_softnet_stat");
1119             common_error = 0;
1120         } else {
1121             netisr_stats = reallocz(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
1122             bzero(netisr_stats, (ncpus + 1) * sizeof(struct netisr_stats));
1123             for (i = 0; i < num_netisr_workstreams; i++) {
1124                 for (n = 0; n < num_netisr_works; n++) {
1125                     if (netisr_workstream[i].snws_wsid == netisr_work[n].snw_wsid) {
1126                         netisr_stats[netisr_workstream[i].snws_cpu].dispatched += netisr_work[n].snw_dispatched;
1127                         netisr_stats[netisr_workstream[i].snws_cpu].hybrid_dispatched += netisr_work[n].snw_hybrid_dispatched;
1128                         netisr_stats[netisr_workstream[i].snws_cpu].qdrops += netisr_work[n].snw_qdrops;
1129                         netisr_stats[netisr_workstream[i].snws_cpu].queued += netisr_work[n].snw_queued;
1130                     }
1131                 }
1132             }
1133             for (i = 0; i < ncpus; i++) {
1134                 netisr_stats[ncpus].dispatched += netisr_stats[i].dispatched;
1135                 netisr_stats[ncpus].hybrid_dispatched += netisr_stats[i].hybrid_dispatched;
1136                 netisr_stats[ncpus].qdrops += netisr_stats[i].qdrops;
1137                 netisr_stats[ncpus].queued += netisr_stats[i].queued;
1138             }
1139         }
1140     }
1141
1142     // --------------------------------------------------------------------
1143
1144     if (likely(do_netisr)) {
1145         st = rrdset_find_bytype_localhost("system", "softnet_stat");
1146         if (unlikely(!st)) {
1147             st = rrdset_create_localhost("system", "softnet_stat", NULL, "softnet_stat", NULL, "System softnet_stat", "events/s", 955, update_every, RRDSET_TYPE_LINE);
1148             rrddim_add(st, "dispatched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1149             rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1150             rrddim_add(st, "qdrops", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1151             rrddim_add(st, "queued", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1152         }
1153         else rrdset_next(st);
1154
1155         rrddim_set(st, "dispatched", netisr_stats[ncpus].dispatched);
1156         rrddim_set(st, "hybrid_dispatched", netisr_stats[ncpus].hybrid_dispatched);
1157         rrddim_set(st, "qdrops", netisr_stats[ncpus].qdrops);
1158         rrddim_set(st, "queued", netisr_stats[ncpus].queued);
1159         rrdset_done(st);
1160     }
1161
1162     // --------------------------------------------------------------------
1163
1164     if (likely(do_netisr_per_core)) {
1165         for (i = 0; i < ncpus ;i++) {
1166             snprintfz(netstat_cpuid, 21, "cpu%d_softnet_stat", i);
1167
1168             st = rrdset_find_bytype_localhost("cpu", netstat_cpuid);
1169             if (unlikely(!st)) {
1170                 st = rrdset_create_localhost("cpu", netstat_cpuid, NULL, "softnet_stat", NULL, "Per CPU netisr statistics", "events/s", 1101 + i, update_every, RRDSET_TYPE_LINE);
1171                 rrddim_add(st, "dispatched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1172                 rrddim_add(st, "hybrid_dispatched", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1173                 rrddim_add(st, "qdrops", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1174                 rrddim_add(st, "queued", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1175             }
1176             else rrdset_next(st);
1177
1178             rrddim_set(st, "dispatched", netisr_stats[i].dispatched);
1179             rrddim_set(st, "hybrid_dispatched", netisr_stats[i].hybrid_dispatched);
1180             rrddim_set(st, "qdrops", netisr_stats[i].qdrops);
1181             rrddim_set(st, "queued", netisr_stats[i].queued);
1182             rrdset_done(st);
1183         }
1184     }
1185
1186     // --------------------------------------------------------------------
1187
1188     if (likely(do_bandwidth)) {
1189         if (unlikely(getifaddrs(&ifap))) {
1190             error("FREEBSD: getifaddrs()");
1191             do_bandwidth = 0;
1192             error("DISABLED: system.ipv4");
1193         } else {
1194             iftot.ift_ibytes = iftot.ift_obytes = 0;
1195             for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1196                 if (ifa->ifa_addr->sa_family != AF_INET)
1197                         continue;
1198                 iftot.ift_ibytes += IFA_DATA(ibytes);
1199                 iftot.ift_obytes += IFA_DATA(obytes);
1200             }
1201
1202             st = rrdset_find_localhost("system.ipv4");
1203             if (unlikely(!st)) {
1204                 st = rrdset_create_localhost("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA);
1205
1206                 rrddim_add(st, "InOctets", "received", 8, 1024, RRD_ALGORITHM_INCREMENTAL);
1207                 rrddim_add(st, "OutOctets", "sent", -8, 1024, RRD_ALGORITHM_INCREMENTAL);
1208             }
1209             else rrdset_next(st);
1210
1211             rrddim_set(st, "InOctets", iftot.ift_ibytes);
1212             rrddim_set(st, "OutOctets", iftot.ift_obytes);
1213             rrdset_done(st);
1214
1215             // --------------------------------------------------------------------
1216
1217             iftot.ift_ibytes = iftot.ift_obytes = 0;
1218             for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1219                 if (ifa->ifa_addr->sa_family != AF_INET6)
1220                         continue;
1221                 iftot.ift_ibytes += IFA_DATA(ibytes);
1222                 iftot.ift_obytes += IFA_DATA(obytes);
1223             }
1224
1225             st = rrdset_find_localhost("system.ipv6");
1226             if (unlikely(!st)) {
1227                 st = rrdset_create_localhost("system", "ipv6", NULL, "network", NULL, "IPv6 Bandwidth", "kilobits/s", 500, update_every, RRDSET_TYPE_AREA);
1228
1229                 rrddim_add(st, "received", NULL, 8, 1024, RRD_ALGORITHM_INCREMENTAL);
1230                 rrddim_add(st, "sent", NULL, -8, 1024, RRD_ALGORITHM_INCREMENTAL);
1231             }
1232             else rrdset_next(st);
1233
1234             rrddim_set(st, "sent", iftot.ift_obytes);
1235             rrddim_set(st, "received", iftot.ift_ibytes);
1236             rrdset_done(st);
1237
1238             for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1239                 if (ifa->ifa_addr->sa_family != AF_LINK)
1240                         continue;
1241
1242                 // --------------------------------------------------------------------
1243
1244                 st = rrdset_find_bytype_localhost("net", ifa->ifa_name);
1245                 if (unlikely(!st)) {
1246                     st = rrdset_create_localhost("net", ifa->ifa_name, NULL, ifa->ifa_name, "net.net", "Bandwidth", "kilobits/s", 7000, update_every, RRDSET_TYPE_AREA);
1247
1248                     rrddim_add(st, "received", NULL, 8, 1024, RRD_ALGORITHM_INCREMENTAL);
1249                     rrddim_add(st, "sent", NULL, -8, 1024, RRD_ALGORITHM_INCREMENTAL);
1250                 }
1251                 else rrdset_next(st);
1252
1253                 rrddim_set(st, "received", IFA_DATA(ibytes));
1254                 rrddim_set(st, "sent", IFA_DATA(obytes));
1255                 rrdset_done(st);
1256
1257                 // --------------------------------------------------------------------
1258
1259                 st = rrdset_find_bytype_localhost("net_packets", ifa->ifa_name);
1260                 if (unlikely(!st)) {
1261                     st = rrdset_create_localhost("net_packets", ifa->ifa_name, NULL, ifa->ifa_name, "net.packets", "Packets", "packets/s", 7001, update_every, RRDSET_TYPE_LINE);
1262                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1263
1264                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1265                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1266                     rrddim_add(st, "multicast_received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1267                     rrddim_add(st, "multicast_sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1268                 }
1269                 else rrdset_next(st);
1270
1271                 rrddim_set(st, "received", IFA_DATA(ipackets));
1272                 rrddim_set(st, "sent", IFA_DATA(opackets));
1273                 rrddim_set(st, "multicast_received", IFA_DATA(imcasts));
1274                 rrddim_set(st, "multicast_sent", IFA_DATA(omcasts));
1275                 rrdset_done(st);
1276
1277                 // --------------------------------------------------------------------
1278
1279                 st = rrdset_find_bytype_localhost("net_errors", ifa->ifa_name);
1280                 if (unlikely(!st)) {
1281                     st = rrdset_create_localhost("net_errors", ifa->ifa_name, NULL, ifa->ifa_name, "net.errors", "Interface Errors", "errors/s", 7002, update_every, RRDSET_TYPE_LINE);
1282                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1283
1284                     rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1285                     rrddim_add(st, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1286                 }
1287                 else rrdset_next(st);
1288
1289                 rrddim_set(st, "inbound", IFA_DATA(ierrors));
1290                 rrddim_set(st, "outbound", IFA_DATA(oerrors));
1291                 rrdset_done(st);
1292
1293                 // --------------------------------------------------------------------
1294
1295                 st = rrdset_find_bytype_localhost("net_drops", ifa->ifa_name);
1296                 if (unlikely(!st)) {
1297                     st = rrdset_create_localhost("net_drops", ifa->ifa_name, NULL, ifa->ifa_name, "net.drops", "Interface Drops", "drops/s", 7003, update_every, RRDSET_TYPE_LINE);
1298                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1299
1300                     rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1301 #if __FreeBSD__ >= 11
1302                     rrddim_add(st, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1303 #endif
1304                 }
1305                 else rrdset_next(st);
1306
1307                 rrddim_set(st, "inbound", IFA_DATA(iqdrops));
1308 #if __FreeBSD__ >= 11
1309                 rrddim_set(st, "outbound", IFA_DATA(oqdrops));
1310 #endif
1311                 rrdset_done(st);
1312
1313                 // --------------------------------------------------------------------
1314
1315                 st = rrdset_find_bytype_localhost("net_events", ifa->ifa_name);
1316                 if (unlikely(!st)) {
1317                     st = rrdset_create_localhost("net_events", ifa->ifa_name, NULL, ifa->ifa_name, "net.events", "Network Interface Events", "events/s", 7006, update_every, RRDSET_TYPE_LINE);
1318                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1319
1320                     rrddim_add(st, "frames", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1321                     rrddim_add(st, "collisions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1322                     rrddim_add(st, "carrier", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1323                 }
1324                 else rrdset_next(st);
1325
1326                 rrddim_set(st, "collisions", IFA_DATA(collisions));
1327                 rrdset_done(st);
1328             }
1329
1330             freeifaddrs(ifap);
1331         }
1332     }
1333
1334     // --------------------------------------------------------------------
1335
1336     // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
1337     if (likely(do_tcp_sockets)) {
1338         if (unlikely(GETSYSCTL_BY_NAME("net.inet.tcp.states", tcps_states))) {
1339             do_tcp_sockets = 0;
1340             error("DISABLED: ipv4.tcpsock");
1341         } else {
1342             if (likely(do_tcp_sockets)) {
1343                 st = rrdset_find_localhost("ipv4.tcpsock");
1344                 if (unlikely(!st)) {
1345                     st = rrdset_create_localhost("ipv4", "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections",
1346                                        "active connections", 2500, update_every, RRDSET_TYPE_LINE);
1347
1348                     rrddim_add(st, "CurrEstab", "connections", 1, 1, RRD_ALGORITHM_ABSOLUTE);
1349                 } else
1350                     rrdset_next(st);
1351
1352                 rrddim_set(st, "CurrEstab", tcps_states[TCPS_ESTABLISHED]);
1353                 rrdset_done(st);
1354             }
1355         }
1356     }
1357
1358     // --------------------------------------------------------------------
1359
1360     // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
1361     if (likely(do_tcp_packets || do_tcp_errors || do_tcp_handshake || do_tcpext_connaborts || do_tcpext_ofo || do_tcpext_syscookies || do_ecn)) {
1362         if (unlikely(GETSYSCTL_BY_NAME("net.inet.tcp.stats", tcpstat))){
1363             do_tcp_packets = 0;
1364             error("DISABLED: ipv4.tcppackets");
1365             do_tcp_errors = 0;
1366             error("DISABLED: ipv4.tcperrors");
1367             do_tcp_handshake = 0;
1368             error("DISABLED: ipv4.tcphandshake");
1369             do_tcpext_connaborts = 0;
1370             error("DISABLED: ipv4.tcpconnaborts");
1371             do_tcpext_ofo = 0;
1372             error("DISABLED: ipv4.tcpofo");
1373             do_tcpext_syscookies = 0;
1374             error("DISABLED: ipv4.tcpsyncookies");
1375             do_ecn = 0;
1376             error("DISABLED: ipv4.ecnpkts");
1377         } else {
1378             if (likely(do_tcp_packets)) {
1379                 st = rrdset_find_localhost("ipv4.tcppackets");
1380                 if (unlikely(!st)) {
1381                     st = rrdset_create_localhost("ipv4", "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets",
1382                                        "packets/s",
1383                                        2600, update_every, RRDSET_TYPE_LINE);
1384
1385                     rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1386                     rrddim_add(st, "OutSegs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1387                 } else
1388                     rrdset_next(st);
1389
1390                 rrddim_set(st, "InSegs", tcpstat.tcps_rcvtotal);
1391                 rrddim_set(st, "OutSegs", tcpstat.tcps_sndtotal);
1392                 rrdset_done(st);
1393             }
1394
1395             // --------------------------------------------------------------------
1396
1397             if (likely(do_tcp_errors)) {
1398                 st = rrdset_find_localhost("ipv4.tcperrors");
1399                 if (unlikely(!st)) {
1400                     st = rrdset_create_localhost("ipv4", "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors",
1401                                        "packets/s",
1402                                        2700, update_every, RRDSET_TYPE_LINE);
1403                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1404
1405                     rrddim_add(st, "InErrs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1406                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1407                     rrddim_add(st, "RetransSegs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1408                 } else
1409                     rrdset_next(st);
1410
1411 #if __FreeBSD__ >= 11
1412                 rrddim_set(st, "InErrs", tcpstat.tcps_rcvbadoff + tcpstat.tcps_rcvreassfull + tcpstat.tcps_rcvshort);
1413 #else
1414                 rrddim_set(st, "InErrs", tcpstat.tcps_rcvbadoff + tcpstat.tcps_rcvshort);
1415 #endif
1416                 rrddim_set(st, "InCsumErrors", tcpstat.tcps_rcvbadsum);
1417                 rrddim_set(st, "RetransSegs", tcpstat.tcps_sndrexmitpack);
1418                 rrdset_done(st);
1419             }
1420
1421             // --------------------------------------------------------------------
1422
1423             if (likely(do_tcp_handshake)) {
1424                 st = rrdset_find_localhost("ipv4.tcphandshake");
1425                 if (unlikely(!st)) {
1426                     st = rrdset_create_localhost("ipv4", "tcphandshake", NULL, "tcp", NULL,
1427                                        "IPv4 TCP Handshake Issues",
1428                                        "events/s", 2900, update_every, RRDSET_TYPE_LINE);
1429                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1430
1431                     rrddim_add(st, "EstabResets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1432                     rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1433                     rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1434                     rrddim_add(st, "AttemptFails", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1435                 } else
1436                     rrdset_next(st);
1437
1438                 rrddim_set(st, "EstabResets", tcpstat.tcps_drops);
1439                 rrddim_set(st, "ActiveOpens", tcpstat.tcps_connattempt);
1440                 rrddim_set(st, "PassiveOpens", tcpstat.tcps_accepts);
1441                 rrddim_set(st, "AttemptFails", tcpstat.tcps_conndrops);
1442                 rrdset_done(st);
1443             }
1444
1445             // --------------------------------------------------------------------
1446
1447             if (do_tcpext_connaborts == CONFIG_BOOLEAN_YES || (do_tcpext_connaborts == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_rcvpackafterwin || tcpstat.tcps_rcvafterclose || tcpstat.tcps_rcvmemdrop || tcpstat.tcps_persistdrop || tcpstat.tcps_finwait2_drops))) {
1448                 do_tcpext_connaborts = CONFIG_BOOLEAN_YES;
1449                 st = rrdset_find_localhost("ipv4.tcpconnaborts");
1450                 if (unlikely(!st)) {
1451                     st = rrdset_create_localhost("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts", "connections/s", 3010, update_every, RRDSET_TYPE_LINE);
1452
1453                     rrddim_add(st, "TCPAbortOnData",    "baddata",     1, 1, RRD_ALGORITHM_INCREMENTAL);
1454                     rrddim_add(st, "TCPAbortOnClose",   "userclosed",  1, 1, RRD_ALGORITHM_INCREMENTAL);
1455                     rrddim_add(st, "TCPAbortOnMemory",  "nomemory",    1, 1, RRD_ALGORITHM_INCREMENTAL);
1456                     rrddim_add(st, "TCPAbortOnTimeout", "timeout",     1, 1, RRD_ALGORITHM_INCREMENTAL);
1457                     rrddim_add(st, "TCPAbortOnLinger",  "linger",      1, 1, RRD_ALGORITHM_INCREMENTAL);
1458                 }
1459                 else rrdset_next(st);
1460
1461                 rrddim_set(st, "TCPAbortOnData",    tcpstat.tcps_rcvpackafterwin);
1462                 rrddim_set(st, "TCPAbortOnClose",   tcpstat.tcps_rcvafterclose);
1463                 rrddim_set(st, "TCPAbortOnMemory",  tcpstat.tcps_rcvmemdrop);
1464                 rrddim_set(st, "TCPAbortOnTimeout", tcpstat.tcps_persistdrop);
1465                 rrddim_set(st, "TCPAbortOnLinger",  tcpstat.tcps_finwait2_drops);
1466                 rrdset_done(st);
1467             }
1468
1469             // --------------------------------------------------------------------
1470
1471             if (do_tcpext_ofo == CONFIG_BOOLEAN_YES || (do_tcpext_ofo == CONFIG_BOOLEAN_AUTO && tcpstat.tcps_rcvoopack)) {
1472                 do_tcpext_ofo = CONFIG_BOOLEAN_YES;
1473                 st = rrdset_find_localhost("ipv4.tcpofo");
1474                 if (unlikely(!st)) {
1475                     st = rrdset_create_localhost("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue", "packets/s", 3050, update_every, RRDSET_TYPE_LINE);
1476
1477                     rrddim_add(st, "TCPOFOQueue", "inqueue",  1, 1, RRD_ALGORITHM_INCREMENTAL);
1478                 }
1479                 else rrdset_next(st);
1480
1481                 rrddim_set(st, "TCPOFOQueue",   tcpstat.tcps_rcvoopack);
1482                 rrdset_done(st);
1483             }
1484
1485             // --------------------------------------------------------------------
1486
1487             if (do_tcpext_syscookies == CONFIG_BOOLEAN_YES || (do_tcpext_syscookies == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_sc_sendcookie || tcpstat.tcps_sc_recvcookie || tcpstat.tcps_sc_zonefail))) {
1488                 do_tcpext_syscookies = CONFIG_BOOLEAN_YES;
1489
1490                 st = rrdset_find_localhost("ipv4.tcpsyncookies");
1491                 if (unlikely(!st)) {
1492                     st = rrdset_create_localhost("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies", "packets/s", 3100, update_every, RRDSET_TYPE_LINE);
1493
1494                     rrddim_add(st, "SyncookiesRecv",   "received",  1, 1, RRD_ALGORITHM_INCREMENTAL);
1495                     rrddim_add(st, "SyncookiesSent",   "sent",     -1, 1, RRD_ALGORITHM_INCREMENTAL);
1496                     rrddim_add(st, "SyncookiesFailed", "failed",   -1, 1, RRD_ALGORITHM_INCREMENTAL);
1497                 }
1498                 else rrdset_next(st);
1499
1500                 rrddim_set(st, "SyncookiesRecv",   tcpstat.tcps_sc_recvcookie);
1501                 rrddim_set(st, "SyncookiesSent",   tcpstat.tcps_sc_sendcookie);
1502                 rrddim_set(st, "SyncookiesFailed", tcpstat.tcps_sc_zonefail);
1503                 rrdset_done(st);
1504             }
1505
1506             // --------------------------------------------------------------------
1507
1508             if (do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_ecn_ce || tcpstat.tcps_ecn_ect0 || tcpstat.tcps_ecn_ect1))) {
1509                 do_ecn = CONFIG_BOOLEAN_YES;
1510                 st = rrdset_find_localhost("ipv4.ecnpkts");
1511                 if (unlikely(!st)) {
1512                     st = rrdset_create_localhost("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics", "packets/s", 8700, update_every, RRDSET_TYPE_LINE);
1513                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1514
1515                     rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1516                     rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1517                     rrddim_add(st, "InECT0Pkts", "ECTP0", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1518                     rrddim_add(st, "InECT1Pkts", "ECTP1", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1519                 }
1520                 else rrdset_next(st);
1521
1522                 rrddim_set(st, "InCEPkts", tcpstat.tcps_ecn_ce);
1523                 rrddim_set(st, "InNoECTPkts", tcpstat.tcps_ecn_ce - (tcpstat.tcps_ecn_ect0 + tcpstat.tcps_ecn_ect1));
1524                 rrddim_set(st, "InECT0Pkts", tcpstat.tcps_ecn_ect0);
1525                 rrddim_set(st, "InECT1Pkts", tcpstat.tcps_ecn_ect1);
1526                 rrdset_done(st);
1527             }
1528
1529         }
1530     }
1531
1532     // --------------------------------------------------------------------
1533
1534     // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
1535     if (likely(do_udp_packets || do_udp_errors)) {
1536         if (unlikely(GETSYSCTL_BY_NAME("net.inet.udp.stats", udpstat))) {
1537             do_udp_packets = 0;
1538             error("DISABLED: ipv4.udppackets");
1539             do_udp_errors = 0;
1540             error("DISABLED: ipv4.udperrors");
1541         } else {
1542             if (likely(do_udp_packets)) {
1543                 st = rrdset_find_localhost("ipv4.udppackets");
1544                 if (unlikely(!st)) {
1545                     st = rrdset_create_localhost("ipv4", "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets",
1546                                        "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
1547
1548                     rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1549                     rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1550                 } else
1551                     rrdset_next(st);
1552
1553                 rrddim_set(st, "InDatagrams", udpstat.udps_ipackets);
1554                 rrddim_set(st, "OutDatagrams", udpstat.udps_opackets);
1555                 rrdset_done(st);
1556             }
1557
1558             // --------------------------------------------------------------------
1559
1560             if (likely(do_udp_errors)) {
1561                 st = rrdset_find_localhost("ipv4.udperrors");
1562                 if (unlikely(!st)) {
1563                     st = rrdset_create_localhost("ipv4", "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s",
1564                                        2701, update_every, RRDSET_TYPE_LINE);
1565                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1566
1567                     rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1568                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1569                     rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1570                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1571                     rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1572                 } else
1573                     rrdset_next(st);
1574
1575                 rrddim_set(st, "InErrors", udpstat.udps_hdrops + udpstat.udps_badlen);
1576                 rrddim_set(st, "NoPorts", udpstat.udps_noport);
1577                 rrddim_set(st, "RcvbufErrors", udpstat.udps_fullsock);
1578                 rrddim_set(st, "InCsumErrors", udpstat.udps_badsum + udpstat.udps_nosum);
1579                 rrddim_set(st, "IgnoredMulti", udpstat.udps_filtermcast);
1580                 rrdset_done(st);
1581             }
1582         }
1583     }
1584
1585     // --------------------------------------------------------------------
1586
1587     if (likely(do_icmp_packets || do_icmpmsg)) {
1588         if (unlikely(GETSYSCTL_BY_NAME("net.inet.icmp.stats", icmpstat))) {
1589             do_icmp_packets = 0;
1590             error("DISABLED: ipv4.icmp");
1591             error("DISABLED: ipv4.icmp_errors");
1592             do_icmpmsg = 0;
1593             error("DISABLED: ipv4.icmpmsg");
1594         } else {
1595             for (i = 0; i <= ICMP_MAXTYPE; i++) {
1596                 icmp_total.msgs_in += icmpstat.icps_inhist[i];
1597                 icmp_total.msgs_out += icmpstat.icps_outhist[i];
1598             }
1599             icmp_total.msgs_in += icmpstat.icps_badcode + icmpstat.icps_badlen + icmpstat.icps_checksum + icmpstat.icps_tooshort;
1600
1601             // --------------------------------------------------------------------
1602
1603             if (likely(do_icmp_packets)) {
1604                 st = rrdset_find_localhost("ipv4.icmp");
1605                 if (unlikely(!st)) {
1606                     st = rrdset_create_localhost("ipv4", "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s",
1607                                        2602,
1608                                        update_every, RRDSET_TYPE_LINE);
1609
1610                     rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1611                     rrddim_add(st, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1612                 } else
1613                     rrdset_next(st);
1614
1615                 rrddim_set(st, "InMsgs", icmp_total.msgs_in);
1616                 rrddim_set(st, "OutMsgs", icmp_total.msgs_out);
1617
1618                 rrdset_done(st);
1619
1620                 // --------------------------------------------------------------------
1621
1622                 st = rrdset_find_localhost("ipv4.icmp_errors");
1623                 if (unlikely(!st)) {
1624                     st = rrdset_create_localhost("ipv4", "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors",
1625                                        "packets/s",
1626                                        2603, update_every, RRDSET_TYPE_LINE);
1627
1628                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1629                     rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1630                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1631                 } else
1632                     rrdset_next(st);
1633
1634                 rrddim_set(st, "InErrors", icmpstat.icps_badcode + icmpstat.icps_badlen + icmpstat.icps_checksum + icmpstat.icps_tooshort);
1635                 rrddim_set(st, "OutErrors", icmpstat.icps_error);
1636                 rrddim_set(st, "InCsumErrors", icmpstat.icps_checksum);
1637
1638                 rrdset_done(st);
1639             }
1640
1641             // --------------------------------------------------------------------
1642
1643             if (likely(do_icmpmsg)) {
1644                 st = rrdset_find_localhost("ipv4.icmpmsg");
1645                 if (unlikely(!st)) {
1646                     st = rrdset_create_localhost("ipv4", "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messsages",
1647                                        "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
1648
1649                     rrddim_add(st, "InEchoReps", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1650                     rrddim_add(st, "OutEchoReps", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1651                     rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1652                     rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1653                 } else
1654                     rrdset_next(st);
1655
1656                     rrddim_set(st, "InEchoReps", icmpstat.icps_inhist[ICMP_ECHOREPLY]);
1657                     rrddim_set(st, "OutEchoReps", icmpstat.icps_outhist[ICMP_ECHOREPLY]);
1658                     rrddim_set(st, "InEchos", icmpstat.icps_inhist[ICMP_ECHO]);
1659                     rrddim_set(st, "OutEchos", icmpstat.icps_outhist[ICMP_ECHO]);
1660
1661                 rrdset_done(st);
1662             }
1663         }
1664     }
1665
1666     // --------------------------------------------------------------------
1667
1668     // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
1669     if (likely(do_ip_packets || do_ip_fragsout || do_ip_fragsin || do_ip_errors)) {
1670         if (unlikely(GETSYSCTL_BY_NAME("net.inet.ip.stats", ipstat))) {
1671             do_ip_packets = 0;
1672             error("DISABLED: ipv4.packets");
1673             do_ip_fragsout = 0;
1674             error("DISABLED: ipv4.fragsout");
1675             do_ip_fragsin = 0;
1676             error("DISABLED: ipv4.fragsin");
1677             do_ip_errors = 0;
1678             error("DISABLED: ipv4.errors");
1679         } else {
1680             if (likely(do_ip_packets)) {
1681                 st = rrdset_find_localhost("ipv4.packets");
1682                 if (unlikely(!st)) {
1683                     st = rrdset_create_localhost("ipv4", "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s",
1684                                        3000, update_every, RRDSET_TYPE_LINE);
1685
1686                     rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1687                     rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1688                     rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1689                     rrddim_add(st, "InDelivers", "delivered", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1690                 } else
1691                     rrdset_next(st);
1692
1693                 rrddim_set(st, "OutRequests", ipstat.ips_localout);
1694                 rrddim_set(st, "InReceives", ipstat.ips_total);
1695                 rrddim_set(st, "ForwDatagrams", ipstat.ips_forward);
1696                 rrddim_set(st, "InDelivers", ipstat.ips_delivered);
1697                 rrdset_done(st);
1698             }
1699
1700             // --------------------------------------------------------------------
1701
1702             if (likely(do_ip_fragsout)) {
1703                 st = rrdset_find_localhost("ipv4.fragsout");
1704                 if (unlikely(!st)) {
1705                     st = rrdset_create_localhost("ipv4", "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent",
1706                                        "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
1707                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1708
1709                     rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1710                     rrddim_add(st, "FragFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1711                     rrddim_add(st, "FragCreates", "created", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1712                 } else
1713                     rrdset_next(st);
1714
1715                 rrddim_set(st, "FragOKs", ipstat.ips_fragmented);
1716                 rrddim_set(st, "FragFails", ipstat.ips_cantfrag);
1717                 rrddim_set(st, "FragCreates", ipstat.ips_ofragments);
1718                 rrdset_done(st);
1719             }
1720
1721             // --------------------------------------------------------------------
1722
1723             if (likely(do_ip_fragsin)) {
1724                 st = rrdset_find_localhost("ipv4.fragsin");
1725                 if (unlikely(!st)) {
1726                     st = rrdset_create_localhost("ipv4", "fragsin", NULL, "fragments", NULL,
1727                                        "IPv4 Fragments Reassembly",
1728                                        "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
1729                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1730
1731                     rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1732                     rrddim_add(st, "ReasmFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
1733                     rrddim_add(st, "ReasmReqds", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
1734                 } else
1735                     rrdset_next(st);
1736
1737                 rrddim_set(st, "ReasmOKs", ipstat.ips_fragments);
1738                 rrddim_set(st, "ReasmFails", ipstat.ips_fragdropped);
1739                 rrddim_set(st, "ReasmReqds", ipstat.ips_reassembled);
1740                 rrdset_done(st);
1741             }
1742
1743             // --------------------------------------------------------------------
1744
1745             if (likely(do_ip_errors)) {
1746                 st = rrdset_find_localhost("ipv4.errors");
1747                 if (unlikely(!st)) {
1748                     st = rrdset_create_localhost("ipv4", "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s",
1749                                        3002,
1750                                        update_every, RRDSET_TYPE_LINE);
1751                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1752
1753                     rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1754                     rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1755
1756                     rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1757                     rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1758
1759                     rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1760                     rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1761                 } else
1762                     rrdset_next(st);
1763
1764                 rrddim_set(st, "InDiscards", ipstat.ips_badsum + ipstat.ips_tooshort + ipstat.ips_toosmall + ipstat.ips_toolong);
1765                 rrddim_set(st, "OutDiscards", ipstat.ips_odropped);
1766                 rrddim_set(st, "InHdrErrors", ipstat.ips_badhlen + ipstat.ips_badlen + ipstat.ips_badoptions + ipstat.ips_badvers);
1767                 rrddim_set(st, "InAddrErrors", ipstat.ips_badaddr);
1768                 rrddim_set(st, "InUnknownProtos", ipstat.ips_noproto);
1769                 rrddim_set(st, "OutNoRoutes", ipstat.ips_noroute);
1770                 rrdset_done(st);
1771             }
1772         }
1773     }
1774
1775     // --------------------------------------------------------------------
1776
1777     if (likely(do_ip6_packets || do_ip6_fragsout || do_ip6_fragsin || do_ip6_errors)) {
1778         if (unlikely(GETSYSCTL_BY_NAME("net.inet6.ip6.stats", ip6stat))) {
1779             do_ip6_packets = 0;
1780             error("DISABLED: ipv6.packets");
1781             do_ip6_fragsout = 0;
1782             error("DISABLED: ipv6.fragsout");
1783             do_ip6_fragsin = 0;
1784             error("DISABLED: ipv6.fragsin");
1785             do_ip6_errors = 0;
1786             error("DISABLED: ipv6.errors");
1787         } else {
1788             if (do_ip6_packets == CONFIG_BOOLEAN_YES || (do_ip6_packets == CONFIG_BOOLEAN_AUTO &&
1789                                                           (ip6stat.ip6s_localout || ip6stat.ip6s_total ||
1790                                                            ip6stat.ip6s_forward || ip6stat.ip6s_delivered))) {
1791                 do_ip6_packets = CONFIG_BOOLEAN_YES;
1792                 st = rrdset_find_localhost("ipv6.packets");
1793                 if (unlikely(!st)) {
1794                     st = rrdset_create_localhost("ipv6", "packets", NULL, "packets", NULL, "IPv6 Packets", "packets/s", 3000,
1795                                        update_every, RRDSET_TYPE_LINE);
1796
1797                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1798                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1799                     rrddim_add(st, "forwarded", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1800                     rrddim_add(st, "delivers", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1801                 } else
1802                     rrdset_next(st);
1803
1804                 rrddim_set(st, "sent", ip6stat.ip6s_localout);
1805                 rrddim_set(st, "received", ip6stat.ip6s_total);
1806                 rrddim_set(st, "forwarded", ip6stat.ip6s_forward);
1807                 rrddim_set(st, "delivers", ip6stat.ip6s_delivered);
1808                 rrdset_done(st);
1809             }
1810
1811             // --------------------------------------------------------------------
1812
1813             if (do_ip6_fragsout == CONFIG_BOOLEAN_YES || (do_ip6_fragsout == CONFIG_BOOLEAN_AUTO &&
1814                                                            (ip6stat.ip6s_fragmented || ip6stat.ip6s_cantfrag ||
1815                                                             ip6stat.ip6s_ofragments))) {
1816                 do_ip6_fragsout = CONFIG_BOOLEAN_YES;
1817                 st = rrdset_find_localhost("ipv6.fragsout");
1818                 if (unlikely(!st)) {
1819                     st = rrdset_create_localhost("ipv6", "fragsout", NULL, "fragments", NULL, "IPv6 Fragments Sent",
1820                                        "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
1821                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1822
1823                     rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1824                     rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1825                     rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1826                 } else
1827                     rrdset_next(st);
1828
1829                 rrddim_set(st, "ok", ip6stat.ip6s_fragmented);
1830                 rrddim_set(st, "failed", ip6stat.ip6s_cantfrag);
1831                 rrddim_set(st, "all", ip6stat.ip6s_ofragments);
1832                 rrdset_done(st);
1833             }
1834
1835             // --------------------------------------------------------------------
1836
1837             if (do_ip6_fragsin == CONFIG_BOOLEAN_YES || (do_ip6_fragsin == CONFIG_BOOLEAN_AUTO &&
1838                                                           (ip6stat.ip6s_reassembled || ip6stat.ip6s_fragdropped ||
1839                                                            ip6stat.ip6s_fragtimeout || ip6stat.ip6s_fragments))) {
1840                 do_ip6_fragsin = CONFIG_BOOLEAN_YES;
1841                 st = rrdset_find_localhost("ipv6.fragsin");
1842                 if (unlikely(!st)) {
1843                     st = rrdset_create_localhost("ipv6", "fragsin", NULL, "fragments", NULL, "IPv6 Fragments Reassembly",
1844                                        "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
1845                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1846
1847                     rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1848                     rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1849                     rrddim_add(st, "timeout", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1850                     rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1851                 } else
1852                     rrdset_next(st);
1853
1854                 rrddim_set(st, "ok", ip6stat.ip6s_reassembled);
1855                 rrddim_set(st, "failed", ip6stat.ip6s_fragdropped);
1856                 rrddim_set(st, "timeout", ip6stat.ip6s_fragtimeout);
1857                 rrddim_set(st, "all", ip6stat.ip6s_fragments);
1858                 rrdset_done(st);
1859             }
1860
1861             // --------------------------------------------------------------------
1862
1863             if (do_ip6_errors == CONFIG_BOOLEAN_YES || (do_ip6_errors == CONFIG_BOOLEAN_AUTO && (
1864                     ip6stat.ip6s_toosmall ||
1865                     ip6stat.ip6s_odropped ||
1866                     ip6stat.ip6s_badoptions ||
1867                     ip6stat.ip6s_badvers ||
1868                     ip6stat.ip6s_exthdrtoolong ||
1869                     ip6stat.ip6s_sources_none ||
1870                     ip6stat.ip6s_tooshort ||
1871                     ip6stat.ip6s_cantforward ||
1872                     ip6stat.ip6s_noroute))) {
1873                 do_ip6_errors = CONFIG_BOOLEAN_YES;
1874                 st = rrdset_find_localhost("ipv6.errors");
1875                 if (unlikely(!st)) {
1876                     st = rrdset_create_localhost("ipv6", "errors", NULL, "errors", NULL, "IPv6 Errors", "packets/s", 3002,
1877                                        update_every, RRDSET_TYPE_LINE);
1878                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
1879
1880                     rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1881                     rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1882
1883                     rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1884                     rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1885                     rrddim_add(st, "InTruncatedPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1886                     rrddim_add(st, "InNoRoutes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1887
1888                     rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1889                 } else
1890                     rrdset_next(st);
1891
1892                 rrddim_set(st, "InDiscards", ip6stat.ip6s_toosmall);
1893                 rrddim_set(st, "OutDiscards", ip6stat.ip6s_odropped);
1894
1895                 rrddim_set(st, "InHdrErrors",
1896                            ip6stat.ip6s_badoptions + ip6stat.ip6s_badvers + ip6stat.ip6s_exthdrtoolong);
1897                 rrddim_set(st, "InAddrErrors", ip6stat.ip6s_sources_none);
1898                 rrddim_set(st, "InTruncatedPkts", ip6stat.ip6s_tooshort);
1899                 rrddim_set(st, "InNoRoutes", ip6stat.ip6s_cantforward);
1900
1901                 rrddim_set(st, "OutNoRoutes", ip6stat.ip6s_noroute);
1902                 rrdset_done(st);
1903             }
1904         }
1905     }
1906
1907     // --------------------------------------------------------------------
1908
1909     if (likely(do_icmp6 || do_icmp6_redir || do_icmp6_errors || do_icmp6_echos || do_icmp6_router || do_icmp6_neighbor || do_icmp6_types)) {
1910         if (unlikely(GETSYSCTL_BY_NAME("net.inet6.icmp6.stats", icmp6stat))) {
1911             do_icmp6 = 0;
1912             error("DISABLED: ipv6.icmp");
1913         } else {
1914             for (i = 0; i <= ICMP6_MAXTYPE; i++) {
1915                 icmp6_total.msgs_in += icmp6stat.icp6s_inhist[i];
1916                 icmp6_total.msgs_out += icmp6stat.icp6s_outhist[i];
1917             }
1918             icmp6_total.msgs_in += icmp6stat.icp6s_badcode + icmp6stat.icp6s_badlen + icmp6stat.icp6s_checksum + icmp6stat.icp6s_tooshort;
1919             if (do_icmp6 == CONFIG_BOOLEAN_YES || (do_icmp6 == CONFIG_BOOLEAN_AUTO && (icmp6_total.msgs_in || icmp6_total.msgs_out))) {
1920                 do_icmp6 = CONFIG_BOOLEAN_YES;
1921                 st = rrdset_find_localhost("ipv6.icmp");
1922                 if (unlikely(!st)) {
1923                     st = rrdset_create_localhost("ipv6", "icmp", NULL, "icmp", NULL, "IPv6 ICMP Messages",
1924                                        "messages/s", 10000, update_every, RRDSET_TYPE_LINE);
1925
1926                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1927                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1928                 } else
1929                     rrdset_next(st);
1930
1931                 rrddim_set(st, "sent", icmp6_total.msgs_in);
1932                 rrddim_set(st, "received", icmp6_total.msgs_out);
1933                 rrdset_done(st);
1934             }
1935
1936             // --------------------------------------------------------------------
1937
1938             if (do_icmp6_redir == CONFIG_BOOLEAN_YES || (do_icmp6_redir == CONFIG_BOOLEAN_AUTO && (icmp6stat.icp6s_inhist[ND_REDIRECT] || icmp6stat.icp6s_outhist[ND_REDIRECT]))) {
1939                 do_icmp6_redir = CONFIG_BOOLEAN_YES;
1940                 st = rrdset_find_localhost("ipv6.icmpredir");
1941                 if (unlikely(!st)) {
1942                     st = rrdset_create_localhost("ipv6", "icmpredir", NULL, "icmp", NULL, "IPv6 ICMP Redirects",
1943                                        "redirects/s", 10050, update_every, RRDSET_TYPE_LINE);
1944
1945                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1946                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1947                 } else
1948                     rrdset_next(st);
1949
1950                 rrddim_set(st, "sent", icmp6stat.icp6s_inhist[ND_REDIRECT]);
1951                 rrddim_set(st, "received", icmp6stat.icp6s_outhist[ND_REDIRECT]);
1952                 rrdset_done(st);
1953             }
1954
1955             // --------------------------------------------------------------------
1956
1957             if (do_icmp6_errors == CONFIG_BOOLEAN_YES || (do_icmp6_errors == CONFIG_BOOLEAN_AUTO && (
1958                                                                             icmp6stat.icp6s_badcode ||
1959                                                                             icmp6stat.icp6s_badlen ||
1960                                                                             icmp6stat.icp6s_checksum ||
1961                                                                             icmp6stat.icp6s_tooshort ||
1962                                                                             icmp6stat.icp6s_error ||
1963                                                                             icmp6stat.icp6s_inhist[ICMP6_DST_UNREACH] ||
1964                                                                             icmp6stat.icp6s_inhist[ICMP6_TIME_EXCEEDED] ||
1965                                                                             icmp6stat.icp6s_inhist[ICMP6_PARAM_PROB] ||
1966                                                                             icmp6stat.icp6s_outhist[ICMP6_DST_UNREACH] ||
1967                                                                             icmp6stat.icp6s_outhist[ICMP6_TIME_EXCEEDED] ||
1968                                                                             icmp6stat.icp6s_outhist[ICMP6_PARAM_PROB]))) {
1969                 do_icmp6_errors = CONFIG_BOOLEAN_YES;
1970                 st = rrdset_find_localhost("ipv6.icmperrors");
1971                 if (unlikely(!st)) {
1972                     st = rrdset_create_localhost("ipv6", "icmperrors", NULL, "icmp", NULL, "IPv6 ICMP Errors", "errors/s", 10100, update_every, RRDSET_TYPE_LINE);
1973
1974                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1975                     rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1976
1977                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1978                     rrddim_add(st, "InDestUnreachs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1979                     rrddim_add(st, "InPktTooBigs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1980                     rrddim_add(st, "InTimeExcds", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1981                     rrddim_add(st, "InParmProblems", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1982                     rrddim_add(st, "OutDestUnreachs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1983                     rrddim_add(st, "OutTimeExcds", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1984                     rrddim_add(st, "OutParmProblems", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1985                 } else
1986                     rrdset_next(st);
1987
1988                 rrddim_set(st, "InErrors", icmp6stat.icp6s_badcode + icmp6stat.icp6s_badlen + icmp6stat.icp6s_checksum + icmp6stat.icp6s_tooshort);
1989                 rrddim_set(st, "OutErrors", icmp6stat.icp6s_error);
1990                 rrddim_set(st, "InCsumErrors", icmp6stat.icp6s_checksum);
1991                 rrddim_set(st, "InDestUnreachs", icmp6stat.icp6s_inhist[ICMP6_DST_UNREACH]);
1992                 rrddim_set(st, "InPktTooBigs", icmp6stat.icp6s_badlen);
1993                 rrddim_set(st, "InTimeExcds", icmp6stat.icp6s_inhist[ICMP6_TIME_EXCEEDED]);
1994                 rrddim_set(st, "InParmProblems", icmp6stat.icp6s_inhist[ICMP6_PARAM_PROB]);
1995                 rrddim_set(st, "OutDestUnreachs", icmp6stat.icp6s_outhist[ICMP6_DST_UNREACH]);
1996                 rrddim_set(st, "OutTimeExcds", icmp6stat.icp6s_outhist[ICMP6_TIME_EXCEEDED]);
1997                 rrddim_set(st, "OutParmProblems", icmp6stat.icp6s_outhist[ICMP6_PARAM_PROB]);
1998                 rrdset_done(st);
1999             }
2000
2001             // --------------------------------------------------------------------
2002
2003             if (do_icmp6_echos == CONFIG_BOOLEAN_YES || (do_icmp6_echos == CONFIG_BOOLEAN_AUTO && (
2004                                                                  icmp6stat.icp6s_inhist[ICMP6_ECHO_REQUEST] ||
2005                                                                  icmp6stat.icp6s_outhist[ICMP6_ECHO_REQUEST] ||
2006                                                                  icmp6stat.icp6s_inhist[ICMP6_ECHO_REPLY] ||
2007                                                                  icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]))) {
2008                 do_icmp6_echos = CONFIG_BOOLEAN_YES;
2009                 st = rrdset_find_localhost("ipv6.icmpechos");
2010                 if (unlikely(!st)) {
2011                     st = rrdset_create_localhost("ipv6", "icmpechos", NULL, "icmp", NULL, "IPv6 ICMP Echo", "messages/s", 10200, update_every, RRDSET_TYPE_LINE);
2012
2013                     rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2014                     rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2015                     rrddim_add(st, "InEchoReplies", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2016                     rrddim_add(st, "OutEchoReplies", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2017                 } else
2018                     rrdset_next(st);
2019
2020                 rrddim_set(st, "InEchos", icmp6stat.icp6s_inhist[ICMP6_ECHO_REQUEST]);
2021                 rrddim_set(st, "OutEchos", icmp6stat.icp6s_outhist[ICMP6_ECHO_REQUEST]);
2022                 rrddim_set(st, "InEchoReplies", icmp6stat.icp6s_inhist[ICMP6_ECHO_REPLY]);
2023                 rrddim_set(st, "OutEchoReplies", icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]);
2024                 rrdset_done(st);
2025             }
2026
2027             // --------------------------------------------------------------------
2028
2029             if (do_icmp6_router == CONFIG_BOOLEAN_YES || (do_icmp6_router == CONFIG_BOOLEAN_AUTO && (
2030                                                                     icmp6stat.icp6s_inhist[ND_ROUTER_SOLICIT] ||
2031                                                                     icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT] ||
2032                                                                     icmp6stat.icp6s_inhist[ND_ROUTER_ADVERT] ||
2033                                                                     icmp6stat.icp6s_outhist[ND_ROUTER_ADVERT]))) {
2034                 do_icmp6_router = CONFIG_BOOLEAN_YES;
2035                 st = rrdset_find_localhost("ipv6.icmprouter");
2036                 if (unlikely(!st)) {
2037                     st = rrdset_create_localhost("ipv6", "icmprouter", NULL, "icmp", NULL, "IPv6 Router Messages", "messages/s", 10400, update_every, RRDSET_TYPE_LINE);
2038
2039                     rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2040                     rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2041                     rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2042                     rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2043                 } else
2044                     rrdset_next(st);
2045
2046                 rrddim_set(st, "InSolicits", icmp6stat.icp6s_inhist[ND_ROUTER_SOLICIT]);
2047                 rrddim_set(st, "OutSolicits", icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT]);
2048                 rrddim_set(st, "InAdvertisements", icmp6stat.icp6s_inhist[ND_ROUTER_ADVERT]);
2049                 rrddim_set(st, "OutAdvertisements", icmp6stat.icp6s_outhist[ND_ROUTER_ADVERT]);
2050                 rrdset_done(st);
2051             }
2052
2053             // --------------------------------------------------------------------
2054
2055             if (do_icmp6_neighbor == CONFIG_BOOLEAN_YES || (do_icmp6_neighbor == CONFIG_BOOLEAN_AUTO && (
2056                                                                     icmp6stat.icp6s_inhist[ND_NEIGHBOR_SOLICIT] ||
2057                                                                     icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT] ||
2058                                                                     icmp6stat.icp6s_inhist[ND_NEIGHBOR_ADVERT] ||
2059                                                                     icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]))) {
2060                 do_icmp6_neighbor = CONFIG_BOOLEAN_YES;
2061                 st = rrdset_find_localhost("ipv6.icmpneighbor");
2062                 if (unlikely(!st)) {
2063                     st = rrdset_create_localhost("ipv6", "icmpneighbor", NULL, "icmp", NULL, "IPv6 Neighbor Messages", "messages/s", 10500, update_every, RRDSET_TYPE_LINE);
2064
2065                     rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2066                     rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2067                     rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2068                     rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2069                 } else
2070                     rrdset_next(st);
2071
2072                 rrddim_set(st, "InSolicits", icmp6stat.icp6s_inhist[ND_NEIGHBOR_SOLICIT]);
2073                 rrddim_set(st, "OutSolicits", icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]);
2074                 rrddim_set(st, "InAdvertisements", icmp6stat.icp6s_inhist[ND_NEIGHBOR_ADVERT]);
2075                 rrddim_set(st, "OutAdvertisements", icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]);
2076                 rrdset_done(st);
2077             }
2078
2079             // --------------------------------------------------------------------
2080
2081             if (do_icmp6_types == CONFIG_BOOLEAN_YES || (do_icmp6_types == CONFIG_BOOLEAN_AUTO && (
2082                                                                     icmp6stat.icp6s_inhist[1] ||
2083                                                                     icmp6stat.icp6s_inhist[128] ||
2084                                                                     icmp6stat.icp6s_inhist[129] ||
2085                                                                     icmp6stat.icp6s_inhist[136] ||
2086                                                                     icmp6stat.icp6s_outhist[1] ||
2087                                                                     icmp6stat.icp6s_outhist[128] ||
2088                                                                     icmp6stat.icp6s_outhist[129] ||
2089                                                                     icmp6stat.icp6s_outhist[133] ||
2090                                                                     icmp6stat.icp6s_outhist[135] ||
2091                                                                     icmp6stat.icp6s_outhist[136]))) {
2092                 do_icmp6_types = CONFIG_BOOLEAN_YES;
2093                 st = rrdset_find_localhost("ipv6.icmptypes");
2094                 if (unlikely(!st)) {
2095                     st = rrdset_create_localhost("ipv6", "icmptypes", NULL, "icmp", NULL, "IPv6 ICMP Types",
2096                                        "messages/s", 10700, update_every, RRDSET_TYPE_LINE);
2097
2098                     rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2099                     rrddim_add(st, "InType128", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2100                     rrddim_add(st, "InType129", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2101                     rrddim_add(st, "InType136", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
2102                     rrddim_add(st, "OutType1", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2103                     rrddim_add(st, "OutType128", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2104                     rrddim_add(st, "OutType129", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2105                     rrddim_add(st, "OutType133", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2106                     rrddim_add(st, "OutType135", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2107                     rrddim_add(st, "OutType143", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
2108                 } else
2109                     rrdset_next(st);
2110
2111                 rrddim_set(st, "InType1", icmp6stat.icp6s_inhist[1]);
2112                 rrddim_set(st, "InType128", icmp6stat.icp6s_inhist[128]);
2113                 rrddim_set(st, "InType129", icmp6stat.icp6s_inhist[129]);
2114                 rrddim_set(st, "InType136", icmp6stat.icp6s_inhist[136]);
2115                 rrddim_set(st, "OutType1", icmp6stat.icp6s_outhist[1]);
2116                 rrddim_set(st, "OutType128", icmp6stat.icp6s_outhist[128]);
2117                 rrddim_set(st, "OutType129", icmp6stat.icp6s_outhist[129]);
2118                 rrddim_set(st, "OutType133", icmp6stat.icp6s_outhist[133]);
2119                 rrddim_set(st, "OutType135", icmp6stat.icp6s_outhist[135]);
2120                 rrddim_set(st, "OutType143", icmp6stat.icp6s_outhist[143]);
2121                 rrdset_done(st);
2122             }
2123         }
2124     }
2125
2126     // --------------------------------------------------------------------------
2127
2128     if (likely(do_space || do_inodes)) {
2129         // there is no mount info in sysctl MIBs
2130         if (unlikely(!(mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)))) {
2131             error("FREEBSD: getmntinfo() failed");
2132             do_space = 0;
2133             error("DISABLED: disk_space.X");
2134             do_inodes = 0;
2135             error("DISABLED: disk_inodes.X");
2136         } else {
2137             for (i = 0; i < mntsize; i++) {
2138                 if (mntbuf[i].f_flags == MNT_RDONLY ||
2139                         mntbuf[i].f_blocks == 0 ||
2140                         // taken from gnulib/mountlist.c and shortened to FreeBSD related fstypes
2141                         strcmp(mntbuf[i].f_fstypename, "autofs") == 0 ||
2142                         strcmp(mntbuf[i].f_fstypename, "procfs") == 0 ||
2143                         strcmp(mntbuf[i].f_fstypename, "subfs") == 0 ||
2144                         strcmp(mntbuf[i].f_fstypename, "devfs") == 0 ||
2145                         strcmp(mntbuf[i].f_fstypename, "none") == 0)
2146                     continue;
2147
2148                 // --------------------------------------------------------------------------
2149
2150                 if (likely(do_space)) {
2151                     st = rrdset_find_bytype_localhost("disk_space", mntbuf[i].f_mntonname);
2152                     if (unlikely(!st)) {
2153                         snprintfz(title, 4096, "Disk Space Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
2154                         st = rrdset_create_localhost("disk_space", mntbuf[i].f_mntonname, NULL, mntbuf[i].f_mntonname, "disk.space", title, "GB", 2023,
2155                                            update_every,
2156                                            RRDSET_TYPE_STACKED);
2157
2158                         rrddim_add(st, "avail", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
2159                         rrddim_add(st, "used", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
2160                         rrddim_add(st, "reserved_for_root", "reserved for root", mntbuf[i].f_bsize, GIGA_FACTOR,
2161                                 RRD_ALGORITHM_ABSOLUTE);
2162                     } else
2163                         rrdset_next(st);
2164
2165                     rrddim_set(st, "avail", (collected_number) mntbuf[i].f_bavail);
2166                     rrddim_set(st, "used", (collected_number) (mntbuf[i].f_blocks - mntbuf[i].f_bfree));
2167                     rrddim_set(st, "reserved_for_root", (collected_number) (mntbuf[i].f_bfree - mntbuf[i].f_bavail));
2168                     rrdset_done(st);
2169                 }
2170
2171                 // --------------------------------------------------------------------------
2172
2173                 if (likely(do_inodes)) {
2174                     st = rrdset_find_bytype_localhost("disk_inodes", mntbuf[i].f_mntonname);
2175                     if (unlikely(!st)) {
2176                         snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
2177                         st = rrdset_create_localhost("disk_inodes", mntbuf[i].f_mntonname, NULL, mntbuf[i].f_mntonname, "disk.inodes", title, "Inodes", 2024,
2178                                            update_every, RRDSET_TYPE_STACKED);
2179
2180                         rrddim_add(st, "avail", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
2181                         rrddim_add(st, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
2182                         rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRD_ALGORITHM_ABSOLUTE);
2183                     } else
2184                         rrdset_next(st);
2185
2186                     rrddim_set(st, "avail", (collected_number) mntbuf[i].f_ffree);
2187                     rrddim_set(st, "used", (collected_number) (mntbuf[i].f_files - mntbuf[i].f_ffree));
2188                     rrdset_done(st);
2189                 }
2190             }
2191         }
2192     }
2193
2194     // --------------------------------------------------------------------
2195
2196     if (likely(do_uptime)) {
2197             clock_gettime(CLOCK_UPTIME, &up_time);
2198             st = rrdset_find_localhost("system.uptime");
2199
2200             if(unlikely(!st)) {
2201                 st = rrdset_create_localhost("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000, update_every, RRDSET_TYPE_LINE);
2202                 rrddim_add(st, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
2203             }
2204             else rrdset_next(st);
2205
2206             rrddim_set(st, "uptime", up_time.tv_sec);
2207             rrdset_done(st);
2208     }
2209
2210     return 0;
2211 }