read netfilter count of sockets and max sockets on systems without /proc/net/stat/nf_conntrack
Costa Tsaousis (ktsaou) committed
Nov 22, 2016 at 02:12 UTC
39a47636e1a86691c02af94f165c0de6779486c1
1 file changed
+107
-65
src/proc_net_stat_conntrack.c
+107
-65
@@ -4,83 +4,125 @@
4
#define RRD_TYPE_NET_STAT_CONNTRACK "conntrack"
5
6
int do_proc_net_stat_conntrack(int update_every, unsigned long long dt) {
7
- (void)dt;
8
-
7
static procfile *ff = NULL;
8
static int do_sockets = -1, do_new = -1, do_changes = -1, do_expect = -1, do_search = -1, do_errors = -1;
9
+ static unsigned long long get_max_every = 10 * 1000000ULL, usec_since_last_max = 0;
10
+ static int read_count = 1, read_full = 1;
11
+ static char *nf_conntrack_filename, *nf_conntrack_count_filename, *nf_conntrack_max_filename;
12
+ static RRDVAR *rrdvar_max = NULL;
13
12
- if(unlikely(do_sockets == -1)) {
13
- do_sockets = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connections", 1);
14
- do_new = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter new connections", 1);
15
- do_changes = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection changes", 1);
16
- do_expect = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection expectations", 1);
17
- do_search = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection searches", 1);
18
- do_errors = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter errors", 1);
19
- }
14
+ unsigned long long aentries = 0, asearched = 0, afound = 0, anew = 0, ainvalid = 0, aignore = 0, adelete = 0, adelete_list = 0,
15
+ ainsert = 0, ainsert_failed = 0, adrop = 0, aearly_drop = 0, aicmp_error = 0, aexpect_new = 0, aexpect_create = 0, aexpect_delete = 0, asearch_restart = 0;
16
21
- if(unlikely(!ff)) {
17
+ if(unlikely(do_sockets == -1)) {
18
char filename[FILENAME_MAX + 1];
19
snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/stat/nf_conntrack");
24
- ff = procfile_open(config_get("plugin:proc:/proc/net/stat/nf_conntrack", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
25
- if(unlikely(!ff))
26
- return 1;
27
- }
20
+ nf_conntrack_filename = config_get("plugin:proc:/proc/net/stat/nf_conntrack", "filename to monitor", filename);
21
29
- ff = procfile_readall(ff);
30
- if(unlikely(!ff))
31
- return 0; // we return 0, so that we will retry to open it next time
22
+ snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/sys/net/netfilter/nf_conntrack_max");
23
+ nf_conntrack_max_filename = config_get("plugin:proc:/proc/sys/net/netfilter/nf_conntrack_max", "filename to monitor", filename);
24
+ get_max_every = config_get_number("plugin:proc:/proc/sys/net/netfilter/nf_conntrack_max", "read every seconds", 10) * 1000000ULL;
25
33
- uint32_t lines = procfile_lines(ff), l;
26
+ read_full = 1;
27
+ ff = procfile_open(nf_conntrack_filename, " \t:", PROCFILE_FLAG_DEFAULT);
28
+ if(!ff) read_full = 0;
29
35
- unsigned long long aentries = 0, asearched = 0, afound = 0, anew = 0, ainvalid = 0, aignore = 0, adelete = 0, adelete_list = 0,
36
- ainsert = 0, ainsert_failed = 0, adrop = 0, aearly_drop = 0, aicmp_error = 0, aexpect_new = 0, aexpect_create = 0, aexpect_delete = 0, asearch_restart = 0;
30
+ do_new = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter new connections", read_full);
31
+ do_changes = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection changes", read_full);
32
+ do_expect = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection expectations", read_full);
33
+ do_search = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connection searches", read_full);
34
+ do_errors = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter errors", read_full);
35
38
- for(l = 1; l < lines ;l++) {
39
- uint32_t words = procfile_linewords(ff, l);
40
- if(unlikely(words < 17)) {
41
- if(unlikely(words)) error("Cannot read /proc/net/stat/nf_conntrack line. Expected 17 params, read %u.", words);
42
- continue;
36
+ read_count = !read_full;
37
+ if(read_count) {
38
+ snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/sys/net/netfilter/nf_conntrack_count");
39
+ nf_conntrack_count_filename = config_get("plugin:proc:/proc/sys/net/netfilter/nf_conntrack_count", "filename to monitor", filename);
40
+
41
+ if(read_single_number_file(nf_conntrack_count_filename, &aentries))
42
+ read_count = 0;
43
}
44
45
- unsigned long long tentries = 0, tsearched = 0, tfound = 0, tnew = 0, tinvalid = 0, tignore = 0, tdelete = 0, tdelete_list = 0, tinsert = 0, tinsert_failed = 0, tdrop = 0, tearly_drop = 0, ticmp_error = 0, texpect_new = 0, texpect_create = 0, texpect_delete = 0, tsearch_restart = 0;
46
-
47
- tentries = strtoull(procfile_lineword(ff, l, 0), NULL, 16);
48
- tsearched = strtoull(procfile_lineword(ff, l, 1), NULL, 16);
49
- tfound = strtoull(procfile_lineword(ff, l, 2), NULL, 16);
50
- tnew = strtoull(procfile_lineword(ff, l, 3), NULL, 16);
51
- tinvalid = strtoull(procfile_lineword(ff, l, 4), NULL, 16);
52
- tignore = strtoull(procfile_lineword(ff, l, 5), NULL, 16);
53
- tdelete = strtoull(procfile_lineword(ff, l, 6), NULL, 16);
54
- tdelete_list = strtoull(procfile_lineword(ff, l, 7), NULL, 16);
55
- tinsert = strtoull(procfile_lineword(ff, l, 8), NULL, 16);
56
- tinsert_failed = strtoull(procfile_lineword(ff, l, 9), NULL, 16);
57
- tdrop = strtoull(procfile_lineword(ff, l, 10), NULL, 16);
58
- tearly_drop = strtoull(procfile_lineword(ff, l, 11), NULL, 16);
59
- ticmp_error = strtoull(procfile_lineword(ff, l, 12), NULL, 16);
60
- texpect_new = strtoull(procfile_lineword(ff, l, 13), NULL, 16);
61
- texpect_create = strtoull(procfile_lineword(ff, l, 14), NULL, 16);
62
- texpect_delete = strtoull(procfile_lineword(ff, l, 15), NULL, 16);
63
- tsearch_restart = strtoull(procfile_lineword(ff, l, 16), NULL, 16);
64
-
65
- if(unlikely(!aentries)) aentries = tentries;
66
-
67
- // sum all the cpus together
68
- asearched += tsearched; // conntrack.search
69
- afound += tfound; // conntrack.search
70
- anew += tnew; // conntrack.new
71
- ainvalid += tinvalid; // conntrack.new
72
- aignore += tignore; // conntrack.new
73
- adelete += tdelete; // conntrack.changes
74
- adelete_list += tdelete_list; // conntrack.changes
75
- ainsert += tinsert; // conntrack.changes
76
- ainsert_failed += tinsert_failed; // conntrack.errors
77
- adrop += tdrop; // conntrack.errors
78
- aearly_drop += tearly_drop; // conntrack.errors
79
- aicmp_error += ticmp_error; // conntrack.errors
80
- aexpect_new += texpect_new; // conntrack.expect
81
- aexpect_create += texpect_create; // conntrack.expect
82
- aexpect_delete += texpect_delete; // conntrack.expect
83
- asearch_restart += tsearch_restart; // conntrack.search
45
+ do_sockets = config_get_boolean("plugin:proc:/proc/net/stat/nf_conntrack", "netfilter connections", read_count);
46
+
47
+ if(!read_count && !read_full)
48
+ return 1;
49
+
50
+ rrdvar_max = rrdvar_custom_host_variable_create(&localhost, "nf.conntrack.max");
51
+ }
52
+
53
+ if(likely(read_full)) {
54
+ if(unlikely(!ff)) {
55
+ ff = procfile_open(nf_conntrack_filename, " \t:", PROCFILE_FLAG_DEFAULT);
56
+ if(unlikely(!ff))
57
+ return 0; // we return 0, so that we will retry to open it next time
58
+ }
59
+
60
+ ff = procfile_readall(ff);
61
+ if(unlikely(!ff))
62
+ return 0; // we return 0, so that we will retry to open it next time
63
+
64
+ uint32_t lines = procfile_lines(ff), l;
65
+
66
+ for(l = 1; l < lines ;l++) {
67
+ uint32_t words = procfile_linewords(ff, l);
68
+ if(unlikely(words < 17)) {
69
+ if(unlikely(words)) error("Cannot read /proc/net/stat/nf_conntrack line. Expected 17 params, read %u.", words);
70
+ continue;
71
+ }
72
+
73
+ unsigned long long tentries = 0, tsearched = 0, tfound = 0, tnew = 0, tinvalid = 0, tignore = 0, tdelete = 0, tdelete_list = 0, tinsert = 0, tinsert_failed = 0, tdrop = 0, tearly_drop = 0, ticmp_error = 0, texpect_new = 0, texpect_create = 0, texpect_delete = 0, tsearch_restart = 0;
74
+
75
+ tentries = strtoull(procfile_lineword(ff, l, 0), NULL, 16);
76
+ tsearched = strtoull(procfile_lineword(ff, l, 1), NULL, 16);
77
+ tfound = strtoull(procfile_lineword(ff, l, 2), NULL, 16);
78
+ tnew = strtoull(procfile_lineword(ff, l, 3), NULL, 16);
79
+ tinvalid = strtoull(procfile_lineword(ff, l, 4), NULL, 16);
80
+ tignore = strtoull(procfile_lineword(ff, l, 5), NULL, 16);
81
+ tdelete = strtoull(procfile_lineword(ff, l, 6), NULL, 16);
82
+ tdelete_list = strtoull(procfile_lineword(ff, l, 7), NULL, 16);
83
+ tinsert = strtoull(procfile_lineword(ff, l, 8), NULL, 16);
84
+ tinsert_failed = strtoull(procfile_lineword(ff, l, 9), NULL, 16);
85
+ tdrop = strtoull(procfile_lineword(ff, l, 10), NULL, 16);
86
+ tearly_drop = strtoull(procfile_lineword(ff, l, 11), NULL, 16);
87
+ ticmp_error = strtoull(procfile_lineword(ff, l, 12), NULL, 16);
88
+ texpect_new = strtoull(procfile_lineword(ff, l, 13), NULL, 16);
89
+ texpect_create = strtoull(procfile_lineword(ff, l, 14), NULL, 16);
90
+ texpect_delete = strtoull(procfile_lineword(ff, l, 15), NULL, 16);
91
+ tsearch_restart = strtoull(procfile_lineword(ff, l, 16), NULL, 16);
92
+
93
+ if(unlikely(!aentries)) aentries = tentries;
94
+
95
+ // sum all the cpus together
96
+ asearched += tsearched; // conntrack.search
97
+ afound += tfound; // conntrack.search
98
+ anew += tnew; // conntrack.new
99
+ ainvalid += tinvalid; // conntrack.new
100
+ aignore += tignore; // conntrack.new
101
+ adelete += tdelete; // conntrack.changes
102
+ adelete_list += tdelete_list; // conntrack.changes
103
+ ainsert += tinsert; // conntrack.changes
104
+ ainsert_failed += tinsert_failed; // conntrack.errors
105
+ adrop += tdrop; // conntrack.errors
106
+ aearly_drop += tearly_drop; // conntrack.errors
107
+ aicmp_error += ticmp_error; // conntrack.errors
108
+ aexpect_new += texpect_new; // conntrack.expect
109
+ aexpect_create += texpect_create; // conntrack.expect
110
+ aexpect_delete += texpect_delete; // conntrack.expect
111
+ asearch_restart += tsearch_restart; // conntrack.search
112
+ }
113
+ }
114
+ else {
115
+ if(unlikely(read_single_number_file(nf_conntrack_count_filename, &aentries)))
116
+ return 0; // we return 0, so that we will retry to open it next time
117
+ }
118
+
119
+ usec_since_last_max += dt;
120
+ if(unlikely(rrdvar_max && usec_since_last_max > get_max_every)) {
121
+ usec_since_last_max = 0;
122
+
123
+ unsigned long long max;
124
+ if(likely(!read_single_number_file(nf_conntrack_max_filename, &max)))
125
+ rrdvar_custom_host_variable_set(rrdvar_max, max);
126
}
127
128
RRDSET *st;