diff options
| author | Thomas Haller <thaller@redhat.com> | 2017-03-01 17:31:52 +0100 |
|---|---|---|
| committer | Thomas Haller <thaller@redhat.com> | 2017-03-08 16:07:54 +0100 |
| commit | 3111912e63fa74d70fb0b5ceb2feb50dd63da1cb (patch) | |
| tree | 33e86f19532b6b7f52878227504924f525399a87 | |
| parent | 8eaa40dbb0e12ed6cf09a5985768c1e8247d0377 (diff) | |
| download | NetworkManager-3111912e63fa74d70fb0b5ceb2feb50dd63da1cb.tar.gz | |
WIP: device: change assuming connections behavior and keep external devices unmanaged (bgo#746440)th/assume-vs-unmanaged-bgo746440-2
Until now, NetworkManager tries to "assume" connections on externally
configured devices.
This behavior is fundamentally wrong because "assuming" has two
contradicting meanings:
a) for one, it means not to touch externally configured devices that
are not supposed to be managed by NetworkManager. NetworkManager goes
through great lengths trying not to mess with such devices, most
notably software devices like a bridge. NetworkManager does this, to
present the interface as up and configured, although this is a
pretend-only mode and the device is not managed by NetworkManager.
b) it also has the meaning during restart, where NetworkManager leaves
interfaces up during exit and tries to take them over on start. In
this case, NetworkManager wants to manage the device, but it wants to
take it over non-destructively, without breaking connectivity.
These are fundamentally different things, because for a) NetworkManager should
not touch the interface at all, while for b) it very much should touch it,
for example to extend DHCP leases and renew addresses.
Until now, this was done by generating an in-memory connection and trying to
match it to any of it's existing setting profiles. If a match is found, that
connection will be assumed, otherwise the generated connection is added as
in-memory connection.
Other then that, there is little difference between whether
NetworkManager is able to match an existing connection or whether
it uses the generated connections. In some cases it affects whether
to lean more towards behavior a) or b). But of courese, the match itself
is only a guess and NetworkManager doesn't make up it's mind whether it wants
to manage the device or not.
Fix that. Now, NetworkManager decides early what to do and whether to manage
the device (b) or not (a). For one, NetworkManager will store the state of the
devices during exit in /var/run/NetworkManager/devices. Thus, after a restart,
NetworkManager knows whether it managed the device before or not. In case
NetworkManager is started the first time since boot, the decision is made
based on user-configuration, UDEV, and default behaviors. Default behaviors
are for example that existing software devices are unmanaged by default,
while real devices default to be managed.
Therefore, the case a), really becomes having external devices as unmanaged.
NetworkManager will no longer pretend a connection is active. This for
example means that no dispatcher events will run for previously assumed
devices. Such a pretend-only, active state could be reintroduced later.
If NetworkManager decides to manage the device (b), it will now move
the device through states unavailable/disconnected, and eventually
autoconnect will start as usual. The graceful take-over is done
only when the run-state file indicates a connection that was active
previously on the device. In that case, NetworkManager will assume
that connection. But once full activation state is reached, an assumed
connection is not any different from a regular
activation/autoactivation.
This of course changes existing behavior in many ways. This is only
a first commit, surely there are many follow up issues.
A lot of code becames now unused. This will be removed in later commits
to keep the diff smaller.
https://bugzilla.gnome.org/show_bug.cgi?id=746440
https://bugzilla.redhat.com/show_bug.cgi?id=1394579
| -rw-r--r-- | man/NetworkManager.conf.xml | 14 | ||||
| -rw-r--r-- | src/devices/nm-device-private.h | 1 | ||||
| -rw-r--r-- | src/devices/nm-device-vlan.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device.c | 359 | ||||
| -rw-r--r-- | src/devices/nm-device.h | 7 | ||||
| -rw-r--r-- | src/devices/team/nm-device-team.c | 3 | ||||
| -rw-r--r-- | src/nm-active-connection.c | 81 | ||||
| -rw-r--r-- | src/nm-active-connection.h | 2 | ||||
| -rw-r--r-- | src/nm-config-data.c | 12 | ||||
| -rw-r--r-- | src/nm-config-data.h | 1 | ||||
| -rw-r--r-- | src/nm-dispatcher.c | 206 | ||||
| -rw-r--r-- | src/nm-manager.c | 259 | ||||
| -rw-r--r-- | src/nm-policy.c | 109 | ||||
| -rw-r--r-- | src/nm-types.h | 5 | ||||
| -rw-r--r-- | src/settings/nm-settings-connection.h | 1 |
15 files changed, 309 insertions, 753 deletions
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 7ca496bfb0..4dbb8abfad 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -239,20 +239,6 @@ no-auto-default=* </varlistentry> <varlistentry> - <term><varname>assume-ipv6ll-only</varname></term> - <listitem> - <para> - Specify devices for which NetworkManager will try to - generate a connection based on initial configuration when - the device only has an IPv6 link-local address. - </para> - <para>See <xref linkend="device-spec"/> for the syntax how to - specify a device. - </para> - </listitem> - </varlistentry> - - <varlistentry> <term><varname>configure-and-quit</varname></term> <listitem> <para> diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index a4067f9c26..b4fffc96b6 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -100,7 +100,6 @@ void nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave void nm_device_set_carrier (NMDevice *self, gboolean carrier); -void nm_device_queue_recheck_assume (NMDevice *device); void nm_device_queue_recheck_available (NMDevice *device, NMDeviceStateReason available_reason, NMDeviceStateReason unavailable_reason); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 3cef73d3f9..d9379ecaff 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -96,7 +96,7 @@ parent_hwaddr_maybe_changed (NMDevice *parent, NMSettingIPConfig *s_ip6; /* Never touch assumed devices */ - if (nm_device_has_activation_type_assume_or_external ((NMDevice *) self)) + if (nm_device_is_assuming ((NMDevice *) self)) return; connection = nm_device_get_applied_connection ((NMDevice *) self); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 26a1216f4f..d88587dd18 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -142,7 +142,6 @@ enum { IP6_SUBNET_NEEDED, REMOVED, RECHECK_AUTO_ACTIVATE, - RECHECK_ASSUME, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -212,6 +211,11 @@ typedef struct _NMDevicePrivate { GSList *pending_actions; GSList *dad6_failed_addrs; + /* The connection-uuid we preferrably try to autoactivate in a non-destructive way + * (that is: assuming the connection). This ID is only used between moving the + * device from UNMANAGED to UNAVAILABLE, before creating the active-connection. */ + char *next_activation_connection_uuid; + NMDevice *parent_device; char * udi; @@ -274,7 +278,6 @@ typedef struct _NMDevicePrivate { gulong act_request_id; ActivationHandleData act_handle4; /* for layer2 and IPv4. */ ActivationHandleData act_handle6; - guint recheck_assume_id; struct { guint call_id; NMDeviceStateReason available_reason; @@ -1596,25 +1599,22 @@ nm_device_get_physical_port_id (NMDevice *self) /*****************************************************************************/ -static gboolean -nm_device_has_activation_type_external (NMDevice *self) +gboolean +nm_device_is_assuming (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; - return priv->act_request - && NM_IN_SET (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)), - NM_ACTIVATION_TYPE_EXTERNAL); -} + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); -gboolean -nm_device_has_activation_type_assume_or_external (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->next_activation_connection_uuid) + return TRUE; 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); + && priv->state > NM_DEVICE_STATE_DISCONNECTED + && priv->state < NM_DEVICE_STATE_ACTIVATED + && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_ASSUME; } static SlaveInfo * @@ -1972,12 +1972,12 @@ device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink) if ( plink->master > 0 && plink->master == nm_device_get_ifindex (priv->master)) { /* call add-slave again. We expect @self already to be added to - * the master, but this also triggers a recheck-assume. */ + * the master. */ nm_device_master_add_slave (priv->master, self, FALSE); return; } - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); } if (plink->master > 0) { NMDevice *master; @@ -2615,6 +2615,9 @@ realize_start_setup (NMDevice *self, nm_device_set_unmanaged_by_user_udev (self); + if (plink && plink->master > 0) + nm_device_set_unmanaged_flags (self, NM_UNMANAGED_IS_SLAVE, TRUE); + nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT, plink && !plink->initialized); } @@ -2910,7 +2913,7 @@ slave_state_changed (NMDevice *slave, } /* Don't touch the device if its state changed externally. */ - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) + if (nm_device_is_assuming (self)) configure = FALSE; if (release) { @@ -2940,7 +2943,6 @@ nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) NMDevicePrivate *priv; NMDevicePrivate *slave_priv; SlaveInfo *info; - gboolean changed = FALSE; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); @@ -2977,16 +2979,13 @@ nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) * because slave_priv->is_enslaved is not true, thus the value * didn't change yet. */ - g_warn_if_fail (!NM_FLAGS_HAS (slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE)); - nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - changed = TRUE; - } else + if (nm_device_get_managed (self, FALSE)) + nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_NONE); + return TRUE; + } else { g_return_val_if_fail (slave_priv->master == self, FALSE); - - nm_device_queue_recheck_assume (self); - nm_device_queue_recheck_assume (slave); - - return changed; + return FALSE; + } } /** @@ -3079,10 +3078,6 @@ nm_device_master_release_slaves (NMDevice *self) NMDeviceStateReason reason; gboolean configure = TRUE; - /* Don't release the slaves if this connection doesn't belong to NM. */ - if (nm_device_has_activation_type_external (self)) - return; - reason = priv->state_reason; if (priv->state == NM_DEVICE_STATE_FAILED) reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; @@ -3173,8 +3168,7 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success) nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE); else nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); - } else - nm_device_queue_recheck_assume (self); + } } /** @@ -3261,7 +3255,7 @@ nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config) if (priv->master) { /* this is called when something externally messes with the slave or during shut-down. * Release the slave from master, but don't touch the device. */ - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); } if (!unconfigure_ip_config) @@ -3673,11 +3667,9 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) && g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0 && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con)) - && !priv->slaves - && !nm_config_data_get_assume_ipv6ll_only (NM_CONFIG_GET_DATA, self)) { + && !priv->slaves) { _LOGD (LOGD_DEVICE, "ignoring generated connection (IPv6LL-only and not in master-slave relationship)"); - g_object_unref (connection); - connection = NULL; + g_clear_object (&connection); } return connection; @@ -3785,86 +3777,50 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave return strcmp (connection_type, slave_type) == 0; } -/** - * nm_device_can_assume_connections: - * @self: #NMDevice instance - * - * This is a convenience function to determine whether connection assumption - * is available for this device. - * - * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not - */ -static gboolean -nm_device_can_assume_connections (NMDevice *self) -{ - return !!NM_DEVICE_GET_CLASS (self)->update_connection; -} - -static gboolean -unmanaged_on_quit (NMDevice *self) +void +nm_device_next_activation_store (NMDevice *self, + char *connection_uuid) { - NMConnection *connection; - - /* NMDeviceWifi overwrites this function to always unmanage wifi devices. - * - * For all other types, if the device type can assume connections, we leave - * it up on quit. - * - * Originally, we would only keep devices up that can be assumed afterwards. - * However, that meant we unmanged layer-2 only devices. So, this was step - * by step refined to unmanage less (commit 25aaaab3, rh#1311988, rh#1333983). - * But there are more scenarios where we also want to keep the device up - * (rh#1378418, rh#1371126). */ - if (!nm_device_can_assume_connections (self)) - return TRUE; + NMDevicePrivate *priv; - /* the only exception are IPv4 shared connections. We unmanage them on quit. */ - connection = nm_device_get_applied_connection (self); - if (connection) { - if (NM_IN_STRSET (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - /* shared connections are to be unmangaed. */ - return TRUE; - } - } + g_return_if_fail (NM_IS_DEVICE (self)); - return FALSE; -} + priv = NM_DEVICE_GET_PRIVATE (self); -gboolean -nm_device_unmanage_on_quit (NMDevice *self) -{ - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_free (priv->next_activation_connection_uuid); + priv->next_activation_connection_uuid = connection_uuid; - return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self); + if (connection_uuid) + _LOGD (LOGD_DEVICE, "next-activation: store %s", connection_uuid); } -static gboolean -nm_device_emit_recheck_assume (gpointer user_data) +char * +nm_device_next_activation_retrieve (NMDevice *self) { - NMDevice *self = user_data; NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); priv = NM_DEVICE_GET_PRIVATE (self); - priv->recheck_assume_id = 0; - if (!nm_device_get_act_request (self)) { - _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal"); - g_signal_emit (self, signals[RECHECK_ASSUME], 0); - } - return G_SOURCE_REMOVE; + if (priv->next_activation_connection_uuid) + _LOGD (LOGD_DEVICE, "next-activation: retrieve %s", priv->next_activation_connection_uuid); + + return g_steal_pointer (&priv->next_activation_connection_uuid); } -void -nm_device_queue_recheck_assume (NMDevice *self) +static gboolean +unmanaged_on_quit (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + return FALSE; +} + +gboolean +nm_device_unmanage_on_quit (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - if ( !priv->recheck_assume_id - && nm_device_can_assume_connections (self)) - priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self); + return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self); } static gboolean @@ -3878,7 +3834,10 @@ recheck_available (gpointer user_data) priv->recheck_available.call_id = 0; - now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); + now_available = nm_device_is_available (self, + priv->next_activation_connection_uuid + ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST + : NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) { new_state = NM_DEVICE_STATE_DISCONNECTED; @@ -4113,12 +4072,12 @@ master_ready (NMDevice *self, nm_device_get_iface (master)); if (priv->master && priv->master != master) - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); - /* If the master didn't change, add-slave only rechecks whether to assume a connection. */ + /* If the master didn't change, add-slave doesn't do anything. */ nm_device_master_add_slave (master, self, - nm_active_connection_has_activation_type_assume_or_external (active) ? FALSE : TRUE); + !nm_device_is_assuming (self)); } static void @@ -4186,7 +4145,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); @@ -4198,7 +4156,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_is_assuming (self)) { NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &failure_reason); @@ -4253,13 +4211,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_is_assuming (self)) { NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; if (!nm_device_bring_up (self, FALSE, &no_firmware)) { @@ -4287,9 +4244,6 @@ 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) - && slave_state <= NM_DEVICE_STATE_DISCONNECTED) - nm_device_queue_recheck_assume (info->slave); } if (lldp_rx_enabled (self) && priv->ifindex > 0) { @@ -4412,7 +4366,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_is_assuming (self)) { /* We have assumed configuration, but couldn't redo it. No problem, * move to check state. */ _set_ip_state (self, AF_INET, IP_DONE); @@ -4604,7 +4558,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_is_assuming (self)) { /* DAD not needed, signal success */ cb (self, configs, TRUE); @@ -4905,8 +4859,8 @@ 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)) { - /* For assumed connections ignore all addresses and routes. */ + if (nm_device_is_assuming (self)) { + /* For assuming ignore all addresses and routes. */ nm_ip4_config_reset_addresses (priv->con_ip4_config); nm_ip4_config_reset_routes (priv->con_ip4_config); } @@ -4931,8 +4885,8 @@ 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)) { - /* For assumed connections ignore all addresses and routes. */ + if (nm_device_is_assuming (self)) { + /* For assuming ignore all addresses and routes. */ nm_ip6_config_reset_addresses (priv->con_ip6_config); nm_ip6_config_reset_routes (priv->con_ip6_config); } @@ -5068,13 +5022,6 @@ ip4_config_merge_and_apply (NMDevice *self, goto END_ADD_DEFAULT_ROUTE; } - /* a generated-assumed connection detects the default route from the platform, - * 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) - goto END_ADD_DEFAULT_ROUTE; - /* At this point, we treat assumed and non-assumed connections alike. * For assumed connections we do that because we still manage RA and DHCP * leases for them, so we must extend/update the default route on commits. @@ -5148,7 +5095,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_is_assuming (self); success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync); g_object_unref (composite); @@ -5221,7 +5168,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_is_assuming (self)) { dhcp_schedule_restart (self, AF_INET, "connection is assumed"); return; } @@ -5813,13 +5760,6 @@ ip6_config_merge_and_apply (NMDevice *self, goto END_ADD_DEFAULT_ROUTE; } - /* a generated-assumed connection detects the default route from the platform, - * 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) - goto END_ADD_DEFAULT_ROUTE; - /* At this point, we treat assumed and non-assumed connections alike. * For assumed connections we do that because we still manage RA and DHCP * leases for them, so we must extend/update the default route on commits. @@ -5899,7 +5839,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_is_assuming (self); success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync); g_object_unref (composite); @@ -6013,7 +5953,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_is_assuming (self)) { dhcp_schedule_restart (self, AF_INET6, "connection is assumed"); return; } @@ -6595,7 +6535,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_is_assuming (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; @@ -7262,7 +7202,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_is_assuming (self)) set_nm_ipv6ll (self, TRUE); /* Re-enable IPv6 on the interface */ @@ -7292,7 +7232,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_is_assuming (self)) { switch (ip6_privacy) { case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: @@ -7535,22 +7475,18 @@ 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)) - priv->fw_ready = TRUE; - else { - if (!priv->fw_call) { - zone = nm_setting_connection_get_zone (s_con); - - _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default"); - priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), - nm_device_get_ip_iface (self), - zone, - FALSE, - fw_change_zone_cb_stage2, - self); - } - return; + if (!priv->fw_call) { + zone = nm_setting_connection_get_zone (s_con); + + _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default"); + priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), + nm_device_get_ip_iface (self), + zone, + FALSE, + fw_change_zone_cb_stage2, + self); } + return; } activation_source_schedule (self, activate_stage3_ip_config_start, AF_INET); @@ -7837,7 +7773,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_is_assuming (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)); @@ -7986,7 +7922,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_is_assuming (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)); @@ -8942,9 +8878,10 @@ _device_activate (NMDevice *self, NMActRequest *req) connection = nm_act_request_get_applied_connection (req); g_assert (connection); - _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)", + _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)%s", nm_connection_get_id (connection), - nm_connection_get_uuid (connection)); + nm_connection_get_uuid (connection), + nm_device_is_assuming (self) ? " (assuming)" : ""); delete_on_deactivate_unschedule (self); @@ -9188,7 +9125,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_is_assuming (self); _commit_mtu (self, new_config); /* For assumed devices we must not touch the kernel-routes, such as the device-route. @@ -9238,21 +9175,6 @@ 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)) { - NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self)); - NMSetting *s_ip4; - - g_object_freeze_notify (G_OBJECT (settings_connection)); - - nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP4_CONFIG); - s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); - nm_connection_add_setting (settings_connection, s_ip4); - - g_object_thaw_notify (G_OBJECT (settings_connection)); - } - - nm_device_queue_recheck_assume (self); } return success; @@ -9393,21 +9315,6 @@ 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)) { - NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self)); - NMSetting *s_ip6; - - g_object_freeze_notify (G_OBJECT (settings_connection)); - - nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP6_CONFIG); - s_ip6 = nm_ip6_config_create_setting (priv->ip6_config); - nm_connection_add_setting (settings_connection, s_ip6); - - g_object_thaw_notify (G_OBJECT (settings_connection)); - } - - nm_device_queue_recheck_assume (self); - if (priv->ndisc) ndisc_set_router_config (priv->ndisc, self); } @@ -10854,9 +10761,8 @@ nm_device_update_firewall_zone (NMDevice *self) if (!applied_connection) return; - 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)) { + if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) { + s_con = nm_connection_get_setting_connection (applied_connection); nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (self), nm_setting_connection_get_zone (s_con), @@ -11347,8 +11253,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)) { + && connection) { nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (self), NULL, @@ -11479,7 +11384,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean /* slave: mark no longer enslaved */ if ( priv->master && nm_platform_link_get_master (NM_PLATFORM_GET, priv->ifindex) <= 0) - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); /* Take out any entries in the routing table and any IP address the device had. */ ifindex = nm_device_get_ip_ifindex (self); @@ -11572,8 +11477,6 @@ nm_device_spawn_iface_helper (NMDevice *self) if (priv->state != NM_DEVICE_STATE_ACTIVATED) return; - if (!nm_device_can_assume_connections (self)) - return; connection = nm_device_get_applied_connection (self); g_assert (connection); @@ -11830,6 +11733,9 @@ _set_state_full (NMDevice *self, old_state = priv->state; + if (state > NM_DEVICE_STATE_DISCONNECTED) + g_free (nm_device_next_activation_retrieve (self)); + /* Do nothing if state isn't changing, but as a special case allow * re-setting UNAVAILABLE if the device is missing firmware so that we * can retry device initialization. @@ -11893,14 +11799,9 @@ _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: + if (nm_device_state_reason_check (reason) == 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: + 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); @@ -11908,18 +11809,17 @@ _set_state_full (NMDevice *self, nm_device_hw_addr_reset (self, "unmanage"); set_nm_ipv6ll (self, FALSE); restore_ip6_properties (self); - break; } } break; 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 (!nm_device_is_assuming (self)) ip6_managed_setup (self); } - if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + if (!nm_device_is_assuming (self)) { 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."); @@ -11946,7 +11846,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 (!nm_device_is_assuming (self)) { /* Ensure IPv6 is set up as it may not have been done when * entering the UNAVAILABLE state depending on the reason. */ @@ -11989,12 +11889,16 @@ _set_state_full (NMDevice *self, * we can't change states again from the state handler for a variety of * reasons. */ - if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { + if (nm_device_is_available (self, + priv->next_activation_connection_uuid + ? NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST + : NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { nm_device_queue_recheck_available (self, NM_DEVICE_STATE_REASON_NONE, NM_DEVICE_STATE_REASON_NONE); } else { _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED"); + g_free (nm_device_next_activation_retrieve (self)); } break; case NM_DEVICE_STATE_DEACTIVATING: @@ -12064,14 +11968,6 @@ _set_state_full (NMDevice *self, */ _cancel_activation (self); - if (nm_device_has_activation_type_assume_or_external (self)) { - /* Avoid tearing down assumed connection, assume it's connected */ - nm_device_queue_state (self, - NM_DEVICE_STATE_ACTIVATED, - NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - break; - } - connection = nm_device_get_settings_connection (self); _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: failed for connection '%s'", @@ -12101,8 +11997,7 @@ _set_state_full (NMDevice *self, applied_connection = nm_device_get_applied_connection (self); if ( applied_connection - && priv->ifindex != priv->ip_ifindex - && !nm_device_has_activation_type_external (self)) { + && priv->ifindex != priv->ip_ifindex) { NMSettingConnection *s_con; const char *zone; @@ -13182,7 +13077,6 @@ dispose (GObject *object) g_hash_table_remove_all (priv->ip6_saved_properties); - nm_clear_g_source (&priv->recheck_assume_id); nm_clear_g_source (&priv->recheck_available.call_id); nm_clear_g_source (&priv->check_delete_unrealized_id); @@ -13254,6 +13148,8 @@ finalize (GObject *object) g_free (priv->dhcp_anycast_address); g_free (priv->current_stable_id); + g_free (priv->next_activation_connection_uuid); + g_hash_table_unref (priv->ip6_saved_properties); g_hash_table_unref (priv->available_connections); @@ -13301,18 +13197,10 @@ set_property (GObject *object, guint prop_id, break; case PROP_MANAGED: if (nm_device_is_real (self)) { - gboolean managed; - NMDeviceStateReason reason; - - managed = g_value_get_boolean (value); - if (managed) - reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; - else - reason = NM_DEVICE_STATE_REASON_REMOVED; nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_USER_EXPLICIT, - !managed, - reason); + !g_value_get_boolean (value), + NM_DEVICE_STATE_REASON_USER_REQUESTED); } break; case PROP_AUTOCONNECT: @@ -13873,13 +13761,6 @@ nm_device_class_init (NMDeviceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - signals[RECHECK_ASSUME] = - g_signal_new (NM_DEVICE_RECHECK_ASSUME, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), NMDBUS_TYPE_DEVICE_SKELETON, "Reapply", impl_device_reapply, diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 78ffe166aa..034827646a 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -119,7 +119,6 @@ nm_device_state_reason_check (NMDeviceStateReason reason) #define NM_DEVICE_IP6_SUBNET_NEEDED "ip6-subnet-needed" #define NM_DEVICE_REMOVED "removed" #define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate" -#define NM_DEVICE_RECHECK_ASSUME "recheck-assume" #define NM_DEVICE_STATE_CHANGED "state-changed" #define NM_DEVICE_LINK_INITIALIZED "link-initialized" #define NM_DEVICE_AUTOCONNECT_ALLOWED "autoconnect-allowed" @@ -488,7 +487,11 @@ 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); +void nm_device_next_activation_store (NMDevice *self, + char *connection_uuid); +char *nm_device_next_activation_retrieve (NMDevice *self); + +gboolean nm_device_is_assuming (NMDevice *device); gboolean nm_device_unmanage_on_quit (NMDevice *self); diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index d7cbd3660e..f94bc1966d 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -372,7 +372,6 @@ teamd_dbus_appeared (GDBusConnection *connection, g_return_if_fail (priv->teamd_dbus_watch); _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); - nm_device_queue_recheck_assume (device); /* If another teamd grabbed the bus name while our teamd was starting, * just ignore the death of our teamd and run with the existing one. @@ -416,7 +415,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_is_assuming (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 4181607f39..3a12547a4c 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -49,12 +49,12 @@ typedef struct _NMActiveConnectionPrivate { bool is_default6:1; bool state_set:1; bool vpn:1; - bool master_ready:1; /* TODO: when the user updates a connection with an extern activation * type, the activation type must be updated to FULL. */ NMActivationType activation_type:3; + bool master_ready:1; NMAuthSubject *subject; NMActiveConnection *master; @@ -105,13 +105,8 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT #define NM_ACTIVE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMActiveConnection, NM_IS_ACTIVE_CONNECTION) -/*****************************************************************************/ - static void check_master_ready (NMActiveConnection *self); static void _device_cleanup (NMActiveConnection *self); -static void _settings_connection_notify_flags (NMSettingsConnection *settings_connection, - GParamSpec *param, - NMActiveConnection *self); /*****************************************************************************/ @@ -189,15 +184,12 @@ _set_settings_connection (NMActiveConnection *self, NMSettingsConnection *connec if (priv->settings_connection) { g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_updated, self); g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_removed, self); - g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_notify_flags, self); g_clear_object (&priv->settings_connection); } if (connection) { priv->settings_connection = g_object_ref (connection); g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self); g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, (GCallback) _settings_connection_removed, self); - if (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL) - g_signal_connect (connection, "notify::"NM_SETTINGS_CONNECTION_FLAGS, (GCallback) _settings_connection_notify_flags, self); } } @@ -225,14 +217,6 @@ nm_active_connection_set_state (NMActiveConnection *self, state_to_string (new_state), state_to_string (priv->state)); - if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED - && priv->activation_type == NM_ACTIVATION_TYPE_ASSUME) { - /* assuming connections mean to gracefully take over an externally - * configured device. Once activation is complete, an assumed - * activation *is* the same as a full activation. */ - _set_activation_type (self, NM_ACTIVATION_TYPE_FULL); - } - old_state = priv->state; priv->state = new_state; priv->state_set = TRUE; @@ -585,10 +569,8 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device) g_signal_connect (device, "notify::" NM_DEVICE_METERED, G_CALLBACK (device_metered_changed), self); - if (priv->activation_type != NM_ACTIVATION_TYPE_EXTERNAL) { - priv->pending_activation_id = g_strdup_printf (NM_PENDING_ACTIONPREFIX_ACTIVATION"%p", (void *)self); - nm_device_add_pending_action (device, priv->pending_activation_id, TRUE); - } + priv->pending_activation_id = g_strdup_printf (NM_PENDING_ACTIONPREFIX_ACTIVATION"%p", (void *)self); + nm_device_add_pending_action (device, priv->pending_activation_id, TRUE); } else { /* The ActiveConnection's device can only be cleared after the * connection is activated. @@ -731,6 +713,8 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m check_master_ready (self); } +/*****************************************************************************/ + NMActivationType nm_active_connection_get_activation_type (NMActiveConnection *self) { @@ -739,49 +723,6 @@ nm_active_connection_get_activation_type (NMActiveConnection *self) return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->activation_type; } -static void -_set_activation_type (NMActiveConnection *self, - NMActivationType activation_type) -{ - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); - - if (priv->activation_type == activation_type) - return; - - _LOGD ("update activation type from %s to %s", - 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); -} - -/*****************************************************************************/ - -static void -_settings_connection_notify_flags (NMSettingsConnection *settings_connection, - GParamSpec *param, - NMActiveConnection *self) -{ - nm_assert (NM_IS_ACTIVE_CONNECTION (self)); - nm_assert (NM_IS_SETTINGS_CONNECTION (settings_connection)); - nm_assert (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL); - nm_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection == settings_connection); - - if (nm_settings_connection_get_nm_generated (settings_connection)) - return; - - g_signal_handlers_disconnect_by_func (settings_connection, _settings_connection_notify_flags, self); - _set_activation_type (self, NM_ACTIVATION_TYPE_FULL); - nm_device_reapply_settings_immediately (nm_active_connection_get_device (self)); -} - /*****************************************************************************/ static void unwatch_parent (NMActiveConnection *self, gboolean unref); @@ -1136,9 +1077,7 @@ set_property (GObject *object, guint prop_id, case PROP_INT_ACTIVATION_TYPE: /* construct-only */ i = g_value_get_int (value); - if (!NM_IN_SET (i, NM_ACTIVATION_TYPE_FULL, - NM_ACTIVATION_TYPE_ASSUME, - NM_ACTIVATION_TYPE_EXTERNAL)) + if (!NM_IN_SET (i, NM_ACTIVATION_TYPE_FULL, NM_ACTIVATION_TYPE_ASSUME)) g_return_if_reached (); priv->activation_type = (NMActivationType) i; break; @@ -1189,8 +1128,10 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); - if (!priv->applied_connection && priv->settings_connection) - priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection)); + if (!priv->applied_connection && priv->settings_connection) { + priv->applied_connection = + nm_simple_connection_new_clone ((NMConnection *) priv->settings_connection); + } if (priv->applied_connection) nm_connection_clear_secrets (priv->applied_connection); @@ -1386,7 +1327,7 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) obj_properties[PROP_INT_ACTIVATION_TYPE] = g_param_spec_int (NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, "", "", NM_ACTIVATION_TYPE_FULL, - NM_ACTIVATION_TYPE_EXTERNAL, + NM_ACTIVATION_TYPE_ASSUME, NM_ACTIVATION_TYPE_FULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | 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-config-data.c b/src/nm-config-data.c index a49a3bad97..275c035355 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -100,7 +100,6 @@ typedef struct { } no_auto_default; GSList *ignore_carrier; - GSList *assume_ipv6ll_only; char *dns_mode; char *rc_manager; @@ -315,15 +314,6 @@ nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device) return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier); } -gboolean -nm_config_data_get_assume_ipv6ll_only (const NMConfigData *self, NMDevice *device) -{ - g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE); - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->assume_ipv6ll_only); -} - GKeyFile * nm_config_data_clone_keyfile_intern (const NMConfigData *self) { @@ -1525,7 +1515,6 @@ constructed (GObject *object) priv->rc_manager = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NULL)); priv->ignore_carrier = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier", NULL); - priv->assume_ipv6ll_only = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only", NULL); priv->no_auto_default.specs_config = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "no-auto-default", NULL); @@ -1600,7 +1589,6 @@ finalize (GObject *gobject) g_free (priv->rc_manager); g_slist_free_full (priv->ignore_carrier, g_free); - g_slist_free_full (priv->assume_ipv6ll_only, g_free); nm_global_dns_config_free (priv->global_dns); diff --git a/src/nm-config-data.h b/src/nm-config-data.h index d7d14a61e9..8c1366586b 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -170,7 +170,6 @@ const char *nm_config_data_get_dns_mode (const NMConfigData *self); const char *nm_config_data_get_rc_manager (const NMConfigData *self); gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device); -gboolean nm_config_data_get_assume_ipv6ll_only (const NMConfigData *self, NMDevice *device); NMGlobalDnsConfig *nm_config_data_get_global_dns_config (const NMConfigData *self); char *nm_config_data_get_connection_default (const NMConfigData *self, diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index f344b4b893..7fab095f51 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -21,16 +21,14 @@ #include "nm-default.h" -#include "nm-dispatcher.h" - #include <string.h> #include <errno.h> +#include "nm-dispatcher.h" #include "nm-dispatcher-api.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-connectivity.h" -#include "nm-act-request.h" #include "devices/nm-device.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" @@ -72,14 +70,14 @@ static Monitor monitors[3] = { }; static const Monitor* -_get_monitor_by_action (NMDispatcherAction action) +_get_monitor_by_action (DispatcherAction action) { switch (action) { - case NM_DISPATCHER_ACTION_PRE_UP: - case NM_DISPATCHER_ACTION_VPN_PRE_UP: + case DISPATCHER_ACTION_PRE_UP: + case DISPATCHER_ACTION_VPN_PRE_UP: return &monitors[MONITOR_INDEX_PRE_UP]; - case NM_DISPATCHER_ACTION_PRE_DOWN: - case NM_DISPATCHER_ACTION_VPN_PRE_DOWN: + case DISPATCHER_ACTION_PRE_DOWN: + case DISPATCHER_ACTION_VPN_PRE_DOWN: return &monitors[MONITOR_INDEX_PRE_DOWN]; default: return &monitors[MONITOR_INDEX_DEFAULT]; @@ -313,9 +311,9 @@ fill_vpn_props (NMProxyConfig *proxy_config, } typedef struct { - NMDispatcherAction action; + DispatcherAction action; guint request_id; - NMDispatcherFunc callback; + DispatcherFunc callback; gpointer user_data; guint idle_id; } DispatchInfo; @@ -364,7 +362,7 @@ dispatch_result_to_string (DispatchResult result) } static void -dispatcher_results_process (guint request_id, NMDispatcherAction action, GVariantIter *results) +dispatcher_results_process (guint request_id, DispatcherAction action, GVariantIter *results) { const char *script, *err; guint32 result; @@ -442,22 +440,22 @@ dispatcher_done_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) } static const char *action_table[] = { - [NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ACTION_HOSTNAME, - [NM_DISPATCHER_ACTION_PRE_UP] = NMD_ACTION_PRE_UP, - [NM_DISPATCHER_ACTION_UP] = NMD_ACTION_UP, - [NM_DISPATCHER_ACTION_PRE_DOWN] = NMD_ACTION_PRE_DOWN, - [NM_DISPATCHER_ACTION_DOWN] = NMD_ACTION_DOWN, - [NM_DISPATCHER_ACTION_VPN_PRE_UP] = NMD_ACTION_VPN_PRE_UP, - [NM_DISPATCHER_ACTION_VPN_UP] = NMD_ACTION_VPN_UP, - [NM_DISPATCHER_ACTION_VPN_PRE_DOWN] = NMD_ACTION_VPN_PRE_DOWN, - [NM_DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN, - [NM_DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE, - [NM_DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE, - [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE + [DISPATCHER_ACTION_HOSTNAME] = NMD_ACTION_HOSTNAME, + [DISPATCHER_ACTION_PRE_UP] = NMD_ACTION_PRE_UP, + [DISPATCHER_ACTION_UP] = NMD_ACTION_UP, + [DISPATCHER_ACTION_PRE_DOWN] = NMD_ACTION_PRE_DOWN, + [DISPATCHER_ACTION_DOWN] = NMD_ACTION_DOWN, + [DISPATCHER_ACTION_VPN_PRE_UP] = NMD_ACTION_VPN_PRE_UP, + [DISPATCHER_ACTION_VPN_UP] = NMD_ACTION_VPN_UP, + [DISPATCHER_ACTION_VPN_PRE_DOWN] = NMD_ACTION_VPN_PRE_DOWN, + [DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN, + [DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE, + [DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE, + [DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE }; static const char * -action_to_string (NMDispatcherAction action) +action_to_string (DispatcherAction action) { g_assert ((gsize) action < G_N_ELEMENTS (action_table)); return action_table[action]; @@ -476,18 +474,17 @@ dispatcher_idle_cb (gpointer user_data) } static gboolean -_dispatcher_call (NMDispatcherAction action, +_dispatcher_call (DispatcherAction action, gboolean blocking, - NMDevice *device, NMSettingsConnection *settings_connection, NMConnection *applied_connection, - gboolean activation_type_external, + NMDevice *device, NMConnectivityState connectivity_state, const char *vpn_iface, NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, - NMDispatcherFunc callback, + DispatcherFunc callback, gpointer user_data, guint *out_call_id) { @@ -520,8 +517,8 @@ _dispatcher_call (NMDispatcherAction action, _ensure_requests (); /* All actions except 'hostname' and 'connectivity-change' require a device */ - if ( action == NM_DISPATCHER_ACTION_HOSTNAME - || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + if ( action == DISPATCHER_ACTION_HOSTNAME + || action == DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { _LOGD ("(%u) dispatching action '%s'%s", reqid, action_to_string (action), blocking @@ -576,11 +573,6 @@ _dispatcher_call (NMDispatcherAction action, NMD_CONNECTION_PROPS_FILENAME, g_variant_new_string (filename)); } - if (activation_type_external) { - g_variant_builder_add (&connection_props, "{sv}", - NMD_CONNECTION_PROPS_EXTERNAL, - g_variant_new_boolean (TRUE)); - } } g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT); @@ -592,8 +584,8 @@ _dispatcher_call (NMDispatcherAction action, g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); /* hostname and connectivity-change actions don't send device data */ - if ( action != NM_DISPATCHER_ACTION_HOSTNAME - && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + if ( action != DISPATCHER_ACTION_HOSTNAME + && action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { fill_device_props (device, &device_props, &device_proxy_props, @@ -697,73 +689,41 @@ done: } /** - * nm_dispatcher_call_hostname: - * @callback: a caller-supplied callback to execute when done - * @user_data: caller-supplied pointer passed to @callback - * @out_call_id: on success, a call identifier which can be passed to - * nm_dispatcher_call_cancel() - * - * This method always invokes the dispatcher action asynchronously. - * - * Returns: %TRUE if the action was dispatched, %FALSE on failure - */ -gboolean -nm_dispatcher_call_hostname (NMDispatcherFunc callback, - gpointer user_data, - guint *out_call_id) -{ - return _dispatcher_call (NM_DISPATCHER_ACTION_HOSTNAME, FALSE, - NULL, NULL, NULL, FALSE, - NM_CONNECTIVITY_UNKNOWN, - NULL, NULL, NULL, NULL, - callback, user_data, out_call_id); -} - -/** - * nm_dispatcher_call_device: - * @action: the %NMDispatcherAction + * nm_dispatcher_call: + * @action: the %DispatcherAction + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @device: the #NMDevice the action applies to - * @act_request: the #NMActRequest for the action. If %NULL, us the - * current request of the device. * @callback: a caller-supplied callback to execute when done * @user_data: caller-supplied pointer passed to @callback * @out_call_id: on success, a call identifier which can be passed to * nm_dispatcher_call_cancel() * - * This method always invokes the device dispatcher action asynchronously. To ignore + * This method always invokes the dispatcher action asynchronously. To ignore * the result, pass %NULL to @callback. * * Returns: %TRUE if the action was dispatched, %FALSE on failure */ gboolean -nm_dispatcher_call_device (NMDispatcherAction action, - NMDevice *device, - NMActRequest *act_request, - NMDispatcherFunc callback, - gpointer user_data, - guint *out_call_id) +nm_dispatcher_call (DispatcherAction action, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, + NMDevice *device, + DispatcherFunc callback, + gpointer user_data, + guint *out_call_id) { - if (!act_request) { - act_request = nm_device_get_act_request (device); - if (!act_request) - return FALSE; - } - return _dispatcher_call (action, FALSE, - device, - nm_act_request_get_settings_connection (act_request), - nm_act_request_get_applied_connection (act_request), - nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL, - NM_CONNECTIVITY_UNKNOWN, - NULL, NULL, NULL, NULL, + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device, + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, callback, user_data, out_call_id); } /** - * nm_dispatcher_call_device_sync(): - * @action: the %NMDispatcherAction + * nm_dispatcher_call_sync(): + * @action: the %DispatcherAction + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @device: the #NMDevice the action applies to - * @act_request: the #NMActRequest for the action. If %NULL, us the - * current request of the device. * * This method always invokes the dispatcher action synchronously and it may * take a long time to return. @@ -771,28 +731,18 @@ nm_dispatcher_call_device (NMDispatcherAction action, * Returns: %TRUE if the action was dispatched, %FALSE on failure */ gboolean -nm_dispatcher_call_device_sync (NMDispatcherAction action, - NMDevice *device, - NMActRequest *act_request) +nm_dispatcher_call_sync (DispatcherAction action, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, + NMDevice *device) { - if (!act_request) { - act_request = nm_device_get_act_request (device); - if (!act_request) - return FALSE; - } - return _dispatcher_call (action, TRUE, - device, - nm_act_request_get_settings_connection (act_request), - nm_act_request_get_applied_connection (act_request), - nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL, - NM_CONNECTIVITY_UNKNOWN, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL); + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device, + NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } /** * nm_dispatcher_call_vpn(): - * @action: the %NMDispatcherAction + * @action: the %DispatcherAction * @settings_connection: the #NMSettingsConnection the action applies to * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection @@ -811,7 +761,7 @@ nm_dispatcher_call_device_sync (NMDispatcherAction action, * Returns: %TRUE if the action was dispatched, %FALSE on failure */ gboolean -nm_dispatcher_call_vpn (NMDispatcherAction action, +nm_dispatcher_call_vpn (DispatcherAction action, NMSettingsConnection *settings_connection, NMConnection *applied_connection, NMDevice *parent_device, @@ -819,23 +769,18 @@ nm_dispatcher_call_vpn (NMDispatcherAction action, NMProxyConfig *vpn_proxy_config, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config, - NMDispatcherFunc callback, + DispatcherFunc callback, gpointer user_data, guint *out_call_id) { - return _dispatcher_call (action, FALSE, - parent_device, - settings_connection, - applied_connection, - FALSE, - NM_CONNECTIVITY_UNKNOWN, - vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config, - callback, user_data, out_call_id); + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config, + vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id); } /** * nm_dispatcher_call_vpn_sync(): - * @action: the %NMDispatcherAction + * @action: the %DispatcherAction * @settings_connection: the #NMSettingsConnection the action applies to * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection @@ -850,7 +795,7 @@ nm_dispatcher_call_vpn (NMDispatcherAction action, * Returns: %TRUE if the action was dispatched, %FALSE on failure */ gboolean -nm_dispatcher_call_vpn_sync (NMDispatcherAction action, +nm_dispatcher_call_vpn_sync (DispatcherAction action, NMSettingsConnection *settings_connection, NMConnection *applied_connection, NMDevice *parent_device, @@ -859,39 +804,26 @@ nm_dispatcher_call_vpn_sync (NMDispatcherAction action, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config) { - return _dispatcher_call (action, TRUE, - parent_device, - settings_connection, - applied_connection, - FALSE, - NM_CONNECTIVITY_UNKNOWN, - vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config, - NULL, NULL, NULL); + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, + parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config, + vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL); } /** * nm_dispatcher_call_connectivity(): + * @action: the %DispatcherAction * @connectivity_state: the #NMConnectivityState value - * @callback: a caller-supplied callback to execute when done - * @user_data: caller-supplied pointer passed to @callback - * @out_call_id: on success, a call identifier which can be passed to - * nm_dispatcher_call_cancel() * * This method does not block the caller. * * Returns: %TRUE if the action was dispatched, %FALSE on failure */ gboolean -nm_dispatcher_call_connectivity (NMConnectivityState connectivity_state, - NMDispatcherFunc callback, - gpointer user_data, - guint *out_call_id) +nm_dispatcher_call_connectivity (DispatcherAction action, + NMConnectivityState connectivity_state) { - return _dispatcher_call (NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, FALSE, - NULL, NULL, NULL, FALSE, - connectivity_state, - NULL, NULL, NULL, NULL, - callback, user_data, out_call_id); + return _dispatcher_call (action, FALSE, NULL, NULL, NULL, connectivity_state, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); } void diff --git a/src/nm-manager.c b/src/nm-manager.c index 13c00144f7..9e6da13c38 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -265,8 +265,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self); g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self); - if ( nm_active_connection_has_activation_type_assume_or_external (active) - && (connection = nm_active_connection_get_settings_connection (active)) + if ( (connection = nm_active_connection_get_settings_connection (active)) && nm_settings_connection_get_garbage_collect (connection)) g_object_ref (connection); else @@ -795,16 +794,14 @@ 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_device_is_assuming (nm_active_connection_get_device (ac))) { 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 (best_state < NM_STATE_DISCONNECTING) - best_state = NM_STATE_DISCONNECTING; - } + if (best_state < NM_STATE_DISCONNECTING) + best_state = NM_STATE_DISCONNECTING; break; default: break; @@ -1685,244 +1682,6 @@ done: g_clear_error (&error); } -static gboolean -match_connection_filter (NMConnection *connection, gpointer user_data) -{ - - return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection); -} - -/** - * get_existing_connection: - * @manager: #NMManager instance - * @device: #NMDevice instance - * @assume_connection_uuid: if present, try to assume a connection with this - * UUID. If no uuid is given or no matching connection is found, we - * only do external activation. - * @out_generated: (allow-none): return TRUE, if the connection was generated. - * - * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if - * the device does not support assuming existing connections. - */ -static NMSettingsConnection * -get_existing_connection (NMManager *self, - NMDevice *device, - const char *assume_connection_uuid, - gboolean *out_generated) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMConnection *connection = NULL; - NMSettingsConnection *added = NULL; - GError *error = NULL; - NMDevice *master = NULL; - int ifindex = nm_device_get_ifindex (device); - - if (out_generated) - *out_generated = FALSE; - - nm_device_capture_initial_config (device); - - if (ifindex) { - int master_ifindex = nm_platform_link_get_master (NM_PLATFORM_GET, ifindex); - - if (master_ifindex) { - master = nm_manager_get_device_by_ifindex (self, master_ifindex); - if (!master) { - _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)", - nm_device_get_iface (device), nm_platform_link_get_name (NM_PLATFORM_GET, master_ifindex), master_ifindex); - return NULL; - } - if (!nm_device_get_act_request (master)) { - _LOGD (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates", - nm_device_get_iface (device), nm_device_get_iface (master)); - return NULL; - } - } - } - - /* The core of the API is nm_device_generate_connection() function and - * update_connection() virtual method and the convenient connection_type - * class attribute. Subclasses supporting the new API must have - * update_connection() implemented, otherwise nm_device_generate_connection() - * returns NULL. - */ - connection = nm_device_generate_connection (device, master); - if (!connection) - return NULL; - - /* Now we need to compare the generated connection to each configured - * connection. The comparison function is the heart of the connection - * assumption implementation and it must compare the connections very - * carefully to sort out various corner cases. Also, the comparison is - * not entirely symmetric. - * - * When no configured connection matches the generated connection, we keep - * the generated connection instead. - */ - if (assume_connection_uuid) { - gs_free_slist GSList *connections = NULL; - gs_free NMSettingsConnection **cons = NULL; - NMSettingsConnection *matched; - guint i, len; - - cons = nm_manager_get_activatable_connections (self, &len, FALSE); - for (i = 0; i < len; i++) { - if (nm_streq0 (assume_connection_uuid, nm_connection_get_uuid (NM_CONNECTION (cons[i])))) { - connections = g_slist_append (NULL, cons[i]); - break; - } - } - connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp); - matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, - connection, - nm_device_has_carrier (device), - nm_device_get_ip4_route_metric (device), - nm_device_get_ip6_route_metric (device), - match_connection_filter, - device)); - if (matched) { - _LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'", - nm_device_get_iface (device), - nm_settings_connection_get_id (matched)); - g_object_unref (connection); - return matched; - } - } - - _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'", - nm_device_get_iface (device), - nm_connection_get_id (connection)); - - added = nm_settings_add_connection (priv->settings, connection, FALSE, &error); - if (added) { - nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | - NM_SETTINGS_CONNECTION_FLAGS_GARBAGE_COLLECT, - TRUE); - if (out_generated) - *out_generated = TRUE; - } else { - _LOGW (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s", - nm_device_get_iface (device), - nm_connection_get_id (connection), - error->message); - g_clear_error (&error); - } - g_object_unref (connection); - - return added ? added : NULL; -} - -static gboolean -assume_connection (NMManager *self, - NMDevice *device, - NMSettingsConnection *connection, - gboolean generated) -{ - NMActiveConnection *active, *master_ac; - NMAuthSubject *subject; - GError *error = NULL; - - _LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection", - nm_device_get_iface (device)); - - /* Move device to DISCONNECTED to activate the connection */ - if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) { - nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - } - g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - - subject = nm_auth_subject_new_internal (); - active = _new_active_connection (self, NM_CONNECTION (connection), NULL, NULL, - device, subject, - generated ? NM_ACTIVATION_TYPE_EXTERNAL : NM_ACTIVATION_TYPE_ASSUME, - &error); - g_object_unref (subject); - - if (!active) { - _LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s", - nm_connection_get_path (NM_CONNECTION (connection)), - error->message); - g_error_free (error); - return FALSE; - } - - /* If the device is a slave or VLAN, find the master ActiveConnection */ - master_ac = NULL; - if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac) - nm_active_connection_set_master (active, master_ac); - - nm_exported_object_export (NM_EXPORTED_OBJECT (active)); - active_connection_add (self, active); - nm_device_queue_activation (device, NM_ACT_REQUEST (active)); - g_object_unref (active); - - return TRUE; -} - -static gboolean -recheck_assume_connection (NMManager *self, - NMDevice *device, - const char *assume_connection_uuid) -{ - NMSettingsConnection *connection; - gboolean was_unmanaged = FALSE, success, generated = FALSE; - NMDeviceState state; - - g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - if (nm_device_get_is_nm_owned (device)) - return FALSE; - - if (!nm_device_get_managed (device, FALSE)) - return FALSE; - - state = nm_device_get_state (device); - if (state > NM_DEVICE_STATE_DISCONNECTED) - return FALSE; - - connection = get_existing_connection (self, device, assume_connection_uuid, &generated); - if (!connection) { - _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection", - nm_device_get_iface (device)); - return FALSE; - } - - if (state == NM_DEVICE_STATE_UNMANAGED) { - was_unmanaged = TRUE; - nm_device_state_changed (device, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - } - - success = assume_connection (self, device, connection, generated); - if (!success) { - if (was_unmanaged) { - nm_device_state_changed (device, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_CONFIG_FAILED); - } - - if (generated) { - _LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection", - nm_device_get_iface (device)); - - nm_settings_connection_delete (connection, NULL, NULL); - } - } - - return success; -} - -static void -recheck_assume_connection_cb (NMDevice *device, gpointer user_data) -{ - recheck_assume_connection (user_data, device, NULL); -} - static void device_ifindex_changed (NMDevice *device, GParamSpec *pspec, @@ -1994,8 +1753,7 @@ _device_realize_finish (NMManager *self, if (!nm_device_get_managed (device, FALSE)) return; - if (recheck_assume_connection (self, device, connection_uuid_to_assume)) - return; + nm_device_next_activation_store (device, g_strdup (connection_uuid_to_assume)); /* if we failed to assume a connection for the managed device, but the device * is still unavailable. Set UNAVAILABLE state again, this time with NOW_MANAGED. */ @@ -2064,10 +1822,6 @@ add_device (NMManager *self, NMDevice *device, GError **error) G_CALLBACK (device_removed_cb), self); - g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME, - G_CALLBACK (recheck_assume_connection_cb), - self); - g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE, G_CALLBACK (device_ip_iface_changed), self); @@ -2914,7 +2668,8 @@ autoconnect_slaves (NMManager *self, GError *local_err = NULL; gboolean ret = FALSE; - if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { + if ( !nm_device_is_assuming (master_device) + && should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { GSList *slaves, *iter; iter = slaves = find_slaves (self, master_connection, master_device); diff --git a/src/nm-policy.c b/src/nm-policy.c index 2aff2b7820..4d534ff963 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -932,6 +932,64 @@ check_activating_devices (NMPolicy *self) g_object_thaw_notify (object); } +static NMSettingsConnection * +_find_connection_to_assume (NMPolicy *self, + NMDevice *device, + gboolean *out_had_next_activation) +{ + NMPolicyPrivate *priv; + NMSettingsConnection *connection; + gs_free const char *uuid = NULL; + const NMPlatformLink *pllink; + + uuid = nm_device_next_activation_retrieve (device); + if (!uuid) { + *out_had_next_activation = FALSE; + return NULL; + } + + *out_had_next_activation = TRUE; + + priv = NM_POLICY_GET_PRIVATE (self); + + connection = nm_settings_get_connection_by_uuid (priv->settings, uuid); + if (!connection) + return NULL; + + if (nm_manager_get_connection_device (priv->manager, NM_CONNECTION (connection))) { + /* if the connection is already active on another device, it cannot be + * activated here. */ + return NULL; + } + + if (!nm_device_check_connection_available (device, + NM_CONNECTION (connection), + NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, + NULL)) { + /* the connection must be compatible and available on the device. */ + return NULL; + } + + /* only if the device exists. */ + pllink = nm_platform_link_get (NM_PLATFORM_GET, + nm_device_get_ip_ifindex (device)); + if (!pllink) + return NULL; + + if (nm_setting_connection_get_slave_type (nm_connection_get_setting_connection (NM_CONNECTION (connection)))) { + /* a slave. Is the link still enslaved? */ + if (pllink->master <= 0) + return NULL; + } else { + /* the device must be up and not a slave. */ + if ( pllink->master > 0 + || !NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP)) + return NULL; + } + + return connection; +} + typedef struct { NMPolicy *policy; NMDevice *device; @@ -960,8 +1018,9 @@ auto_activate_device (NMPolicy *self, NMPolicyPrivate *priv; NMSettingsConnection *best_connection; gs_free char *specific_object = NULL; - gs_free NMSettingsConnection **connections = NULL; - guint i, len; + guint i; + gboolean had_next_activation = FALSE; + gboolean assume = FALSE; nm_assert (NM_IS_POLICY (self)); nm_assert (NM_IS_DEVICE (device)); @@ -975,20 +1034,38 @@ auto_activate_device (NMPolicy *self, if (nm_device_get_act_request (device)) return; - connections = nm_manager_get_activatable_connections (priv->manager, &len, TRUE); - if (!connections[0]) - return; + best_connection = _find_connection_to_assume (self, device, &had_next_activation); - /* Find the first connection that should be auto-activated */ - best_connection = NULL; - for (i = 0; i < len; i++) { - NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]); + if (had_next_activation && !best_connection) { + if (!nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { + /* the device had a next-activation scheduled which brought it into state + * DISCONNECTED. But as the next-activation is not applicable, the device + * is no longer available. Revert to unavailable. */ + nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NONE); + return; + } + } - if (!nm_settings_connection_can_autoconnect (candidate)) - continue; - if (nm_device_can_auto_connect (device, (NMConnection *) candidate, &specific_object)) { - best_connection = candidate; - break; + if (best_connection) + assume = TRUE; + else { + gs_free NMSettingsConnection **connections = NULL; + + connections = nm_manager_get_activatable_connections (priv->manager, NULL, TRUE); + if (!connections[0]) + return; + + /* Find the first connection that should be auto-activated */ + best_connection = NULL; + for (i = 0; connections[i]; i++) { + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]); + + if (!nm_settings_connection_can_autoconnect (candidate)) + continue; + if (nm_device_can_auto_connect (device, (NMConnection *) candidate, &specific_object)) { + best_connection = candidate; + break; + } } } @@ -1005,7 +1082,9 @@ auto_activate_device (NMPolicy *self, specific_object, device, subject, - NM_ACTIVATION_TYPE_FULL, + assume + ? NM_ACTIVATION_TYPE_ASSUME + : NM_ACTIVATION_TYPE_FULL, &error)) { _LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: (%d) %s", nm_settings_connection_get_id (best_connection), diff --git a/src/nm-types.h b/src/nm-types.h index 83891ab61e..2062cc9337 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -64,11 +64,6 @@ typedef enum { /* gracefully/seamlessly take over the device. This leaves additional * IP addresses and does not restore missing manual addresses. */ NM_ACTIVATION_TYPE_ASSUME = 1, - - /* external activation. This device is not managed by NM, instead - * a in-memory connection is generated and NM pretends the device - * to be active, but it doesn't do anything really. */ - NM_ACTIVATION_TYPE_EXTERNAL = 2, } NMActivationType; typedef enum { diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 827ec32535..9d6b71fda9 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -61,6 +61,7 @@ * @NM_SETTINGS_CONNECTION_FLAGS_GARBAGE_COLLECT: The connection will be deleted * when it disconnects. That is for in-memory connections (unsaved), which are * currently active but cleanup on disconnect. + * FIXME: this flag is not yet properly implemented. * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags * * #NMSettingsConnection flags. |
