about summary refs log tree commit diff
path: root/src/nm-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-manager.c')
-rw-r--r--src/nm-manager.c857
1 files changed, 329 insertions, 528 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f8be6d37..ad906169 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -310,8 +310,7 @@ static void _emit_device_added_removed (NMManager *self,
 
 static NMActiveConnection *_new_active_connection (NMManager *self,
                                                    gboolean is_vpn,
-                                                   NMSettingsConnection *sett_conn,
-                                                   NMConnection *incompl_conn,
+                                                   NMConnection *connection,
                                                    NMConnection *applied,
                                                    const char *specific_object,
                                                    NMDevice *device,
@@ -320,7 +319,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self,
                                                    NMActivationReason activation_reason,
                                                    GError **error);
 
-static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
+static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
 
 static gboolean find_master (NMManager *self,
                              NMConnection *connection,
@@ -332,8 +331,7 @@ static gboolean find_master (NMManager *self,
 
 static void nm_manager_update_state (NMManager *manager);
 
-static void connection_changed (NMManager *self,
-                                NMSettingsConnection *sett_conn);
+static void connection_changed (NMManager *self, NMConnection *connection);
 static void device_sleep_cb (NMDevice *device,
                              GParamSpec *pspec,
                              NMManager *self);
@@ -355,7 +353,7 @@ static void active_connection_parent_active (NMActiveConnection *active,
                                              NMManager *self);
 
 static NMActiveConnection *active_connection_find (NMManager *self,
-                                                   NMSettingsConnection *sett_conn,
+                                                   NMSettingsConnection *settings_connection,
                                                    const char *uuid,
                                                    NMActiveConnectionState max_state,
                                                    GPtrArray **out_all_matching);
@@ -949,7 +947,7 @@ nm_manager_get_active_connections (NMManager *manager)
 
 static NMActiveConnection *
 active_connection_find (NMManager *self,
-                        NMSettingsConnection *sett_conn,
+                        NMSettingsConnection *settings_connection,
                         const char *uuid,
                         NMActiveConnectionState max_state /* candidates in state @max_state will be found */,
                         GPtrArray **out_all_matching)
@@ -959,18 +957,16 @@ active_connection_find (NMManager *self,
 	NMActiveConnection *best_ac = NULL;
 	GPtrArray *all = NULL;
 
-	nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn));
+	nm_assert (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection));
 	nm_assert (!out_all_matching || !*out_all_matching);
 
 	c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) {
-		NMSettingsConnection *ac_conn;
+		NMSettingsConnection *con;
 
-		ac_conn = nm_active_connection_get_settings_connection (ac);
-		if (   sett_conn
-		    && sett_conn != ac_conn)
+		con = nm_active_connection_get_settings_connection (ac);
+		if (settings_connection && con != settings_connection)
 			continue;
-		if (   uuid
-		    && !nm_streq0 (uuid, nm_settings_connection_get_uuid (ac_conn)))
+		if (uuid && !nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (con))))
 			continue;
 		if (nm_active_connection_get_state (ac) > max_state)
 			continue;
@@ -1009,73 +1005,47 @@ active_connection_find (NMManager *self,
 
 static NMActiveConnection *
 active_connection_find_by_connection (NMManager *self,
-                                      NMSettingsConnection *sett_conn,
                                       NMConnection *connection,
                                       NMActiveConnectionState max_state,
                                       GPtrArray **out_all_matching)
 {
+	gboolean is_settings_connection;
+
 	nm_assert (NM_IS_MANAGER (self));
-	nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn));
-	nm_assert (!connection || NM_IS_CONNECTION (connection));
-	nm_assert (sett_conn || connection);
-	nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn));
+	nm_assert (NM_IS_CONNECTION (connection));
 
+	is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
 	/* Depending on whether connection is a settings connection,
 	 * either lookup by object-identity of @connection, or compare the UUID */
 	return active_connection_find (self,
-	                               sett_conn,
-	                               sett_conn ? NULL : nm_connection_get_uuid (connection),
+	                               is_settings_connection ? NM_SETTINGS_CONNECTION (connection) : NULL,
+	                               is_settings_connection ? NULL : nm_connection_get_uuid (connection),
 	                               max_state,
 	                               out_all_matching);
 }
 
-typedef struct {
-	NMManager *self;
-	gboolean for_auto_activation;
-} GetActivatableConnectionsFilterData;
-
 static gboolean
 _get_activatable_connections_filter (NMSettings *settings,
-                                     NMSettingsConnection *sett_conn,
+                                     NMSettingsConnection *connection,
                                      gpointer user_data)
 {
-	const GetActivatableConnectionsFilterData *d = user_data;
-	NMConnectionMultiConnect multi_connect;
-
-	if (NM_FLAGS_HAS (nm_settings_connection_get_flags (sett_conn),
+	if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection),
 	                  NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE))
 		return FALSE;
 
-	multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn));
-	if (   multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE
-	    || (   multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE
-	        && !d->for_auto_activation))
-		return TRUE;
-
 	/* the connection is activatable, if it has no active-connections that are in state
 	 * activated, activating, or waiting to be activated. */
-	return !active_connection_find (d->self,
-	                                sett_conn,
-	                                NULL,
-	                                NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
-	                                NULL);
+	return !active_connection_find (user_data, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL);
 }
 
 NMSettingsConnection **
-nm_manager_get_activatable_connections (NMManager *manager,
-                                        gboolean for_auto_activation,
-                                        gboolean sort,
-                                        guint *out_len)
+nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboolean sort)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-	const GetActivatableConnectionsFilterData d = {
-		.self = manager,
-		.for_auto_activation = for_auto_activation,
-	};
 
 	return nm_settings_get_connections_clone (priv->settings, out_len,
 	                                          _get_activatable_connections_filter,
-	                                          (gpointer) &d,
+	                                          manager,
 	                                          sort ? nm_settings_connection_cmp_autoconnect_priority_p_with_data : NULL,
 	                                          NULL);
 }
@@ -1086,8 +1056,8 @@ active_connection_get_by_path (NMManager *self, const char *path)
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	NMActiveConnection *ac;
 
-	ac = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
-	                                    path);
+	ac = (NMActiveConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
+	                                                           path);
 	if (   !ac
 	    || !NM_IS_ACTIVE_CONNECTION (ac)
 	    || c_list_is_empty (&ac->active_connections_lst))
@@ -1223,8 +1193,8 @@ nm_manager_get_device_by_path (NMManager *self, const char *path)
 
 	g_return_val_if_fail (path, NULL);
 
-	device = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
-	                                        path);
+	device = (NMDevice *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)),
+	                                                     path);
 	if (   !device
 	    || !NM_IS_DEVICE (device)
 	    || c_list_is_empty (&device->devices_lst))
@@ -1274,7 +1244,7 @@ find_device_by_permanent_hw_addr (NMManager *self, const char *hwaddr)
 }
 
 static NMDevice *
-find_device_by_ip_iface (NMManager *self, const char *iface)
+find_device_by_ip_iface (NMManager *self, const gchar *iface)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	NMDevice *device;
@@ -1320,7 +1290,7 @@ find_device_by_iface (NMManager *self,
 
 		if (strcmp (nm_device_get_iface (candidate), iface))
 			continue;
-		if (connection && !nm_device_check_connection_compatible (candidate, connection, NULL))
+		if (connection && !nm_device_check_connection_compatible (candidate, connection))
 			continue;
 		if (slave) {
 			if (!nm_device_is_master (candidate))
@@ -1489,23 +1459,20 @@ manager_device_state_changed (NMDevice *device,
 	    && new_state > NM_DEVICE_STATE_UNMANAGED)
 		retry_connections_for_parent_device (self, device);
 
-	if (NM_IN_SET (new_state,
-	               NM_DEVICE_STATE_UNMANAGED,
-	               NM_DEVICE_STATE_UNAVAILABLE,
-	               NM_DEVICE_STATE_DISCONNECTED,
-	               NM_DEVICE_STATE_PREPARE,
-	               NM_DEVICE_STATE_FAILED))
+	switch (new_state) {
+	case NM_DEVICE_STATE_UNMANAGED:
+	case NM_DEVICE_STATE_UNAVAILABLE:
+	case NM_DEVICE_STATE_DISCONNECTED:
+	case NM_DEVICE_STATE_PREPARE:
+	case NM_DEVICE_STATE_FAILED:
 		_notify (self, PROP_ACTIVE_CONNECTIONS);
+		break;
+	default:
+		break;
+	}
 
-	if (NM_IN_SET (new_state,
-	               NM_DEVICE_STATE_UNMANAGED,
-	               NM_DEVICE_STATE_DISCONNECTED,
-	               NM_DEVICE_STATE_ACTIVATED))
-		nm_manager_write_device_state (self, device);
-
-	if (NM_IN_SET (new_state,
-	               NM_DEVICE_STATE_UNAVAILABLE,
-	               NM_DEVICE_STATE_DISCONNECTED))
+	if (   new_state == NM_DEVICE_STATE_UNAVAILABLE
+	    || new_state == NM_DEVICE_STATE_DISCONNECTED)
 		nm_settings_device_added (priv->settings, device);
 }
 
@@ -1740,9 +1707,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM
 			return candidate;
 
 		if (   !first_compatible
-		    && nm_device_check_connection_compatible (candidate,
-		                                              nm_settings_connection_get_connection (parent_connection),
-		                                              NULL))
+		    && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection)))
 			first_compatible = candidate;
 	}
 
@@ -1836,13 +1801,13 @@ const char *
 nm_manager_iface_for_uuid (NMManager *self, const char *uuid)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	NMSettingsConnection *sett_conn;
+	NMSettingsConnection *connection;
 
-	sett_conn = nm_settings_get_connection_by_uuid (priv->settings, uuid);
-	if (!sett_conn)
+	connection = nm_settings_get_connection_by_uuid (priv->settings, uuid);
+	if (!connection)
 		return NULL;
 
-	return nm_connection_get_interface_name (nm_settings_connection_get_connection (sett_conn));
+	return nm_connection_get_interface_name (NM_CONNECTION (connection));
 }
 
 NMDevice *
@@ -1912,7 +1877,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
 
 	/* See if there's a device that is already compatible with this connection */
 	c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) {
-		if (nm_device_check_connection_compatible (dev_candidate, connection, NULL)) {
+		if (nm_device_check_connection_compatible (dev_candidate, connection)) {
 			if (nm_device_is_real (dev_candidate)) {
 				_LOG3D (LOGD_DEVICE, connection, "already created virtual interface name %s",
 				       iface);
@@ -1965,10 +1930,10 @@ system_create_virtual_device (NMManager *self, NMConnection *connection)
 	                                                 NULL, NULL,
 	                                                 nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL);
 	for (i = 0; connections[i]; i++) {
-		NMConnection *candidate = nm_settings_connection_get_connection (connections[i]);
+		NMConnection *candidate = NM_CONNECTION (connections[i]);
 		NMSettingConnection *s_con;
 
-		if (!nm_device_check_connection_compatible (device, candidate, NULL))
+		if (!nm_device_check_connection_compatible (device, candidate))
 			continue;
 
 		s_con = nm_connection_get_setting_connection (candidate);
@@ -2011,19 +1976,18 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device)
 	                                                 NULL, NULL,
 	                                                 nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL);
 	for (i = 0; connections[i]; i++) {
-		NMSettingsConnection *sett_conn = connections[i];
-		NMConnection *connection = nm_settings_connection_get_connection (sett_conn);
+		NMConnection *candidate = NM_CONNECTION (connections[i]);
 		gs_free_error GError *error = NULL;
 		gs_free char *ifname = NULL;
 		NMDevice *parent;
 
-		parent = find_parent_device_for_connection (self, connection, NULL);
+		parent = find_parent_device_for_connection (self, candidate, NULL);
 		if (parent == device) {
 			/* Only try to activate devices that don't already exist */
-			ifname = nm_manager_get_connection_iface (self, connection, &parent, &error);
+			ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error);
 			if (ifname) {
 				if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname))
-					connection_changed (self, sett_conn);
+					connection_changed (self, candidate);
 			}
 		}
 	}
@@ -2031,10 +1995,9 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device)
 
 static void
 connection_changed (NMManager *self,
-                    NMSettingsConnection *sett_conn)
+                    NMConnection *connection)
 {
 	NMDevice *device;
-	NMConnection *connection = nm_settings_connection_get_connection (sett_conn);
 
 	if (!nm_connection_is_virtual (connection))
 		return;
@@ -2051,20 +2014,20 @@ connection_changed (NMManager *self,
 
 static void
 connection_added_cb (NMSettings *settings,
-                     NMSettingsConnection *sett_conn,
+                     NMConnection *connection,
                      NMManager *self)
 {
-	connection_changed (self, sett_conn);
+	connection_changed (self, connection);
 }
 
 static void
 connection_updated_cb (NMSettings *settings,
-                       NMSettingsConnection *sett_conn,
+                       NMConnection *connection,
                        gboolean by_user,
                        NMManager *self)
 {
 	if (by_user)
-		connection_changed (self, sett_conn);
+		connection_changed (self, connection);
 }
 
 /*****************************************************************************/
@@ -2407,20 +2370,6 @@ done:
 	g_clear_error (&error);
 }
 
-static gboolean
-new_activation_allowed_for_connection (NMManager *self,
-                                       NMSettingsConnection *connection)
-{
-	if (NM_IN_SET (_nm_connection_get_multi_connect (nm_settings_connection_get_connection (connection)),
-	               NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE,
-	               NM_CONNECTION_MULTI_CONNECT_MULTIPLE))
-		return TRUE;
-
-	return !active_connection_find (self, connection, NULL,
-	                                NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
-	                                NULL);
-}
-
 /**
  * get_existing_connection:
  * @manager: #NMManager instance
@@ -2437,12 +2386,12 @@ get_existing_connection (NMManager *self,
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	gs_unref_object NMConnection *connection = NULL;
-	NMSettingsConnection *added;
+	NMSettingsConnection *added = NULL;
 	GError *error = NULL;
 	gs_free_error GError *gen_error = NULL;
 	NMDevice *master = NULL;
 	int ifindex = nm_device_get_ifindex (device);
-	NMSettingsConnection *matched = NULL;
+	NMSettingsConnection *matched;
 	NMSettingsConnection *connection_checked = NULL;
 	gboolean assume_state_guess_assume = FALSE;
 	const char *assume_state_connection_uuid = NULL;
@@ -2508,25 +2457,28 @@ get_existing_connection (NMManager *self,
 	 */
 	if (   assume_state_connection_uuid
 	    && (connection_checked = nm_settings_get_connection_by_uuid (priv->settings, assume_state_connection_uuid))
-	    && new_activation_allowed_for_connection (self, connection_checked)
-	    && nm_device_check_connection_compatible (device,
-	                                              nm_settings_connection_get_connection (connection_checked),
-	                                              NULL)) {
+	    && !active_connection_find (self, connection_checked, NULL,
+	                                NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
+	                                NULL)
+	    && nm_device_check_connection_compatible (device, NM_CONNECTION (connection_checked))) {
 
 		if (connection) {
-			NMConnection *con = nm_settings_connection_get_connection (connection_checked);
-
-			if (nm_utils_match_connection ((NMConnection *[]) { con, NULL },
-			                               connection,
-			                               TRUE,
-			                               nm_device_has_carrier (device),
-			                               nm_device_get_route_metric (device, AF_INET),
-			                               nm_device_get_route_metric (device, AF_INET6),
-			                               NULL, NULL))
-				matched = connection_checked;
+			NMConnection *const connections[] = {
+				NM_CONNECTION (connection_checked),
+				NULL,
+			};
+
+			matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
+			                                                             connection,
+			                                                             TRUE,
+			                                                             nm_device_has_carrier (device),
+			                                                             nm_device_get_route_metric (device, AF_INET),
+			                                                             nm_device_get_route_metric (device, AF_INET6),
+			                                                             NULL, NULL));
 		} else
 			matched = connection_checked;
-	}
+	} else
+		matched = NULL;
 
 	if (!matched && only_by_uuid) {
 		_LOG2D (LOGD_DEVICE, device, "assume: cannot generate connection: %s",
@@ -2535,51 +2487,32 @@ get_existing_connection (NMManager *self,
 	}
 
 	if (!matched && assume_state_guess_assume) {
-		gs_free NMSettingsConnection **sett_conns = NULL;
+		gs_free NMSettingsConnection **connections = NULL;
 		guint len, i, j;
 
 		/* the state file doesn't indicate a connection UUID to assume. Search the
 		 * persistent connections for a matching candidate. */
-		sett_conns = nm_manager_get_activatable_connections (self, FALSE, FALSE, &len);
+		connections = nm_manager_get_activatable_connections (self, &len, FALSE);
 		if (len > 0) {
 			for (i = 0, j = 0; i < len; i++) {
-				NMSettingsConnection *sett_conn = sett_conns[i];
+				NMConnection *con = NM_CONNECTION (connections[i]);
 
-				if (   sett_conn != connection_checked
-				    && nm_device_check_connection_compatible (device,
-				                                              nm_settings_connection_get_connection (sett_conn),
-				                                              NULL))
-					sett_conns[j++] = sett_conn;
+				if (   con != NM_CONNECTION (connection_checked)
+				    && nm_device_check_connection_compatible (device, con))
+					connections[j++] = connections[i];
 			}
-			sett_conns[j] = NULL;
+			connections[j] = NULL;
 			len = j;
-			if (len > 0) {
-				gs_free NMConnection **conns = NULL;
-				NMConnection *con;
-
-				g_qsort_with_data (sett_conns, len, sizeof (sett_conns[0]),
-				                   nm_settings_connection_cmp_timestamp_p_with_data, NULL);
-
-				conns = nm_settings_connections_array_to_connections (sett_conns, len);
-
-				con = nm_utils_match_connection (conns,
-				                                 connection,
-				                                 FALSE,
-				                                 nm_device_has_carrier (device),
-				                                 nm_device_get_route_metric (device, AF_INET),
-				                                 nm_device_get_route_metric (device, AF_INET6),
-				                                 NULL,
-				                                 NULL);
-				if (con) {
-					for (i = 0; i < len; i++) {
-						if (conns[i] == con) {
-							matched = sett_conns[i];
-							break;
-						}
-					}
-					nm_assert (matched);
-				}
-			}
+			g_qsort_with_data (connections, len, sizeof (connections[0]),
+			                   nm_settings_connection_cmp_timestamp_p_with_data, NULL);
+
+			matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection ((NMConnection *const*) connections,
+			                                                             connection,
+			                                                             FALSE,
+			                                                             nm_device_has_carrier (device),
+			                                                             nm_device_get_route_metric (device, AF_INET),
+			                                                             nm_device_get_route_metric (device, AF_INET6),
+			                                                             NULL, NULL));
 		}
 	}
 
@@ -2608,7 +2541,7 @@ get_existing_connection (NMManager *self,
 		return NULL;
 	}
 
-	nm_settings_connection_set_flags (added,
+	nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
 	                                  NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED |
 	                                  NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE,
 	                                  TRUE);
@@ -2620,7 +2553,7 @@ static gboolean
 recheck_assume_connection (NMManager *self,
                            NMDevice *device)
 {
-	NMSettingsConnection *sett_conn;
+	NMSettingsConnection *connection;
 	gboolean was_unmanaged = FALSE;
 	gboolean generated = FALSE;
 	NMDeviceState state;
@@ -2642,9 +2575,9 @@ recheck_assume_connection (NMManager *self,
 		return FALSE;
 	}
 
-	sett_conn = get_existing_connection (self, device, &generated);
+	connection = get_existing_connection (self, device, &generated);
 	/* log  no reason. get_existing_connection() already does it. */
-	if (!sett_conn)
+	if (!connection)
 		return FALSE;
 
 	nm_device_sys_iface_state_set (device,
@@ -2676,8 +2609,7 @@ recheck_assume_connection (NMManager *self,
 		subject = nm_auth_subject_new_internal ();
 		active = _new_active_connection (self,
 		                                 FALSE,
-		                                 sett_conn,
-		                                 NULL,
+		                                 NM_CONNECTION (connection),
 		                                 NULL,
 		                                 NULL,
 		                                 device,
@@ -2688,7 +2620,7 @@ recheck_assume_connection (NMManager *self,
 
 		if (!active) {
 			_LOGW (LOGD_DEVICE, "assume: assumed connection %s failed to activate: %s",
-			       nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)),
+			       nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)),
 			       error->message);
 			g_error_free (error);
 
@@ -2700,7 +2632,7 @@ recheck_assume_connection (NMManager *self,
 
 			if (generated) {
 				_LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed");
-				nm_settings_connection_delete (sett_conn, NULL);
+				nm_settings_connection_delete (connection, 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);
@@ -2710,14 +2642,7 @@ recheck_assume_connection (NMManager *self,
 
 		/* If the device is a slave or VLAN, find the master ActiveConnection */
 		master_ac = NULL;
-		if (   find_master (self,
-		                    nm_settings_connection_get_connection (sett_conn),
-		                    device,
-		                    NULL,
-		                    NULL,
-		                    &master_ac,
-		                    NULL)
-		    && master_ac)
+		if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
 			nm_active_connection_set_master (active, master_ac);
 
 		active_connection_add (self, active);
@@ -3321,11 +3246,9 @@ nm_manager_get_devices (NMManager *manager)
 
 static NMDevice *
 nm_manager_get_best_device_for_connection (NMManager *self,
-                                           NMSettingsConnection *sett_conn,
                                            NMConnection *connection,
                                            gboolean for_user_request,
-                                           GHashTable *unavailable_devices,
-                                           GError **error)
+                                           GHashTable *unavailable_devices)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	NMActiveConnectionState ac_state;
@@ -3334,25 +3257,16 @@ nm_manager_get_best_device_for_connection (NMManager *self,
 	NMDevice *device;
 	NMDeviceCheckConAvailableFlags flags;
 	gs_unref_ptrarray GPtrArray *all_ac_arr = NULL;
-	gs_free_error GError *local_best = NULL;
-
-	nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn));
-	nm_assert (!connection || NM_IS_CONNECTION (connection));
-	nm_assert (sett_conn || connection);
-	nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn));
-
-	if (!connection)
-		connection = nm_settings_connection_get_connection (sett_conn);
 
 	flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
 
-	ac = active_connection_find_by_connection (self, sett_conn, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr);
+	ac = active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr);
 	if (ac) {
 
 		ac_device = nm_active_connection_get_device (ac);
 		if (   ac_device
 		    && (   (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device))
-		        || !nm_device_check_connection_available (ac_device, connection, flags, NULL, NULL)))
+		        || !nm_device_check_connection_available (ac_device, connection, flags, NULL)))
 			ac_device = NULL;
 
 		if (all_ac_arr) {
@@ -3369,7 +3283,7 @@ nm_manager_get_best_device_for_connection (NMManager *self,
 
 				if (   !ac_device2
 				    || (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device2))
-				    || !nm_device_check_connection_available (ac_device2, connection, flags, NULL, NULL))
+				    || !nm_device_check_connection_available (ac_device2, connection, flags, NULL))
 					continue;
 
 				ac_state2 = nm_active_connection_get_state (ac2);
@@ -3417,53 +3331,15 @@ found_better:
 
 	/* Pick the first device that's compatible with the connection. */
 	c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
-		GError *local = NULL;
 
-		if (   unavailable_devices
-		    && g_hash_table_contains (unavailable_devices, device))
+		if (unavailable_devices && g_hash_table_contains (unavailable_devices, device))
 			continue;
 
-		if (nm_device_check_connection_available (device,
-		                                          connection,
-		                                          flags,
-		                                          NULL,
-		                                          error ? &local : NULL))
+		if (nm_device_check_connection_available (device, connection, flags, NULL))
 			return device;
-
-		if (error) {
-			gboolean reset_error;
-
-			if (!local_best)
-				reset_error = TRUE;
-			else if (local_best->domain != NM_UTILS_ERROR)
-				reset_error = (local->domain == NM_UTILS_ERROR);
-			else {
-				reset_error = (   local->domain == NM_UTILS_ERROR
-			                   && local_best->code < local->code);
-			}
-
-			if (reset_error) {
-				g_clear_error (&local_best);
-				g_set_error (&local_best,
-				             local->domain,
-				             local->code,
-				             "device %s not available because %s",
-				             nm_device_get_iface (device),
-				             local->message);
-			}
-			g_error_free (local);
-		}
 	}
 
-	if (error) {
-		if (local_best)
-			g_propagate_error (error, g_steal_pointer (&local_best));
-		else {
-			nm_utils_error_set_literal (error,
-			                            NM_UTILS_ERROR_UNKNOWN,
-			                            "no suitable device found");
-		}
-	}
+	/* No luck. :( */
 	return NULL;
 }
 
@@ -3632,7 +3508,7 @@ find_master (NMManager *self,
 	NMSettingConnection *s_con;
 	const char *master;
 	NMDevice *master_device = NULL;
-	NMSettingsConnection *master_connection;
+	NMSettingsConnection *master_connection = NULL;
 
 	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
@@ -3651,9 +3527,7 @@ find_master (NMManager *self,
 		}
 
 		master_connection = nm_device_get_settings_connection (master_device);
-		if (   master_connection
-		    && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection),
-		                                  connection)) {
+		if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) {
 			g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
 			             "The active connection on %s is not compatible",
 			             nm_device_get_iface (master_device));
@@ -3753,9 +3627,7 @@ ensure_master_active_connection (NMManager *self,
 		 * be already activated on the device, eg returned from find_master().
 		 */
 		g_assert (!master_connection || master_connection == device_connection);
-		if (   device_connection
-		    && !is_compatible_with_slave (nm_settings_connection_get_connection (device_connection),
-		                                  connection)) {
+		if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) {
 			g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
 			             "The active connection %s is not compatible",
 			             nm_connection_get_id (connection));
@@ -3780,22 +3652,17 @@ ensure_master_active_connection (NMManager *self,
 			g_assert (master_connection == NULL);
 
 			/* Find a compatible connection and activate this device using it */
-			connections = nm_manager_get_activatable_connections (self, FALSE, TRUE, NULL);
+			connections = nm_manager_get_activatable_connections (self, NULL, TRUE);
 			for (i = 0; connections[i]; i++) {
 				NMSettingsConnection *candidate = connections[i];
-				NMConnection *cand_conn = nm_settings_connection_get_connection (candidate);
 
 				/* Ensure eg bond/team slave and the candidate master is a
 				 * bond/team master
 				 */
-				if (!is_compatible_with_slave (cand_conn, connection))
+				if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection))
 					continue;
 
-				if (nm_device_check_connection_available (master_device,
-				                                          cand_conn,
-				                                          NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
-				                                          NULL,
-				                                          NULL)) {
+				if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
 					master_ac = nm_manager_activate_connection (self,
 					                                            candidate,
 					                                            NULL,
@@ -3831,11 +3698,7 @@ ensure_master_active_connection (NMManager *self,
 				continue;
 			}
 
-			if (!nm_device_check_connection_available (candidate,
-			                                           nm_settings_connection_get_connection (master_connection),
-			                                           NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
-			                                           NULL,
-			                                           NULL))
+			if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL))
 				continue;
 
 			if (!nm_device_is_software (candidate)) {
@@ -3874,18 +3737,18 @@ typedef struct {
 /**
  * find_slaves:
  * @manager: #NMManager object
- * @sett_conn: the master #NMSettingsConnection to find slave connections for
- * @device: the master #NMDevice for the @sett_conn
+ * @connection: the master #NMSettingsConnection to find slave connections for
+ * @device: the master #NMDevice for the @connection
  * @out_n_slaves: on return, the number of slaves found
  *
- * Given an #NMSettingsConnection, attempts to find its slaves. If @sett_conn is not
+ * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not
  * master, or has not any slaves, this will return %NULL.
  *
- * Returns: an array of #SlaveConnectionInfo for given master @sett_conn, or %NULL
+ * Returns: an array of #SlaveConnectionInfo for given master @connection, or %NULL
  **/
 static SlaveConnectionInfo *
 find_slaves (NMManager *manager,
-             NMSettingsConnection *sett_conn,
+             NMSettingsConnection *connection,
              NMDevice *device,
              guint *out_n_slaves)
 {
@@ -3900,7 +3763,7 @@ find_slaves (NMManager *manager,
 
 	nm_assert (out_n_slaves);
 
-	s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn));
+	s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
 	g_return_val_if_fail (s_con, NULL);
 
 	devices = g_hash_table_new (nm_direct_hash, NULL);
@@ -3915,23 +3778,15 @@ find_slaves (NMManager *manager,
 	for (i = 0; i < n_all_connections; i++) {
 		NMSettingsConnection *master_connection = NULL;
 		NMDevice *master_device = NULL, *slave_device;
-		NMSettingsConnection *candidate = all_connections[i];
-
-		find_master (manager,
-		             nm_settings_connection_get_connection (candidate),
-		             NULL,
-		             &master_connection,
-		             &master_device,
-		             NULL,
-		             NULL);
-		if (   (master_connection && master_connection == sett_conn)
+		NMConnection *candidate = NM_CONNECTION (all_connections[i]);
+
+		find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL);
+		if (   (master_connection && master_connection == connection)
 		    || (master_device && master_device == device)) {
 			slave_device = nm_manager_get_best_device_for_connection (manager,
 			                                                          candidate,
-			                                                          NULL,
 			                                                          FALSE,
-			                                                          devices,
-			                                                          NULL);
+			                                                          devices);
 
 			if (!slaves) {
 				/* what we allocate is quite likely much too large. Don't bother, it is only
@@ -3940,7 +3795,7 @@ find_slaves (NMManager *manager,
 			}
 
 			nm_assert (n_slaves < n_all_connections);
-			slaves[n_slaves].connection = candidate,
+			slaves[n_slaves].connection = NM_SETTINGS_CONNECTION (candidate),
 			slaves[n_slaves].device = slave_device,
 			n_slaves++;
 
@@ -3959,29 +3814,32 @@ static gboolean
 should_connect_slaves (NMConnection *connection, NMDevice *device)
 {
 	NMSettingConnection *s_con;
-	NMSettingConnectionAutoconnectSlaves val;
+	NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
+	gs_free char *value = NULL;
 
 	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
 
-	val = nm_setting_connection_get_autoconnect_slaves (s_con);
-	if (val != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT)
+	/* Check autoconnect-slaves property */
+	autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con);
+	if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT)
 		goto out;
 
-	val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
-	                                                   "connection.autoconnect-slaves",
-	                                                   device,
-	                                                   0, 1, -1);
+	/* Check configuration default for autoconnect-slaves property */
+	value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+	                                               "connection.autoconnect-slaves", device);
+	if (value)
+		autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
 
 out:
-	if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
+	if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO)
 		return FALSE;
-	if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
+	if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES)
 		return TRUE;
 	return FALSE;
 }
 
-static int
+static gint
 compare_slaves (gconstpointer a, gconstpointer b, gpointer sort_by_name)
 {
 	const SlaveConnectionInfo *a_info = a;
@@ -4009,8 +3867,7 @@ autoconnect_slaves (NMManager *self,
 {
 	GError *local_err = NULL;
 
-	if (should_connect_slaves (nm_settings_connection_get_connection (master_connection),
-	                           master_device)) {
+	if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) {
 		gs_free SlaveConnectionInfo *slaves = NULL;
 		guint i, n_slaves = 0;
 
@@ -4151,7 +4008,7 @@ active_connection_parent_active (NMActiveConnection *active,
 {
 	NMDevice *device = nm_active_connection_get_device (active);
 	GError *error = NULL;
-	NMSettingsConnection *sett_conn;
+	NMSettingsConnection *connection;
 	NMDevice *parent;
 
 	g_signal_handlers_disconnect_by_func (active,
@@ -4167,13 +4024,10 @@ active_connection_parent_active (NMActiveConnection *active,
 		return;
 	}
 
-	sett_conn = nm_active_connection_get_settings_connection (active);
+	connection = nm_active_connection_get_settings_connection (active);
 	parent = nm_active_connection_get_device (parent_ac);
 
-	if (!nm_device_create_and_realize (device,
-	                                   nm_settings_connection_get_connection (sett_conn),
-	                                   parent,
-	                                   &error)) {
+	if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) {
 		_LOGW (LOGD_CORE, "Could not realize device '%s': %s",
 		       nm_device_get_iface (device), error->message);
 		nm_active_connection_set_state_fail (active,
@@ -4191,13 +4045,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 {
 	NMDevice *device, *master_device = NULL;
 	NMConnection *applied;
-	NMSettingsConnection *sett_conn;
+	NMSettingsConnection *connection;
 	NMSettingsConnection *master_connection = NULL;
 	NMConnection *existing_connection = NULL;
 	NMActiveConnection *master_ac = NULL;
 	NMAuthSubject *subject;
-	GError *local = NULL;
-	NMConnectionMultiConnect multi_connect;
 
 	g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
 	g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
@@ -4208,8 +4060,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 	device = nm_active_connection_get_device (active);
 	g_return_val_if_fail (device != NULL, FALSE);
 
-	sett_conn = nm_active_connection_get_settings_connection (active);
-	nm_assert (sett_conn);
+	connection = nm_active_connection_get_settings_connection (active);
+	nm_assert (connection);
 
 	applied = nm_active_connection_get_applied_connection (active);
 
@@ -4231,13 +4083,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 	}
 
 	/* Final connection must be available on device */
-	if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL, &local)) {
+	if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) {
 		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
-		             "Connection '%s' is not available on device %s because %s",
-		             nm_settings_connection_get_id (sett_conn),
-		             nm_device_get_iface (device),
-		             local->message);
-		g_error_free (local);
+		             "Connection '%s' is not available on the device %s at this time.",
+		             nm_settings_connection_get_id (connection), nm_device_get_iface (device));
 		return FALSE;
 	}
 
@@ -4248,9 +4097,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 	if (!nm_device_is_real (device)) {
 		NMDevice *parent;
 
-		parent = find_parent_device_for_connection (self,
-		                                            nm_settings_connection_get_connection (sett_conn),
-		                                            NULL);
+		parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
 
 		if (parent && !nm_device_is_real (parent)) {
 			NMSettingsConnection *parent_con;
@@ -4262,11 +4109,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 				return FALSE;
 			}
 
-			parent_ac = nm_manager_activate_connection (self,
-			                                            parent_con,
-			                                            NULL,
-			                                            NULL,
-			                                            parent,
+			parent_ac = nm_manager_activate_connection (self, parent_con, NULL, NULL, parent,
 			                                            subject,
 			                                            NM_ACTIVATION_TYPE_MANAGED,
 			                                            nm_active_connection_get_activation_reason (active),
@@ -4284,10 +4127,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 			nm_active_connection_set_parent (active, parent_ac);
 		} else {
 			/* We can realize now; no need to wait for a parent device. */
-			if (!nm_device_create_and_realize (device,
-			                                   nm_settings_connection_get_connection (sett_conn),
-			                                   parent,
-			                                   error)) {
+			if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
 				g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
 				return FALSE;
 			}
@@ -4295,15 +4135,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 	}
 
 	/* Try to find the master connection/device if the connection has a dependency */
-	if (!find_master (self,
-	                  applied,
-	                  device,
-	                  &master_connection,
-	                  &master_device,
-	                  &master_ac,
+	if (!find_master (self, applied, device,
+	                  &master_connection, &master_device, &master_ac,
 	                  error)) {
 		g_prefix_error (error, "Can not find a master for %s: ",
-		                nm_settings_connection_get_id (sett_conn));
+		                nm_settings_connection_get_id (connection));
 		return FALSE;
 	}
 
@@ -4313,23 +4149,21 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 	if (master_connection || master_device) {
 		if (master_connection) {
 			_LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'",
-			       nm_settings_connection_get_id (sett_conn),
+			       nm_settings_connection_get_id (connection),
 			       nm_settings_connection_get_id (master_connection));
 		}
 		if (master_device) {
 			_LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'",
-			       nm_settings_connection_get_id (sett_conn),
+			       nm_settings_connection_get_id (connection),
 			       nm_device_get_ip_iface (master_device));
 		}
 
 		/* Ensure eg bond slave and the candidate master is a bond master */
-		if (   master_connection
-		    && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection),
-		                                  applied)) {
+		if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) {
 			g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
 			             "The master connection '%s' is not compatible with '%s'",
 			             nm_settings_connection_get_id (master_connection),
-			             nm_settings_connection_get_id (sett_conn));
+			             nm_settings_connection_get_id (connection));
 			return FALSE;
 		}
 
@@ -4348,7 +4182,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 					                nm_device_get_ip_iface (device));
 				} else {
 					g_prefix_error (error, "Master connection '%s' can't be activated: ",
-					                nm_settings_connection_get_id (sett_conn));
+					                nm_settings_connection_get_id (connection));
 				}
 				return FALSE;
 			}
@@ -4365,30 +4199,22 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 
 		nm_active_connection_set_master (active, master_ac);
 		_LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
-		       nm_settings_connection_get_id (sett_conn),
+		       nm_settings_connection_get_id (connection),
 		       master_ac,
 		       nm_dbus_object_get_path (NM_DBUS_OBJECT  (master_ac)) ?: "");
 	}
 
 	/* Check slaves for master connection and possibly activate them */
-	autoconnect_slaves (self, sett_conn, device, nm_active_connection_get_subject (active));
-
-	multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn));
-	if (   multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE
-	    || (   multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE
-	        && NM_IN_SET (nm_active_connection_get_activation_reason (active),
-	                      NM_ACTIVATION_REASON_ASSUME,
-	                      NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES,
-	                      NM_ACTIVATION_REASON_USER_REQUEST))) {
-		/* the profile can be activated multiple times. Proceed. */
-	} else {
+	autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
+
+	{
 		gs_unref_ptrarray GPtrArray *all_ac_arr = NULL;
 		NMActiveConnection *ac;
 		guint i, n_all;
 
 		/* Disconnect the connection if already connected or queued for activation.
 		 * The connection cannot be active multiple times (at the same time).  */
-		ac = active_connection_find (self, sett_conn, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
+		ac = active_connection_find (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
 		                             &all_ac_arr);
 		if (ac) {
 			n_all = all_ac_arr ? all_ac_arr->len : ((guint) 1);
@@ -4451,7 +4277,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError
 		 * is exported, make sure the manager's activating-connection property
 		 * is up-to-date.
 		 */
-		policy_activating_ac_changed (G_OBJECT (priv->policy), NULL, self);
+		policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
 	}
 
 	return success;
@@ -4460,8 +4286,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError
 static NMActiveConnection *
 _new_active_connection (NMManager *self,
                         gboolean is_vpn,
-                        NMSettingsConnection *sett_conn,
-                        NMConnection *incompl_conn,
+                        NMConnection *connection,
                         NMConnection *applied,
                         const char *specific_object,
                         NMDevice *device,
@@ -4471,19 +4296,18 @@ _new_active_connection (NMManager *self,
                         GError **error)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+	NMSettingsConnection *settings_connection = NULL;
 	NMDevice *parent_device;
 
-	nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn));
-	nm_assert (!incompl_conn || NM_IS_CONNECTION (incompl_conn));
-	nm_assert ((!incompl_conn) ^ (!sett_conn));
-	nm_assert (NM_IS_AUTH_SUBJECT (subject));
-	nm_assert (is_vpn == _connection_is_vpn (sett_conn
-	                                         ? nm_settings_connection_get_connection (sett_conn)
-	                                         : incompl_conn));
+	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+	g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
+
+	nm_assert (is_vpn == _connection_is_vpn (connection));
 	nm_assert (is_vpn || NM_IS_DEVICE (device));
 	nm_assert (!nm_streq0 (specific_object, "/"));
-	nm_assert (!applied || NM_IS_CONNECTION (applied));
-	nm_assert (!is_vpn || !applied);
+
+	if (NM_IS_SETTINGS_CONNECTION (connection))
+		settings_connection = (NMSettingsConnection *) connection;
 
 	if (is_vpn) {
 		NMActiveConnection *parent;
@@ -4491,20 +4315,21 @@ _new_active_connection (NMManager *self,
 		/* FIXME: for VPN connections, we don't allow re-activating an
 		 * already active connection. It's a bug, and should be fixed together
 		 * when reworking VPN handling. */
-		if (active_connection_find_by_connection (self,
-		                                          sett_conn,
-		                                          incompl_conn,
-		                                          NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
-		                                          NULL)) {
+		if (active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL)) {
 			g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
 			             "Connection '%s' is already active",
-			             sett_conn ? nm_settings_connection_get_id (sett_conn) : nm_connection_get_id (incompl_conn));
+			             nm_connection_get_id (connection));
 			return NULL;
 		}
 
+		/* FIXME: apparently, activation here only works if @connection is
+		 * a settings-connection. Which is not the case during AddAndActivatate.
+		 * Probably, AddAndActivate is broken for VPN. */
 		if (activation_type != NM_ACTIVATION_TYPE_MANAGED)
 			g_return_val_if_reached (NULL);
 
+		g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
+
 		if (specific_object) {
 			/* Find the specific connection the client requested we use */
 			parent = active_connection_get_by_path (self, specific_object);
@@ -4535,14 +4360,14 @@ _new_active_connection (NMManager *self,
 			return NULL;
 		}
 
-		return (NMActiveConnection *) nm_vpn_connection_new (sett_conn,
+		return (NMActiveConnection *) nm_vpn_connection_new (settings_connection,
 		                                                     parent_device,
 		                                                     nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)),
 		                                                     activation_reason,
 		                                                     subject);
 	}
 
-	return (NMActiveConnection *) nm_act_request_new (sett_conn,
+	return (NMActiveConnection *) nm_act_request_new (settings_connection,
 	                                                  applied,
 	                                                  specific_object,
 	                                                  subject,
@@ -4603,17 +4428,17 @@ fail:
 /**
  * nm_manager_activate_connection():
  * @self: the #NMManager
- * @sett_conn: the #NMSettingsConnection to activate on @device
+ * @connection: the #NMSettingsConnection to activate on @device
  * @applied: (allow-none): the applied connection to activate on @device
  * @specific_object: the specific object path, if any, for the activation
- * @device: the #NMDevice to activate @sett_conn on. Can be %NULL for VPNs.
+ * @device: the #NMDevice to activate @connection on. Can be %NULL for VPNs.
  * @subject: the subject which requested activation
  * @activation_type: whether to assume the connection. That is, take over gracefully,
  *   non-destructible.
  * @activation_reason: the reason for activation
  * @error: return location for an error
  *
- * Begins a new internally-initiated activation of @sett_conn on @device.
+ * Begins a new internally-initiated activation of @connection on @device.
  * @subject should be the subject of the activation that triggered this
  * one, or if this is an autoconnect request, a new internal subject.
  * The returned #NMActiveConnection is owned by the Manager and should be
@@ -4621,11 +4446,11 @@ fail:
  * is supplied, it shall not be modified by the caller afterwards.
  *
  * Returns: (transfer none): the new #NMActiveConnection that tracks
- * activation of @sett_conn on @device
+ * activation of @connection on @device
  */
 NMActiveConnection *
 nm_manager_activate_connection (NMManager *self,
-                                NMSettingsConnection *sett_conn,
+                                NMSettingsConnection *connection,
                                 NMConnection *applied,
                                 const char *specific_object,
                                 NMDevice *device,
@@ -4640,15 +4465,15 @@ nm_manager_activate_connection (NMManager *self,
 	gboolean is_vpn;
 
 	g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
-	g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), NULL);
-	is_vpn = _connection_is_vpn (nm_settings_connection_get_connection (sett_conn));
+	g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL);
+	is_vpn = _connection_is_vpn (NM_CONNECTION (connection));
 	g_return_val_if_fail (is_vpn || NM_IS_DEVICE (device), NULL);
 	g_return_val_if_fail (!error || !*error, NULL);
 	nm_assert (!nm_streq0 (specific_object, "/"));
 
 	priv = NM_MANAGER_GET_PRIVATE (self);
 
-	if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn),
+	if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection),
 	                                          subject,
 	                                          NM_MANAGER_ERROR,
 	                                          NM_MANAGER_ERROR_PERMISSION_DENIED,
@@ -4666,7 +4491,7 @@ nm_manager_activate_connection (NMManager *self,
 			continue;
 
 		active = async_op_data->ac_auth.active;
-		if (   sett_conn == nm_active_connection_get_settings_connection (active)
+		if (   connection == nm_active_connection_get_settings_connection (active)
 		    && nm_streq0 (nm_active_connection_get_specific_object (active), specific_object)
 		    && (!device || nm_active_connection_get_device (active) == device)
 		    && nm_auth_subject_is_internal (nm_active_connection_get_subject (active))
@@ -4677,8 +4502,7 @@ nm_manager_activate_connection (NMManager *self,
 
 	active = _new_active_connection (self,
 	                                 is_vpn,
-	                                 sett_conn,
-	                                 NULL,
+	                                 NM_CONNECTION (connection),
 	                                 applied,
 	                                 specific_object,
 	                                 device,
@@ -4701,9 +4525,7 @@ nm_manager_activate_connection (NMManager *self,
  * validate_activation_request:
  * @self: the #NMManager
  * @context: the D-Bus context of the requestor
- * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there
- *   is only a partial activation.
- * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified)
+ * @connection: the partial or complete #NMConnection to be activated
  * @device_path: the object path of the device to be activated, or NULL
  * @out_device: on successful reutrn, the #NMDevice to be activated with @connection
  *   The caller may pass in a device which shortcuts the lookup by path.
@@ -4722,7 +4544,6 @@ nm_manager_activate_connection (NMManager *self,
 static NMAuthSubject *
 validate_activation_request (NMManager *self,
                              GDBusMethodInvocation *context,
-                             NMSettingsConnection *sett_conn,
                              NMConnection *connection,
                              const char *device_path,
                              NMDevice **out_device,
@@ -4733,16 +4554,10 @@ validate_activation_request (NMManager *self,
 	gboolean is_vpn = FALSE;
 	gs_unref_object NMAuthSubject *subject = NULL;
 
-	nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn));
-	nm_assert (!connection || NM_IS_CONNECTION (connection));
-	nm_assert (sett_conn || connection);
-	nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn));
+	nm_assert (NM_IS_CONNECTION (connection));
 	nm_assert (out_device);
 	nm_assert (out_is_vpn);
 
-	if (!connection)
-		connection = nm_settings_connection_get_connection (sett_conn);
-
 	/* Validate the caller */
 	subject = nm_auth_subject_new_unix_process_from_context (context);
 	if (!subject) {
@@ -4778,20 +4593,17 @@ validate_activation_request (NMManager *self,
 			return NULL;
 		}
 	} else if (!is_vpn) {
-		gs_free_error GError *local = NULL;
-
-		device = nm_manager_get_best_device_for_connection (self, sett_conn, connection, TRUE, NULL, &local);
+		device = nm_manager_get_best_device_for_connection (self, connection, TRUE, NULL);
 		if (!device) {
 			gs_free char *iface = NULL;
 
 			/* VPN and software-device connections don't need a device yet,
 			 * but non-virtual connections do ... */
 			if (!nm_connection_is_virtual (connection)) {
-				g_set_error (error,
-				             NM_MANAGER_ERROR,
-				             NM_MANAGER_ERROR_UNKNOWN_DEVICE,
-				             "No suitable device found for this connection (%s).",
-				             local->message);
+				g_set_error_literal (error,
+				                     NM_MANAGER_ERROR,
+				                     NM_MANAGER_ERROR_UNKNOWN_DEVICE,
+				                     "No suitable device found for this connection.");
 				return NULL;
 			}
 
@@ -4877,7 +4689,7 @@ impl_manager_activate_connection (NMDBusObject *obj,
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	gs_unref_object NMActiveConnection *active = NULL;
 	gs_unref_object NMAuthSubject *subject = NULL;
-	NMSettingsConnection *sett_conn = NULL;
+	NMSettingsConnection *connection = NULL;
 	NMDevice *device = NULL;
 	gboolean is_vpn = FALSE;
 	GError *error = NULL;
@@ -4897,8 +4709,8 @@ impl_manager_activate_connection (NMDBusObject *obj,
 	 * (since this is an explicit request, not an auto-activation request).
 	 */
 	if (connection_path) {
-		sett_conn = nm_settings_get_connection_by_path (priv->settings, connection_path);
-		if (!sett_conn) {
+		connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
+		if (!connection) {
 			error = g_error_new_literal (NM_MANAGER_ERROR,
 			                             NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
 			                             "Connection could not be found.");
@@ -4918,15 +4730,14 @@ impl_manager_activate_connection (NMDBusObject *obj,
 			goto error;
 		}
 
-		sett_conn = nm_device_get_best_connection (device, specific_object_path, &error);
-		if (!sett_conn)
+		connection = nm_device_get_best_connection (device, specific_object_path, &error);
+		if (!connection)
 			goto error;
 	}
 
 	subject = validate_activation_request (self,
 	                                       invocation,
-	                                       sett_conn,
-	                                       NULL,
+	                                       NM_CONNECTION (connection),
 	                                       device_path,
 	                                       &device,
 	                                       &is_vpn,
@@ -4936,8 +4747,7 @@ impl_manager_activate_connection (NMDBusObject *obj,
 
 	active = _new_active_connection (self,
 	                                 is_vpn,
-	                                 sett_conn,
-	                                 NULL,
+	                                 NM_CONNECTION (connection),
 	                                 NULL,
 	                                 specific_object_path,
 	                                 device,
@@ -4961,8 +4771,8 @@ impl_manager_activate_connection (NMDBusObject *obj,
 	return;
 
 error:
-	if (sett_conn) {
-		nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, sett_conn, FALSE, NULL,
+	if (connection) {
+		nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL,
 		                            subject, error->message);
 	}
 	g_dbus_method_invocation_take_error (invocation, error);
@@ -5077,7 +4887,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 {
 	NMManager *self = NM_MANAGER (obj);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	gs_unref_object NMConnection *incompl_conn = NULL;
+	gs_unref_object NMConnection *connection = NULL;
 	NMActiveConnection *active = NULL;
 	gs_unref_object NMAuthSubject *subject = NULL;
 	GError *error = NULL;
@@ -5086,7 +4896,6 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 	gs_unref_variant GVariant *settings = NULL;
 	const char *device_path;
 	const char *specific_object_path;
-	gs_free NMConnection **conns = NULL;
 
 	g_variant_get (parameters, "(@a{sa{sv}}&o&o)", &settings, &device_path, &specific_object_path);
 
@@ -5100,14 +4909,13 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 	 * specific data being in the connection till then (especially in
 	 * validate_activation_request()).
 	 */
-	incompl_conn = nm_simple_connection_new ();
+	connection = nm_simple_connection_new ();
 	if (settings && g_variant_n_children (settings))
-		_nm_connection_replace_settings (incompl_conn, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL);
+		_nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL);
 
 	subject = validate_activation_request (self,
 	                                       invocation,
-	                                       NULL,
-	                                       incompl_conn,
+	                                       connection,
 	                                       device_path,
 	                                       &device,
 	                                       &is_vpn,
@@ -5117,7 +4925,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 
 	if (is_vpn) {
 		/* Try to fill the VPN's connection setting and name at least */
-		if (!nm_connection_get_setting_vpn (incompl_conn)) {
+		if (!nm_connection_get_setting_vpn (connection)) {
 			error = g_error_new_literal (NM_CONNECTION_ERROR,
 			                             NM_CONNECTION_ERROR_MISSING_SETTING,
 			                             "VPN connections require a 'vpn' setting");
@@ -5125,31 +4933,27 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 			goto error;
 		}
 
-		conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1);
-
 		nm_utils_complete_generic (priv->platform,
-		                           incompl_conn,
+		                           connection,
 		                           NM_SETTING_VPN_SETTING_NAME,
-		                           conns,
+		                           (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL),
 		                           NULL,
 		                           _("VPN connection"),
 		                           NULL,
 		                           FALSE); /* No IPv6 by default for now */
 	} else {
-		conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1);
 		/* Let each device subclass complete the connection */
 		if (!nm_device_complete_connection (device,
-		                                    incompl_conn,
+		                                    connection,
 		                                    specific_object_path,
-		                                    conns,
+		                                    (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL),
 		                                    &error))
 			goto error;
 	}
 
 	active = _new_active_connection (self,
 	                                 is_vpn,
-	                                 NULL,
-	                                 incompl_conn,
+	                                 connection,
 	                                 NULL,
 	                                 specific_object_path,
 	                                 device,
@@ -5160,16 +4964,15 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
 	if (!active)
 		goto error;
 
-	nm_active_connection_authorize (active,
-	                                incompl_conn,
+	nm_active_connection_authorize (active, connection,
 	                                _async_op_complete_ac_auth_cb,
 	                                _async_op_data_new_ac_auth_add_and_activate (self,
 	                                                                             active,
 	                                                                             invocation,
-	                                                                             incompl_conn));
+	                                                                             connection));
 
 	/* we passed the pointers on to _async_op_data_new_ac_auth_add_and_activate() */
-	g_steal_pointer (&incompl_conn);
+	g_steal_pointer (&connection);
 	g_steal_pointer (&active);
 	return;
 
@@ -5286,7 +5089,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj,
 	NMManager *self = NM_MANAGER (obj);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	NMActiveConnection *ac;
-	NMSettingsConnection *sett_conn = NULL;
+	NMSettingsConnection *connection = NULL;
 	GError *error = NULL;
 	NMAuthSubject *subject = NULL;
 	NMAuthChain *chain;
@@ -5297,9 +5100,9 @@ impl_manager_deactivate_connection (NMDBusObject *obj,
 	/* Find the connection by its object path */
 	ac = active_connection_get_by_path (self, active_path);
 	if (ac)
-		sett_conn = nm_active_connection_get_settings_connection (ac);
+		connection = nm_active_connection_get_settings_connection (ac);
 
-	if (!sett_conn) {
+	if (!connection) {
 		error = g_error_new_literal (NM_MANAGER_ERROR,
 		                             NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
 		                             "The connection was not active.");
@@ -5315,7 +5118,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj,
 		goto done;
 	}
 
-	if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn),
+	if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection),
 	                                          subject,
 	                                          NM_MANAGER_ERROR,
 	                                          NM_MANAGER_ERROR_PERMISSION_DENIED,
@@ -5337,9 +5140,8 @@ impl_manager_deactivate_connection (NMDBusObject *obj,
 
 done:
 	if (error) {
-		if (sett_conn) {
-			nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
-			                            sett_conn, FALSE, NULL,
+		if (connection) {
+			nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL,
 			                            subject, error->message);
 		}
 		g_dbus_method_invocation_take_error (invocation, error);
@@ -6088,76 +5890,66 @@ start_factory (NMDeviceFactory *factory, gpointer user_data)
 	nm_device_factory_start (factory);
 }
 
-gboolean
-nm_manager_write_device_state (NMManager *self, NMDevice *device)
+void
+nm_manager_write_device_state (NMManager *self)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	int ifindex;
-	gboolean managed;
-	NMConfigDeviceStateManagedType managed_type;
-	const char *uuid = NULL;
-	const char *perm_hw_addr_fake = NULL;
-	gboolean perm_hw_addr_is_fake;
-	guint32 route_metric_default_aspired;
-	guint32 route_metric_default_effective;
-	int nm_owned;
-
-	ifindex = nm_device_get_ip_ifindex (device);
-	if (ifindex <= 0)
-		return FALSE;
-	if (ifindex == 1) {
-		/* ignore loopback */
-		return FALSE;
-	}
+	NMDevice *device;
+	gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
+	gint nm_owned;
 
-	if (!nm_platform_link_get (priv->platform, ifindex))
-		return FALSE;
+	seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL);
 
-	managed = nm_device_get_managed (device, FALSE);
-	if (managed) {
-		NMSettingsConnection *sett_conn;
+	c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
+		int ifindex;
+		gboolean managed;
+		NMConfigDeviceStateManagedType managed_type;
+		NMConnection *settings_connection;
+		const char *uuid = NULL;
+		const char *perm_hw_addr_fake = NULL;
+		gboolean perm_hw_addr_is_fake;
+		guint32 route_metric_default_aspired;
+		guint32 route_metric_default_effective;
+
+		ifindex = nm_device_get_ip_ifindex (device);
+		if (ifindex <= 0)
+			continue;
+		if (ifindex == 1) {
+			/* ignore loopback */
+			continue;
+		}
 
-		sett_conn = nm_device_get_settings_connection (device);
-		if (sett_conn)
-			uuid = nm_settings_connection_get_uuid (sett_conn);
-		managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED;
-	} else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT))
-		managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED;
-	else
-		managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN;
+		if (!nm_platform_link_get (priv->platform, ifindex))
+			continue;
 
-	perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake);
-	if (perm_hw_addr_fake && !perm_hw_addr_is_fake)
-		perm_hw_addr_fake = NULL;
+		managed = nm_device_get_managed (device, FALSE);
+		if (managed) {
+			settings_connection = NM_CONNECTION (nm_device_get_settings_connection (device));
+			if (settings_connection)
+				uuid = nm_connection_get_uuid (settings_connection);
+			managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED;
+		} else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT))
+			managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED;
+		else
+			managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN;
 
-	nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1;
+		perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake);
+		if (perm_hw_addr_fake && !perm_hw_addr_is_fake)
+			perm_hw_addr_fake = NULL;
 
-	route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN,
-	                                                           TRUE, &route_metric_default_aspired);
+		nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1;
 
-	return nm_config_device_state_write (ifindex,
-	                                     managed_type,
-	                                     perm_hw_addr_fake,
-	                                     uuid,
-	                                     nm_owned,
-	                                     route_metric_default_aspired,
-	                                     route_metric_default_effective);
-}
+		route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN,
+		                                                           TRUE, &route_metric_default_aspired);
 
-void
-nm_manager_write_device_state_all (NMManager *self)
-{
-	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
-	NMDevice *device;
-
-	seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL);
-
-	c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
-		if (nm_manager_write_device_state (self, device)) {
-			g_hash_table_add (seen_ifindexes,
-			                  GINT_TO_POINTER (nm_device_get_ip_ifindex (device)));
-		}
+		if (nm_config_device_state_write (ifindex,
+		                                  managed_type,
+		                                  perm_hw_addr_fake,
+		                                  uuid,
+		                                  nm_owned,
+		                                  route_metric_default_aspired,
+		                                  route_metric_default_effective))
+			g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex));
 	}
 
 	nm_config_device_state_prune_unseen (seen_ifindexes);
@@ -6237,7 +6029,7 @@ nm_manager_start (NMManager *self, GError **error)
 	                                                 NULL, NULL,
 	                                                 nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL);
 	for (i = 0; connections[i]; i++)
-		connection_changed (self, connections[i]);
+		connection_changed (self, NM_CONNECTION (connections[i]));
 
 	nm_clear_g_source (&priv->devices_inited_id);
 	priv->devices_inited_id = g_idle_add_full (G_PRIORITY_LOW + 10, devices_inited_cb, self, NULL);
@@ -6337,19 +6129,25 @@ connection_metered_changed (GObject *object,
 }
 
 static void
-policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
 {
 	NMManager *self = NM_MANAGER (user_data);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+	NMDevice *best;
 	NMActiveConnection *ac;
 
 	/* Note: this assumes that it's not possible for the IP4 default
 	 * route to be going over the default-ip6-device. If that changes,
 	 * we need something more complicated here.
 	 */
-	ac = nm_policy_get_default_ip4_ac (priv->policy);
-	if (!ac)
-		ac = nm_policy_get_default_ip6_ac (priv->policy);
+	best = nm_policy_get_default_ip4_device (priv->policy);
+	if (!best)
+		best = nm_policy_get_default_ip6_device (priv->policy);
+
+	if (best)
+		ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
+	else
+		ac = NULL;
 
 	if (ac != priv->primary_connection) {
 		if (priv->primary_connection) {
@@ -6362,12 +6160,10 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat
 		priv->primary_connection = ac ? g_object_ref (ac) : NULL;
 
 		if (priv->primary_connection) {
-			g_signal_connect (priv->primary_connection,
-			                  NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
+			g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
 			                  G_CALLBACK (connection_metered_changed), self);
 		}
-		_LOGD (LOGD_CORE, "PrimaryConnection now %s",
-		       ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
+		_LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
 		_notify (self, PROP_PRIMARY_CONNECTION);
 		_notify (self, PROP_PRIMARY_CONNECTION_TYPE);
 		nm_manager_update_metered (self);
@@ -6375,29 +6171,34 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat
 }
 
 static void
-policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
 {
 	NMManager *self = NM_MANAGER (user_data);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	NMActiveConnection *activating, *best;
+	NMDevice *activating, *best;
+	NMActiveConnection *ac;
 
-	/* We only look at activating-ip6-ac if activating-ip4-ac
-	 * AND default-ip4-ac are NULL; if default-ip4-ac is
-	 * non-NULL, then activating-ip6-ac is irrelevant, since while
-	 * that AC might become the new default-ip6-ac, it can't
-	 * become primary-connection while default-ip4-ac is set to
+	/* We only look at activating-ip6-device if activating-ip4-device
+	 * AND default-ip4-device are NULL; if default-ip4-device is
+	 * non-NULL, then activating-ip6-device is irrelevant, since while
+	 * that device might become the new default-ip6-device, it can't
+	 * become primary-connection while default-ip4-device is set to
 	 * something else.
 	 */
-	activating = nm_policy_get_activating_ip4_ac (priv->policy);
-	best = nm_policy_get_default_ip4_ac (priv->policy);
+	activating = nm_policy_get_activating_ip4_device (priv->policy);
+	best = nm_policy_get_default_ip4_device (priv->policy);
 	if (!activating && !best)
-		activating = nm_policy_get_activating_ip6_ac (priv->policy);
+		activating = nm_policy_get_activating_ip6_device (priv->policy);
 
-	if (nm_g_object_ref_set (&priv->activating_connection, activating)) {
-		_LOGD (LOGD_CORE, "ActivatingConnection now %s",
-		       activating
-		           ? nm_active_connection_get_settings_connection_id (activating)
-		           : "(none)");
+	if (activating)
+		ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
+	else
+		ac = NULL;
+
+	if (ac != priv->activating_connection) {
+		g_clear_object (&priv->activating_connection);
+		priv->activating_connection = ac ? g_object_ref (ac) : NULL;
+		_LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
 		_notify (self, PROP_ACTIVATING_CONNECTION);
 	}
 }
@@ -6902,12 +6703,12 @@ nm_manager_set_capability (NMManager *self,
 
 	priv = NM_MANAGER_GET_PRIVATE (self);
 
-	idx = nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0),
-	                                         sizeof (guint32),
-	                                         priv->capabilities->len,
-	                                         &cap_i,
-	                                         nm_cmp_uint32_p_with_data,
-	                                         NULL);
+	idx = _nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0),
+	                                          sizeof (guint32),
+	                                          priv->capabilities->len,
+	                                          &cap_i,
+	                                          nm_cmp_uint32_p_with_data,
+	                                          NULL);
 	if (idx >= 0)
 		return;
 
@@ -6988,14 +6789,14 @@ constructed (GObject *object)
 	 */
 
 	priv->policy = nm_policy_new (self, priv->settings);
-	g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_AC,
-	                  G_CALLBACK (policy_default_ac_changed), self);
-	g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_AC,
-	                  G_CALLBACK (policy_default_ac_changed), self);
-	g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_AC,
-	                  G_CALLBACK (policy_activating_ac_changed), self);
-	g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_AC,
-	                  G_CALLBACK (policy_activating_ac_changed), self);
+	g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
+	                  G_CALLBACK (policy_default_device_changed), self);
+	g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
+	                  G_CALLBACK (policy_default_device_changed), self);
+	g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
+	                  G_CALLBACK (policy_activating_device_changed), self);
+	g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
+	                  G_CALLBACK (policy_activating_device_changed), self);
 
 	priv->config = g_object_ref (nm_config_get ());
 	g_signal_connect (G_OBJECT (priv->config),
@@ -7333,8 +7134,8 @@ dispose (GObject *object)
 	}
 
 	if (priv->policy) {
-		g_signal_handlers_disconnect_by_func (priv->policy, policy_default_ac_changed, self);
-		g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_ac_changed, self);
+		g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, self);
+		g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, self);
 		g_clear_object (&priv->policy);
 	}