summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-04-30 14:18:14 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-06-09 18:18:45 +0200
commita86255a0432b2ba88f5d629bffb79dd05bd7590a (patch)
tree9c42495a771f49f1cf8eb96b5ed902cd93d271ad
parent1e39b2320dfe42ca33dfbf12746d63935818ac5a (diff)
downloadNetworkManager-a86255a0432b2ba88f5d629bffb79dd05bd7590a.tar.gz
core: update device 'metered' property on connection state change
The metered property of a NMDevice that reaches the activated state is copied from the active connection and if its value is 'unknown' some heuristics are used to guess the actual value. When the connection is torn down the metered property is reset to 'unknown'.
-rw-r--r--src/devices/nm-device.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index f867ed48a9..63baa63270 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -75,6 +75,7 @@ _LOG_DECLARE_SELF (NMDevice);
static void impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context);
static void impl_device_delete (NMDevice *self, DBusGMethodInvocation *context);
+static void nm_device_update_metered (NMDevice *self);
#include "nm-device-glue.h"
@@ -3362,8 +3363,10 @@ dhcp4_state_changed (NMDhcpClient *client,
if (priv->ip4_state == IP_CONF)
nm_device_activate_schedule_ip4_config_result (self, ip4_config);
- else if (priv->ip4_state == IP_DONE)
+ else if (priv->ip4_state == IP_DONE) {
dhcp4_lease_change (self, ip4_config);
+ nm_device_update_metered (self);
+ }
break;
case NM_DHCP_STATE_TIMEOUT:
dhcp4_fail (self, TRUE);
@@ -7292,6 +7295,59 @@ nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr)
priv->dhcp_anycast_address = g_strdup (addr);
}
+static void
+nm_device_update_metered (NMDevice *self)
+{
+#define NM_METERED_INVALID ((NMMetered) -1)
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMSettingConnection *setting;
+ NMMetered conn_value, value = NM_METERED_INVALID;
+ NMConnection *connection = NULL;
+ NMDeviceState state;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+
+ state = nm_device_get_state (self);
+ if ( state <= NM_DEVICE_STATE_DISCONNECTED
+ || state > NM_DEVICE_STATE_ACTIVATED)
+ value = NM_METERED_UNKNOWN;
+
+ if (value == NM_METERED_INVALID) {
+ connection = nm_device_get_connection (self);
+ if (connection) {
+ setting = nm_connection_get_setting_connection (connection);
+ if (setting) {
+ conn_value = nm_setting_connection_get_metered (setting);
+ if (conn_value != NM_METERED_UNKNOWN)
+ value = conn_value;
+ }
+ }
+ }
+
+ /* Try to guess a value using the metered flag in IP configuration */
+ if (value == NM_METERED_INVALID) {
+ if ( priv->ip4_config
+ && priv->ip4_state == IP_DONE
+ && nm_ip4_config_get_metered (priv->ip4_config))
+ value = NM_METERED_GUESS_YES;
+ }
+
+ /* Otherwise look at connection type */
+ if (value == NM_METERED_INVALID) {
+ if ( nm_connection_is_type (connection, NM_SETTING_GSM_SETTING_NAME)
+ || nm_connection_is_type (connection, NM_SETTING_CDMA_SETTING_NAME))
+ value = NM_METERED_GUESS_YES;
+ else
+ value = NM_METERED_GUESS_NO;
+ }
+
+ if (value != priv->metered) {
+ _LOGD (LOGD_DEVICE, "set metered value %d", value);
+ priv->metered = value;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_METERED);
+ }
+}
+
/**
* nm_device_check_connection_available():
* @self: the #NMDevice
@@ -7749,6 +7805,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, gboolean deconfig
nm_platform_address_flush (NM_PLATFORM_GET, ifindex);
}
+ nm_device_update_metered (self);
_cleanup_generic_post (self, deconfigure);
}
@@ -8221,6 +8278,7 @@ _set_state_full (NMDevice *self,
break;
case NM_DEVICE_STATE_ACTIVATED:
_LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
+ nm_device_update_metered (self);
nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL);
break;
case NM_DEVICE_STATE_FAILED: