X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fnetlink.c;h=ef851d354937a0069969b7822b5ce6de0879a739;hb=aff80830f1154a5b6c4da16a0b1033aafde14e24;hp=073efe9e9358bdff54c0f6706f41ef499ea73760;hpb=97deb523823b1f04880d584a19bc2b0e7e10d96a;p=collectd.git diff --git a/src/netlink.c b/src/netlink.c index 073efe9e..ef851d35 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1,6 +1,6 @@ /** * collectd - src/netlink.c - * Copyright (C) 2007 Florian octo Forster + * Copyright (C) 2007-2010 Florian octo Forster * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,7 +16,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster **/ #include "collectd.h" @@ -25,9 +25,15 @@ #include #include + #include #include -#include +#if HAVE_LINUX_GEN_STATS_H +# include +#endif +#if HAVE_LINUX_PKT_SCHED_H +# include +#endif #if HAVE_LIBNETLINK_H # include @@ -155,51 +161,51 @@ static int check_ignorelist (const char *dev, } /* int check_ignorelist */ static void submit_one (const char *dev, const char *type, - const char *type_instance, counter_t value) + const char *type_instance, derive_t value) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].counter = value; + values[0].derive = value; vl.values = values; vl.values_len = 1; - vl.time = time (NULL); - strcpy (vl.host, hostname_g); - strcpy (vl.plugin, "netlink"); - strncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); + sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - plugin_dispatch_values (type, &vl); + plugin_dispatch_values (&vl); } /* void submit_one */ static void submit_two (const char *dev, const char *type, const char *type_instance, - counter_t rx, counter_t tx) + derive_t rx, derive_t tx) { value_t values[2]; value_list_t vl = VALUE_LIST_INIT; - values[0].counter = rx; - values[1].counter = tx; + values[0].derive = rx; + values[1].derive = tx; vl.values = values; vl.values_len = 2; - vl.time = time (NULL); - strcpy (vl.host, hostname_g); - strcpy (vl.plugin, "netlink"); - strncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); + sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - plugin_dispatch_values (type, &vl); + plugin_dispatch_values (&vl); } /* void submit_two */ -static int link_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, - void *args) +static int link_filter (const struct sockaddr_nl __attribute__((unused)) *sa, + struct nlmsghdr *nmh, void __attribute__((unused)) *args) { struct ifinfomsg *msg; int msg_len; @@ -231,10 +237,6 @@ static int link_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, return (-1); } - if (attrs[IFLA_STATS] == NULL) - return (-1); - stats = RTA_DATA (attrs[IFLA_STATS]); - if (attrs[IFLA_IFNAME] == NULL) { ERROR ("netlink plugin: link_filter: attrs[IFLA_IFNAME] == NULL"); @@ -244,7 +246,7 @@ static int link_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, /* Update the `iflist'. It's used to know which interfaces exist and query * them later for qdiscs and classes. */ - if (msg->ifi_index >= iflist_len) + if ((msg->ifi_index >= 0) && ((size_t) msg->ifi_index >= iflist_len)) { char **temp; @@ -267,6 +269,13 @@ static int link_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, iflist[msg->ifi_index] = strdup (dev); } + if (attrs[IFLA_STATS] == NULL) + { + DEBUG ("netlink plugin: link_filter: No statistics for interface %s.", dev); + return (0); + } + stats = RTA_DATA (attrs[IFLA_STATS]); + if (check_ignorelist (dev, "interface", NULL) == 0) { submit_two (dev, "if_octets", NULL, stats->rx_bytes, stats->tx_bytes); @@ -305,8 +314,8 @@ static int link_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, return (0); } /* int link_filter */ -static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, - void *args) +static int qos_filter (const struct sockaddr_nl __attribute__((unused)) *sa, + struct nlmsghdr *nmh, void *args) { struct tcmsg *msg; int msg_len; @@ -350,10 +359,11 @@ static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, return (0); } - if (msg->tcm_ifindex >= iflist_len) + if ((msg->tcm_ifindex >= 0) + && ((size_t) msg->tcm_ifindex >= iflist_len)) { ERROR ("netlink plugin: qos_filter: msg->tcm_ifindex = %i " - ">= iflist_len = %i", + ">= iflist_len = %zu", msg->tcm_ifindex, iflist_len); return (-1); } @@ -386,11 +396,10 @@ static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, if (strcmp (tc_type, "filter") == 0) numberic_id = msg->tcm_parent; - snprintf (tc_inst, sizeof (tc_inst), "%s-%x:%x", + ssnprintf (tc_inst, sizeof (tc_inst), "%s-%x:%x", (const char *) RTA_DATA (attrs[TCA_KIND]), numberic_id >> 16, numberic_id & 0x0000FFFF); - tc_inst[sizeof (tc_inst) - 1] = '\0'; } DEBUG ("netlink plugin: qos_filter: got %s for %s (%i).", @@ -399,6 +408,7 @@ static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, if (check_ignorelist (dev, tc_type, tc_inst)) return (0); +#if HAVE_TCA_STATS2 if (attrs[TCA_STATS2]) { struct rtattr *attrs_stats[TCA_STATS_MAX + 1]; @@ -411,9 +421,8 @@ static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, struct gnet_stats_basic bs; char type_instance[DATA_MAX_NAME_LEN]; - snprintf (type_instance, sizeof (type_instance), "%s-%s", + ssnprintf (type_instance, sizeof (type_instance), "%s-%s", tc_type, tc_inst); - type_instance[sizeof (type_instance) - 1] = '\0'; memset (&bs, '\0', sizeof (bs)); memcpy (&bs, RTA_DATA (attrs_stats[TCA_STATS_BASIC]), @@ -423,6 +432,34 @@ static int qos_filter (const struct sockaddr_nl *sa, struct nlmsghdr *nmh, submit_one (dev, "ipt_packets", type_instance, bs.packets); } } +#endif /* TCA_STATS2 */ +#if HAVE_TCA_STATS && HAVE_TCA_STATS2 + else +#endif +#if HAVE_TCA_STATS + if (attrs[TCA_STATS] != NULL) + { + struct tc_stats ts; + char type_instance[DATA_MAX_NAME_LEN]; + + ssnprintf (type_instance, sizeof (type_instance), "%s-%s", + tc_type, tc_inst); + + memset(&ts, '\0', sizeof (ts)); + memcpy(&ts, RTA_DATA (attrs[TCA_STATS]), + MIN (RTA_PAYLOAD (attrs[TCA_STATS]), sizeof (ts))); + + submit_one (dev, "ipt_bytes", type_instance, ts.bytes); + submit_one (dev, "ipt_packets", type_instance, ts.packets); + } +#endif /* TCA_STATS */ +#if HAVE_TCA_STATS || HAVE_TCA_STATS2 + else +#endif + { + DEBUG ("netlink plugin: qos_filter: Have neither TCA_STATS2 nor " + "TCA_STATS."); + } return (0); } /* int qos_filter */ @@ -489,9 +526,7 @@ static int ir_config (const char *key, const char *value) } else { - if ((strcasecmp (fields[0], "yes") == 0) - || (strcasecmp (fields[0], "true") == 0) - || (strcasecmp (fields[0], "on") == 0)) + if (IS_TRUE (fields[0])) ir_ignorelist_invert = 0; else ir_ignorelist_invert = 1; @@ -544,9 +579,9 @@ static int ir_read (void) /* `link_filter' will update `iflist' which is used here to iterate over all * interfaces. */ - for (ifindex = 0; ifindex < iflist_len; ifindex++) + for (ifindex = 0; (size_t) ifindex < iflist_len; ifindex++) { - int type_index; + size_t type_index; if (iflist[ifindex] == NULL) continue;