summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-03-13 15:34:14 +0100
committerThomas Haller <thaller@redhat.com>2017-03-16 16:39:25 +0100
commitbcfb7d03400b58a35801d12d886ed6afa6d672f4 (patch)
treebd132a4832275a1346e7d04628c2595704a8dffc
parente3d8e8560171331cfafc3041d4f67c9081e5b1b2 (diff)
downloadNetworkManager-th/assume-vs-unmanaged-bgo746440.tar.gz
device: track system interface state in NMDeviceth/assume-vs-unmanaged-bgo746440
When deciding whether to touch a device we sometimes look at whether the active connection is external/assumed. In many cases however, there is no active connection around (e.g. while moving the device from state unmanaged to disconnected before assuming). So in most cases we instead look at the device-state-reason to decide whether to touch the interface (see nm_device_state_reason_check()). Often it's desirable to have no state and passing data as function arguments. However, the state reason has to be passed along several hops (e.g. a queued state change). Or a change to a master/slave can affect the slave/master, where we pass on the state reason. Or an intermediate event might invalidate a previous state reason. Passing the state whether to touch a device or not as a state-reason is cumbersome and limited. Instead, the device should be aware of whats going on. Add a sys-iface-state with: - SYS_IFACE_STATE_EXTERNAL: meaning, NM should not touch it - SYS_IFACE_STATE_ASSUME: meaning, NM is gracefully taking over - SYS_IFACE_STATE_MANAGED: meaning, the device is managed by NM - SYS_IFACE_STATE_REMOVED: the device no longer exists This replaces most checks of nm_device_state_reason_check() and nm_active_connection_get_activation_type() by instead looking at the sys-iface-state of the device. This patch probably has still issues, but the previous behavior was not very clear either. We will need to identify those issues in future tests and tweak the behavior. At least, now there is one flag that describes how to behave.
-rw-r--r--src/devices/nm-device-vlan.c5
-rw-r--r--src/devices/nm-device.c209
-rw-r--r--src/devices/nm-device.h16
-rw-r--r--src/devices/team/nm-device-team.c2
-rw-r--r--src/nm-active-connection.c14
-rw-r--r--src/nm-active-connection.h2
-rw-r--r--src/nm-manager.c21
7 files changed, 184 insertions, 85 deletions
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 4bee5497c2..ada4f3295f 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -90,13 +90,14 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
GParamSpec *pspec,
gpointer user_data)
{
- NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
+ NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceVlan *self = NM_DEVICE_VLAN (device);
NMConnection *connection;
const char *new_mac, *old_mac;
NMSettingIPConfig *s_ip6;
/* Never touch assumed devices */
- if (nm_device_has_activation_type_assume_or_external ((NMDevice *) self))
+ if (nm_device_sys_iface_state_is_external_or_assume (device))
return;
connection = nm_device_get_applied_connection ((NMDevice *) self);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index efa365c77a..ee0d95fdb9 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -308,6 +308,8 @@ typedef struct _NMDevicePrivate {
bool v4_commit_first_time:1;
bool v6_commit_first_time:1;
+ NMDeviceSysIfaceState sys_iface_state:2;
+
/* Generic DHCP stuff */
guint32 dhcp_timeout;
char * dhcp_anycast_address;
@@ -611,6 +613,69 @@ nm_device_get_settings (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->settings;
}
+/*****************************************************************************/
+
+NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_sys_iface_state_to_str, NMDeviceSysIfaceState,
+ NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"),
+);
+
+NMDeviceSysIfaceState
+nm_device_sys_iface_state_get (NMDevice *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+
+ return NM_DEVICE_GET_PRIVATE (self)->sys_iface_state;
+}
+
+gboolean
+nm_device_sys_iface_state_is_external (NMDevice *self)
+{
+ return NM_IN_SET (nm_device_sys_iface_state_get (self),
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+}
+
+gboolean
+nm_device_sys_iface_state_is_external_or_assume (NMDevice *self)
+{
+ return NM_IN_SET (nm_device_sys_iface_state_get (self),
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+}
+
+void
+nm_device_sys_iface_state_set (NMDevice *self,
+ NMDeviceSysIfaceState sys_iface_state)
+{
+ NMDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+ g_return_if_fail (NM_IN_SET (sys_iface_state,
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME,
+ NM_DEVICE_SYS_IFACE_STATE_MANAGED,
+ NM_DEVICE_SYS_IFACE_STATE_REMOVED));
+
+ priv = NM_DEVICE_GET_PRIVATE (self);
+ if (priv->sys_iface_state != sys_iface_state) {
+ _LOGT (LOGD_DEVICE, "sys-iface-state: %s -> %s",
+ _sys_iface_state_to_str (priv->sys_iface_state),
+ _sys_iface_state_to_str (sys_iface_state));
+ priv->sys_iface_state = sys_iface_state;
+ }
+
+ /* this function only sets a flag, no immediate actions are initiated.
+ *
+ * If you change this, make sure that all callers are fine with such actions. */
+
+ nm_assert (priv->sys_iface_state == sys_iface_state);
+}
+
+/*****************************************************************************/
+
static void
init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
{
@@ -1598,27 +1663,6 @@ nm_device_get_physical_port_id (NMDevice *self)
/*****************************************************************************/
-static gboolean
-nm_device_has_activation_type_external (NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-
- return priv->act_request
- && NM_IN_SET (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)),
- NM_ACTIVATION_TYPE_EXTERNAL);
-}
-
-gboolean
-nm_device_has_activation_type_assume_or_external (NMDevice *self)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-
- return priv->act_request
- && NM_IN_SET (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)),
- NM_ACTIVATION_TYPE_ASSUME,
- NM_ACTIVATION_TYPE_EXTERNAL);
-}
-
static SlaveInfo *
find_slave_info (NMDevice *self, NMDevice *slave)
{
@@ -2581,6 +2625,8 @@ realize_start_setup (NMDevice *self,
_notify (self, PROP_MTU);
}
+ nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+
if (plink) {
g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
update_device_from_platform_link (self, plink);
@@ -2954,7 +3000,6 @@ slave_state_changed (NMDevice *slave,
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean release = FALSE;
- gboolean configure = TRUE;
_LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
nm_device_get_iface (slave),
@@ -2977,12 +3022,10 @@ slave_state_changed (NMDevice *slave,
release = TRUE;
}
- /* Don't touch the device if its state changed externally. */
- if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
- configure = FALSE;
-
if (release) {
- nm_device_master_release_one_slave (self, slave, configure, reason);
+ nm_device_master_release_one_slave (self, slave,
+ priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED,
+ reason);
/* Bridge/bond/team interfaces are left up until manually deactivated */
if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
_LOGD (LOGD_DEVICE, "last slave removed; remaining activated");
@@ -3148,7 +3191,7 @@ nm_device_master_release_slaves (NMDevice *self)
gboolean configure = TRUE;
/* Don't release the slaves if this connection doesn't belong to NM. */
- if (nm_device_has_activation_type_external (self))
+ if (nm_device_sys_iface_state_is_external (self))
return;
reason = priv->state_reason;
@@ -3226,6 +3269,14 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
_LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
priv->is_enslaved = TRUE;
+
+ if ( NM_IN_SET_TYPED (NMDeviceSysIfaceState,
+ priv->sys_iface_state,
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME)
+ && nm_device_sys_iface_state_get (priv->master) == NM_DEVICE_SYS_IFACE_STATE_MANAGED)
+ nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+
_notify (self, PROP_MASTER);
_notify (priv->master, PROP_SLAVES);
} else if (activating) {
@@ -4186,7 +4237,7 @@ master_ready (NMDevice *self,
/* If the master didn't change, add-slave only rechecks whether to assume a connection. */
nm_device_master_add_slave (master,
self,
- nm_active_connection_has_activation_type_assume_or_external (active) ? FALSE : TRUE);
+ !nm_device_sys_iface_state_is_external_or_assume (self));
}
static void
@@ -4254,7 +4305,6 @@ activate_stage1_device_prepare (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
- NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
_set_ip_state (self, AF_INET, IP_NONE);
_set_ip_state (self, AF_INET6, IP_NONE);
@@ -4266,7 +4316,7 @@ activate_stage1_device_prepare (NMDevice *self)
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */
- if (!nm_active_connection_has_activation_type_assume_or_external (active)) {
+ if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &failure_reason);
@@ -4358,13 +4408,12 @@ activate_stage2_device_config (NMDevice *self)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret;
gboolean no_firmware = FALSE;
- NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
GSList *iter;
nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */
- if (!nm_active_connection_has_activation_type_assume_or_external (active)) {
+ if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
@@ -4392,7 +4441,7 @@ activate_stage2_device_config (NMDevice *self)
if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave));
- else if ( nm_device_has_activation_type_external (self)
+ else if ( nm_device_sys_iface_state_is_external (self)
&& slave_state <= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queue_recheck_assume (info->slave);
}
@@ -4493,7 +4542,7 @@ check_ip_state (NMDevice *self, gboolean may_fail)
&& (priv->ip6_state == IP_FAIL || (ip6_ignore && priv->ip6_state == IP_DONE))) {
/* Either both methods failed, or only one failed and the other is
* disabled */
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* We have assumed configuration, but couldn't redo it. No problem,
* move to check state. */
_set_ip_state (self, AF_INET, IP_DONE);
@@ -4685,7 +4734,7 @@ ipv4_dad_start (NMDevice *self, NMIP4Config **configs, ArpingCallback cb)
|| !hw_addr
|| !hw_addr_len
|| !addr_found
- || nm_device_has_activation_type_assume_or_external (self)) {
+ || nm_device_sys_iface_state_is_external_or_assume (self)) {
/* DAD not needed, signal success */
cb (self, configs, TRUE);
@@ -4986,7 +5035,7 @@ ensure_con_ip4_config (NMDevice *self)
nm_connection_get_setting_ip4_config (connection),
nm_device_get_ip4_route_metric (self));
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* For assumed connections ignore all addresses and routes. */
nm_ip4_config_reset_addresses (priv->con_ip4_config);
nm_ip4_config_reset_routes (priv->con_ip4_config);
@@ -5012,7 +5061,7 @@ ensure_con_ip6_config (NMDevice *self)
nm_connection_get_setting_ip6_config (connection),
nm_device_get_ip6_route_metric (self));
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* For assumed connections ignore all addresses and routes. */
nm_ip6_config_reset_addresses (priv->con_ip6_config);
nm_ip6_config_reset_routes (priv->con_ip6_config);
@@ -5154,7 +5203,7 @@ ip4_config_merge_and_apply (NMDevice *self,
* but if the IP method is automatic we need to update the default route to
* maintain connectivity.
*/
- if (nm_device_has_activation_type_external (self) && !auto_method)
+ if (nm_device_sys_iface_state_is_external (self) && !auto_method)
goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike.
@@ -5230,7 +5279,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit
&& priv->v4_commit_first_time
- && !nm_device_has_activation_type_assume_or_external (self);
+ && !nm_device_sys_iface_state_is_external_or_assume (self);
success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync);
g_object_unref (composite);
@@ -5303,7 +5352,7 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
* device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again.
*/
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
dhcp_schedule_restart (self, AF_INET, "connection is assumed");
return;
}
@@ -5901,7 +5950,7 @@ ip6_config_merge_and_apply (NMDevice *self,
* but if the IP method is automatic we need to update the default route to
* maintain connectivity.
*/
- if (nm_device_has_activation_type_external (self) && !auto_method)
+ if (nm_device_sys_iface_state_is_external (self) && !auto_method)
goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike.
@@ -5983,7 +6032,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit
&& priv->v6_commit_first_time
- && !nm_device_has_activation_type_assume_or_external (self);
+ && !nm_device_sys_iface_state_is_external_or_assume (self);
success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync);
g_object_unref (composite);
@@ -6097,7 +6146,7 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
* device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again.
*/
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
dhcp_schedule_restart (self, AF_INET6, "connection is assumed");
return;
}
@@ -6682,7 +6731,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
if (ifindex <= 0)
return;
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* for assumed connections we don't tamper with the MTU. This is
* a bug and supposed to be fixed by the unmanaged/assumed rework. */
return;
@@ -7349,7 +7398,7 @@ act_stage3_ip6_config_start (NMDevice *self,
* IPv6LL if this is not an assumed connection, since assumed connections
* will already have IPv6 set up.
*/
- if (!nm_device_has_activation_type_assume_or_external (self))
+ if (!nm_device_sys_iface_state_is_external_or_assume (self))
set_nm_ipv6ll (self, TRUE);
/* Re-enable IPv6 on the interface */
@@ -7379,7 +7428,7 @@ act_stage3_ip6_config_start (NMDevice *self,
_LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
if ( ret != NM_ACT_STAGE_RETURN_FAILURE
- && !nm_device_has_activation_type_assume_or_external (self)) {
+ && !nm_device_sys_iface_state_is_external_or_assume (self)) {
switch (ip6_privacy) {
case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
@@ -7622,7 +7671,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
s_con = nm_connection_get_setting_connection (connection);
if (!priv->fw_ready) {
- if (nm_device_has_activation_type_external (self))
+ if (nm_device_sys_iface_state_is_external (self))
priv->fw_ready = TRUE;
else {
if (!priv->fw_call) {
@@ -7924,7 +7973,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
/* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self);
- if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_has_activation_type_assume_or_external (self)) {
+ if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) {
nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
@@ -8073,7 +8122,7 @@ activate_stage5_ip6_config_commit (NMDevice *self)
/* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self);
- if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_has_activation_type_assume_or_external (self)) {
+ if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) {
nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
@@ -8202,7 +8251,24 @@ act_request_set (NMDevice *self, NMActRequest *act_request)
"notify::"NM_EXPORTED_OBJECT_PATH,
G_CALLBACK (act_request_set_cb),
self);
+
+ switch (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request))) {
+ case NM_ACTIVATION_TYPE_EXTERNAL:
+ break;
+ case NM_ACTIVATION_TYPE_ASSUME:
+ if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
+ nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+ break;
+ case NM_ACTIVATION_TYPE_MANAGED:
+ if (NM_IN_SET_TYPED (NMDeviceSysIfaceState,
+ priv->sys_iface_state,
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME))
+ nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+ break;
+ }
}
+
_notify (self, PROP_ACTIVE_CONNECTION);
}
@@ -9301,7 +9367,7 @@ nm_device_set_ip4_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config) {
- gboolean assumed = nm_device_has_activation_type_assume_or_external (self);
+ gboolean assumed = nm_device_sys_iface_state_is_external_or_assume (self);
_commit_mtu (self, new_config);
/* For assumed devices we must not touch the kernel-routes, such as the device-route.
@@ -9352,7 +9418,7 @@ nm_device_set_ip4_config (NMDevice *self,
if (old_config != priv->ip4_config)
nm_exported_object_clear_and_unexport (&old_config);
- if (nm_device_has_activation_type_external (self)) {
+ if (nm_device_sys_iface_state_is_external (self)) {
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
NMSetting *s_ip4;
@@ -9506,7 +9572,7 @@ nm_device_set_ip6_config (NMDevice *self,
if (old_config != priv->ip6_config)
nm_exported_object_clear_and_unexport (&old_config);
- if (nm_device_has_activation_type_external (self)) {
+ if (nm_device_sys_iface_state_is_external (self)) {
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
NMSetting *s_ip6;
@@ -10985,7 +11051,7 @@ nm_device_update_firewall_zone (NMDevice *self)
s_con = nm_connection_get_setting_connection (applied_connection);
if ( nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED
- && !nm_device_has_activation_type_external (self)) {
+ && !nm_device_sys_iface_state_is_external (self)) {
nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
nm_setting_connection_get_zone (s_con),
@@ -11486,7 +11552,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
connection = nm_device_get_applied_connection (self);
if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
&& connection
- && !nm_device_has_activation_type_external (self)) {
+ && !nm_device_sys_iface_state_is_external (self)) {
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
NULL,
@@ -12004,6 +12070,14 @@ _set_state_full (NMDevice *self,
/* Cache the activation request for the dispatcher */
req = nm_g_object_ref (priv->act_request);
+ if ( state > NM_DEVICE_STATE_UNMANAGED
+ && nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NOW_MANAGED
+ && NM_IN_SET_TYPED (NMDeviceSysIfaceState,
+ priv->sys_iface_state,
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME))
+ nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
if (available_connections_del_all (self))
_notify (self, PROP_AVAILABLE_CONNECTIONS);
@@ -12027,14 +12101,12 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNMANAGED:
nm_device_set_firmware_missing (self, FALSE);
if (old_state > NM_DEVICE_STATE_UNMANAGED) {
- switch (nm_device_state_reason_check (reason)) {
- case NM_DEVICE_STATE_REASON_REMOVED:
- nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED);
- break;
- case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED:
- nm_device_cleanup (self, reason, CLEANUP_TYPE_KEEP);
- break;
- default:
+ if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
+ nm_device_cleanup (self, reason,
+ priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED
+ ? CLEANUP_TYPE_REMOVED
+ : CLEANUP_TYPE_KEEP);
+ } else {
/* Clean up if the device is now unmanaged but was activated */
if (nm_device_get_act_request (self))
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
@@ -12049,11 +12121,11 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNAVAILABLE:
if (old_state == NM_DEVICE_STATE_UNMANAGED) {
save_ip6_properties (self);
- if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
+ if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED)
ip6_managed_setup (self);
}
- if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
+ if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
_LOGW (LOGD_PLATFORM, "firmware may be missing.");
@@ -12080,7 +12152,7 @@ _set_state_full (NMDevice *self,
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
} else if (old_state < NM_DEVICE_STATE_DISCONNECTED) {
- if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
+ if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
/* Ensure IPv6 is set up as it may not have been done when
* entering the UNAVAILABLE state depending on the reason.
*/
@@ -12198,7 +12270,7 @@ _set_state_full (NMDevice *self,
*/
_cancel_activation (self);
- if (nm_device_has_activation_type_assume_or_external (self)) {
+ if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* Avoid tearing down assumed connection, assume it's connected */
nm_device_queue_state (self,
NM_DEVICE_STATE_ACTIVATED,
@@ -12236,7 +12308,7 @@ _set_state_full (NMDevice *self,
if ( applied_connection
&& priv->ifindex != priv->ip_ifindex
- && !nm_device_has_activation_type_external (self)) {
+ && !nm_device_sys_iface_state_is_external (self)) {
NMSettingConnection *s_con;
const char *zone;
@@ -13183,6 +13255,7 @@ nm_device_init (NMDevice *self)
priv->unmanaged_mask = priv->unmanaged_flags;
priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+ priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 2aca285eac..073e1fbdf2 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -30,6 +30,13 @@
#include "nm-rfkill-manager.h"
#include "NetworkManagerUtils.h"
+typedef enum {
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME,
+ NM_DEVICE_SYS_IFACE_STATE_MANAGED,
+ NM_DEVICE_SYS_IFACE_STATE_REMOVED,
+} NMDeviceSysIfaceState;
+
static inline NMDeviceStateReason
nm_device_state_reason_check (NMDeviceStateReason reason)
{
@@ -489,8 +496,6 @@ gboolean nm_device_complete_connection (NMDevice *device,
gboolean nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection);
gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnection *connection);
-gboolean nm_device_has_activation_type_assume_or_external (NMDevice *device);
-
gboolean nm_device_unmanage_on_quit (NMDevice *self);
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);
@@ -612,6 +617,13 @@ gboolean nm_device_get_autoconnect (NMDevice *device);
void nm_device_set_autoconnect_intern (NMDevice *device, gboolean autoconnect);
void nm_device_emit_recheck_auto_activate (NMDevice *device);
+NMDeviceSysIfaceState nm_device_sys_iface_state_get (NMDevice *device);
+
+gboolean nm_device_sys_iface_state_is_external (NMDevice *self);
+gboolean nm_device_sys_iface_state_is_external_or_assume (NMDevice *self);
+
+void nm_device_sys_iface_state_set (NMDevice *device, NMDeviceSysIfaceState sys_iface_state);
+
void nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason);
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c
index d7cbd3660e..6906c759d6 100644
--- a/src/devices/team/nm-device-team.c
+++ b/src/devices/team/nm-device-team.c
@@ -416,7 +416,7 @@ teamd_dbus_appeared (GDBusConnection *connection,
success = teamd_read_config (device);
if (success)
nm_device_activate_schedule_stage2_device_config (device);
- else if (!nm_device_has_activation_type_assume_or_external (device))
+ else if (!nm_device_sys_iface_state_is_external_or_assume (device))
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
}
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 1cdef98cef..320ba45828 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -752,14 +752,14 @@ _set_activation_type (NMActiveConnection *self,
nm_activation_type_to_string (priv->activation_type),
nm_activation_type_to_string (activation_type));
priv->activation_type = activation_type;
-}
-gboolean
-nm_active_connection_has_activation_type_assume_or_external (NMActiveConnection *self)
-{
- return NM_IN_SET (nm_active_connection_get_activation_type (self),
- NM_ACTIVATION_TYPE_ASSUME,
- NM_ACTIVATION_TYPE_EXTERNAL);
+ if ( priv->activation_type == NM_ACTIVATION_TYPE_MANAGED
+ && priv->device
+ && self == NM_ACTIVE_CONNECTION (nm_device_get_act_request (priv->device))
+ && NM_IN_SET (nm_device_sys_iface_state_get (priv->device),
+ NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
+ NM_DEVICE_SYS_IFACE_STATE_ASSUME))
+ nm_device_sys_iface_state_set (priv->device, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
}
/*****************************************************************************/
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index 15f69733da..ba231c3077 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -159,8 +159,6 @@ void nm_active_connection_set_master (NMActiveConnection *self,
void nm_active_connection_set_parent (NMActiveConnection *self,
NMActiveConnection *parent);
-gboolean nm_active_connection_has_activation_type_assume_or_external (NMActiveConnection *self);
-
NMActivationType nm_active_connection_get_activation_type (NMActiveConnection *self);
void nm_active_connection_clear_secrets (NMActiveConnection *self);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 0cd534f15f..649f8464fd 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -815,13 +815,17 @@ find_best_device_state (NMManager *manager, gboolean *force_connectivity_check)
}
break;
case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
- if (!nm_active_connection_has_activation_type_assume_or_external (ac)) {
+ if (!NM_IN_SET (nm_active_connection_get_activation_type (ac),
+ NM_ACTIVATION_TYPE_EXTERNAL,
+ NM_ACTIVATION_TYPE_ASSUME)) {
if (best_state != NM_STATE_CONNECTED_GLOBAL)
best_state = NM_STATE_CONNECTING;
}
break;
case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
- if (!nm_active_connection_has_activation_type_assume_or_external (ac)) {
+ if (!NM_IN_SET (nm_active_connection_get_activation_type (ac),
+ NM_ACTIVATION_TYPE_EXTERNAL,
+ NM_ACTIVATION_TYPE_ASSUME)) {
if (best_state < NM_STATE_DISCONNECTING)
best_state = NM_STATE_DISCONNECTING;
}
@@ -1034,8 +1038,10 @@ remove_device (NMManager *self,
if (unmanage) {
if (quitting)
nm_device_set_unmanaged_by_quitting (device);
- else
+ else {
+ nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
+ }
} else if (quitting && nm_config_get_configure_and_quit (priv->config)) {
nm_device_spawn_iface_helper (device);
}
@@ -1854,6 +1860,9 @@ recheck_assume_connection (NMManager *self,
if (state > NM_DEVICE_STATE_DISCONNECTED)
return FALSE;
+ if (nm_device_sys_iface_state_get (device) != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
+ return FALSE;
+
connection = get_existing_connection (self, device, assume_connection_uuid, &generated);
if (!connection) {
_LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
@@ -1864,6 +1873,9 @@ recheck_assume_connection (NMManager *self,
_LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
nm_device_get_iface (device));
+ if (!generated)
+ nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+
/* Move device to DISCONNECTED to activate the connection */
if (state == NM_DEVICE_STATE_UNMANAGED) {
was_unmanaged = TRUE;
@@ -1908,6 +1920,9 @@ recheck_assume_connection (NMManager *self,
nm_device_get_iface (device));
nm_settings_connection_delete (connection, NULL, NULL);
+ } else {
+ if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
+ nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
}
return FALSE;
}