@cryptotaxi247 / netdata-1 / commits / a0bed880f

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