proc_net_netstat.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "plugin_proc.h"
  3. #define RRD_TYPE_NET_NETSTAT "ip"
  4. #define PLUGIN_PROC_MODULE_NETSTAT_NAME "/proc/net/netstat"
  5. #define CONFIG_SECTION_PLUGIN_PROC_NETSTAT "plugin:" PLUGIN_PROC_CONFIG_NAME ":" PLUGIN_PROC_MODULE_NETSTAT_NAME
  6. unsigned long long tcpext_TCPSynRetrans = 0;
  7. static void parse_line_pair(procfile *ff, ARL_BASE *base, size_t header_line, size_t values_line) {
  8. size_t hwords = procfile_linewords(ff, header_line);
  9. size_t vwords = procfile_linewords(ff, values_line);
  10. size_t w;
  11. if(unlikely(vwords > hwords)) {
  12. 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);
  13. vwords = hwords;
  14. }
  15. for(w = 1; w < vwords ;w++) {
  16. if(unlikely(arl_check(base, procfile_lineword(ff, header_line, w), procfile_lineword(ff, values_line, w))))
  17. break;
  18. }
  19. }
  20. int do_proc_net_netstat(int update_every, usec_t dt) {
  21. (void)dt;
  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. do_tcpext_syn_queue = -1, do_tcpext_accept_queue = -1;
  25. static uint32_t hash_ipext = 0, hash_tcpext = 0;
  26. static procfile *ff = NULL;
  27. static ARL_BASE *arl_tcpext = NULL;
  28. static ARL_BASE *arl_ipext = NULL;
  29. // --------------------------------------------------------------------
  30. // IP
  31. // IP bandwidth
  32. static unsigned long long ipext_InOctets = 0;
  33. static unsigned long long ipext_OutOctets = 0;
  34. // IP input errors
  35. static unsigned long long ipext_InNoRoutes = 0;
  36. static unsigned long long ipext_InTruncatedPkts = 0;
  37. static unsigned long long ipext_InCsumErrors = 0;
  38. // IP multicast bandwidth
  39. static unsigned long long ipext_InMcastOctets = 0;
  40. static unsigned long long ipext_OutMcastOctets = 0;
  41. // IP multicast packets
  42. static unsigned long long ipext_InMcastPkts = 0;
  43. static unsigned long long ipext_OutMcastPkts = 0;
  44. // IP broadcast bandwidth
  45. static unsigned long long ipext_InBcastOctets = 0;
  46. static unsigned long long ipext_OutBcastOctets = 0;
  47. // IP broadcast packets
  48. static unsigned long long ipext_InBcastPkts = 0;
  49. static unsigned long long ipext_OutBcastPkts = 0;
  50. // IP ECN
  51. static unsigned long long ipext_InNoECTPkts = 0;
  52. static unsigned long long ipext_InECT1Pkts = 0;
  53. static unsigned long long ipext_InECT0Pkts = 0;
  54. static unsigned long long ipext_InCEPkts = 0;
  55. // --------------------------------------------------------------------
  56. // IP TCP
  57. // IP TCP Reordering
  58. static unsigned long long tcpext_TCPRenoReorder = 0;
  59. static unsigned long long tcpext_TCPFACKReorder = 0;
  60. static unsigned long long tcpext_TCPSACKReorder = 0;
  61. static unsigned long long tcpext_TCPTSReorder = 0;
  62. // IP TCP SYN Cookies
  63. static unsigned long long tcpext_SyncookiesSent = 0;
  64. static unsigned long long tcpext_SyncookiesRecv = 0;
  65. static unsigned long long tcpext_SyncookiesFailed = 0;
  66. // IP TCP Out Of Order Queue
  67. // http://www.spinics.net/lists/netdev/msg204696.html
  68. static unsigned long long tcpext_TCPOFOQueue = 0; // Number of packets queued in OFO queue
  69. static unsigned long long tcpext_TCPOFODrop = 0; // Number of packets meant to be queued in OFO but dropped because socket rcvbuf limit hit.
  70. static unsigned long long tcpext_TCPOFOMerge = 0; // Number of packets in OFO that were merged with other packets.
  71. static unsigned long long tcpext_OfoPruned = 0; // packets dropped from out-of-order queue because of socket buffer overrun
  72. // IP TCP connection resets
  73. // https://github.com/ecki/net-tools/blob/bd8bceaed2311651710331a7f8990c3e31be9840/statistics.c
  74. static unsigned long long tcpext_TCPAbortOnData = 0; // connections reset due to unexpected data
  75. static unsigned long long tcpext_TCPAbortOnClose = 0; // connections reset due to early user close
  76. static unsigned long long tcpext_TCPAbortOnMemory = 0; // connections aborted due to memory pressure
  77. static unsigned long long tcpext_TCPAbortOnTimeout = 0; // connections aborted due to timeout
  78. static unsigned long long tcpext_TCPAbortOnLinger = 0; // connections aborted after user close in linger timeout
  79. static unsigned long long tcpext_TCPAbortFailed = 0; // times unable to send RST due to no memory
  80. // https://perfchron.com/2015/12/26/investigating-linux-network-issues-with-netstat-and-nstat/
  81. static unsigned long long tcpext_ListenOverflows = 0; // times the listen queue of a socket overflowed
  82. static unsigned long long tcpext_ListenDrops = 0; // SYNs to LISTEN sockets ignored
  83. // IP TCP memory pressures
  84. static unsigned long long tcpext_TCPMemoryPressures = 0;
  85. static unsigned long long tcpext_TCPReqQFullDrop = 0;
  86. static unsigned long long tcpext_TCPReqQFullDoCookies = 0;
  87. // shared: tcpext_TCPSynRetrans
  88. if(unlikely(!arl_ipext)) {
  89. hash_ipext = simple_hash("IpExt");
  90. hash_tcpext = simple_hash("TcpExt");
  91. do_bandwidth = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "bandwidth", CONFIG_BOOLEAN_AUTO);
  92. do_inerrors = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "input errors", CONFIG_BOOLEAN_AUTO);
  93. do_mcast = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "multicast bandwidth", CONFIG_BOOLEAN_AUTO);
  94. do_bcast = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "broadcast bandwidth", CONFIG_BOOLEAN_AUTO);
  95. do_mcast_p = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "multicast packets", CONFIG_BOOLEAN_AUTO);
  96. do_bcast_p = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "broadcast packets", CONFIG_BOOLEAN_AUTO);
  97. do_ecn = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "ECN packets", CONFIG_BOOLEAN_AUTO);
  98. do_tcpext_reorder = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP reorders", CONFIG_BOOLEAN_AUTO);
  99. do_tcpext_syscookies = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP SYN cookies", CONFIG_BOOLEAN_AUTO);
  100. do_tcpext_ofo = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO);
  101. do_tcpext_connaborts = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP connection aborts", CONFIG_BOOLEAN_AUTO);
  102. do_tcpext_memory = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP memory pressures", CONFIG_BOOLEAN_AUTO);
  103. do_tcpext_syn_queue = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP SYN queue", CONFIG_BOOLEAN_AUTO);
  104. do_tcpext_accept_queue = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "TCP accept queue", CONFIG_BOOLEAN_AUTO);
  105. arl_ipext = arl_create("netstat/ipext", NULL, 60);
  106. arl_tcpext = arl_create("netstat/tcpext", NULL, 60);
  107. // --------------------------------------------------------------------
  108. // IP
  109. if(do_bandwidth != CONFIG_BOOLEAN_NO) {
  110. arl_expect(arl_ipext, "InOctets", &ipext_InOctets);
  111. arl_expect(arl_ipext, "OutOctets", &ipext_OutOctets);
  112. }
  113. if(do_inerrors != CONFIG_BOOLEAN_NO) {
  114. arl_expect(arl_ipext, "InNoRoutes", &ipext_InNoRoutes);
  115. arl_expect(arl_ipext, "InTruncatedPkts", &ipext_InTruncatedPkts);
  116. arl_expect(arl_ipext, "InCsumErrors", &ipext_InCsumErrors);
  117. }
  118. if(do_mcast != CONFIG_BOOLEAN_NO) {
  119. arl_expect(arl_ipext, "InMcastOctets", &ipext_InMcastOctets);
  120. arl_expect(arl_ipext, "OutMcastOctets", &ipext_OutMcastOctets);
  121. }
  122. if(do_mcast_p != CONFIG_BOOLEAN_NO) {
  123. arl_expect(arl_ipext, "InMcastPkts", &ipext_InMcastPkts);
  124. arl_expect(arl_ipext, "OutMcastPkts", &ipext_OutMcastPkts);
  125. }
  126. if(do_bcast != CONFIG_BOOLEAN_NO) {
  127. arl_expect(arl_ipext, "InBcastPkts", &ipext_InBcastPkts);
  128. arl_expect(arl_ipext, "OutBcastPkts", &ipext_OutBcastPkts);
  129. }
  130. if(do_bcast_p != CONFIG_BOOLEAN_NO) {
  131. arl_expect(arl_ipext, "InBcastOctets", &ipext_InBcastOctets);
  132. arl_expect(arl_ipext, "OutBcastOctets", &ipext_OutBcastOctets);
  133. }
  134. if(do_ecn != CONFIG_BOOLEAN_NO) {
  135. arl_expect(arl_ipext, "InNoECTPkts", &ipext_InNoECTPkts);
  136. arl_expect(arl_ipext, "InECT1Pkts", &ipext_InECT1Pkts);
  137. arl_expect(arl_ipext, "InECT0Pkts", &ipext_InECT0Pkts);
  138. arl_expect(arl_ipext, "InCEPkts", &ipext_InCEPkts);
  139. }
  140. // --------------------------------------------------------------------
  141. // IP TCP
  142. if(do_tcpext_reorder != CONFIG_BOOLEAN_NO) {
  143. arl_expect(arl_tcpext, "TCPFACKReorder", &tcpext_TCPFACKReorder);
  144. arl_expect(arl_tcpext, "TCPSACKReorder", &tcpext_TCPSACKReorder);
  145. arl_expect(arl_tcpext, "TCPRenoReorder", &tcpext_TCPRenoReorder);
  146. arl_expect(arl_tcpext, "TCPTSReorder", &tcpext_TCPTSReorder);
  147. }
  148. if(do_tcpext_syscookies != CONFIG_BOOLEAN_NO) {
  149. arl_expect(arl_tcpext, "SyncookiesSent", &tcpext_SyncookiesSent);
  150. arl_expect(arl_tcpext, "SyncookiesRecv", &tcpext_SyncookiesRecv);
  151. arl_expect(arl_tcpext, "SyncookiesFailed", &tcpext_SyncookiesFailed);
  152. }
  153. if(do_tcpext_ofo != CONFIG_BOOLEAN_NO) {
  154. arl_expect(arl_tcpext, "TCPOFOQueue", &tcpext_TCPOFOQueue);
  155. arl_expect(arl_tcpext, "TCPOFODrop", &tcpext_TCPOFODrop);
  156. arl_expect(arl_tcpext, "TCPOFOMerge", &tcpext_TCPOFOMerge);
  157. arl_expect(arl_tcpext, "OfoPruned", &tcpext_OfoPruned);
  158. }
  159. if(do_tcpext_connaborts != CONFIG_BOOLEAN_NO) {
  160. arl_expect(arl_tcpext, "TCPAbortOnData", &tcpext_TCPAbortOnData);
  161. arl_expect(arl_tcpext, "TCPAbortOnClose", &tcpext_TCPAbortOnClose);
  162. arl_expect(arl_tcpext, "TCPAbortOnMemory", &tcpext_TCPAbortOnMemory);
  163. arl_expect(arl_tcpext, "TCPAbortOnTimeout", &tcpext_TCPAbortOnTimeout);
  164. arl_expect(arl_tcpext, "TCPAbortOnLinger", &tcpext_TCPAbortOnLinger);
  165. arl_expect(arl_tcpext, "TCPAbortFailed", &tcpext_TCPAbortFailed);
  166. }
  167. if(do_tcpext_memory != CONFIG_BOOLEAN_NO) {
  168. arl_expect(arl_tcpext, "TCPMemoryPressures", &tcpext_TCPMemoryPressures);
  169. }
  170. if(do_tcpext_accept_queue != CONFIG_BOOLEAN_NO) {
  171. arl_expect(arl_tcpext, "ListenOverflows", &tcpext_ListenOverflows);
  172. arl_expect(arl_tcpext, "ListenDrops", &tcpext_ListenDrops);
  173. }
  174. if(do_tcpext_syn_queue != CONFIG_BOOLEAN_NO) {
  175. arl_expect(arl_tcpext, "TCPReqQFullDrop", &tcpext_TCPReqQFullDrop);
  176. arl_expect(arl_tcpext, "TCPReqQFullDoCookies", &tcpext_TCPReqQFullDoCookies);
  177. }
  178. // shared metrics
  179. arl_expect(arl_tcpext, "TCPSynRetrans", &tcpext_TCPSynRetrans);
  180. }
  181. if(unlikely(!ff)) {
  182. char filename[FILENAME_MAX + 1];
  183. snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/net/netstat");
  184. ff = procfile_open(config_get(CONFIG_SECTION_PLUGIN_PROC_NETSTAT, "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
  185. if(unlikely(!ff)) return 1;
  186. }
  187. ff = procfile_readall(ff);
  188. if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
  189. size_t lines = procfile_lines(ff), l;
  190. size_t words;
  191. arl_begin(arl_ipext);
  192. arl_begin(arl_tcpext);
  193. for(l = 0; l < lines ;l++) {
  194. char *key = procfile_lineword(ff, l, 0);
  195. uint32_t hash = simple_hash(key);
  196. if(unlikely(hash == hash_ipext && strcmp(key, "IpExt") == 0)) {
  197. size_t h = l++;
  198. words = procfile_linewords(ff, l);
  199. if(unlikely(words < 2)) {
  200. error("Cannot read /proc/net/netstat IpExt line. Expected 2+ params, read %zu.", words);
  201. continue;
  202. }
  203. parse_line_pair(ff, arl_ipext, h, l);
  204. // --------------------------------------------------------------------
  205. if(do_bandwidth == CONFIG_BOOLEAN_YES || (do_bandwidth == CONFIG_BOOLEAN_AUTO &&
  206. (ipext_InOctets ||
  207. ipext_OutOctets ||
  208. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  209. do_bandwidth = CONFIG_BOOLEAN_YES;
  210. static RRDSET *st_system_ip = NULL;
  211. static RRDDIM *rd_in = NULL, *rd_out = NULL;
  212. if(unlikely(!st_system_ip)) {
  213. st_system_ip = rrdset_create_localhost(
  214. "system"
  215. , RRD_TYPE_NET_NETSTAT
  216. , NULL
  217. , "network"
  218. , NULL
  219. , "IP Bandwidth"
  220. , "kilobits/s"
  221. , PLUGIN_PROC_NAME
  222. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  223. , NETDATA_CHART_PRIO_SYSTEM_IP
  224. , update_every
  225. , RRDSET_TYPE_AREA
  226. );
  227. rd_in = rrddim_add(st_system_ip, "InOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  228. rd_out = rrddim_add(st_system_ip, "OutOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  229. }
  230. else
  231. rrdset_next(st_system_ip);
  232. rrddim_set_by_pointer(st_system_ip, rd_in, ipext_InOctets);
  233. rrddim_set_by_pointer(st_system_ip, rd_out, ipext_OutOctets);
  234. rrdset_done(st_system_ip);
  235. }
  236. // --------------------------------------------------------------------
  237. if(do_inerrors == CONFIG_BOOLEAN_YES || (do_inerrors == CONFIG_BOOLEAN_AUTO &&
  238. (ipext_InNoRoutes ||
  239. ipext_InTruncatedPkts ||
  240. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  241. do_inerrors = CONFIG_BOOLEAN_YES;
  242. static RRDSET *st_ip_inerrors = NULL;
  243. static RRDDIM *rd_noroutes = NULL, *rd_truncated = NULL, *rd_checksum = NULL;
  244. if(unlikely(!st_ip_inerrors)) {
  245. st_ip_inerrors = rrdset_create_localhost(
  246. RRD_TYPE_NET_NETSTAT
  247. , "inerrors"
  248. , NULL
  249. , "errors"
  250. , NULL
  251. , "IP Input Errors"
  252. , "packets/s"
  253. , PLUGIN_PROC_NAME
  254. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  255. , NETDATA_CHART_PRIO_IP_ERRORS
  256. , update_every
  257. , RRDSET_TYPE_LINE
  258. );
  259. rrdset_flag_set(st_ip_inerrors, RRDSET_FLAG_DETAIL);
  260. rd_noroutes = rrddim_add(st_ip_inerrors, "InNoRoutes", "noroutes", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  261. rd_truncated = rrddim_add(st_ip_inerrors, "InTruncatedPkts", "truncated", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  262. rd_checksum = rrddim_add(st_ip_inerrors, "InCsumErrors", "checksum", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  263. }
  264. else
  265. rrdset_next(st_ip_inerrors);
  266. rrddim_set_by_pointer(st_ip_inerrors, rd_noroutes, ipext_InNoRoutes);
  267. rrddim_set_by_pointer(st_ip_inerrors, rd_truncated, ipext_InTruncatedPkts);
  268. rrddim_set_by_pointer(st_ip_inerrors, rd_checksum, ipext_InCsumErrors);
  269. rrdset_done(st_ip_inerrors);
  270. }
  271. // --------------------------------------------------------------------
  272. if(do_mcast == CONFIG_BOOLEAN_YES || (do_mcast == CONFIG_BOOLEAN_AUTO &&
  273. (ipext_InMcastOctets ||
  274. ipext_OutMcastOctets ||
  275. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  276. do_mcast = CONFIG_BOOLEAN_YES;
  277. static RRDSET *st_ip_mcast = NULL;
  278. static RRDDIM *rd_in = NULL, *rd_out = NULL;
  279. if(unlikely(!st_ip_mcast)) {
  280. st_ip_mcast = rrdset_create_localhost(
  281. RRD_TYPE_NET_NETSTAT
  282. , "mcast"
  283. , NULL
  284. , "multicast"
  285. , NULL
  286. , "IP Multicast Bandwidth"
  287. , "kilobits/s"
  288. , PLUGIN_PROC_NAME
  289. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  290. , NETDATA_CHART_PRIO_IP_MCAST
  291. , update_every
  292. , RRDSET_TYPE_AREA
  293. );
  294. rrdset_flag_set(st_ip_mcast, RRDSET_FLAG_DETAIL);
  295. rd_in = rrddim_add(st_ip_mcast, "InMcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  296. rd_out = rrddim_add(st_ip_mcast, "OutMcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  297. }
  298. else
  299. rrdset_next(st_ip_mcast);
  300. rrddim_set_by_pointer(st_ip_mcast, rd_in, ipext_InMcastOctets);
  301. rrddim_set_by_pointer(st_ip_mcast, rd_out, ipext_OutMcastOctets);
  302. rrdset_done(st_ip_mcast);
  303. }
  304. // --------------------------------------------------------------------
  305. if(do_bcast == CONFIG_BOOLEAN_YES || (do_bcast == CONFIG_BOOLEAN_AUTO &&
  306. (ipext_InBcastOctets ||
  307. ipext_OutBcastOctets ||
  308. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  309. do_bcast = CONFIG_BOOLEAN_YES;
  310. static RRDSET *st_ip_bcast = NULL;
  311. static RRDDIM *rd_in = NULL, *rd_out = NULL;
  312. if(unlikely(!st_ip_bcast)) {
  313. st_ip_bcast = rrdset_create_localhost(
  314. RRD_TYPE_NET_NETSTAT
  315. , "bcast"
  316. , NULL
  317. , "broadcast"
  318. , NULL
  319. , "IP Broadcast Bandwidth"
  320. , "kilobits/s"
  321. , PLUGIN_PROC_NAME
  322. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  323. , NETDATA_CHART_PRIO_IP_BCAST
  324. , update_every
  325. , RRDSET_TYPE_AREA
  326. );
  327. rrdset_flag_set(st_ip_bcast, RRDSET_FLAG_DETAIL);
  328. rd_in = rrddim_add(st_ip_bcast, "InBcastOctets", "received", 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  329. rd_out = rrddim_add(st_ip_bcast, "OutBcastOctets", "sent", -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  330. }
  331. else
  332. rrdset_next(st_ip_bcast);
  333. rrddim_set_by_pointer(st_ip_bcast, rd_in, ipext_InBcastOctets);
  334. rrddim_set_by_pointer(st_ip_bcast, rd_out, ipext_OutBcastOctets);
  335. rrdset_done(st_ip_bcast);
  336. }
  337. // --------------------------------------------------------------------
  338. if(do_mcast_p == CONFIG_BOOLEAN_YES || (do_mcast_p == CONFIG_BOOLEAN_AUTO &&
  339. (ipext_InMcastPkts ||
  340. ipext_OutMcastPkts ||
  341. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  342. do_mcast_p = CONFIG_BOOLEAN_YES;
  343. static RRDSET *st_ip_mcastpkts = NULL;
  344. static RRDDIM *rd_in = NULL, *rd_out = NULL;
  345. if(unlikely(!st_ip_mcastpkts)) {
  346. st_ip_mcastpkts = rrdset_create_localhost(
  347. RRD_TYPE_NET_NETSTAT
  348. , "mcastpkts"
  349. , NULL
  350. , "multicast"
  351. , NULL
  352. , "IP Multicast Packets"
  353. , "packets/s"
  354. , PLUGIN_PROC_NAME
  355. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  356. , NETDATA_CHART_PRIO_IP_MCAST_PACKETS
  357. , update_every
  358. , RRDSET_TYPE_LINE
  359. );
  360. rrdset_flag_set(st_ip_mcastpkts, RRDSET_FLAG_DETAIL);
  361. rd_in = rrddim_add(st_ip_mcastpkts, "InMcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  362. rd_out = rrddim_add(st_ip_mcastpkts, "OutMcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  363. }
  364. else rrdset_next(st_ip_mcastpkts);
  365. rrddim_set_by_pointer(st_ip_mcastpkts, rd_in, ipext_InMcastPkts);
  366. rrddim_set_by_pointer(st_ip_mcastpkts, rd_out, ipext_OutMcastPkts);
  367. rrdset_done(st_ip_mcastpkts);
  368. }
  369. // --------------------------------------------------------------------
  370. if(do_bcast_p == CONFIG_BOOLEAN_YES || (do_bcast_p == CONFIG_BOOLEAN_AUTO &&
  371. (ipext_InBcastPkts ||
  372. ipext_OutBcastPkts ||
  373. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  374. do_bcast_p = CONFIG_BOOLEAN_YES;
  375. static RRDSET *st_ip_bcastpkts = NULL;
  376. static RRDDIM *rd_in = NULL, *rd_out = NULL;
  377. if(unlikely(!st_ip_bcastpkts)) {
  378. st_ip_bcastpkts = rrdset_create_localhost(
  379. RRD_TYPE_NET_NETSTAT
  380. , "bcastpkts"
  381. , NULL
  382. , "broadcast"
  383. , NULL
  384. , "IP Broadcast Packets"
  385. , "packets/s"
  386. , PLUGIN_PROC_NAME
  387. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  388. , NETDATA_CHART_PRIO_IP_BCAST_PACKETS
  389. , update_every
  390. , RRDSET_TYPE_LINE
  391. );
  392. rrdset_flag_set(st_ip_bcastpkts, RRDSET_FLAG_DETAIL);
  393. rd_in = rrddim_add(st_ip_bcastpkts, "InBcastPkts", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  394. rd_out = rrddim_add(st_ip_bcastpkts, "OutBcastPkts", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  395. }
  396. else
  397. rrdset_next(st_ip_bcastpkts);
  398. rrddim_set_by_pointer(st_ip_bcastpkts, rd_in, ipext_InBcastPkts);
  399. rrddim_set_by_pointer(st_ip_bcastpkts, rd_out, ipext_OutBcastPkts);
  400. rrdset_done(st_ip_bcastpkts);
  401. }
  402. // --------------------------------------------------------------------
  403. if(do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO &&
  404. (ipext_InCEPkts ||
  405. ipext_InECT0Pkts ||
  406. ipext_InECT1Pkts ||
  407. ipext_InNoECTPkts ||
  408. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  409. do_ecn = CONFIG_BOOLEAN_YES;
  410. static RRDSET *st_ecnpkts = NULL;
  411. static RRDDIM *rd_cep = NULL, *rd_noectp = NULL, *rd_ectp0 = NULL, *rd_ectp1 = NULL;
  412. if(unlikely(!st_ecnpkts)) {
  413. st_ecnpkts = rrdset_create_localhost(
  414. RRD_TYPE_NET_NETSTAT
  415. , "ecnpkts"
  416. , NULL
  417. , "ecn"
  418. , NULL
  419. , "IP ECN Statistics"
  420. , "packets/s"
  421. , PLUGIN_PROC_NAME
  422. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  423. , NETDATA_CHART_PRIO_IP_ECN
  424. , update_every
  425. , RRDSET_TYPE_LINE
  426. );
  427. rrdset_flag_set(st_ecnpkts, RRDSET_FLAG_DETAIL);
  428. rd_cep = rrddim_add(st_ecnpkts, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  429. rd_noectp = rrddim_add(st_ecnpkts, "InNoECTPkts", "NoECTP", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  430. rd_ectp0 = rrddim_add(st_ecnpkts, "InECT0Pkts", "ECTP0", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  431. rd_ectp1 = rrddim_add(st_ecnpkts, "InECT1Pkts", "ECTP1", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  432. }
  433. else rrdset_next(st_ecnpkts);
  434. rrddim_set_by_pointer(st_ecnpkts, rd_cep, ipext_InCEPkts);
  435. rrddim_set_by_pointer(st_ecnpkts, rd_noectp, ipext_InNoECTPkts);
  436. rrddim_set_by_pointer(st_ecnpkts, rd_ectp0, ipext_InECT0Pkts);
  437. rrddim_set_by_pointer(st_ecnpkts, rd_ectp1, ipext_InECT1Pkts);
  438. rrdset_done(st_ecnpkts);
  439. }
  440. }
  441. else if(unlikely(hash == hash_tcpext && strcmp(key, "TcpExt") == 0)) {
  442. size_t h = l++;
  443. words = procfile_linewords(ff, l);
  444. if(unlikely(words < 2)) {
  445. error("Cannot read /proc/net/netstat TcpExt line. Expected 2+ params, read %zu.", words);
  446. continue;
  447. }
  448. parse_line_pair(ff, arl_tcpext, h, l);
  449. // --------------------------------------------------------------------
  450. if(do_tcpext_memory == CONFIG_BOOLEAN_YES || (do_tcpext_memory == CONFIG_BOOLEAN_AUTO &&
  451. (tcpext_TCPMemoryPressures ||
  452. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  453. do_tcpext_memory = CONFIG_BOOLEAN_YES;
  454. static RRDSET *st_tcpmemorypressures = NULL;
  455. static RRDDIM *rd_pressures = NULL;
  456. if(unlikely(!st_tcpmemorypressures)) {
  457. st_tcpmemorypressures = rrdset_create_localhost(
  458. RRD_TYPE_NET_NETSTAT
  459. , "tcpmemorypressures"
  460. , NULL
  461. , "tcp"
  462. , NULL
  463. , "TCP Memory Pressures"
  464. , "events/s"
  465. , PLUGIN_PROC_NAME
  466. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  467. , NETDATA_CHART_PRIO_IP_TCP_MEM
  468. , update_every
  469. , RRDSET_TYPE_LINE
  470. );
  471. rd_pressures = rrddim_add(st_tcpmemorypressures, "TCPMemoryPressures", "pressures", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  472. }
  473. else
  474. rrdset_next(st_tcpmemorypressures);
  475. rrddim_set_by_pointer(st_tcpmemorypressures, rd_pressures, tcpext_TCPMemoryPressures);
  476. rrdset_done(st_tcpmemorypressures);
  477. }
  478. // --------------------------------------------------------------------
  479. if(do_tcpext_connaborts == CONFIG_BOOLEAN_YES || (do_tcpext_connaborts == CONFIG_BOOLEAN_AUTO &&
  480. (tcpext_TCPAbortOnData ||
  481. tcpext_TCPAbortOnClose ||
  482. tcpext_TCPAbortOnMemory ||
  483. tcpext_TCPAbortOnTimeout ||
  484. tcpext_TCPAbortOnLinger ||
  485. tcpext_TCPAbortFailed ||
  486. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  487. do_tcpext_connaborts = CONFIG_BOOLEAN_YES;
  488. static RRDSET *st_tcpconnaborts = NULL;
  489. static RRDDIM *rd_baddata = NULL, *rd_userclosed = NULL, *rd_nomemory = NULL, *rd_timeout = NULL, *rd_linger = NULL, *rd_failed = NULL;
  490. if(unlikely(!st_tcpconnaborts)) {
  491. st_tcpconnaborts = rrdset_create_localhost(
  492. RRD_TYPE_NET_NETSTAT
  493. , "tcpconnaborts"
  494. , NULL
  495. , "tcp"
  496. , NULL
  497. , "TCP Connection Aborts"
  498. , "connections/s"
  499. , PLUGIN_PROC_NAME
  500. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  501. , NETDATA_CHART_PRIO_IP_TCP_CONNABORTS
  502. , update_every
  503. , RRDSET_TYPE_LINE
  504. );
  505. rd_baddata = rrddim_add(st_tcpconnaborts, "TCPAbortOnData", "baddata", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  506. rd_userclosed = rrddim_add(st_tcpconnaborts, "TCPAbortOnClose", "userclosed", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  507. rd_nomemory = rrddim_add(st_tcpconnaborts, "TCPAbortOnMemory", "nomemory", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  508. rd_timeout = rrddim_add(st_tcpconnaborts, "TCPAbortOnTimeout", "timeout", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  509. rd_linger = rrddim_add(st_tcpconnaborts, "TCPAbortOnLinger", "linger", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  510. rd_failed = rrddim_add(st_tcpconnaborts, "TCPAbortFailed", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  511. }
  512. else
  513. rrdset_next(st_tcpconnaborts);
  514. rrddim_set_by_pointer(st_tcpconnaborts, rd_baddata, tcpext_TCPAbortOnData);
  515. rrddim_set_by_pointer(st_tcpconnaborts, rd_userclosed, tcpext_TCPAbortOnClose);
  516. rrddim_set_by_pointer(st_tcpconnaborts, rd_nomemory, tcpext_TCPAbortOnMemory);
  517. rrddim_set_by_pointer(st_tcpconnaborts, rd_timeout, tcpext_TCPAbortOnTimeout);
  518. rrddim_set_by_pointer(st_tcpconnaborts, rd_linger, tcpext_TCPAbortOnLinger);
  519. rrddim_set_by_pointer(st_tcpconnaborts, rd_failed, tcpext_TCPAbortFailed);
  520. rrdset_done(st_tcpconnaborts);
  521. }
  522. // --------------------------------------------------------------------
  523. if(do_tcpext_reorder == CONFIG_BOOLEAN_YES || (do_tcpext_reorder == CONFIG_BOOLEAN_AUTO &&
  524. (tcpext_TCPRenoReorder ||
  525. tcpext_TCPFACKReorder ||
  526. tcpext_TCPSACKReorder ||
  527. tcpext_TCPTSReorder ||
  528. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  529. do_tcpext_reorder = CONFIG_BOOLEAN_YES;
  530. static RRDSET *st_tcpreorders = NULL;
  531. static RRDDIM *rd_timestamp = NULL, *rd_sack = NULL, *rd_fack = NULL, *rd_reno = NULL;
  532. if(unlikely(!st_tcpreorders)) {
  533. st_tcpreorders = rrdset_create_localhost(
  534. RRD_TYPE_NET_NETSTAT
  535. , "tcpreorders"
  536. , NULL
  537. , "tcp"
  538. , NULL
  539. , "TCP Reordered Packets by Detection Method"
  540. , "packets/s"
  541. , PLUGIN_PROC_NAME
  542. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  543. , NETDATA_CHART_PRIO_IP_TCP_REORDERS
  544. , update_every
  545. , RRDSET_TYPE_LINE
  546. );
  547. rd_timestamp = rrddim_add(st_tcpreorders, "TCPTSReorder", "timestamp", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  548. rd_sack = rrddim_add(st_tcpreorders, "TCPSACKReorder", "sack", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  549. rd_fack = rrddim_add(st_tcpreorders, "TCPFACKReorder", "fack", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  550. rd_reno = rrddim_add(st_tcpreorders, "TCPRenoReorder", "reno", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  551. }
  552. else
  553. rrdset_next(st_tcpreorders);
  554. rrddim_set_by_pointer(st_tcpreorders, rd_timestamp, tcpext_TCPTSReorder);
  555. rrddim_set_by_pointer(st_tcpreorders, rd_sack, tcpext_TCPSACKReorder);
  556. rrddim_set_by_pointer(st_tcpreorders, rd_fack, tcpext_TCPFACKReorder);
  557. rrddim_set_by_pointer(st_tcpreorders, rd_reno, tcpext_TCPRenoReorder);
  558. rrdset_done(st_tcpreorders);
  559. }
  560. // --------------------------------------------------------------------
  561. if(do_tcpext_ofo == CONFIG_BOOLEAN_YES || (do_tcpext_ofo == CONFIG_BOOLEAN_AUTO &&
  562. (tcpext_TCPOFOQueue ||
  563. tcpext_TCPOFODrop ||
  564. tcpext_TCPOFOMerge ||
  565. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  566. do_tcpext_ofo = CONFIG_BOOLEAN_YES;
  567. static RRDSET *st_ip_tcpofo = NULL;
  568. static RRDDIM *rd_inqueue = NULL, *rd_dropped = NULL, *rd_merged = NULL, *rd_pruned = NULL;
  569. if(unlikely(!st_ip_tcpofo)) {
  570. st_ip_tcpofo = rrdset_create_localhost(
  571. RRD_TYPE_NET_NETSTAT
  572. , "tcpofo"
  573. , NULL
  574. , "tcp"
  575. , NULL
  576. , "TCP Out-Of-Order Queue"
  577. , "packets/s"
  578. , PLUGIN_PROC_NAME
  579. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  580. , NETDATA_CHART_PRIO_IP_TCP_OFO
  581. , update_every
  582. , RRDSET_TYPE_LINE
  583. );
  584. rd_inqueue = rrddim_add(st_ip_tcpofo, "TCPOFOQueue", "inqueue", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  585. rd_dropped = rrddim_add(st_ip_tcpofo, "TCPOFODrop", "dropped", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  586. rd_merged = rrddim_add(st_ip_tcpofo, "TCPOFOMerge", "merged", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  587. rd_pruned = rrddim_add(st_ip_tcpofo, "OfoPruned", "pruned", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  588. }
  589. else
  590. rrdset_next(st_ip_tcpofo);
  591. rrddim_set_by_pointer(st_ip_tcpofo, rd_inqueue, tcpext_TCPOFOQueue);
  592. rrddim_set_by_pointer(st_ip_tcpofo, rd_dropped, tcpext_TCPOFODrop);
  593. rrddim_set_by_pointer(st_ip_tcpofo, rd_merged, tcpext_TCPOFOMerge);
  594. rrddim_set_by_pointer(st_ip_tcpofo, rd_pruned, tcpext_OfoPruned);
  595. rrdset_done(st_ip_tcpofo);
  596. }
  597. // --------------------------------------------------------------------
  598. if(do_tcpext_syscookies == CONFIG_BOOLEAN_YES || (do_tcpext_syscookies == CONFIG_BOOLEAN_AUTO &&
  599. (tcpext_SyncookiesSent ||
  600. tcpext_SyncookiesRecv ||
  601. tcpext_SyncookiesFailed ||
  602. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  603. do_tcpext_syscookies = CONFIG_BOOLEAN_YES;
  604. static RRDSET *st_syncookies = NULL;
  605. static RRDDIM *rd_received = NULL, *rd_sent = NULL, *rd_failed = NULL;
  606. if(unlikely(!st_syncookies)) {
  607. st_syncookies = rrdset_create_localhost(
  608. RRD_TYPE_NET_NETSTAT
  609. , "tcpsyncookies"
  610. , NULL
  611. , "tcp"
  612. , NULL
  613. , "TCP SYN Cookies"
  614. , "packets/s"
  615. , PLUGIN_PROC_NAME
  616. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  617. , NETDATA_CHART_PRIO_IP_TCP_SYNCOOKIES
  618. , update_every
  619. , RRDSET_TYPE_LINE
  620. );
  621. rd_received = rrddim_add(st_syncookies, "SyncookiesRecv", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  622. rd_sent = rrddim_add(st_syncookies, "SyncookiesSent", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  623. rd_failed = rrddim_add(st_syncookies, "SyncookiesFailed", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
  624. }
  625. else
  626. rrdset_next(st_syncookies);
  627. rrddim_set_by_pointer(st_syncookies, rd_received, tcpext_SyncookiesRecv);
  628. rrddim_set_by_pointer(st_syncookies, rd_sent, tcpext_SyncookiesSent);
  629. rrddim_set_by_pointer(st_syncookies, rd_failed, tcpext_SyncookiesFailed);
  630. rrdset_done(st_syncookies);
  631. }
  632. // --------------------------------------------------------------------
  633. if(do_tcpext_syn_queue == CONFIG_BOOLEAN_YES || (do_tcpext_syn_queue == CONFIG_BOOLEAN_AUTO &&
  634. (tcpext_TCPReqQFullDrop ||
  635. tcpext_TCPReqQFullDoCookies ||
  636. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  637. do_tcpext_syn_queue = CONFIG_BOOLEAN_YES;
  638. static RRDSET *st_syn_queue = NULL;
  639. static RRDDIM
  640. *rd_TCPReqQFullDrop = NULL,
  641. *rd_TCPReqQFullDoCookies = NULL;
  642. if(unlikely(!st_syn_queue)) {
  643. st_syn_queue = rrdset_create_localhost(
  644. RRD_TYPE_NET_NETSTAT
  645. , "tcp_syn_queue"
  646. , NULL
  647. , "tcp"
  648. , NULL
  649. , "TCP SYN Queue Issues"
  650. , "packets/s"
  651. , PLUGIN_PROC_NAME
  652. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  653. , NETDATA_CHART_PRIO_IP_TCP_SYN_QUEUE
  654. , update_every
  655. , RRDSET_TYPE_LINE
  656. );
  657. rd_TCPReqQFullDrop = rrddim_add(st_syn_queue, "TCPReqQFullDrop", "drops", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  658. rd_TCPReqQFullDoCookies = rrddim_add(st_syn_queue, "TCPReqQFullDoCookies", "cookies", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  659. }
  660. else
  661. rrdset_next(st_syn_queue);
  662. rrddim_set_by_pointer(st_syn_queue, rd_TCPReqQFullDrop, tcpext_TCPReqQFullDrop);
  663. rrddim_set_by_pointer(st_syn_queue, rd_TCPReqQFullDoCookies, tcpext_TCPReqQFullDoCookies);
  664. rrdset_done(st_syn_queue);
  665. }
  666. // --------------------------------------------------------------------
  667. if(do_tcpext_accept_queue == CONFIG_BOOLEAN_YES || (do_tcpext_accept_queue == CONFIG_BOOLEAN_AUTO &&
  668. (tcpext_ListenOverflows ||
  669. tcpext_ListenDrops ||
  670. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  671. do_tcpext_accept_queue = CONFIG_BOOLEAN_YES;
  672. static RRDSET *st_accept_queue = NULL;
  673. static RRDDIM *rd_overflows = NULL,
  674. *rd_drops = NULL;
  675. if(unlikely(!st_accept_queue)) {
  676. st_accept_queue = rrdset_create_localhost(
  677. RRD_TYPE_NET_NETSTAT
  678. , "tcp_accept_queue"
  679. , NULL
  680. , "tcp"
  681. , NULL
  682. , "TCP Accept Queue Issues"
  683. , "packets/s"
  684. , PLUGIN_PROC_NAME
  685. , PLUGIN_PROC_MODULE_NETSTAT_NAME
  686. , NETDATA_CHART_PRIO_IP_TCP_ACCEPT_QUEUE
  687. , update_every
  688. , RRDSET_TYPE_LINE
  689. );
  690. rd_overflows = rrddim_add(st_accept_queue, "ListenOverflows", "overflows", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  691. rd_drops = rrddim_add(st_accept_queue, "ListenDrops", "drops", 1, 1, RRD_ALGORITHM_INCREMENTAL);
  692. }
  693. else
  694. rrdset_next(st_accept_queue);
  695. rrddim_set_by_pointer(st_accept_queue, rd_overflows, tcpext_ListenOverflows);
  696. rrddim_set_by_pointer(st_accept_queue, rd_drops, tcpext_ListenDrops);
  697. rrdset_done(st_accept_queue);
  698. }
  699. }
  700. }
  701. return 0;
  702. }