diff options
Diffstat (limited to 'src/plugin_nfacct.c')
-rw-r--r-- | src/plugin_nfacct.c | 314 |
1 files changed, 147 insertions, 167 deletions
diff --git a/src/plugin_nfacct.c b/src/plugin_nfacct.c index 6cde66e0c..b2396fac1 100644 --- a/src/plugin_nfacct.c +++ b/src/plugin_nfacct.c @@ -1,222 +1,202 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#ifdef INTERNAL_PLUGIN_NFACCT -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <time.h> -#include <errno.h> +#include "common.h" +#ifdef INTERNAL_PLUGIN_NFACCT #include <libmnl/libmnl.h> #include <libnetfilter_acct/libnetfilter_acct.h> -#include "main.h" -#include "global_statistics.h" -#include "common.h" -#include "appconfig.h" -#include "log.h" -#include "rrd.h" -#include "plugin_proc.h" - struct mynfacct { - const char *name; - uint64_t pkts; - uint64_t bytes; - struct nfacct *nfacct; + const char *name; + uint64_t pkts; + uint64_t bytes; + struct nfacct *nfacct; }; struct nfacct_list { - int size; - int len; - struct mynfacct data[]; + int size; + int len; + struct mynfacct data[]; } *nfacct_list = NULL; static int nfacct_callback(const struct nlmsghdr *nlh, void *data) { - if(data) {}; - - if(!nfacct_list || nfacct_list->len == nfacct_list->size) { - int size = (nfacct_list) ? nfacct_list->size : 0; - int len = (nfacct_list) ? nfacct_list->len : 0; - size++; - - info("nfacct.plugin: increasing nfacct_list to size %d", size); - - nfacct_list = realloc(nfacct_list, sizeof(struct nfacct_list) + (sizeof(struct mynfacct) * size)); - if(!nfacct_list) { - error("nfacct.plugin: cannot allocate nfacct_list."); - return MNL_CB_OK; - } - - nfacct_list->data[len].nfacct = nfacct_alloc(); - if(!nfacct_list->data[size - 1].nfacct) { - error("nfacct.plugin: nfacct_alloc() failed."); - free(nfacct_list); - nfacct_list = NULL; - return MNL_CB_OK; - } - - nfacct_list->size = size; - nfacct_list->len = len; - } - - if(nfacct_nlmsg_parse_payload(nlh, nfacct_list->data[nfacct_list->len].nfacct) < 0) { - error("nfacct.plugin: nfacct_nlmsg_parse_payload() failed."); - return MNL_CB_OK; - } - - nfacct_list->data[nfacct_list->len].name = nfacct_attr_get_str(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_NAME); - nfacct_list->data[nfacct_list->len].pkts = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_PKTS); - nfacct_list->data[nfacct_list->len].bytes = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_BYTES); - - nfacct_list->len++; - return MNL_CB_OK; + if(data) {}; + + if(!nfacct_list || nfacct_list->len == nfacct_list->size) { + int size = (nfacct_list) ? nfacct_list->size : 0; + int len = (nfacct_list) ? nfacct_list->len : 0; + size++; + + info("nfacct.plugin: increasing nfacct_list to size %d", size); + + nfacct_list = realloc(nfacct_list, sizeof(struct nfacct_list) + (sizeof(struct mynfacct) * size)); + if(!nfacct_list) { + error("nfacct.plugin: cannot allocate nfacct_list."); + return MNL_CB_OK; + } + + nfacct_list->data[len].nfacct = nfacct_alloc(); + if(!nfacct_list->data[size - 1].nfacct) { + error("nfacct.plugin: nfacct_alloc() failed."); + free(nfacct_list); + nfacct_list = NULL; + return MNL_CB_OK; + } + + nfacct_list->size = size; + nfacct_list->len = len; + } + + if(nfacct_nlmsg_parse_payload(nlh, nfacct_list->data[nfacct_list->len].nfacct) < 0) { + error("nfacct.plugin: nfacct_nlmsg_parse_payload() failed."); + return MNL_CB_OK; + } + + nfacct_list->data[nfacct_list->len].name = nfacct_attr_get_str(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_NAME); + nfacct_list->data[nfacct_list->len].pkts = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_PKTS); + nfacct_list->data[nfacct_list->len].bytes = nfacct_attr_get_u64(nfacct_list->data[nfacct_list->len].nfacct, NFACCT_ATTR_BYTES); + + nfacct_list->len++; + return MNL_CB_OK; } void *nfacct_main(void *ptr) { - if(ptr) { ; } + if(ptr) { ; } - info("NFACCT thread created with task id %d", gettid()); + info("NFACCT thread created with task id %d", gettid()); - if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) - error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED."); + if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0) + error("nfacct.plugin: Cannot set pthread cancel type to DEFERRED."); - if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) - error("nfacct.plugin: Cannot set pthread cancel state to ENABLE."); + if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) + error("nfacct.plugin: Cannot set pthread cancel state to ENABLE."); - char buf[MNL_SOCKET_BUFFER_SIZE]; - struct mnl_socket *nl = NULL; - struct nlmsghdr *nlh = NULL; - unsigned int seq = 0, portid = 0; + char buf[MNL_SOCKET_BUFFER_SIZE]; + struct mnl_socket *nl = NULL; + struct nlmsghdr *nlh = NULL; + unsigned int seq = 0, portid = 0; - seq = time(NULL) - 1; + seq = time(NULL) - 1; - nl = mnl_socket_open(NETLINK_NETFILTER); - if(!nl) { - error("nfacct.plugin: mnl_socket_open() failed"); - pthread_exit(NULL); - return NULL; - } + nl = mnl_socket_open(NETLINK_NETFILTER); + if(!nl) { + error("nfacct.plugin: mnl_socket_open() failed"); + pthread_exit(NULL); + return NULL; + } - if(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { - mnl_socket_close(nl); - error("nfacct.plugin: mnl_socket_bind() failed"); - pthread_exit(NULL); - return NULL; - } - portid = mnl_socket_get_portid(nl); + if(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { + mnl_socket_close(nl); + error("nfacct.plugin: mnl_socket_bind() failed"); + pthread_exit(NULL); + return NULL; + } + portid = mnl_socket_get_portid(nl); - // ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ - struct timeval last, now; - unsigned long long usec = 0, susec = 0; - RRDSET *st = NULL; + struct timeval last, now; + unsigned long long usec = 0, susec = 0; + RRDSET *st = NULL; - gettimeofday(&last, NULL); + gettimeofday(&last, NULL); - // ------------------------------------------------------------------------ + // ------------------------------------------------------------------------ - while(1) { - if(unlikely(netdata_exit)) break; + while(1) { + if(unlikely(netdata_exit)) break; - seq++; + seq++; - nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq); - if(!nlh) { - mnl_socket_close(nl); - error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed"); - pthread_exit(NULL); - return NULL; - } + nlh = nfacct_nlmsg_build_hdr(buf, NFNL_MSG_ACCT_GET, NLM_F_DUMP, seq); + if(!nlh) { + mnl_socket_close(nl); + error("nfacct.plugin: nfacct_nlmsg_build_hdr() failed"); + pthread_exit(NULL); + return NULL; + } - if(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - error("nfacct.plugin: mnl_socket_send"); - pthread_exit(NULL); - return NULL; - } + if(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + error("nfacct.plugin: mnl_socket_send"); + pthread_exit(NULL); + return NULL; + } - if(nfacct_list) nfacct_list->len = 0; + if(nfacct_list) nfacct_list->len = 0; - int ret; - while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) { - if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break; - } + int ret; + while((ret = mnl_socket_recvfrom(nl, buf, sizeof(buf))) > 0) { + if((ret = mnl_cb_run(buf, ret, seq, portid, nfacct_callback, NULL)) <= 0) break; + } - if (ret == -1) { - error("nfacct.plugin: error communicating with kernel."); - pthread_exit(NULL); - return NULL; - } + if (ret == -1) { + error("nfacct.plugin: error communicating with kernel."); + pthread_exit(NULL); + return NULL; + } - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- - gettimeofday(&now, NULL); - usec = usecdiff(&now, &last) - susec; - debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec); + gettimeofday(&now, NULL); + usec = usec_dt(&now, &last) - susec; + debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec); - if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; - else susec = rrd_update_every * 1000000ULL / 2ULL; + if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec; + else susec = rrd_update_every * 1000000ULL / 2ULL; - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- - if(nfacct_list && nfacct_list->len) { - int i; + if(nfacct_list && nfacct_list->len) { + int i; - st = rrdset_find_bytype("netfilter", "nfacct_packets"); - if(!st) { - st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 1006, rrd_update_every, RRDSET_TYPE_STACKED); + st = rrdset_find_bytype("netfilter", "nfacct_packets"); + if(!st) { + st = rrdset_create("netfilter", "nfacct_packets", NULL, "nfacct", NULL, "Netfilter Accounting Packets", "packets/s", 1006, rrd_update_every, RRDSET_TYPE_STACKED); - for(i = 0; i < nfacct_list->len ; i++) - rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); - } - else rrdset_next(st); + for(i = 0; i < nfacct_list->len ; i++) + rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); + } + else rrdset_next(st); - for(i = 0; i < nfacct_list->len ; i++) { - RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); + for(i = 0; i < nfacct_list->len ; i++) { + RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); - if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); - if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts); - } + if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL); + if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts); + } - rrdset_done(st); + rrdset_done(st); - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- - st = rrdset_find_bytype("netfilter", "nfacct_bytes"); - if(!st) { - st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 1007, rrd_update_every, RRDSET_TYPE_STACKED); + st = rrdset_find_bytype("netfilter", "nfacct_bytes"); + if(!st) { + st = rrdset_create("netfilter", "nfacct_bytes", NULL, "nfacct", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 1007, rrd_update_every, RRDSET_TYPE_STACKED); - for(i = 0; i < nfacct_list->len ; i++) - rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); - } - else rrdset_next(st); + for(i = 0; i < nfacct_list->len ; i++) + rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); + } + else rrdset_next(st); - for(i = 0; i < nfacct_list->len ; i++) { - RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); + for(i = 0; i < nfacct_list->len ; i++) { + RRDDIM *rd = rrddim_find(st, nfacct_list->data[i].name); - if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); - if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes); - } + if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL); + if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes); + } - rrdset_done(st); - } + rrdset_done(st); + } - // -------------------------------------------------------------------- + // -------------------------------------------------------------------- - usleep(susec); + usleep(susec); - // copy current to last - bcopy(&now, &last, sizeof(struct timeval)); - } + // copy current to last + bcopy(&now, &last, sizeof(struct timeval)); + } - mnl_socket_close(nl); - pthread_exit(NULL); - return NULL; + mnl_socket_close(nl); + pthread_exit(NULL); + return NULL; } #endif |