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