diff --git a/src/nm-manager.c b/src/nm-manager.c
index bf8be64..2b7bf36 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -150,14 +150,16 @@ static gboolean find_master (NMManager *self,
                              NMConnection **out_master_connection,
                              NMDevice **out_master_device,
                              NMActiveConnection **out_master_ac,
                              GError **error);
 
 static void nm_manager_update_state (NMManager *manager);
 
+static void recheck_assume_connection (NMDevice *device, gpointer user_data);
+
 #define SSD_POKE_INTERVAL 120
 #define ORIGDEV_TAG "originating-device"
 
 typedef struct {
 	gboolean user_enabled;
 	gboolean sw_enabled;
 	gboolean hw_enabled;
@@ -671,14 +673,25 @@ manager_device_state_changed (NMDevice *device,
 	case NM_DEVICE_STATE_PREPARE:
 	case NM_DEVICE_STATE_FAILED:
 		g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
 		break;
 	default:
 		break;
 	}
+
+	if (new_state == NM_DEVICE_STATE_PREPARE) {
+		const GSList *iter;
+
+		for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) {
+			NMDevice *candidate = NM_DEVICE (iter->data);
+
+			if ((candidate != device) && (nm_device_get_state (candidate) <= NM_DEVICE_STATE_DISCONNECTED))
+				recheck_assume_connection (candidate, self);
+		}
+	}
 }
 
 static void device_has_pending_action_changed (NMDevice *device,
                                                GParamSpec *pspec,
                                                NMManager *self);
 
 static void
@@ -1511,31 +1524,58 @@ local_slist_free (void *loc)
 
 static gboolean
 match_connection_filter (NMConnection *connection, gpointer user_data)
 {
 	return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
 }
 
+static gboolean
+connection_master_exists (NMManager *self,
+                          NMConnection *connection,
+                          NMDevice *device,
+                          NMActiveConnection **out_master_ac)
+{
+	NMSettingConnection *s_con;
+
+	g_return_val_if_fail (out_master_ac != NULL, FALSE);
+	g_return_val_if_fail (*out_master_ac == NULL, FALSE);
+
+	find_master (self, connection, device, NULL, NULL, out_master_ac, NULL);
+	s_con = nm_connection_get_setting_connection (connection);
+	if (nm_setting_connection_get_master (s_con) || nm_setting_connection_get_slave_type (s_con)) {
+		if (!*out_master_ac) {
+			nm_log_dbg (LOGD_DEVICE, "(%s): master not yet found, postponing activation",
+			            nm_device_get_iface (device));
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
 /**
  * get_existing_connection:
  * @manager: #NMManager instance
  * @device: #NMDevice instance
+ * @master_ac:
  *
  * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
  *   the device does not support assuming existing connections.
  */
 static NMConnection *
-get_existing_connection (NMManager *manager, NMDevice *device)
+get_existing_connection (NMManager *manager, NMDevice *device, NMActiveConnection **out_master_ac)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
 	free_slist GSList *connections = nm_manager_get_activatable_connections (manager);
 	NMConnection *connection = NULL, *matched;
 	NMSettingsConnection *added = NULL;
 	GError *error = NULL;
 
+	g_return_val_if_fail (out_master_ac != NULL, NULL);
+	g_return_val_if_fail (*out_master_ac == NULL, NULL);
+
 	nm_device_capture_initial_config (device);
 
 	/* 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.
@@ -1560,21 +1600,28 @@ get_existing_connection (NMManager *manager, NMDevice *device)
 	                                     match_connection_filter,
 	                                     device);
 	if (matched) {
 		nm_log_info (LOGD_DEVICE, "(%s): found matching connection '%s'",
 		             nm_device_get_iface (device),
 		             nm_connection_get_id (matched));
 		g_object_unref (connection);
-		return matched;
+
+		return connection_master_exists (manager, matched, device, out_master_ac) ? matched : NULL;
 	}
 
 	nm_log_dbg (LOGD_DEVICE, "(%s): generated connection '%s'",
 	            nm_device_get_iface (device),
 	            nm_connection_get_id (connection));
 
+	/* Check for the master before adding the generated connection to Settings */
+	if (!connection_master_exists (manager, connection, device, out_master_ac)) {
+		g_object_unref (connection);
+		return NULL;
+	}
+
 	added = nm_settings_add_connection (priv->settings, connection, FALSE, &error);
 	if (added)
 		nm_settings_connection_set_nm_generated (added);
 	else {
 		nm_log_warn (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s",
 		             nm_device_get_iface (device),
 		             nm_connection_get_id (connection),
@@ -1583,17 +1630,20 @@ get_existing_connection (NMManager *manager, NMDevice *device)
 	}
 	g_object_unref (connection);
 
 	return added ? NM_CONNECTION (added) : NULL;
 }
 
 static gboolean
-assume_connection (NMManager *self, NMDevice *device, NMConnection *connection)
+assume_connection (NMManager *self,
+                   NMDevice *device,
+                   NMConnection *connection,
+                   NMActiveConnection *master_ac)
 {
-	NMActiveConnection *active, *master_ac;
+	NMActiveConnection *active;
 	NMAuthSubject *subject;
 	GError *error = NULL;
 
 	nm_log_dbg (LOGD_DEVICE, "(%s): will attempt to assume connection",
 	            nm_device_get_iface (device));
 
 	/* Move device to DISCONNECTED to activate the connection */
@@ -1613,57 +1663,58 @@ assume_connection (NMManager *self, NMDevice *device, NMConnection *connection)
 		             nm_connection_get_path (connection),
 		             error ? error->code : -1,
 		             error && error->message ? error->message : "(unknown)");
 		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, connection, device, NULL, NULL, &master_ac, NULL) && master_ac)
+	if (master_ac)
 		nm_active_connection_set_master (active, master_ac);
-
 	nm_active_connection_set_assumed (active, TRUE);
 	nm_active_connection_export (active);
 	active_connection_add (self, active);
 	nm_device_queue_activation (device, NM_ACT_REQUEST (active));
 	g_object_unref (active);
 
 	return TRUE;
 }
 
 static void
 recheck_assume_connection (NMDevice *device, gpointer user_data)
 {
 	NMManager *self = user_data;
-	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	const GSList *unmanaged_specs;
 	NMConnection *connection;
 	gboolean was_unmanaged = FALSE;
+	NMActiveConnection *master_ac = NULL;
 
 	if (manager_sleeping (self))
 		return;
-	unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
-	if (nm_device_spec_match_list (device, unmanaged_specs))
+	if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER))
+		return;
+	/* Check for activation request, not PREPARE state, to avoid race
+	 * when PREPARE stage is scheduled but has not yet run.
+	 */
+	if (nm_device_get_act_request (device))
 		return;
 
-	connection = get_existing_connection (self, device);
+	connection = get_existing_connection (self, device, &master_ac);
 	if (!connection) {
-		nm_log_info (LOGD_DEVICE, "can't assume; no connection");
+		nm_log_dbg (LOGD_DEVICE, "(%s) can't assume; failed to generate existing connection",
+		            nm_device_get_iface (device));
 		return;
 	}
 
 	if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
 		was_unmanaged = TRUE;
 		nm_device_state_changed (device,
 		                         NM_DEVICE_STATE_UNAVAILABLE,
 		                         NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
 	}
 
-	if (!assume_connection (self, device, connection)) {
+	if (!assume_connection (self, device, connection, master_ac)) {
 		if (was_unmanaged) {
 			nm_device_state_changed (device,
 			                         NM_DEVICE_STATE_UNAVAILABLE,
 			                         NM_DEVICE_STATE_REASON_CONFIG_FAILED);
 			nm_device_state_changed (device,
 			                         NM_DEVICE_STATE_UNMANAGED,
 			                         NM_DEVICE_STATE_REASON_CONFIG_FAILED);
@@ -1686,14 +1737,15 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con)
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	const char *iface, *driver, *type_desc;
 	char *path;
 	static guint32 devcount = 0;
 	const GSList *unmanaged_specs;
 	gboolean user_unmanaged, sleeping;
 	NMConnection *connection = NULL;
+	NMActiveConnection *master_ac = NULL;
 	gboolean enabled = FALSE;
 	RfKillType rtype;
 	GSList *iter, *remove = NULL;
 
 	/* No duplicates */
 	if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device)))
 		return;
@@ -1768,15 +1820,15 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con)
 	nm_dbus_manager_register_object (priv->dbus_mgr, path, device);
 	nm_log_info (LOGD_CORE, "(%s): exported as %s", iface, path);
 	g_free (path);
 
 	/* Don't generate a connection e.g. for devices NM just created, or
 	 * for the loopback, or when we're sleeping. */
 	if (generate_con && !user_unmanaged && !sleeping)
-		connection = get_existing_connection (self, device);
+		connection = get_existing_connection (self, device, &master_ac);
 
 	/* Start the device if it's supposed to be managed. Note that this will
 	 * manage default-unmanaged devices if they have a generated connection.
 	 */
 	if (nm_device_get_managed (device) || connection) {
 		nm_device_state_changed (device,
 		                         NM_DEVICE_STATE_UNAVAILABLE,
@@ -1793,15 +1845,15 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con)
 	 */
 	system_create_virtual_devices (self);
 
 	/* If the device has a connection it can assume, do that now. If it's a
 	 * device that we might ever want to assume a connection on, then set that up.
 	 */
 	if (connection)
-		assume_connection (self, device, connection);
+		assume_connection (self, device, connection, master_ac);
 	if (generate_con) {
 		g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME,
 		                  G_CALLBACK (recheck_assume_connection), self);
 	}
 }
 
 static NMDevice *
