---
configure.ac | 13 ++++++++++++-
src/util/virstats.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index a12186b..8001e24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -275,7 +275,7 @@ dnl and various less common threadsafe functions
AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \
getmntent_r getpwuid_r getuid kill mmap newlocale posix_fallocate \
posix_memalign prlimit regexec sched_getaffinity setgroups setns \
- setrlimit symlink sysctlbyname])
+ setrlimit symlink sysctlbyname getifaddrs])
dnl Availability of pthread functions. Because of $LIB_PTHREAD, we
dnl cannot use AC_CHECK_FUNCS_ONCE. LIB_PTHREAD and LIBMULTITHREAD
@@ -2691,6 +2691,17 @@ if test $with_freebsd = yes; then
)
fi
+# FreeBSD 10-STABLE requires _IFI_OQDROPS to be defined for if_data.ifi_oqdrops
+# field be available
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -D_IFI_OQDROPS"
+
+AC_CHECK_MEMBERS([struct if_data.ifi_oqdrops],
+ [],
+ [CFLAGS="$old_CFLAGS"],
+ [#include <net/if.h>
+ ])
+
# Check if we need to look for ifconfig
if test "$want_ifconfig" = "yes"; then
AC_PATH_PROG([IFCONFIG_PATH], [ifconfig])
diff --git a/src/util/virstats.c b/src/util/virstats.c
index 17ef5b6..910803f 100644
--- a/src/util/virstats.c
+++ b/src/util/virstats.c
@@ -29,6 +29,11 @@
#include <unistd.h>
#include <regex.h>
+#ifdef HAVE_GETIFADDRS
+# include <net/if.h>
+# include <ifaddrs.h>
+#endif
+
#include "virerror.h"
#include "datatypes.h"
#include "virstats.h"
@@ -114,6 +119,52 @@ virNetInterfaceStats(const char *path,
_("/proc/net/dev: Interface not found"));
return -1;
}
+#elif defined(HAVE_GETIFADDRS)
+int
+virNetInterfaceStats(const char *path,
+ struct _virDomainInterfaceStats *stats)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct if_data *ifd;
+ int ret = -1;
+
+ if (getifaddrs(&ifap) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Could not get interface list"));
+ return -1;
+ }
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family != AF_LINK)
+ continue;
+
+ if (STREQ(ifa->ifa_name, path)) {
+ ifd = (struct if_data *)ifa->ifa_data;
+ stats->tx_bytes = ifd->ifi_ibytes;
+ stats->tx_packets = ifd->ifi_ipackets;
+ stats->tx_errs = ifd->ifi_ierrors;
+ stats->tx_drop = ifd->ifi_iqdrops;
+ stats->rx_bytes = ifd->ifi_obytes;
+ stats->rx_packets = ifd->ifi_opackets;
+ stats->rx_errs = ifd->ifi_oerrors;
+# ifdef HAVE_STRUCT_IF_DATA_IFI_OQDROPS
+ stats->rx_drop = ifd->ifi_oqdrops;
+# else
+ stats->rx_drop = 0;
+# endif
+
+ ret = 0;
+ break;
+ }
+ }
+
+ if (ret < 0)
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Interface not found"));
+
+ freeifaddrs(ifap);
+ return ret;
+}
#else
int
virNetInterfaceStats(const char *path ATTRIBUTE_UNUSED,
--
1.9.0