]> arthur.barton.de Git - netdata.git/blob - src/proc_net_netstat.c
Merge pull request #1998 from ktsaou/master
[netdata.git] / src / proc_net_netstat.c
1 #include "common.h"
2
3 static void parse_line_pair(procfile *ff, ARL_BASE *base, size_t header_line, size_t values_line) {
4     size_t hwords = procfile_linewords(ff, header_line);
5     size_t vwords = procfile_linewords(ff, values_line);
6     size_t w;
7
8     if(unlikely(vwords > hwords)) {
9         error("File /proc/net/netstat on header line %zu has %zu words, but on value line %zu has %zu words.", header_line, hwords, values_line, vwords);
10         vwords = hwords;
11     }
12
13     for(w = 1; w < vwords ;w++) {
14         if(unlikely(arl_check(base, procfile_lineword(ff, header_line, w), procfile_lineword(ff, values_line, w))))
15             break;
16     }
17 }
18
19 int do_proc_net_netstat(int update_every, usec_t dt) {
20     (void)dt;
21
22     static int do_bandwidth = -1, do_inerrors = -1, do_mcast = -1, do_bcast = -1, do_mcast_p = -1, do_bcast_p = -1, do_ecn = -1, \
23         do_tcpext_reorder = -1, do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1, do_tcpext_memory = -1;
24     static uint32_t hash_ipext = 0, hash_tcpext = 0;
25     static procfile *ff = NULL;
26
27     static ARL_BASE *arl_tcpext = NULL;
28     static ARL_BASE *arl_ipext = NULL;
29
30     // --------------------------------------------------------------------
31     // IPv4
32
33     // IPv4 bandwidth
34     static unsigned long long ipext_InOctets = 0;
35     static unsigned long long ipext_OutOctets = 0;
36
37     // IPv4 input errors
38     static unsigned long long ipext_InNoRoutes = 0;
39     static unsigned long long ipext_InTruncatedPkts = 0;
40     static unsigned long long ipext_InCsumErrors = 0;
41
42     // IPv4 multicast bandwidth
43     static unsigned long long ipext_InMcastOctets = 0;
44     static unsigned long long ipext_OutMcastOctets = 0;
45
46     // IPv4 multicast packets
47     static unsigned long long ipext_InMcastPkts = 0;
48     static unsigned long long ipext_OutMcastPkts = 0;
49
50     // IPv4 broadcast bandwidth
51     static unsigned long long ipext_InBcastOctets = 0;
52     static unsigned long long ipext_OutBcastOctets = 0;
53
54     // IPv4 broadcast packets
55     static unsigned long long ipext_InBcastPkts = 0;
56     static unsigned long long ipext_OutBcastPkts = 0;
57
58     // IPv4 ECN
59     static unsigned long long ipext_InNoECTPkts = 0;
60     static unsigned long long ipext_InECT1Pkts = 0;
61     static unsigned long long ipext_InECT0Pkts = 0;
62     static unsigned long long ipext_InCEPkts = 0;
63
64     // --------------------------------------------------------------------
65     // IPv4 TCP
66
67     // IPv4 TCP Reordering
68     static unsigned long long tcpext_TCPRenoReorder = 0;
69     static unsigned long long tcpext_TCPFACKReorder = 0;
70     static unsigned long long tcpext_TCPSACKReorder = 0;
71     static unsigned long long tcpext_TCPTSReorder = 0;
72
73     // IPv4 TCP SYN Cookies
74     static unsigned long long tcpext_SyncookiesSent = 0;
75     static unsigned long long tcpext_SyncookiesRecv = 0;
76     static unsigned long long tcpext_SyncookiesFailed = 0;
77
78     // IPv4 TCP Out Of Order Queue
79     // http://www.spinics.net/lists/netdev/msg204696.html
80     static unsigned long long tcpext_TCPOFOQueue = 0; // Number of packets queued in OFO queue
81     static unsigned long long tcpext_TCPOFODrop = 0;  // Number of packets meant to be queued in OFO but dropped because socket rcvbuf limit hit.
82     static unsigned long long tcpext_TCPOFOMerge = 0; // Number of packets in OFO that were merged with other packets.
83     static unsigned long long tcpext_OfoPruned = 0;   // packets dropped from out-of-order queue because of socket buffer overrun
84
85     // IPv4 TCP connection resets
86     // https://github.com/ecki/net-tools/blob/bd8bceaed2311651710331a7f8990c3e31be9840/statistics.c
87     static unsigned long long tcpext_TCPAbortOnData = 0;    // connections reset due to unexpected data
88     static unsigned long long tcpext_TCPAbortOnClose = 0;   // connections reset due to early user close
89     static unsigned long long tcpext_TCPAbortOnMemory = 0;  // connections aborted due to memory pressure
90     static unsigned long long tcpext_TCPAbortOnTimeout = 0; // connections aborted due to timeout
91     static unsigned long long tcpext_TCPAbortOnLinger = 0;  // connections aborted after user close in linger timeout
92     static unsigned long long tcpext_TCPAbortFailed = 0;    // times unable to send RST due to no memory
93
94     // IPv4 TCP memory pressures
95     static unsigned long long tcpext_TCPMemoryPressures = 0;
96
97     if(unlikely(!arl_ipext)) {
98         hash_ipext = simple_hash("IpExt");
99         hash_tcpext = simple_hash("TcpExt");
100
101         do_bandwidth = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "bandwidth", CONFIG_BOOLEAN_AUTO);
102         do_inerrors  = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "input errors", CONFIG_BOOLEAN_AUTO);
103         do_mcast     = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast bandwidth", CONFIG_BOOLEAN_AUTO);
104         do_bcast     = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast bandwidth", CONFIG_BOOLEAN_AUTO);
105         do_mcast_p   = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "multicast packets", CONFIG_BOOLEAN_AUTO);
106         do_bcast_p   = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "broadcast packets", CONFIG_BOOLEAN_AUTO);
107         do_ecn       = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "ECN packets", CONFIG_BOOLEAN_AUTO);
108
109         do_tcpext_reorder    = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP reorders", CONFIG_BOOLEAN_AUTO);
110         do_tcpext_syscookies = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP SYN cookies", CONFIG_BOOLEAN_AUTO);
111         do_tcpext_ofo        = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO);
112         do_tcpext_connaborts = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP connection aborts", CONFIG_BOOLEAN_AUTO);
113         do_tcpext_memory     = config_get_boolean_ondemand("plugin:proc:/proc/net/netstat", "TCP memory pressures", CONFIG_BOOLEAN_AUTO);
114
115         arl_ipext  = arl_create("netstat/ipext", NULL, 60);
116         arl_tcpext = arl_create("netstat/tcpext", NULL, 60);
117
118         // --------------------------------------------------------------------
119         // IPv4
120
121         if(do_bandwidth != CONFIG_BOOLEAN_NO) {
122             arl_expect(arl_ipext, "InOctets",  &ipext_InOctets);
123             arl_expect(arl_ipext, "OutOctets", &ipext_OutOctets);
124         }
125
126         if(do_inerrors != CONFIG_BOOLEAN_NO) {
127             arl_expect(arl_ipext, "InNoRoutes",      &ipext_InNoRoutes);
128             arl_expect(arl_ipext, "InTruncatedPkts", &ipext_InTruncatedPkts);
129             arl_expect(arl_ipext, "InCsumErrors",    &ipext_InCsumErrors);
130         }
131
132         if(do_mcast != CONFIG_BOOLEAN_NO) {
133             arl_expect(arl_ipext, "InMcastOctets", &ipext_InMcastOctets);
134             arl_expect(arl_ipext, "OutMcastOctets", &ipext_OutMcastOctets);
135         }
136
137         if(do_mcast_p != CONFIG_BOOLEAN_NO) {
138             arl_expect(arl_ipext, "InMcastPkts",  &ipext_InMcastPkts);
139             arl_expect(arl_ipext, "OutMcastPkts", &ipext_OutMcastPkts);
140         }
141
142         if(do_bcast != CONFIG_BOOLEAN_NO) {
143             arl_expect(arl_ipext, "InBcastPkts",  &ipext_InBcastPkts);
144             arl_expect(arl_ipext, "OutBcastPkts", &ipext_OutBcastPkts);
145         }
146
147         if(do_bcast_p != CONFIG_BOOLEAN_NO) {
148             arl_expect(arl_ipext, "InBcastOctets",  &ipext_InBcastOctets);
149             arl_expect(arl_ipext, "OutBcastOctets", &ipext_OutBcastOctets);
150         }
151
152         if(do_ecn != CONFIG_BOOLEAN_NO) {
153             arl_expect(arl_ipext, "InNoECTPkts", &ipext_InNoECTPkts);
154             arl_expect(arl_ipext, "InECT1Pkts",  &ipext_InECT1Pkts);
155             arl_expect(arl_ipext, "InECT0Pkts",  &ipext_InECT0Pkts);
156             arl_expect(arl_ipext, "InCEPkts",    &ipext_InCEPkts);
157         }
158
159         // --------------------------------------------------------------------
160         // IPv4 TCP
161
162         if(do_tcpext_reorder != CONFIG_BOOLEAN_NO) {
163             arl_expect(arl_tcpext, "TCPFACKReorder", &tcpext_TCPFACKReorder);
164             arl_expect(arl_tcpext, "TCPSACKReorder", &tcpext_TCPSACKReorder);
165             arl_expect(arl_tcpext, "TCPRenoReorder", &tcpext_TCPRenoReorder);
166             arl_expect(arl_tcpext, "TCPTSReorder",   &tcpext_TCPTSReorder);
167         }
168
169         if(do_tcpext_syscookies != CONFIG_BOOLEAN_NO) {
170             arl_expect(arl_tcpext, "SyncookiesSent",   &tcpext_SyncookiesSent);
171             arl_expect(arl_tcpext, "SyncookiesRecv",   &tcpext_SyncookiesRecv);
172             arl_expect(arl_tcpext, "SyncookiesFailed", &tcpext_SyncookiesFailed);
173         }
174
175         if(do_tcpext_ofo != CONFIG_BOOLEAN_NO) {
176             arl_expect(arl_tcpext, "TCPOFOQueue", &tcpext_TCPOFOQueue);
177             arl_expect(arl_tcpext, "TCPOFODrop",  &tcpext_TCPOFODrop);
178             arl_expect(arl_tcpext, "TCPOFOMerge", &tcpext_TCPOFOMerge);
179             arl_expect(arl_tcpext, "OfoPruned",   &tcpext_OfoPruned);
180         }
181
182         if(do_tcpext_connaborts != CONFIG_BOOLEAN_NO) {
183             arl_expect(arl_tcpext, "TCPAbortOnData",    &tcpext_TCPAbortOnData);
184             arl_expect(arl_tcpext, "TCPAbortOnClose",   &tcpext_TCPAbortOnClose);
185             arl_expect(arl_tcpext, "TCPAbortOnMemory",  &tcpext_TCPAbortOnMemory);
186             arl_expect(arl_tcpext, "TCPAbortOnTimeout", &tcpext_TCPAbortOnTimeout);
187             arl_expect(arl_tcpext, "TCPAbortOnLinger",  &tcpext_TCPAbortOnLinger);
188             arl_expect(arl_tcpext, "TCPAbortFailed",    &tcpext_TCPAbortFailed);
189         }
190
191         if(do_tcpext_memory != CONFIG_BOOLEAN_NO) {
192             arl_expect(arl_tcpext, "TCPMemoryPressures", &tcpext_TCPMemoryPressures);
193         }
194     }
195
196     if(unlikely(!ff)) {
197         char filename[FILENAME_MAX + 1];
198         snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/netstat");
199         ff = procfile_open(config_get("plugin:proc:/proc/net/netstat", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
200         if(unlikely(!ff)) return 1;
201     }
202
203     ff = procfile_readall(ff);
204     if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
205
206     size_t lines = procfile_lines(ff), l;
207     size_t words;
208
209     arl_begin(arl_ipext);
210     arl_begin(arl_tcpext);
211
212     for(l = 0; l < lines ;l++) {
213         char *key = procfile_lineword(ff, l, 0);
214         uint32_t hash = simple_hash(key);
215
216         if(unlikely(hash == hash_ipext && strcmp(key, "IpExt") == 0)) {
217             size_t h = l++;
218
219             words = procfile_linewords(ff, l);
220             if(unlikely(words < 2)) {
221                 error("Cannot read /proc/net/netstat IpExt line. Expected 2+ params, read %zu.", words);
222                 continue;
223             }
224
225             parse_line_pair(ff, arl_ipext, h, l);
226
227             RRDSET *st;
228
229             // --------------------------------------------------------------------
230
231             if(do_bandwidth == CONFIG_BOOLEAN_YES || (do_bandwidth == CONFIG_BOOLEAN_AUTO && (ipext_InOctets || ipext_OutOctets))) {
232                 do_bandwidth = CONFIG_BOOLEAN_YES;
233                 st = rrdset_find_localhost("system.ipv4");
234                 if(unlikely(!st)) {
235                     st = rrdset_create_localhost("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s"
236                                                  , 500, update_every, RRDSET_TYPE_AREA);
237
238                     rrddim_add(st, "InOctets", "received", 8, 1024, RRD_ALGORITHM_INCREMENTAL);
239                     rrddim_add(st, "OutOctets", "sent", -8, 1024, RRD_ALGORITHM_INCREMENTAL);
240                 }
241                 else rrdset_next(st);
242
243                 rrddim_set(st, "InOctets", ipext_InOctets);
244                 rrddim_set(st, "OutOctets", ipext_OutOctets);
245                 rrdset_done(st);
246             }
247
248             // --------------------------------------------------------------------
249
250             if(do_inerrors == CONFIG_BOOLEAN_YES || (do_inerrors == CONFIG_BOOLEAN_AUTO && (ipext_InNoRoutes || ipext_InTruncatedPkts))) {
251                 do_inerrors = CONFIG_BOOLEAN_YES;
252                 st = rrdset_find_localhost("ipv4.inerrors");
253                 if(unlikely(!st)) {
254                     st = rrdset_create_localhost("ipv4", "inerrors", NULL, "errors", NULL, "IPv4 Input Errors"
255                                                  , "packets/s", 4000, update_every, RRDSET_TYPE_LINE);
256                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
257
258                     rrddim_add(st, "InNoRoutes", "noroutes", 1, 1, RRD_ALGORITHM_INCREMENTAL);
259                     rrddim_add(st, "InTruncatedPkts", "truncated", 1, 1, RRD_ALGORITHM_INCREMENTAL);
260                     rrddim_add(st, "InCsumErrors", "checksum", 1, 1, RRD_ALGORITHM_INCREMENTAL);
261                 }
262                 else rrdset_next(st);
263
264                 rrddim_set(st, "InNoRoutes", ipext_InNoRoutes);
265                 rrddim_set(st, "InTruncatedPkts", ipext_InTruncatedPkts);
266                 rrddim_set(st, "InCsumErrors", ipext_InCsumErrors);
267                 rrdset_done(st);
268             }
269
270             // --------------------------------------------------------------------
271
272             if(do_mcast == CONFIG_BOOLEAN_YES || (do_mcast == CONFIG_BOOLEAN_AUTO && (ipext_InMcastOctets || ipext_OutMcastOctets))) {
273                 do_mcast = CONFIG_BOOLEAN_YES;
274                 st = rrdset_find_localhost("ipv4.mcast");
275                 if(unlikely(!st)) {
276                     st = rrdset_create_localhost("ipv4", "mcast", NULL, "multicast", NULL, "IPv4 Multicast Bandwidth"
277                                                  , "kilobits/s", 9000, update_every, RRDSET_TYPE_AREA);
278                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
279
280                     rrddim_add(st, "InMcastOctets", "received", 8, 1024, RRD_ALGORITHM_INCREMENTAL);
281                     rrddim_add(st, "OutMcastOctets", "sent", -8, 1024, RRD_ALGORITHM_INCREMENTAL);
282                 }
283                 else rrdset_next(st);
284
285                 rrddim_set(st, "InMcastOctets", ipext_InMcastOctets);
286                 rrddim_set(st, "OutMcastOctets", ipext_OutMcastOctets);
287                 rrdset_done(st);
288             }
289
290             // --------------------------------------------------------------------
291
292             if(do_bcast == CONFIG_BOOLEAN_YES || (do_bcast == CONFIG_BOOLEAN_AUTO && (ipext_InBcastOctets || ipext_OutBcastOctets))) {
293                 do_bcast = CONFIG_BOOLEAN_YES;
294                 st = rrdset_find_localhost("ipv4.bcast");
295                 if(unlikely(!st)) {
296                     st = rrdset_create_localhost("ipv4", "bcast", NULL, "broadcast", NULL, "IPv4 Broadcast Bandwidth"
297                                                  , "kilobits/s", 8000, update_every, RRDSET_TYPE_AREA);
298                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
299
300                     rrddim_add(st, "InBcastOctets", "received", 8, 1024, RRD_ALGORITHM_INCREMENTAL);
301                     rrddim_add(st, "OutBcastOctets", "sent", -8, 1024, RRD_ALGORITHM_INCREMENTAL);
302                 }
303                 else rrdset_next(st);
304
305                 rrddim_set(st, "InBcastOctets", ipext_InBcastOctets);
306                 rrddim_set(st, "OutBcastOctets", ipext_OutBcastOctets);
307                 rrdset_done(st);
308             }
309
310             // --------------------------------------------------------------------
311
312             if(do_mcast_p == CONFIG_BOOLEAN_YES || (do_mcast_p == CONFIG_BOOLEAN_AUTO && (ipext_InMcastPkts || ipext_OutMcastPkts))) {
313                 do_mcast_p = CONFIG_BOOLEAN_YES;
314                 st = rrdset_find_localhost("ipv4.mcastpkts");
315                 if(unlikely(!st)) {
316                     st = rrdset_create_localhost("ipv4", "mcastpkts", NULL, "multicast", NULL, "IPv4 Multicast Packets"
317                                                  , "packets/s", 8600, update_every, RRDSET_TYPE_LINE);
318                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
319
320                     rrddim_add(st, "InMcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
321                     rrddim_add(st, "OutMcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
322                 }
323                 else rrdset_next(st);
324
325                 rrddim_set(st, "InMcastPkts", ipext_InMcastPkts);
326                 rrddim_set(st, "OutMcastPkts", ipext_OutMcastPkts);
327                 rrdset_done(st);
328             }
329
330             // --------------------------------------------------------------------
331
332             if(do_bcast_p == CONFIG_BOOLEAN_YES || (do_bcast_p == CONFIG_BOOLEAN_AUTO && (ipext_InBcastPkts || ipext_OutBcastPkts))) {
333                 do_bcast_p = CONFIG_BOOLEAN_YES;
334                 st = rrdset_find_localhost("ipv4.bcastpkts");
335                 if(unlikely(!st)) {
336                     st = rrdset_create_localhost("ipv4", "bcastpkts", NULL, "broadcast", NULL, "IPv4 Broadcast Packets"
337                                                  , "packets/s", 8500, update_every, RRDSET_TYPE_LINE);
338                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
339
340                     rrddim_add(st, "InBcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
341                     rrddim_add(st, "OutBcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
342                 }
343                 else rrdset_next(st);
344
345                 rrddim_set(st, "InBcastPkts", ipext_InBcastPkts);
346                 rrddim_set(st, "OutBcastPkts", ipext_OutBcastPkts);
347                 rrdset_done(st);
348             }
349
350             // --------------------------------------------------------------------
351
352             if(do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO && (ipext_InCEPkts || ipext_InECT0Pkts || ipext_InECT1Pkts || ipext_InNoECTPkts))) {
353                 do_ecn = CONFIG_BOOLEAN_YES;
354                 st = rrdset_find_localhost("ipv4.ecnpkts");
355                 if(unlikely(!st)) {
356                     st = rrdset_create_localhost("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics"
357                                                  , "packets/s", 8700, update_every, RRDSET_TYPE_LINE);
358                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
359
360                     rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL);
361                     rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRD_ALGORITHM_INCREMENTAL);
362                     rrddim_add(st, "InECT0Pkts", "ECTP0", 1, 1, RRD_ALGORITHM_INCREMENTAL);
363                     rrddim_add(st, "InECT1Pkts", "ECTP1", 1, 1, RRD_ALGORITHM_INCREMENTAL);
364                 }
365                 else rrdset_next(st);
366
367                 rrddim_set(st, "InCEPkts", ipext_InCEPkts);
368                 rrddim_set(st, "InNoECTPkts", ipext_InNoECTPkts);
369                 rrddim_set(st, "InECT0Pkts", ipext_InECT0Pkts);
370                 rrddim_set(st, "InECT1Pkts", ipext_InECT1Pkts);
371                 rrdset_done(st);
372             }
373         }
374         else if(unlikely(hash == hash_tcpext && strcmp(key, "TcpExt") == 0)) {
375             size_t h = l++;
376
377             words = procfile_linewords(ff, l);
378             if(unlikely(words < 2)) {
379                 error("Cannot read /proc/net/netstat TcpExt line. Expected 2+ params, read %zu.", words);
380                 continue;
381             }
382
383             parse_line_pair(ff, arl_tcpext, h, l);
384
385             RRDSET *st;
386
387             // --------------------------------------------------------------------
388
389             if(do_tcpext_memory == CONFIG_BOOLEAN_YES || (do_tcpext_memory == CONFIG_BOOLEAN_AUTO && (tcpext_TCPMemoryPressures))) {
390                 do_tcpext_memory = CONFIG_BOOLEAN_YES;
391                 st = rrdset_find_localhost("ipv4.tcpmemorypressures");
392                 if(unlikely(!st)) {
393                     st = rrdset_create_localhost("ipv4", "tcpmemorypressures", NULL, "tcp", NULL, "TCP Memory Pressures"
394                                                  , "events/s", 3000, update_every, RRDSET_TYPE_LINE);
395
396                     rrddim_add(st, "TCPMemoryPressures",   "pressures",  1, 1, RRD_ALGORITHM_INCREMENTAL);
397                 }
398                 else rrdset_next(st);
399
400                 rrddim_set(st, "TCPMemoryPressures", tcpext_TCPMemoryPressures);
401                 rrdset_done(st);
402             }
403
404             // --------------------------------------------------------------------
405
406             if(do_tcpext_connaborts == CONFIG_BOOLEAN_YES || (do_tcpext_connaborts == CONFIG_BOOLEAN_AUTO && (tcpext_TCPAbortOnData || tcpext_TCPAbortOnClose || tcpext_TCPAbortOnMemory || tcpext_TCPAbortOnTimeout || tcpext_TCPAbortOnLinger || tcpext_TCPAbortFailed))) {
407                 do_tcpext_connaborts = CONFIG_BOOLEAN_YES;
408                 st = rrdset_find_localhost("ipv4.tcpconnaborts");
409                 if(unlikely(!st)) {
410                     st = rrdset_create_localhost("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts"
411                                                  , "connections/s", 3010, update_every, RRDSET_TYPE_LINE);
412
413                     rrddim_add(st, "TCPAbortOnData",    "baddata",     1, 1, RRD_ALGORITHM_INCREMENTAL);
414                     rrddim_add(st, "TCPAbortOnClose",   "userclosed",  1, 1, RRD_ALGORITHM_INCREMENTAL);
415                     rrddim_add(st, "TCPAbortOnMemory",  "nomemory",    1, 1, RRD_ALGORITHM_INCREMENTAL);
416                     rrddim_add(st, "TCPAbortOnTimeout", "timeout",     1, 1, RRD_ALGORITHM_INCREMENTAL);
417                     rrddim_add(st, "TCPAbortOnLinger",  "linger",      1, 1, RRD_ALGORITHM_INCREMENTAL);
418                     rrddim_add(st, "TCPAbortFailed",    "failed",     -1, 1, RRD_ALGORITHM_INCREMENTAL);
419                 }
420                 else rrdset_next(st);
421
422                 rrddim_set(st, "TCPAbortOnData",    tcpext_TCPAbortOnData);
423                 rrddim_set(st, "TCPAbortOnClose",   tcpext_TCPAbortOnClose);
424                 rrddim_set(st, "TCPAbortOnMemory",  tcpext_TCPAbortOnMemory);
425                 rrddim_set(st, "TCPAbortOnTimeout", tcpext_TCPAbortOnTimeout);
426                 rrddim_set(st, "TCPAbortOnLinger",  tcpext_TCPAbortOnLinger);
427                 rrddim_set(st, "TCPAbortFailed",    tcpext_TCPAbortFailed);
428                 rrdset_done(st);
429             }
430             // --------------------------------------------------------------------
431
432             if(do_tcpext_reorder == CONFIG_BOOLEAN_YES || (do_tcpext_reorder == CONFIG_BOOLEAN_AUTO && (tcpext_TCPRenoReorder || tcpext_TCPFACKReorder || tcpext_TCPSACKReorder || tcpext_TCPTSReorder))) {
433                 do_tcpext_reorder = CONFIG_BOOLEAN_YES;
434                 st = rrdset_find_localhost("ipv4.tcpreorders");
435                 if(unlikely(!st)) {
436                     st = rrdset_create_localhost("ipv4", "tcpreorders", NULL, "tcp", NULL
437                                                  , "TCP Reordered Packets by Detection Method", "packets/s", 3020
438                                                  , update_every, RRDSET_TYPE_LINE);
439
440                     rrddim_add(st, "TCPTSReorder",   "timestamp",   1, 1, RRD_ALGORITHM_INCREMENTAL);
441                     rrddim_add(st, "TCPSACKReorder", "sack",        1, 1, RRD_ALGORITHM_INCREMENTAL);
442                     rrddim_add(st, "TCPFACKReorder", "fack",        1, 1, RRD_ALGORITHM_INCREMENTAL);
443                     rrddim_add(st, "TCPRenoReorder", "reno",        1, 1, RRD_ALGORITHM_INCREMENTAL);
444                 }
445                 else rrdset_next(st);
446
447                 rrddim_set(st, "TCPTSReorder",   tcpext_TCPTSReorder);
448                 rrddim_set(st, "TCPSACKReorder", tcpext_TCPSACKReorder);
449                 rrddim_set(st, "TCPFACKReorder", tcpext_TCPFACKReorder);
450                 rrddim_set(st, "TCPRenoReorder", tcpext_TCPRenoReorder);
451                 rrdset_done(st);
452             }
453
454             // --------------------------------------------------------------------
455
456             if(do_tcpext_ofo == CONFIG_BOOLEAN_YES || (do_tcpext_ofo == CONFIG_BOOLEAN_AUTO && (tcpext_TCPOFOQueue || tcpext_TCPOFODrop || tcpext_TCPOFOMerge))) {
457                 do_tcpext_ofo = CONFIG_BOOLEAN_YES;
458                 st = rrdset_find_localhost("ipv4.tcpofo");
459                 if(unlikely(!st)) {
460                     st = rrdset_create_localhost("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue"
461                                                  , "packets/s", 3050, update_every, RRDSET_TYPE_LINE);
462
463                     rrddim_add(st, "TCPOFOQueue", "inqueue",  1, 1, RRD_ALGORITHM_INCREMENTAL);
464                     rrddim_add(st, "TCPOFODrop",  "dropped", -1, 1, RRD_ALGORITHM_INCREMENTAL);
465                     rrddim_add(st, "TCPOFOMerge", "merged",   1, 1, RRD_ALGORITHM_INCREMENTAL);
466                     rrddim_add(st, "OfoPruned",   "pruned",  -1, 1, RRD_ALGORITHM_INCREMENTAL);
467                 }
468                 else rrdset_next(st);
469
470                 rrddim_set(st, "TCPOFOQueue",   tcpext_TCPOFOQueue);
471                 rrddim_set(st, "TCPOFODrop",    tcpext_TCPOFODrop);
472                 rrddim_set(st, "TCPOFOMerge",   tcpext_TCPOFOMerge);
473                 rrddim_set(st, "OfoPruned",     tcpext_OfoPruned);
474                 rrdset_done(st);
475             }
476
477             // --------------------------------------------------------------------
478
479             if(do_tcpext_syscookies == CONFIG_BOOLEAN_YES || (do_tcpext_syscookies == CONFIG_BOOLEAN_AUTO && (tcpext_SyncookiesSent || tcpext_SyncookiesRecv || tcpext_SyncookiesFailed))) {
480                 do_tcpext_syscookies = CONFIG_BOOLEAN_YES;
481                 st = rrdset_find_localhost("ipv4.tcpsyncookies");
482                 if(unlikely(!st)) {
483                     st = rrdset_create_localhost("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies"
484                                                  , "packets/s", 3100, update_every, RRDSET_TYPE_LINE);
485
486                     rrddim_add(st, "SyncookiesRecv",   "received",  1, 1, RRD_ALGORITHM_INCREMENTAL);
487                     rrddim_add(st, "SyncookiesSent",   "sent",     -1, 1, RRD_ALGORITHM_INCREMENTAL);
488                     rrddim_add(st, "SyncookiesFailed", "failed",   -1, 1, RRD_ALGORITHM_INCREMENTAL);
489                 }
490                 else rrdset_next(st);
491
492                 rrddim_set(st, "SyncookiesRecv",   tcpext_SyncookiesRecv);
493                 rrddim_set(st, "SyncookiesSent",   tcpext_SyncookiesSent);
494                 rrddim_set(st, "SyncookiesFailed", tcpext_SyncookiesFailed);
495                 rrdset_done(st);
496             }
497
498         }
499     }
500
501     return 0;
502 }