added netfilter expectations
Costa Tsaousis (ktsaou) committed
Mar 18, 2017 at 01:50 UTC
a0bed880fad1f94acc83146920d845db46e486c9
1 file changed
+153
-13
src/plugin_nfacct.c
+153
-13
@@ -27,9 +27,14 @@ static struct {
27
struct nfgenmsg *nfh;
28
unsigned int seq;
29
uint32_t portid;
30
+
31
struct nlattr *tb[CTA_STATS_MAX+1];
32
const char *attr2name[CTA_STATS_MAX+1];
33
kernel_uint_t metrics[CTA_STATS_MAX+1];
34
+
35
+ struct nlattr *tb_exp[CTA_STATS_EXP_MAX+1];
36
+ const char *attr2name_exp[CTA_STATS_EXP_MAX+1];
37
+ kernel_uint_t metrics_exp[CTA_STATS_EXP_MAX+1];
38
} nfstat_root = {
39
.update_every = 1,
40
.buf = NULL,
@@ -55,7 +60,14 @@ static struct {
60
[CTA_STATS_ERROR] = "icmp_error",
61
[CTA_STATS_SEARCH_RESTART] = "search_restart",
62
},
58
- .metrics = {}
63
+ .metrics = {},
64
+ .tb_exp = {},
65
+ .attr2name_exp = {
66
+ [CTA_STATS_EXP_NEW] = "new",
67
+ [CTA_STATS_EXP_CREATE] = "created",
68
+ [CTA_STATS_EXP_DELETE] = "deleted",
69
+ },
70
+ .metrics_exp = {}
71
};
72
73
@@ -93,6 +105,23 @@ static void nfstat_cleanup() {
105
nfstat_root.buf_size = 0;
106
}
107
108
+static struct nlmsghdr * nfct_mnl_nlmsghdr_put(char *buf, uint16_t subsys, uint16_t type, uint8_t family, uint32_t seq) {
109
+ struct nlmsghdr *nlh;
110
+ struct nfgenmsg *nfh;
111
+
112
+ nlh = mnl_nlmsg_put_header(buf);
113
+ nlh->nlmsg_type = (subsys << 8) | type;
114
+ nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
115
+ nlh->nlmsg_seq = seq;
116
+
117
+ nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
118
+ nfh->nfgen_family = family;
119
+ nfh->version = NFNETLINK_V0;
120
+ nfh->res_id = 0;
121
+
122
+ return nlh;
123
+}
124
+
125
static int nfct_stats_attr_cb(const struct nlattr *attr, void *data) {
126
const struct nlattr **tb = data;
127
int type = mnl_attr_get_type(attr);
@@ -131,23 +160,14 @@ static int nfstat_callback(const struct nlmsghdr *nlh, void *data) {
160
return MNL_CB_OK;
161
}
162
134
-static int nfstat_collect() {
135
- int i;
136
-
163
+static int nfstat_collect_conntrack() {
164
// zero all metrics - we will sum the metrics of all CPUs later
165
+ int i;
166
for (i = 0; i < CTA_STATS_MAX+1; i++)
167
nfstat_root.metrics[i] = 0;
168
169
// prepare the request
142
- nfstat_root.nlh = mnl_nlmsg_put_header(nfstat_root.buf);
143
- nfstat_root.nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET_STATS_CPU;
144
- nfstat_root.nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
145
- nfstat_root.nlh->nlmsg_seq = nfstat_root.seq++;
146
-
147
- nfstat_root.nfh = mnl_nlmsg_put_extra_header(nfstat_root.nlh, sizeof(struct nfgenmsg));
148
- nfstat_root.nfh->nfgen_family = AF_UNSPEC;
149
- nfstat_root.nfh->version = NFNETLINK_V0;
150
- nfstat_root.nfh->res_id = 0;
170
+ nfstat_root.nlh = nfct_mnl_nlmsghdr_put(nfstat_root.buf, NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET_STATS_CPU, AF_UNSPEC, nfstat_root.seq);
171
172
// send the request
173
if(mnl_socket_sendto(nfstat_root.mnl, nfstat_root.nlh, nfstat_root.nlh->nlmsg_len) < 0) {
@@ -178,6 +198,90 @@ static int nfstat_collect() {
198
return 0;
199
}
200
201
+static int nfexp_stats_attr_cb(const struct nlattr *attr, void *data)
202
+{
203
+ const struct nlattr **tb = data;
204
+ int type = mnl_attr_get_type(attr);
205
+
206
+ if (mnl_attr_type_valid(attr, CTA_STATS_EXP_MAX) < 0)
207
+ return MNL_CB_OK;
208
+
209
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
210
+ error("NFSTAT EXP: mnl_attr_validate() failed");
211
+ return MNL_CB_ERROR;
212
+ }
213
+
214
+ tb[type] = attr;
215
+ return MNL_CB_OK;
216
+}
217
+
218
+static int nfstat_callback_exp(const struct nlmsghdr *nlh, void *data) {
219
+ (void)data;
220
+
221
+ struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
222
+
223
+ mnl_attr_parse(nlh, sizeof(*nfg), nfexp_stats_attr_cb, nfstat_root.tb_exp);
224
+
225
+ int i;
226
+ for (i = 0; i < CTA_STATS_EXP_MAX+1; i++) {
227
+ if (nfstat_root.tb_exp[i]) {
228
+ nfstat_root.metrics_exp[i] += ntohl(mnl_attr_get_u32(nfstat_root.tb_exp[i]));
229
+ }
230
+ }
231
+
232
+ return MNL_CB_OK;
233
+}
234
+
235
+static int nfstat_collect_conntrack_expectations() {
236
+ // zero all metrics - we will sum the metrics of all CPUs later
237
+ int i;
238
+ for (i = 0; i < CTA_STATS_EXP_MAX+1; i++)
239
+ nfstat_root.metrics_exp[i] = 0;
240
+
241
+ // prepare the request
242
+ nfstat_root.nlh = nfct_mnl_nlmsghdr_put(nfstat_root.buf, NFNL_SUBSYS_CTNETLINK_EXP, IPCTNL_MSG_EXP_GET_STATS_CPU, AF_UNSPEC, nfstat_root.seq);
243
+
244
+ // send the request
245
+ if(mnl_socket_sendto(nfstat_root.mnl, nfstat_root.nlh, nfstat_root.nlh->nlmsg_len) < 0) {
246
+ error("NFSTAT: mnl_socket_sendto() failed");
247
+ return 1;
248
+ }
249
+
250
+ // get the reply
251
+ ssize_t ret;
252
+ while ((ret = mnl_socket_recvfrom(nfstat_root.mnl, nfstat_root.buf, nfstat_root.buf_size)) > 0) {
253
+ if(mnl_cb_run(
254
+ nfstat_root.buf
255
+ , (size_t)ret
256
+ , nfstat_root.nlh->nlmsg_seq
257
+ , nfstat_root.portid
258
+ , nfstat_callback_exp
259
+ , NULL
260
+ ) <= MNL_CB_STOP)
261
+ break;
262
+ }
263
+
264
+ // verify we run without issues
265
+ if (ret == -1) {
266
+ error("NFSTAT: error communicating with kernel. This plugin can only work when netdata runs as root.");
267
+ return 1;
268
+ }
269
+
270
+ return 0;
271
+}
272
+
273
+static int nfstat_collect() {
274
+ nfstat_root.seq++;
275
+
276
+ if(nfstat_collect_conntrack())
277
+ return 1;
278
+
279
+ if(nfstat_collect_conntrack_expectations())
280
+ return 1;
281
+
282
+ return 0;
283
+}
284
+
285
static void nfstat_send_metrics() {
286
287
{
@@ -318,6 +422,42 @@ static void nfstat_send_metrics() {
422
423
rrdset_done(st_errors);
424
}
425
+
426
+ // ----------------------------------------------------------------
427
+
428
+ {
429
+ static RRDSET *st_expect = NULL;
430
+ static RRDDIM *rd_new = NULL, *rd_created = NULL, *rd_deleted = NULL;
431
+
432
+ if(!st_expect) {
433
+ st_expect = rrdset_create_localhost(
434
+ RRD_TYPE_NET_STAT_NETFILTER
435
+ , RRD_TYPE_NET_STAT_CONNTRACK "_search"
436
+ , NULL
437
+ , RRD_TYPE_NET_STAT_CONNTRACK
438
+ , NULL
439
+ , "Connection Tracker Expectations"
440
+ , "expectations/s"
441
+ , 3003
442
+ , nfstat_root.update_every
443
+ , RRDSET_TYPE_LINE
444
+ );
445
+ rrdset_flag_set(st_expect, RRDSET_FLAG_DETAIL);
446
+
447
+ rd_created = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_CREATE], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
448
+ rd_deleted = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_DELETE], NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
449
+ rd_new = rrddim_add(st_expect, nfstat_root.attr2name_exp[CTA_STATS_EXP_NEW], NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
450
+ }
451
+ else
452
+ rrdset_next(st_expect);
453
+
454
+ rrddim_set_by_pointer(st_expect, rd_created, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_CREATE]);
455
+ rrddim_set_by_pointer(st_expect, rd_deleted, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_DELETE]);
456
+ rrddim_set_by_pointer(st_expect, rd_new, (collected_number) nfstat_root.metrics_exp[CTA_STATS_EXP_NEW]);
457
+
458
+ rrdset_done(st_expect);
459
+ }
460
+
461
}
462
463
#endif // HAVE_LINUX_NETFILTER_NFNETLINK_CONNTRACK_H