Skip to content

Commit

Permalink
snmp6: add ipv6 statistics
Browse files Browse the repository at this point in the history
ChangeLog: snmp6 plugin: Add plugin for parsing IPv6 statistics

We would like to have pure ipv6 interface statistics. To get them,
we parse the snmp6 interface.

Signed-off-by: Nick Hainke <[email protected]>
  • Loading branch information
PolynomialDivision authored and Vladdrako committed Dec 22, 2020
1 parent a3f5e2d commit d55abab
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -1950,6 +1950,14 @@ TESTS += test_plugin_snmp_agent

endif

if BUILD_PLUGIN_SNMP6
pkglib_LTLIBRARIES += snmp6.la
snmp6_la_SOURCES = src/snmp6.c
snmp6_la_CFLAGS = $(AM_CFLAGS)
snmp6_la_LDFLAGS = $(PLUGIN_LDFLAGS)
snmp6_la_LIBADD = libignorelist.la
endif # BUILD_PLUGIN_SNMP6

if BUILD_PLUGIN_STATSD
pkglib_LTLIBRARIES += statsd.la
statsd_la_SOURCES = src/statsd.c
Expand Down
4 changes: 4 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ Features
network devices such as switches, routers, thermometers, rack monitoring
servers, etc. See collectd-snmp(5).

- snmp6
Read values from SNMP6 (Simple Network Management Protocol). Supports pure
IPv6 interface statistics.

- statsd
Acts as a StatsD server, reading values sent over the network from StatsD
clients and calculating rates and other aggregates out of these values.
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -7158,6 +7158,7 @@ AC_PLUGIN([slurm], [$with_libslurm], [SLURM jobs and no
AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
AC_PLUGIN([snmp_agent], [$with_libnetsnmpagent], [SNMP agent plugin])
AC_PLUGIN([snmp6], [yes], [IPv6 Interface traffic statistics via snmp6])
AC_PLUGIN([statsd], [yes], [StatsD plugin])
AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin])
Expand Down Expand Up @@ -7531,6 +7532,7 @@ AC_MSG_RESULT([ infiniband . . . . . $enable_infiniband])
AC_MSG_RESULT([ intel_pmu . . . . . . $enable_intel_pmu])
AC_MSG_RESULT([ intel_rdt . . . . . . $enable_intel_rdt])
AC_MSG_RESULT([ interface . . . . . . $enable_interface])
AC_MSG_RESULT([ snmp6 . . . . . . . . $enable_snmp6])
AC_MSG_RESULT([ ipc . . . . . . . . . $enable_ipc])
AC_MSG_RESULT([ ipmi . . . . . . . . $enable_ipmi])
AC_MSG_RESULT([ iptables . . . . . . $enable_iptables])
Expand Down
6 changes: 6 additions & 0 deletions src/collectd.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
#@BUILD_PLUGIN_SMART_TRUE@LoadPlugin smart
#@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
#@BUILD_PLUGIN_SNMP_AGENT_TRUE@LoadPlugin snmp_agent
#@BUILD_PLUGIN_SNMP6_TRUE@LoadPlugin snmp6
#@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
#@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
#@BUILD_PLUGIN_SYSEVENT_TRUE@LoadPlugin sysevent
Expand Down Expand Up @@ -1723,6 +1724,11 @@
# TimerCount false
#</Plugin>

#<Plugin snmp6>
# Interface "eth0"
# IgnoreSelected false
#</Plugin>

#<Plugin swap>
# ReportByDevice false
# ReportBytes true
Expand Down
135 changes: 135 additions & 0 deletions src/snmp6.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
This Plugin is based opn the interface.c Plugin.
*/

#if HAVE_LINUX_IF_H
#include <linux/if.h>
#elif HAVE_NET_IF_H
#include <net/if.h>
#endif

#include <ifaddrs.h>

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>

#include "plugin.h"
#include "utils/cmds/putval.h"
#include "utils/common/common.h"
#include "utils/ignorelist/ignorelist.h"

static const char *config_keys[] = {
"Interface",
"IgnoreSelected",
};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);

static ignorelist_t *ignorelist;
struct ifaddrs *if_list;

static int snmp6_config(const char *key, const char *value) {
if (ignorelist == NULL)
ignorelist = ignorelist_create(/* invert = */ 1);

if (strcasecmp(key, "Interface") == 0) {
ignorelist_add(ignorelist, value);
} else if (strcasecmp(key, "IgnoreSelected") == 0) {
int invert = 1;
if (IS_TRUE(value))
invert = 0;
ignorelist_set_invert(ignorelist, invert);
}

return 0;
}

/* Copied from interface.c */
static void snmp6_submit(const char *dev, const char *type, derive_t rx,
derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
{.derive = rx},
{.derive = tx},
};

if (ignorelist_match(ignorelist, dev) != 0)
return;

vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE(values);
sstrncpy(vl.plugin, "snmp6", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance));
sstrncpy(vl.type, type, sizeof(vl.type));

plugin_dispatch_values(&vl);
} /* void if_submit */

int snmp_read(char *ifname) {
FILE *fh;
char buffer[1024];
char *fields[16];
int numfields;
int currline = 0;
derive_t data[76];
char procpath[1024];
int offset = 0;

if (strncmp("all", ifname, strlen("all")) == 0) {
snprintf(procpath, 1024, "/proc/net/snmp6");
offset = 1;
} else {
snprintf(procpath, 1024, "/proc/net/dev_snmp6/%s", ifname);
}

if ((fh = fopen(procpath, "r")) == NULL) {
WARNING("interface plugin: fopen: %s", STRERRNO);
return -1;
}

while (fgets(buffer, 1024, fh) != NULL) {
numfields = strsplit(buffer, fields, 16);

if (numfields < 2)
continue;

data[currline++] = atoll(fields[1]);
}

fclose(fh);

if (currline < 25) {
return -1;
}

snmp6_submit(ifname, "if_octets", data[23 - offset], data[24 - offset]);
snmp6_submit(ifname, "if_octets_mcast", data[25 - offset], data[26 - offset]);
snmp6_submit(ifname, "if_octets_bcast", data[27 - offset], data[28 - offset]);
return 0;
}

int read_all_interfaces(void) {
#ifndef HAVE_IFADDRS_H
return -1;
#else
if (getifaddrs(&if_list) != 0)
return -1;

for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL;
if_ptr = if_ptr->ifa_next) {
snmp_read(if_ptr->ifa_name);
}
snmp_read("all");
return 0;
#endif
}

void module_register(void) {
plugin_register_config("snmp6", snmp6_config, config_keys, config_keys_num);
plugin_register_read("snmp6", read_all_interfaces);
} /* void module_register */
2 changes: 2 additions & 0 deletions src/types.db
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ if_dropped rx:DERIVE:0:U, tx:DERIVE:0:U
if_errors rx:DERIVE:0:U, tx:DERIVE:0:U
if_multicast value:DERIVE:0:U
if_octets rx:DERIVE:0:U, tx:DERIVE:0:U
if_octets_mcast rx:DERIVE:0:U, tx:DERIVE:0:U
if_octets_bcast rx:DERIVE:0:U, tx:DERIVE:0:U
if_packets rx:DERIVE:0:U, tx:DERIVE:0:U
if_rx_dropped value:DERIVE:0:U
if_rx_errors value:DERIVE:0:U
Expand Down

0 comments on commit d55abab

Please sign in to comment.