Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DisplayOptionsPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions NetworkIOMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions NetworkIOMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef struct NetworkIOData_ {
uint64_t packetsReceived;
uint64_t bytesTransmitted;
uint64_t packetsTransmitted;
bool ignoreVirtualIntf;
} NetworkIOData;

extern const MeterClass NetworkIOMeter_class;
Expand Down
1 change: 1 addition & 0 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
31 changes: 29 additions & 2 deletions freebsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ in the source distribution for its full text.
#include <time.h>
#include <net/if.h>
#include <net/if_mib.h>
#include <sys/_types.h>
#include <net/if_types.h>
#include <sys/devicestat.h>
#include <sys/param.h>
#include <sys/resource.h>
Expand Down Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 11 additions & 1 deletion linux/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Since kerel 2.6.13 virtual interfaces are listed in /sys/devices/virtual/net
// Since kernel 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;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list is quite incomplete, and IMO hard-coding it like this is not ideal. I imagine the BSDs and other platforms may have a similar requirement.

The solution we use in pcp.io is to have an interfaces.conf configuration file (optionally, somewhere below /etc) that provides a regular expression - if interfaces match, they are culled from the calculation. This is platform agnostic - different platforms could have different config files - and indeed different sites may have their own naming conventions, custom drivers, etc.

This is the current regex we're using:

# interfaces.conf
#
# Regular expression describing network interfaces (from the
# network.interfaces.* metrics instance domain) that will be
# *excluded* from the network.all.* metrics calculation when
# aggregating (sum) stats from physical interfaces.
#
# Comments are the hash-to-end-of-line variety and any / all
# whitespace characters are removed before pmdalinux(1) uses
# regcomp(3) to compile the regular expression.
#

^(lo |
  bond[0-9]+ |
  team[0-9]+ |
  tun[0-9]+ |
  virbr[0-9]+ |
  virbr[0-9]+-nic |
  cni[0-9]+ |
  cni-podman[0-9]+ |
  docker[0-9]+ |
  veth[0-9]+ |
  face)$

Using a similar approach to this could simplify and improve this PR. Can do away with all the configure.ac/ifdef changes as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, instead of relying on the name of the interface, using the interface type can help simplify things even more. Otherwise you risk breaking things depending on some settings (e.g. systemd's unusable names vs. the good ones like eth0) …


const MeterClass* const Platform_meterTypes[] = {
&CPUMeter_class,
&ClockMeter_class,
Expand Down Expand Up @@ -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;
Expand Down