proc_net_snmp.c \
proc_net_snmp6.c \
proc_net_stat_conntrack.c \
+ proc_net_stat_synproxy.c \
proc_stat.c \
proc_sys_kernel_random_entropy_avail.c \
proc_vmstat.c \
if(nfacct_list && nfacct_list->len) {
int i;
- st = rrdset_find_bytype("nfacct", "packets");
+ st = rrdset_find_bytype("netfilter", "nfacct_packets");
if(!st) {
- st = rrdset_create("nfacct", "packets", NULL, "netfilter", NULL, "Netfilter Accounting Packets", "packets/s", 1006, rrd_update_every, RRDSET_TYPE_STACKED);
+ 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);
// ----------------------------------------------------------------
- st = rrdset_find_bytype("nfacct", "bytes");
+ st = rrdset_find_bytype("netfilter", "nfacct_bytes");
if(!st) {
- st = rrdset_create("nfacct", "bytes", NULL, "netfilter", NULL, "Netfilter Accounting Bandwidth", "kilobytes/s", 1007, rrd_update_every, RRDSET_TYPE_STACKED);
+ 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);
int vdo_proc_net_netstat = !config_get_boolean("plugin:proc", "/proc/net/netstat", 1);
int vdo_proc_net_stat_conntrack = !config_get_boolean("plugin:proc", "/proc/net/stat/conntrack", 1);
int vdo_proc_net_ip_vs_stats = !config_get_boolean("plugin:proc", "/proc/net/ip_vs/stats", 1);
+ int vdo_proc_net_stat_synproxy = !config_get_boolean("plugin:proc", "/proc/net/stat/synproxy", 1);
int vdo_proc_stat = !config_get_boolean("plugin:proc", "/proc/stat", 1);
int vdo_proc_meminfo = !config_get_boolean("plugin:proc", "/proc/meminfo", 1);
int vdo_proc_vmstat = !config_get_boolean("plugin:proc", "/proc/vmstat", 1);
unsigned long long sutime_proc_net_netstat = 0ULL;
unsigned long long sutime_proc_net_stat_conntrack = 0ULL;
unsigned long long sutime_proc_net_ip_vs_stats = 0ULL;
+ unsigned long long sutime_proc_net_stat_synproxy = 0ULL;
unsigned long long sutime_proc_stat = 0ULL;
unsigned long long sutime_proc_meminfo = 0ULL;
unsigned long long sutime_proc_vmstat = 0ULL;
}
if(unlikely(netdata_exit)) break;
+ if(!vdo_proc_net_stat_synproxy) {
+ debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_net_stat_synproxy().");
+ sunow = sutime();
+ vdo_proc_net_stat_synproxy = do_proc_net_stat_synproxy(rrd_update_every, (sutime_proc_net_stat_synproxy > 0)?sunow - sutime_proc_net_stat_synproxy:0ULL);
+ sutime_proc_net_stat_synproxy = sunow;
+ }
+ if(unlikely(netdata_exit)) break;
+
if(!vdo_proc_stat) {
debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_stat().");
sunow = sutime();
extern int do_proc_softirqs(int update_every, unsigned long long dt);
extern int do_sys_kernel_mm_ksm(int update_every, unsigned long long dt);
extern int do_proc_loadavg(int update_every, unsigned long long dt);
+extern int do_proc_net_stat_synproxy(int update_every, unsigned long long dt);
#endif /* NETDATA_PLUGIN_PROC_H */
#include "rrd.h"
#include "plugin_proc.h"
-#define RRD_TYPE_NET_STAT_CONNTRACK "netfilter"
+#define RRD_TYPE_NET_STAT_NETFILTER "netfilter"
+#define RRD_TYPE_NET_STAT_CONNTRACK "conntrack"
#define RRD_TYPE_NET_STAT_CONNTRACK_LEN strlen(RRD_TYPE_NET_STAT_CONNTRACK)
int do_proc_net_stat_conntrack(int update_every, unsigned long long dt) {
// --------------------------------------------------------------------
if(do_sockets) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".sockets");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_sockets");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "sockets", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter Connections", "active connections", 1000, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_sockets", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Connections", "active connections", 1000, update_every, RRDSET_TYPE_LINE);
rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE);
}
// --------------------------------------------------------------------
if(do_new) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".new");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_new");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "new", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter New Connections", "connections/s", 1001, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_new", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker New Connections", "connections/s", 1001, update_every, RRDSET_TYPE_LINE);
rrddim_add(st, "new", NULL, 1, 1, RRDDIM_INCREMENTAL);
rrddim_add(st, "ignore", NULL, -1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
if(do_changes) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".changes");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_changes");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "changes", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter Connection Changes", "changes/s", 1002, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_changes", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Changes", "changes/s", 1002, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "inserted", NULL, 1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
if(do_expect) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".expect");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_expect");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "expect", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter Connection Expectations", "expectations/s", 1003, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_expect", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Expectations", "expectations/s", 1003, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "created", NULL, 1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
if(do_search) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".search");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_search");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "search", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter Connection Searches", "searches/s", 1010, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_search", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Searches", "searches/s", 1010, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "searched", NULL, 1, 1, RRDDIM_INCREMENTAL);
// --------------------------------------------------------------------
if(do_errors) {
- st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".errors");
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_CONNTRACK "_errors");
if(!st) {
- st = rrdset_create(RRD_TYPE_NET_STAT_CONNTRACK, "errors", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Netfilter Errors", "events/s", 1005, update_every, RRDSET_TYPE_LINE);
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_CONNTRACK "_errors", NULL, RRD_TYPE_NET_STAT_CONNTRACK, NULL, "Connection Tracker Errors", "events/s", 1005, update_every, RRDSET_TYPE_LINE);
st->isdetail = 1;
rrddim_add(st, "icmp_error", NULL, 1, 1, RRDDIM_INCREMENTAL);
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "common.h"
+#include "appconfig.h"
+#include "procfile.h"
+#include "rrd.h"
+#include "plugin_proc.h"
+#include "log.h"
+
+#define RRD_TYPE_NET_STAT_NETFILTER "netfilter"
+#define RRD_TYPE_NET_STAT_SYNPROXY "synproxy"
+#define RRD_TYPE_NET_STAT_SYNPROXY_LEN strlen(RRD_TYPE_NET_STAT_SYNPROXY)
+
+int do_proc_net_stat_synproxy(int update_every, unsigned long long dt) {
+ static int do_entries = -1, do_cookies = -1, do_syns = -1, do_reopened = -1;
+ static procfile *ff = NULL;
+
+ if(do_entries == -1) do_entries = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY entries", CONFIG_ONDEMAND_ONDEMAND);
+ if(do_cookies == -1) do_cookies = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY cookies", CONFIG_ONDEMAND_ONDEMAND);
+ if(do_syns == -1) do_syns = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY SYN received", CONFIG_ONDEMAND_ONDEMAND);
+ if(do_reopened == -1) do_reopened = config_get_boolean_ondemand("plugin:proc:/proc/net/stat/synproxy", "SYNPROXY connections reopened", CONFIG_ONDEMAND_ONDEMAND);
+
+ if(dt) {};
+
+ if(!ff) {
+ char filename[FILENAME_MAX + 1];
+ snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/stat/synproxy");
+ ff = procfile_open(config_get("plugin:proc:/proc/net/stat/synproxy", "filename to monitor", filename), " \t,:|", PROCFILE_FLAG_DEFAULT);
+ }
+ if(!ff) return 1;
+
+ ff = procfile_readall(ff);
+ if(!ff) return 0; // we return 0, so that we will retry to open it next time
+
+ // make sure we have 3 lines
+ unsigned long lines = procfile_lines(ff), l;
+ if(lines < 2) {
+ error("/proc/net/stat/synproxy has %d lines, expected no less than 2. Disabling it.", lines);
+ return 1;
+ }
+
+ unsigned long long entries = 0, syn_received = 0, cookie_invalid = 0, cookie_valid = 0, cookie_retrans = 0, conn_reopened = 0;
+
+ // synproxy gives its values per CPU
+ for(l = 1; l < lines ;l++) {
+ int words = procfile_linewords(ff, l);
+ if(words < 6) continue;
+
+ entries += strtoull(procfile_lineword(ff, l, 0), NULL, 16);
+ syn_received += strtoull(procfile_lineword(ff, l, 1), NULL, 16);
+ cookie_invalid += strtoull(procfile_lineword(ff, l, 2), NULL, 16);
+ cookie_valid += strtoull(procfile_lineword(ff, l, 3), NULL, 16);
+ cookie_retrans += strtoull(procfile_lineword(ff, l, 4), NULL, 16);
+ conn_reopened += strtoull(procfile_lineword(ff, l, 5), NULL, 16);
+ }
+
+ unsigned long long events = entries + syn_received + cookie_invalid + cookie_valid + cookie_retrans + conn_reopened;
+
+ RRDSET *st;
+
+ // --------------------------------------------------------------------
+
+ if((do_entries == CONFIG_ONDEMAND_ONDEMAND && events) || do_entries == CONFIG_ONDEMAND_YES) {
+ do_entries = CONFIG_ONDEMAND_YES;
+
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_entries");
+ if(!st) {
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_entries", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Entries Used", "entries", 1004, update_every, RRDSET_TYPE_LINE);
+
+ rrddim_add(st, "entries", NULL, 1, 1, RRDDIM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "entries", entries);
+ rrdset_done(st);
+ }
+
+ // --------------------------------------------------------------------
+
+ if((do_syns == CONFIG_ONDEMAND_ONDEMAND && events) || do_syns == CONFIG_ONDEMAND_YES) {
+ do_syns = CONFIG_ONDEMAND_YES;
+
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_syn_received");
+ if(!st) {
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_syn_received", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY SYN Packets received", "SYN/s", 1001, update_every, RRDSET_TYPE_LINE);
+
+ rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "received", syn_received);
+ rrdset_done(st);
+ }
+
+ // --------------------------------------------------------------------
+
+ if((do_reopened == CONFIG_ONDEMAND_ONDEMAND && events) || do_reopened == CONFIG_ONDEMAND_YES) {
+ do_reopened = CONFIG_ONDEMAND_YES;
+
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened");
+ if(!st) {
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_conn_reopened", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY Connections Reopened", "connections/s", 1003, update_every, RRDSET_TYPE_LINE);
+
+ rrddim_add(st, "reopened", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "reopened", conn_reopened);
+ rrdset_done(st);
+ }
+
+ // --------------------------------------------------------------------
+
+ if((do_cookies == CONFIG_ONDEMAND_ONDEMAND && events) || do_cookies == CONFIG_ONDEMAND_YES) {
+ do_cookies = CONFIG_ONDEMAND_YES;
+
+ st = rrdset_find(RRD_TYPE_NET_STAT_NETFILTER "." RRD_TYPE_NET_STAT_SYNPROXY "_cookies");
+ if(!st) {
+ st = rrdset_create(RRD_TYPE_NET_STAT_NETFILTER, RRD_TYPE_NET_STAT_SYNPROXY "_cookies", NULL, RRD_TYPE_NET_STAT_SYNPROXY, NULL, "SYNPROXY TCP Cookies", "cookies/s", 1002, update_every, RRDSET_TYPE_LINE);
+
+ rrddim_add(st, "valid", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ rrddim_add(st, "invalid", NULL, -1, 1, RRDDIM_INCREMENTAL);
+ rrddim_add(st, "retransmits", NULL, 1, 1, RRDDIM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set(st, "valid", cookie_valid);
+ rrddim_set(st, "invalid", cookie_invalid);
+ rrddim_set(st, "retransmits", cookie_retrans);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
'mem.ksm': {
title: 'Memory Deduper',
info: 'Kernel Same-page Merging (KSM) is the kernel memory de-duper.'
+ },
+
+ 'netfilter.conntrack': {
+ title: 'Connection Tracker',
+ info: 'The following information is taken from <code>/proc/net/stat/nf_conntrack</code>. The connection tracker keeps track of all connections of the machine, inbound and outbound. It works by keeping a database with all open connections, tracking network and address translation and connection expectations.'
+ },
+
+ 'netfilter.nfacct': {
+ title: 'Bandwidth Accounting',
+ info: 'The following information is read using the <code>nfacct.plugin</code>.'
+ },
+
+ 'netfilter.synproxy': {
+ title: 'Anti-DDoS Protection',
+ info: 'The following information is taken from <code>/proc/net/stat/synproxy</code>. <a href="https://github.com/firehol/firehol/wiki/Working-with-SYNPROXY" target="_blank">SYNPROXY</a> is a TCP SYN packets proxy. It is used to protect any TCP server (like a web server) from SYN floods and similar DDoS attacks. It is a netfilter module, in the Linux kernel (since version 3.12). It is optimized to handle millions of packets per second utilizing all CPUs available without any concurrency locking between the connections. It can be used for any kind of TCP traffic (even encrypted), since it does not interfere with the content itself.'
}
};