X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fnetlink.c;h=aa9760f9328b78eb87e14f70501bc1622a57f12d;hb=0003c4d3c184f0f437499d6073cd023dc7b659c2;hp=4ea4fce51b5f302c131106ea77824c68d2f52ecf;hpb=95a086a753aadebe2bb76367fa9b401299ce00a4;p=collectd.git diff --git a/src/netlink.c b/src/netlink.c index 4ea4fce5..aa9760f9 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1,6 +1,9 @@ /** * collectd - src/netlink.c * Copyright (C) 2007-2010 Florian octo Forster + * Copyright (C) 2008-2012 Sebastian Harl + * Copyright (C) 2013 Andreas Henriksson + * Copyright (C) 2013 Marc Fournier * * 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 @@ -17,6 +20,9 @@ * * Authors: * Florian octo Forster + * Sebastian Harl + * Andreas Henriksson + * Marc Fournier **/ #include "collectd.h" @@ -35,10 +41,42 @@ # include #endif -#include #include -//#include -//#include + +struct ir_link_stats_storage_s { + + uint64_t rx_packets; + uint64_t tx_packets; + uint64_t rx_bytes; + uint64_t tx_bytes; + uint64_t rx_errors; + uint64_t tx_errors; + + uint64_t rx_dropped; + uint64_t tx_dropped; + uint64_t multicast; + uint64_t collisions; + + uint64_t rx_length_errors; + uint64_t rx_over_errors; + uint64_t rx_crc_errors; + uint64_t rx_frame_errors; + uint64_t rx_fifo_errors; + uint64_t rx_missed_errors; + + uint64_t tx_aborted_errors; + uint64_t tx_carrier_errors; + uint64_t tx_fifo_errors; + uint64_t tx_heartbeat_errors; + uint64_t tx_window_errors; +}; + +union ir_link_stats_u { + struct rtnl_link_stats *stats32; +#ifdef HAVE_RTNL_LINK_STATS64 + struct rtnl_link_stats64 *stats64; +#endif +}; typedef struct ir_ignorelist_s { @@ -229,10 +267,10 @@ static int update_iflist (struct ifinfomsg *msg, const char *dev) } return (0); -} +} /* int update_iflist */ static void check_ignorelist_and_submit (const char *dev, - struct rtnl_link_stats *stats) + struct ir_link_stats_storage_s *stats) { if (check_ignorelist (dev, "interface", NULL) == 0) @@ -270,15 +308,63 @@ static void check_ignorelist_and_submit (const char *dev, DEBUG ("netlink plugin: Ignoring %s/if_detail.", dev); } +} /* void check_ignorelist_and_submit */ + +#define COPY_RTNL_LINK_VALUE(dst_stats, src_stats, value_name) \ + (dst_stats)->value_name = (src_stats)->value_name + +#define COPY_RTNL_LINK_STATS(dst_stats, src_stats) \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_packets); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_packets); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_bytes); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_bytes); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_dropped); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_dropped); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, multicast); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, collisions); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_length_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_over_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_crc_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_frame_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_fifo_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, rx_missed_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_aborted_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_carrier_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_fifo_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_heartbeat_errors); \ + COPY_RTNL_LINK_VALUE (dst_stats, src_stats, tx_window_errors) + +#ifdef HAVE_RTNL_LINK_STATS64 +static void check_ignorelist_and_submit64 (const char *dev, + struct rtnl_link_stats64 *stats) +{ + struct ir_link_stats_storage_s s; + + COPY_RTNL_LINK_STATS (&s, stats); + + check_ignorelist_and_submit (dev, &s); +} +#endif + +static void check_ignorelist_and_submit32 (const char *dev, + struct rtnl_link_stats *stats) +{ + struct ir_link_stats_storage_s s; + + COPY_RTNL_LINK_STATS(&s, stats); + + check_ignorelist_and_submit (dev, &s); } static int link_filter_cb (const struct nlmsghdr *nlh, - void __attribute__((unused)) *args) + void *args __attribute__((unused))) { struct ifinfomsg *ifm = mnl_nlmsg_get_payload (nlh); struct nlattr *attr; - struct rtnl_link_stats *stats = NULL; const char *dev = NULL; + union ir_link_stats_u stats; if (nlh->nlmsg_type != RTM_NEWLINK) { @@ -287,6 +373,7 @@ static int link_filter_cb (const struct nlmsghdr *nlh, return MNL_CB_ERROR; } + /* Scan attribute list for device name. */ mnl_attr_for_each (attr, nlh, sizeof (*ifm)) { if (mnl_attr_get_type (attr) != IFLA_IFNAME) @@ -309,36 +396,50 @@ static int link_filter_cb (const struct nlmsghdr *nlh, ERROR ("netlink plugin: link_filter_cb: dev == NULL"); return MNL_CB_ERROR; } +#ifdef HAVE_RTNL_LINK_STATS64 + mnl_attr_for_each (attr, nlh, sizeof (*ifm)) + { + if (mnl_attr_get_type (attr) != IFLA_STATS64) + continue; + + if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*stats.stats64)) < 0) + { + ERROR ("netlink plugin: link_filter_cb: IFLA_STATS64 mnl_attr_validate2 failed."); + return MNL_CB_ERROR; + } + stats.stats64 = mnl_attr_get_payload (attr); + check_ignorelist_and_submit64 (dev, stats.stats64); + + return MNL_CB_OK; + } +#endif mnl_attr_for_each (attr, nlh, sizeof (*ifm)) { if (mnl_attr_get_type (attr) != IFLA_STATS) continue; - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*stats)) < 0) + if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*stats.stats32)) < 0) { ERROR ("netlink plugin: link_filter_cb: IFLA_STATS mnl_attr_validate2 failed."); return MNL_CB_ERROR; } - stats = mnl_attr_get_payload (attr); + stats.stats32 = mnl_attr_get_payload (attr); - check_ignorelist_and_submit (dev, stats); - break; - } + check_ignorelist_and_submit32 (dev, stats.stats32); - if (stats == NULL) - { - DEBUG ("netlink plugin: link_filter: No statistics for interface %s.", dev); return MNL_CB_OK; } + DEBUG ("netlink plugin: link_filter: No statistics for interface %s.", dev); return MNL_CB_OK; + } /* int link_filter_cb */ #if HAVE_TCA_STATS2 static int qos_attr_cb (const struct nlattr *attr, void *data) { - struct gnet_stats_basic *bs = *(struct gnet_stats_basic **)data; + struct gnet_stats_basic **bs = (struct gnet_stats_basic **)data; /* skip unsupported attribute in user-space */ if (mnl_attr_type_valid (attr, TCA_STATS_MAX) < 0) @@ -346,12 +447,12 @@ static int qos_attr_cb (const struct nlattr *attr, void *data) if (mnl_attr_get_type (attr) == TCA_STATS_BASIC) { - if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (*bs)) < 0) + if (mnl_attr_validate2 (attr, MNL_TYPE_UNSPEC, sizeof (**bs)) < 0) { ERROR ("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 failed."); return MNL_CB_ERROR; } - bs = mnl_attr_get_payload (attr); + *bs = mnl_attr_get_payload (attr); return MNL_CB_STOP; } @@ -373,7 +474,7 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) char *tc_type; char tc_inst[DATA_MAX_NAME_LEN]; - int __attribute__((unused)) stats_submitted = 0; + _Bool stats_submitted = 0; if (nlh->nlmsg_type == RTM_NEWQDISC) tc_type = "qdisc"; @@ -434,7 +535,7 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args) return (-1); } - { /* The the ID */ + { /* The ID */ uint32_t numberic_id; numberic_id = tm->tcm_handle; @@ -679,7 +780,7 @@ static int ir_read (void) continue; } - DEBUG ("netlink plugin: ir_read: querying %s from %s (%lu).", + DEBUG ("netlink plugin: ir_read: querying %s from %s (%zu).", type_name[type_index], iflist[ifindex], ifindex); nlh = mnl_nlmsg_put_header (buf);