diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index 234df4b68..9d3cfbb97 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -206,6 +206,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* #ifdef HAVE_LIBHWLOC Panel_add(super, (Object*) CheckItem_newByRef("Show topology when selecting affinity by default", &(settings->topologyAffinity))); #endif + Panel_add(super, (Object*) CheckItem_newByRef("Ignore virtual network interfaces to count rx and tx values", &(settings->ignoreVirtualNetworkInterfaces))); return this; } diff --git a/NetworkIOMeter.c b/NetworkIOMeter.c index 784c90ac3..a0fb39664 100644 --- a/NetworkIOMeter.c +++ b/NetworkIOMeter.c @@ -45,6 +45,7 @@ static void NetworkIOMeter_updateValues(Meter* this) { /* update only every 500ms to have a sane span for rate calculation */ if (passedTimeInMs > 500) { + data.ignoreVirtualIntf = host->settings->ignoreVirtualNetworkInterfaces; hasNewData = Platform_getNetworkIO(&data); if (!hasNewData) { status = RATESTATUS_NODATA; diff --git a/NetworkIOMeter.h b/NetworkIOMeter.h index 355b815b2..e47261317 100644 --- a/NetworkIOMeter.h +++ b/NetworkIOMeter.h @@ -17,6 +17,7 @@ typedef struct NetworkIOData_ { uint64_t packetsReceived; uint64_t bytesTransmitted; uint64_t packetsTransmitted; + bool ignoreVirtualIntf; } NetworkIOData; extern const MeterClass NetworkIOMeter_class; diff --git a/Settings.h b/Settings.h index 01e808e86..028b4205f 100644 --- a/Settings.h +++ b/Settings.h @@ -112,6 +112,7 @@ typedef struct Settings_ { bool changed; uint64_t lastUpdate; + bool ignoreVirtualNetworkInterfaces; } Settings; #define Settings_cpuId(settings, cpu) ((settings)->countCPUsFromOne ? (cpu)+1 : (cpu)) diff --git a/freebsd/Platform.c b/freebsd/Platform.c index 0eda02b7a..dd7f098ee 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -16,7 +16,7 @@ in the source distribution for its full text. #include #include #include -#include +#include #include #include #include @@ -150,6 +150,32 @@ void Platform_setBindings(Htop_Action* keys) { (void) keys; } +static bool Platform_isVirtualNetworkInterface(const struct ifmibdata* ifmd) { + switch (ifmd->ifmd_data.ifi_type) { + case IFT_LOOP: // Loopback +#ifdef IFT_VLAN + case IFT_VLAN: // VLAN +#endif + case IFT_TUNNEL: // IP tunnel + case IFT_GIF: // Generic tunnel + case IFT_BRIDGE: // Bridge + case IFT_L2VLAN: // Layer 2 VLAN +#ifdef IFT_FAITH + case IFT_FAITH: // IPv6-to-IPv4 translation +#endif + case IFT_STF: // 6to4 tunnel + case IFT_PPP: // PPP + case IFT_PFSYNC: // pfsync +#ifdef IFT_CARP + case IFT_CARP: // CARP +#endif + return true; + default: + break; + } + return false; +} + int Platform_getUptime(void) { struct timeval bootTime, currTime; const int mib[2] = { CTL_KERN, KERN_BOOTTIME }; @@ -361,7 +387,8 @@ bool Platform_getNetworkIO(NetworkIOData* data) { if (r < 0) continue; - if (ifmd.ifmd_flags & IFF_LOOPBACK) + if ((ifmd.ifmd_flags & IFF_LOOPBACK) || // Loopback must be always ignored + (data->ignoreVirtualIntf && Platform_isVirtualNetworkInterface(&ifmd))) continue; data->bytesReceived += ifmd.ifmd_data.ifi_ibytes; diff --git a/linux/Platform.c b/linux/Platform.c index ddaf1324d..1795d32d4 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -209,6 +209,14 @@ void Platform_setBindings(Htop_Action* keys) { keys[KEY_F(20)] = Platform_actionHigherAutogroupPriority; // Shift-F8 } +static bool Platform_isVirtualNetworkInterface(const char* name) { + char path[PATH_MAX]; + + // Since kerel 2.6.13 virtual interfaces are listed in /sys/devices/virtual/net + xSnprintf(path, sizeof(path), "/sys/devices/virtual/net/%s", name); + return access(path, F_OK) == 0; +} + const MeterClass* const Platform_meterTypes[] = { &CPUMeter_class, &ClockMeter_class, @@ -712,7 +720,9 @@ bool Platform_getNetworkIO(NetworkIOData* data) { &packetsTransmitted) != 5) continue; - if (String_eq(interfaceName, "lo:")) + if (String_eq(interfaceName, "lo:") || // Loopback must be always ignored + (data->ignoreVirtualIntf && Platform_isVirtualNetworkInterface(interfaceName)) + ) continue; data->bytesReceived += bytesReceived;