summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f6b9d3b)
raw | patch | inline | side by side (parent: f6b9d3b)
author | Marek Becka <marek.becka@superhosting.cz> | |
Sun, 22 Sep 2013 22:19:46 +0000 (00:19 +0200) | ||
committer | Marek Becka <marek.becka@superhosting.cz> | |
Sun, 22 Sep 2013 22:19:46 +0000 (00:19 +0200) |
configure.in | patch | blob | history | |
src/netlink.c | patch | blob | history |
diff --git a/configure.in b/configure.in
index c23df178ca1ac0c9dd464894ca1fb407bd32fb78..bf28985365cd5909c5d31106f225c786c0779b18 100644 (file)
--- a/configure.in
+++ b/configure.in
[AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])])
fi
if test "x$with_libmnl" = "xyes"
+then
+ AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors],
+ [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])],
+ [],
+ [
+ #include <linux/if_link.h>
+ ])
+fi
+if test "x$with_libmnl" = "xyes"
then
AC_CHECK_LIB(mnl, mnl_nlmsg_get_payload,
[with_libmnl="yes"],
diff --git a/src/netlink.c b/src/netlink.c
index 422dc8c6fdadaf1b2feb7449cc5f3a82eda1954c..47c13321a9f8c64d7382e0bf903037662a3774c8 100644 (file)
--- a/src/netlink.c
+++ b/src/netlink.c
#include <libmnl/libmnl.h>
+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
{
char *device;
} /* 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)
} /* 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_bytes); \
+ 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 *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)
{
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