#include "common.h"
#include "plugin.h"
#include "utils_complain.h"
+#include "utils_ignorelist.h"
#include <asm/types.h>
#include <errno.h>
/*
* Private variables
*/
+static ignorelist_t *ignorelist = NULL;
+
static interface_list_t *interface_list_head = NULL;
+static int monitor_all_interfaces = 1;
static int connectivity_thread_loop = 0;
static int connectivity_thread_error = 0;
*buf = malloc(strlen((char *)buf2) + 1);
+ if (*buf == NULL) {
+ char errbuf[1024];
+ ERROR("connectivity plugin: malloc failed during gen_message_payload: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ goto err;
+ }
+
sstrncpy(*buf, (char *)buf2, strlen((char *)buf2) + 1);
yajl_gen_free(g);
return -1;
}
+static interface_list_t *add_interface(const char *interface, int status,
+ int prev_status) {
+ interface_list_t *il;
+ char *interface2;
+
+ il = malloc(sizeof(*il));
+ if (il == NULL) {
+ char errbuf[1024];
+ ERROR("connectivity plugin: malloc failed during add_interface: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return NULL;
+ }
+
+ interface2 = strdup(interface);
+ if (interface2 == NULL) {
+ char errbuf[1024];
+ sfree(il);
+ ERROR("connectivity plugin: strdup failed during add_interface: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return NULL;
+ }
+
+ il->interface = interface2;
+ il->status = status;
+ il->prev_status = prev_status;
+ il->timestamp = (long long unsigned int)CDTIME_T_TO_US(cdtime());
+ il->sent = 0;
+ il->next = interface_list_head;
+ interface_list_head = il;
+
+ DEBUG("connectivity plugin: added interface %s", interface2);
+
+ return il;
+}
+
static int connectivity_link_state(struct nlmsghdr *msg) {
int retval = 0;
struct ifinfomsg *ifi = mnl_nlmsg_get_payload(msg);
pthread_mutex_lock(&connectivity_lock);
- interface_list_t *il;
+ interface_list_t *il = NULL;
/* Scan attribute list for device name. */
mnl_attr_for_each(attr, msg, sizeof(*ifi)) {
dev = mnl_attr_get_str(attr);
+ // Check the list of interfaces we should monitor, if we've chosen
+ // a subset. If we don't care about this one, abort.
+ if (ignorelist_match(ignorelist, dev) != 0) {
+ DEBUG("connectivity plugin: Ignoring link state change for unmonitored "
+ "interface: %s",
+ dev);
+ break;
+ }
+
for (il = interface_list_head; il != NULL; il = il->next)
if (strcmp(dev, il->interface) == 0)
break;
+ uint32_t prev_status;
+
if (il == NULL) {
- DEBUG("connectivity plugin: Ignoring link state change for unmonitored "
- "interface: %s",
- dev);
- } else {
- uint32_t prev_status;
-
- prev_status = il->status;
- il->status =
- ((ifi->ifi_flags & IFF_RUNNING) ? LINK_STATE_UP : LINK_STATE_DOWN);
- il->timestamp = (long long unsigned int)CDTIME_T_TO_US(cdtime());
-
- // If the new status is different than the previous status,
- // store the previous status and set sent to zero
- if (il->status != prev_status) {
- il->prev_status = prev_status;
- il->sent = 0;
+ // We haven't encountered this interface yet, so add it to the linked list
+ il = add_interface(dev, LINK_STATE_UNKNOWN, LINK_STATE_UNKNOWN);
+
+ if (il == NULL) {
+ ERROR("connectivity plugin: unable to add interface %s during "
+ "connectivity_link_state",
+ dev);
+ return MNL_CB_ERROR;
}
+ }
+
+ prev_status = il->status;
+ il->status =
+ ((ifi->ifi_flags & IFF_RUNNING) ? LINK_STATE_UP : LINK_STATE_DOWN);
+ il->timestamp = (long long unsigned int)CDTIME_T_TO_US(cdtime());
- DEBUG("connectivity plugin (%llu): Interface %s status is now %s",
- il->timestamp, dev,
- ((ifi->ifi_flags & IFF_RUNNING) ? "UP" : "DOWN"));
+ // If the new status is different than the previous status,
+ // store the previous status and set sent to zero
+ if (il->status != prev_status) {
+ il->prev_status = prev_status;
+ il->sent = 0;
}
+ DEBUG("connectivity plugin (%llu): Interface %s status is now %s",
+ il->timestamp, dev, ((ifi->ifi_flags & IFF_RUNNING) ? "UP" : "DOWN"));
+
// no need to loop again, we found the interface name attr
// (otherwise the first if-statement in the loop would
// have moved us on with 'continue')
static int connectivity_init(void) /* {{{ */
{
- if (interface_list_head == NULL) {
- NOTICE("connectivity plugin: No interfaces have been configured.");
- return (-1);
+ if (monitor_all_interfaces) {
+ NOTICE("connectivity plugin: No interfaces have been selected, so all will "
+ "be monitored");
}
return (start_thread());
static int connectivity_config(const char *key, const char *value) /* {{{ */
{
- if (strcasecmp(key, "Interface") == 0) {
- interface_list_t *il;
- char *interface;
-
- il = malloc(sizeof(*il));
- if (il == NULL) {
- char errbuf[1024];
- ERROR("connectivity plugin: malloc failed during connectivity_config: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
- }
-
- interface = strdup(value);
- if (interface == NULL) {
- char errbuf[1024];
- sfree(il);
- ERROR("connectivity plugin: strdup failed connectivity_config: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
- }
-
- il->interface = interface;
- il->status = LINK_STATE_UNKNOWN;
- il->prev_status = LINK_STATE_UNKNOWN;
- il->timestamp = (long long unsigned int)CDTIME_T_TO_US(cdtime());
- il->sent = 0;
- il->next = interface_list_head;
- interface_list_head = il;
+ if (ignorelist == NULL) {
+ ignorelist = ignorelist_create(/* invert = */ 1);
+ }
+ if (strcasecmp(key, "Interface") == 0) {
+ ignorelist_add(ignorelist, value);
+ monitor_all_interfaces = 0;
} else {
return (-1);
}
if (value == LINK_STATE_UP)
n.severity = NOTIF_OKAY;
- char hostname[1024];
- gethostname(hostname, sizeof(hostname));
-
- sstrncpy(n.host, hostname, sizeof(n.host));
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
sstrncpy(n.plugin_instance, interface, sizeof(n.plugin_instance));
sstrncpy(n.type, "gauge", sizeof(n.type));
sstrncpy(n.type_instance, "interface_status", sizeof(n.type_instance));
il = il_next;
}
+ ignorelist_free(ignorelist);
+
return (0);
} /* }}} int connectivity_shutdown */