mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-02 22:38:01 +00:00
device: add statistics interface
Add statistics interface to all device instances. When active, the properties of this interface are refreshed whenever there is network activity for the device. Activation is performed by changing RefreshRateMs property. If set to zero, the interface is deactivated. If set to other value, the rest of the interface properties are refreshed whenever the related network metric changes, being RefreshRateMs the minimum time between property changes, in milliseconds.
This commit is contained in:
parent
85834a6675
commit
24b193ab64
|
@ -43,6 +43,8 @@ nodist_libnmdbus_la_SOURCES = \
|
|||
nmdbus-device-modem.h \
|
||||
nmdbus-device-olpc-mesh.c \
|
||||
nmdbus-device-olpc-mesh.h \
|
||||
nmdbus-device-statistics.c \
|
||||
nmdbus-device-statistics.h \
|
||||
nmdbus-device-team.c \
|
||||
nmdbus-device-team.h \
|
||||
nmdbus-device-tun.c \
|
||||
|
@ -114,7 +116,8 @@ DBUS_INTERFACE_DOCS = \
|
|||
nmdbus-device-veth-org.freedesktop.NetworkManager.Device.Veth.xml \
|
||||
nmdbus-settings-org.freedesktop.NetworkManager.Settings.xml \
|
||||
nmdbus-device-ethernet-org.freedesktop.NetworkManager.Device.Wired.xml \
|
||||
nmdbus-ip4-config-org.freedesktop.NetworkManager.IP4Config.xml
|
||||
nmdbus-ip4-config-org.freedesktop.NetworkManager.IP4Config.xml \
|
||||
nmdbus-device-statistics-org.freedesktop.NetworkManager.Device.Statistics.xml
|
||||
|
||||
define _make_nmdbus_rule
|
||||
$(1): $(patsubst nmdbus-%.c,nm-%.xml,$(1))
|
||||
|
@ -154,6 +157,7 @@ EXTRA_DIST = \
|
|||
nm-device-macvlan.xml \
|
||||
nm-device-modem.xml \
|
||||
nm-device-olpc-mesh.xml \
|
||||
nm-device-statistics.xml \
|
||||
nm-device-team.xml \
|
||||
nm-device-tun.xml \
|
||||
nm-device-veth.xml \
|
||||
|
|
37
introspection/nm-device-statistics.xml
Normal file
37
introspection/nm-device-statistics.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<node name="/">
|
||||
<interface name="org.freedesktop.NetworkManager.Device.Statistics">
|
||||
|
||||
<!--
|
||||
RefreshRateMs:
|
||||
|
||||
Rate of change of the rest of properties of this interface. If zero, the
|
||||
properties do not change. Otherwise, the properties are refreshed each
|
||||
RefreshRateMs milliseconds in case the underlying counter has changed
|
||||
too.
|
||||
-->
|
||||
<property name="RefreshRateMs" type="u" access="readwrite"/>
|
||||
|
||||
<!--
|
||||
TxBytes:
|
||||
|
||||
Number of transmitted bytes
|
||||
-->
|
||||
<property name="TxBytes" type="t" access="read"/>
|
||||
|
||||
<!--
|
||||
RxBytes:
|
||||
|
||||
Number of received bytes
|
||||
-->
|
||||
<property name="RxBytes" type="t" access="read"/>
|
||||
|
||||
<!--
|
||||
PropertiesChanged:
|
||||
@properties: A dictionary mapping property names to variant boxed values
|
||||
-->
|
||||
<signal name="PropertiesChanged">
|
||||
<arg name="properties" type="a{sv}"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>
|
|
@ -68,6 +68,7 @@
|
|||
#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan"
|
||||
#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre"
|
||||
#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel"
|
||||
#define NM_DBUS_INTERFACE_DEVICE_STATISTICS NM_DBUS_INTERFACE_DEVICE ".Statistics"
|
||||
|
||||
#define NM_DBUS_INTERFACE_SETTINGS "org.freedesktop.NetworkManager.Settings"
|
||||
#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings"
|
||||
|
|
|
@ -331,6 +331,8 @@ libNetworkManager_la_SOURCES = \
|
|||
devices/nm-device-generic.h \
|
||||
devices/nm-device-logging.h \
|
||||
devices/nm-device-private.h \
|
||||
devices/nm-device-statistics.c \
|
||||
devices/nm-device-statistics.h \
|
||||
\
|
||||
dhcp-manager/nm-dhcp-client.c \
|
||||
dhcp-manager/nm-dhcp-client.h \
|
||||
|
|
|
@ -114,6 +114,9 @@ void nm_device_ip_method_failed (NMDevice *self, int family, NMDeviceStateReason
|
|||
|
||||
gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value);
|
||||
|
||||
void nm_device_set_tx_bytes (NMDevice *self, guint64 tx_bytes);
|
||||
void nm_device_set_rx_bytes (NMDevice *self, guint64 rx_bytes);
|
||||
|
||||
#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \
|
||||
NM_DEVICE_CLASS (klass)->connection_type = conn_type; \
|
||||
{ \
|
||||
|
|
99
src/devices/nm-device-statistics.c
Normal file
99
src/devices/nm-device-statistics.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* 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 Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2016 Canonical Ltd
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "nm-device-statistics.h"
|
||||
#include "nm-device-private.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-platform.h"
|
||||
|
||||
#define _NMLOG_DOMAIN LOGD_DEVICE
|
||||
#define _NMLOG(level, ...) \
|
||||
nm_log_obj ((level), _NMLOG_DOMAIN, (self->device), "device-stats", \
|
||||
"(%s): " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
nm_device_get_iface (self->device) ?: "(none)" \
|
||||
_NM_UTILS_MACRO_REST(__VA_ARGS__))
|
||||
|
||||
struct _NMDeviceStatistics {
|
||||
NMDevice *device;
|
||||
guint stats_update_id;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
update_stats (gpointer user_data)
|
||||
{
|
||||
NMDeviceStatistics *self = user_data;
|
||||
guint64 rx_packets;
|
||||
guint64 rx_bytes;
|
||||
guint64 tx_packets;
|
||||
guint64 tx_bytes;
|
||||
int ifindex;
|
||||
|
||||
ifindex = nm_device_get_ip_ifindex (self->device);
|
||||
|
||||
if (nm_platform_link_get_stats (NM_PLATFORM_GET, ifindex,
|
||||
&rx_packets, &rx_bytes,
|
||||
&tx_packets, &tx_bytes)) {
|
||||
_LOGT ("{RX} %"PRIu64" packets %"PRIu64" bytes {TX} %"PRIu64" packets %"PRIu64" bytes",
|
||||
rx_packets, rx_bytes, tx_packets, tx_bytes);
|
||||
|
||||
nm_device_set_tx_bytes (self->device, tx_bytes);
|
||||
nm_device_set_rx_bytes (self->device, rx_bytes);
|
||||
} else {
|
||||
_LOGE ("error no stats available");
|
||||
}
|
||||
|
||||
/* Keep polling */
|
||||
nm_platform_link_refresh (NM_PLATFORM_GET, ifindex);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
|
||||
NMDeviceStatistics *
|
||||
nm_device_statistics_new (NMDevice *device, unsigned rate_ms)
|
||||
{
|
||||
NMDeviceStatistics *self;
|
||||
|
||||
self = g_malloc0 (sizeof (*self));
|
||||
self->device = device;
|
||||
|
||||
self->stats_update_id = g_timeout_add (rate_ms, update_stats, self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_statistics_unref (NMDeviceStatistics *self)
|
||||
{
|
||||
g_source_remove (self->stats_update_id);
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_statistics_change_rate (NMDeviceStatistics *self, unsigned rate_ms)
|
||||
{
|
||||
g_source_remove (self->stats_update_id);
|
||||
|
||||
self->stats_update_id = g_timeout_add (rate_ms, update_stats, self);
|
||||
}
|
31
src/devices/nm-device-statistics.h
Normal file
31
src/devices/nm-device-statistics.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* 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 Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2016 Canonical Ltd
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_DEVICE_STATISTICS_H__
|
||||
#define __NETWORKMANAGER_DEVICE_STATISTICS_H__
|
||||
|
||||
typedef struct _NMDeviceStatistics NMDeviceStatistics;
|
||||
|
||||
NMDeviceStatistics *
|
||||
nm_device_statistics_new (NMDevice *device, unsigned rate_ms);
|
||||
|
||||
void nm_device_statistics_unref (NMDeviceStatistics *self);
|
||||
|
||||
void nm_device_statistics_change_rate (NMDeviceStatistics *self, unsigned rate_ms);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_STATISTICS_H__ */
|
|
@ -66,11 +66,13 @@
|
|||
#include "sd-ipv4ll.h"
|
||||
#include "nm-audit-manager.h"
|
||||
#include "nm-arping-manager.h"
|
||||
#include "nm-device-statistics.h"
|
||||
|
||||
#include "nm-device-logging.h"
|
||||
_LOG_DECLARE_SELF (NMDevice);
|
||||
|
||||
#include "nmdbus-device.h"
|
||||
#include "nmdbus-device-statistics.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
|
||||
|
||||
|
@ -138,6 +140,9 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
|
|||
PROP_LLDP_NEIGHBORS,
|
||||
PROP_REAL,
|
||||
PROP_SLAVES,
|
||||
PROP_REFRESH_RATE_MS,
|
||||
PROP_TX_BYTES,
|
||||
PROP_RX_BYTES,
|
||||
);
|
||||
|
||||
#define DEFAULT_AUTOCONNECT TRUE
|
||||
|
@ -407,6 +412,13 @@ typedef struct _NMDevicePrivate {
|
|||
NMLldpListener *lldp_listener;
|
||||
|
||||
guint check_delete_unrealized_id;
|
||||
|
||||
guint refresh_rate_ms;
|
||||
guint64 tx_bytes;
|
||||
guint64 rx_bytes;
|
||||
|
||||
NMDeviceStatistics *statistics;
|
||||
|
||||
} NMDevicePrivate;
|
||||
|
||||
static gboolean nm_device_set_ip4_config (NMDevice *self,
|
||||
|
@ -769,6 +781,36 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface)
|
|||
g_free (old_ip_iface);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_tx_bytes (NMDevice *self, guint64 tx_bytes)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (tx_bytes == priv->tx_bytes)
|
||||
return;
|
||||
|
||||
priv->tx_bytes = tx_bytes;
|
||||
_notify (self, PROP_TX_BYTES);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_rx_bytes (NMDevice *self, guint64 rx_bytes)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (rx_bytes == priv->rx_bytes)
|
||||
return;
|
||||
|
||||
priv->rx_bytes = rx_bytes;
|
||||
_notify (self, PROP_RX_BYTES);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
||||
{
|
||||
|
@ -2199,6 +2241,11 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
|
|||
priv->carrier = TRUE;
|
||||
}
|
||||
|
||||
if (priv->refresh_rate_ms && !priv->statistics) {
|
||||
priv->statistics = nm_device_statistics_new (self,
|
||||
priv->refresh_rate_ms);
|
||||
}
|
||||
|
||||
klass->realize_start_notify (self, plink);
|
||||
|
||||
/* Do not manage externally created software devices until they are IFF_UP
|
||||
|
@ -2370,6 +2417,14 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||
g_clear_pointer (&priv->physical_port_id, g_free);
|
||||
_notify (self, PROP_PHYSICAL_PORT_ID);
|
||||
}
|
||||
if (priv->statistics) {
|
||||
nm_device_statistics_unref (priv->statistics);
|
||||
priv->statistics = NULL;
|
||||
priv->tx_bytes = 0;
|
||||
priv->tx_bytes = 0;
|
||||
_notify (self, PROP_TX_BYTES);
|
||||
_notify (self, PROP_RX_BYTES);
|
||||
}
|
||||
|
||||
priv->hw_addr_type = HW_ADDR_TYPE_UNSET;
|
||||
g_clear_pointer (&priv->hw_addr_perm, g_free);
|
||||
|
@ -11963,6 +12018,11 @@ nm_device_init (NMDevice *self)
|
|||
|
||||
priv->v4_commit_first_time = TRUE;
|
||||
priv->v6_commit_first_time = TRUE;
|
||||
|
||||
priv->refresh_rate_ms = 0;
|
||||
priv->tx_bytes = 0;
|
||||
priv->rx_bytes = 0;
|
||||
priv->statistics = NULL;
|
||||
}
|
||||
|
||||
static GObject*
|
||||
|
@ -12111,6 +12171,11 @@ dispose (GObject *object)
|
|||
g_clear_object (&priv->lldp_listener);
|
||||
}
|
||||
|
||||
if (priv->statistics) {
|
||||
nm_device_statistics_unref (priv->statistics);
|
||||
priv->statistics = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
|
||||
|
||||
if (nm_clear_g_source (&priv->queued_state.id)) {
|
||||
|
@ -12243,6 +12308,28 @@ set_property (GObject *object, guint prop_id,
|
|||
/* construct only */
|
||||
priv->hw_addr_perm = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_REFRESH_RATE_MS: {
|
||||
guint refresh_rate_ms;
|
||||
|
||||
refresh_rate_ms = g_value_get_uint (value);
|
||||
if (priv->refresh_rate_ms == refresh_rate_ms)
|
||||
break;
|
||||
|
||||
priv->refresh_rate_ms = refresh_rate_ms;
|
||||
_LOGI (LOGD_DEVICE, "statistics refresh rate set to %u ms", priv->refresh_rate_ms);
|
||||
|
||||
if (priv->refresh_rate_ms) {
|
||||
if (priv->statistics)
|
||||
nm_device_statistics_change_rate (priv->statistics, priv->refresh_rate_ms);
|
||||
else
|
||||
priv->statistics =
|
||||
nm_device_statistics_new (self, priv->refresh_rate_ms);
|
||||
} else {
|
||||
nm_device_statistics_unref (priv->statistics);
|
||||
priv->statistics = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -12405,6 +12492,15 @@ get_property (GObject *object, guint prop_id,
|
|||
g_value_take_boxed (value, slave_list);
|
||||
break;
|
||||
}
|
||||
case PROP_REFRESH_RATE_MS:
|
||||
g_value_set_uint (value, priv->refresh_rate_ms);
|
||||
break;
|
||||
case PROP_TX_BYTES:
|
||||
g_value_set_uint64 (value, priv->tx_bytes);
|
||||
break;
|
||||
case PROP_RX_BYTES:
|
||||
g_value_set_uint64 (value, priv->rx_bytes);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -12655,6 +12751,23 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/* Statistics */
|
||||
obj_properties[PROP_REFRESH_RATE_MS] =
|
||||
g_param_spec_uint (NM_DEVICE_STATISTICS_REFRESH_RATE_MS, "", "",
|
||||
0, UINT32_MAX, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_properties[PROP_TX_BYTES] =
|
||||
g_param_spec_uint64 (NM_DEVICE_STATISTICS_TX_BYTES, "", "",
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_properties[PROP_RX_BYTES] =
|
||||
g_param_spec_uint64 (NM_DEVICE_STATISTICS_RX_BYTES, "", "",
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
/* Signals */
|
||||
|
@ -12725,4 +12838,8 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
"Disconnect", impl_device_disconnect,
|
||||
"Delete", impl_device_delete,
|
||||
NULL);
|
||||
|
||||
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
|
||||
NMDBUS_TYPE_DEVICE_STATISTICS_SKELETON,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -88,6 +88,10 @@
|
|||
#define NM_DEVICE_STATE_CHANGED "state-changed"
|
||||
#define NM_DEVICE_LINK_INITIALIZED "link-initialized"
|
||||
|
||||
#define NM_DEVICE_STATISTICS_REFRESH_RATE_MS "refresh-rate-ms"
|
||||
#define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes"
|
||||
#define NM_DEVICE_STATISTICS_RX_BYTES "rx-bytes"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_DEVICE (nm_device_get_type ())
|
||||
|
|
Loading…
Reference in a new issue