summary refs log tree commit diff
path: root/src/devices
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-09-15 01:04:32 +0200
committerMichael Biebl <biebl@debian.org>2018-09-15 01:04:32 +0200
commitc240974325c552cad177c457d6ff04e381fd77a3 (patch)
tree2fe5561359b767db15292c84447be8075a75388a /src/devices
parent8f7a3cbbdd0c0a48277c341dd3a8ec8743ae9735 (diff)
New upstream version 1.14.0 upstream/1.14.0
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/nm-device-6lowpan.c10
-rw-r--r--src/devices/nm-device-wpan.c8
-rw-r--r--src/devices/nm-device.c71
-rw-r--r--src/devices/nm-device.h4
-rw-r--r--src/devices/wifi/nm-device-iwd.c148
-rw-r--r--src/devices/wifi/nm-device-wifi.c1
6 files changed, 158 insertions, 84 deletions
diff --git a/src/devices/nm-device-6lowpan.c b/src/devices/nm-device-6lowpan.c
index 600d1b80..b6b9157c 100644
--- a/src/devices/nm-device-6lowpan.c
+++ b/src/devices/nm-device-6lowpan.c
@@ -114,7 +114,7 @@ create_and_realize (NMDevice *device,
 	NMSetting6Lowpan *s_6lowpan;
 	int parent_ifindex;
 
-	s_6lowpan = nm_connection_get_setting_6lowpan (connection);
+	s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN));
 	g_return_val_if_fail (s_6lowpan, FALSE);
 
 	parent_ifindex = parent ? nm_device_get_ifindex (parent) : 0;
@@ -192,7 +192,7 @@ complete_connection (NMDevice *device,
 	                           NULL,
 	                           TRUE);
 
-	s_6lowpan = nm_connection_get_setting_6lowpan (connection);
+	s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN));
 	if (!s_6lowpan) {
 		g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
 		                     "A '6lowpan' setting is required.");
@@ -215,7 +215,7 @@ complete_connection (NMDevice *device,
 static void
 update_connection (NMDevice *device, NMConnection *connection)
 {
-	NMSetting6Lowpan *s_6lowpan = nm_connection_get_setting_6lowpan (connection);
+	NMSetting6Lowpan *s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN));
 
 	if (!s_6lowpan) {
 		s_6lowpan = (NMSetting6Lowpan *) nm_setting_6lowpan_new ();
@@ -310,7 +310,7 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection)
 
 	g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL);
 
-	s_6lowpan = nm_connection_get_setting_6lowpan (connection);
+	s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN));
 	g_assert (s_6lowpan);
 
 	return nm_setting_6lowpan_get_parent (s_6lowpan);
@@ -326,7 +326,7 @@ get_connection_iface (NMDeviceFactory *factory,
 
 	g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL);
 
-	s_6lowpan = nm_connection_get_setting_6lowpan (connection);
+	s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN));
 	g_assert (s_6lowpan);
 
 	if (!parent_iface)
diff --git a/src/devices/nm-device-wpan.c b/src/devices/nm-device-wpan.c
index dd2ebac1..f910b0b8 100644
--- a/src/devices/nm-device-wpan.c
+++ b/src/devices/nm-device-wpan.c
@@ -69,7 +69,7 @@ complete_connection (NMDevice *device,
 	                           NULL,
 	                           TRUE);
 
-	s_wpan = nm_connection_get_setting_wpan (connection);
+	s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN));
 	if (!s_wpan) {
 		g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
 		                     "A 'wpan' setting is required.");
@@ -82,7 +82,7 @@ complete_connection (NMDevice *device,
 static void
 update_connection (NMDevice *device, NMConnection *connection)
 {
-	NMSettingWpan *s_wpan = nm_connection_get_setting_wpan (connection);
+	NMSettingWpan *s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN));
 
 	if (!s_wpan) {
 		s_wpan = (NMSettingWpan *) nm_setting_wpan_new ();
@@ -99,7 +99,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError
 	if (!NM_DEVICE_CLASS (nm_device_wpan_parent_class)->check_connection_compatible (device, connection, error))
 		return FALSE;
 
-	s_wpan = nm_connection_get_setting_wpan (connection);
+	s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN));
 
 	mac = nm_setting_wpan_get_mac_address (s_wpan);
 	if (mac) {
@@ -143,7 +143,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
 	connection = nm_device_get_applied_connection (device);
 	g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
 
-	s_wpan = nm_connection_get_setting_wpan (connection);
+	s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN));
 	g_return_val_if_fail (s_wpan, NM_ACT_STAGE_RETURN_FAILURE);
 
 	hwaddr = nm_platform_link_get_address (platform, ifindex, &hwaddr_len);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 515e6334..8ca899a2 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -80,7 +80,10 @@
 #include "nm-audit-manager.h"
 #include "nm-connectivity.h"
 #include "nm-dbus-interface.h"
+
+#include "nm-device-generic.h"
 #include "nm-device-vlan.h"
+#include "nm-device-wireguard.h"
 
 #include "nm-device-logging.h"
 _LOG_DECLARE_SELF (NMDevice);
@@ -823,6 +826,13 @@ _ethtool_state_set (NMDevice *self)
 
 /*****************************************************************************/
 
+static gboolean
+is_loopback (NMDevice *self)
+{
+	return    NM_IS_DEVICE_GENERIC (self)
+	       && NM_DEVICE_GET_PRIVATE (self)->ifindex == 1;
+}
+
 NMSettings *
 nm_device_get_settings (NMDevice *self)
 {
@@ -2460,7 +2470,7 @@ concheck_is_possible (NMDevice *self)
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 
 	if (   !nm_device_is_real (self)
-	    || NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_LOOPBACK))
+	    || is_loopback (self))
 		return FALSE;
 
 	/* we enable periodic checks for every device state (except UNKNOWN). Especially with
@@ -4289,10 +4299,13 @@ realize_start_setup (NMDevice *self,
 	                               NM_UNMANAGED_EXTERNAL_DOWN,
 	                               is_unmanaged_external_down (self, TRUE));
 
-	/* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK flag.
+	/* Unmanaged the loopback device with an explicit NM_UNMANAGED_BY_TYPE flag.
 	 * Later we might want to manage 'lo' too. Currently that doesn't work because
 	 * NetworkManager might down the interface or remove the 127.0.0.1 address. */
-	nm_device_set_unmanaged_flags (self, NM_UNMANAGED_LOOPBACK, priv->ifindex == 1);
+	nm_device_set_unmanaged_flags (self,
+	                               NM_UNMANAGED_BY_TYPE,
+	                                  is_loopback (self)
+	                               || NM_IS_DEVICE_WIREGUARD (self));
 
 	nm_device_set_unmanaged_by_user_udev (self);
 	nm_device_set_unmanaged_by_user_conf (self);
@@ -4488,7 +4501,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
 
 	nm_device_set_unmanaged_flags (self,
 	                               NM_UNMANAGED_PARENT |
-	                               NM_UNMANAGED_LOOPBACK |
+	                               NM_UNMANAGED_BY_TYPE |
 	                               NM_UNMANAGED_USER_UDEV |
 	                               NM_UNMANAGED_USER_EXPLICIT |
 	                               NM_UNMANAGED_EXTERNAL_DOWN |
@@ -5596,6 +5609,14 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError **
 		                                        klass->connection_type_check_compatible,
 		                                        error))
 			return FALSE;
+	} else if (klass->check_connection_compatible == check_connection_compatible) {
+		/* the device class does not implement check_connection_compatible nor set
+		 * connection_type_check_compatible. That means, it is by default not compatible
+		 * with any connection type. */
+		nm_utils_error_set_literal (error,
+		                            NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE,
+		                            "device does not support any connections");
+		return FALSE;
 	}
 
 	conn_iface = nm_manager_get_connection_iface (nm_manager_get (),
@@ -7540,6 +7561,7 @@ dhcp4_start (NMDevice *self)
 	gs_unref_bytes GBytes *hwaddr = NULL;
 	gs_unref_bytes GBytes *client_id = NULL;
 	NMConnection *connection;
+	GError *error = NULL;
 
 	connection = nm_device_get_applied_connection (self);
 	g_return_val_if_fail (connection, FALSE);
@@ -7570,10 +7592,14 @@ dhcp4_start (NMDevice *self)
 	                                                client_id,
 	                                                get_dhcp_timeout (self, AF_INET),
 	                                                priv->dhcp_anycast_address,
-	                                                NULL);
+	                                                NULL,
+	                                                &error);
 
-	if (!priv->dhcp4.client)
+	if (!priv->dhcp4.client) {
+		_LOGW (LOGD_DHCP4, "failure to start DHCP: %s", error->message);
+		g_clear_error (&error);
 		return NM_ACT_STAGE_RETURN_FAILURE;
+	}
 
 	priv->dhcp4.state_sigid = g_signal_connect (priv->dhcp4.client,
 	                                            NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
@@ -8375,6 +8401,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
 	gs_unref_bytes GBytes *hwaddr = NULL;
 	gs_unref_bytes GBytes *duid = NULL;
 	gboolean enforce_duid = FALSE;
+	GError *error = NULL;
 
 	const NMPlatformIP6Address *ll_addr = NULL;
 
@@ -8414,23 +8441,29 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
 	                                                priv->dhcp_anycast_address,
 	                                                (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE,
 	                                                nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)),
-	                                                priv->dhcp6.needed_prefixes);
-
-	if (priv->dhcp6.client) {
-		priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client,
-		                                            NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
-		                                            G_CALLBACK (dhcp6_state_changed),
-		                                            self);
-		priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp6.client,
-		                                             NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED,
-		                                             G_CALLBACK (dhcp6_prefix_delegated),
-		                                             self);
+	                                                priv->dhcp6.needed_prefixes,
+	                                                &error);
+	if (!priv->dhcp6.client) {
+		_LOGW (LOGD_DHCP6, "failure to start DHCPv6: %s", error->message);
+		g_clear_error (&error);
+		if (nm_device_sys_iface_state_is_external_or_assume (self))
+			priv->dhcp6.was_active = TRUE;
+		return FALSE;
 	}
 
+	priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client,
+	                                            NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
+	                                            G_CALLBACK (dhcp6_state_changed),
+	                                            self);
+	priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp6.client,
+	                                             NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED,
+	                                             G_CALLBACK (dhcp6_prefix_delegated),
+	                                             self);
+
 	if (nm_device_sys_iface_state_is_external_or_assume (self))
 		priv->dhcp6.was_active = TRUE;
 
-	return !!priv->dhcp6.client;
+	return TRUE;
 }
 
 static gboolean
@@ -12859,7 +12892,7 @@ NM_UTILS_FLAGS2STR_DEFINE (nm_unmanaged_flags2str, NMUnmanagedFlags,
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_SLEEPING, "sleeping"),
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_QUITTING, "quitting"),
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_PARENT, "parent"),
-	NM_UTILS_FLAGS2STR (NM_UNMANAGED_LOOPBACK, "loopback"),
+	NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_TYPE, "by-type"),
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_PLATFORM_INIT, "platform-init"),
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_EXPLICIT, "user-explicit"),
 	NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_DEFAULT, "by-default"),
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 7d74e5b9..6342a657 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -583,7 +583,7 @@ void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device);
  * @NM_UNMANAGED_SLEEPING: %TRUE when unmanaged because NM is sleeping.
  * @NM_UNMANAGED_QUITTING: %TRUE when unmanaged because NM is shutting down.
  * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged
- * @NM_UNMANAGED_LOOPBACK: %TRUE for unmanaging loopback device
+ * @NM_UNMANAGED_BY_TYPE: %TRUE for unmanaging device by type, like loopback.
  * @NM_UNMANAGED_PLATFORM_INIT: %TRUE when unmanaged because platform link not
  *   yet initialized. Unrealized device are also unmanaged for this reason.
  * @NM_UNMANAGED_USER_EXPLICIT: %TRUE when unmanaged by explicit user decision
@@ -614,7 +614,7 @@ typedef enum { /*< skip >*/
 	NM_UNMANAGED_SLEEPING      = (1LL <<  0),
 	NM_UNMANAGED_QUITTING      = (1LL <<  1),
 	NM_UNMANAGED_PARENT        = (1LL <<  2),
-	NM_UNMANAGED_LOOPBACK      = (1LL <<  3),
+	NM_UNMANAGED_BY_TYPE       = (1LL <<  3),
 	NM_UNMANAGED_PLATFORM_INIT = (1LL <<  4),
 	NM_UNMANAGED_USER_EXPLICIT = (1LL <<  5),
 	NM_UNMANAGED_USER_SETTINGS = (1LL <<  6),
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 56b1f853..32d49916 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -229,6 +229,85 @@ vardict_from_network_type (const char *type)
 }
 
 static void
+insert_ap_from_network (GHashTable *aps, GDBusProxy *proxy, const char *path, int16_t signal, uint32_t ap_id)
+{
+	gs_unref_object GDBusProxy *network_proxy = NULL;
+	gs_unref_variant GVariant *name_value = NULL, *type_value = NULL;
+	const char *name, *type;
+	GVariantBuilder builder;
+	gs_unref_variant GVariant *props = NULL;
+	GVariant *rsn;
+	uint8_t bssid[6];
+	NMWifiAP *ap;
+	GError *error;
+
+	network_proxy = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy),
+	                                       G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+	                                       NULL,
+	                                       NM_IWD_SERVICE,
+	                                       path,
+	                                       NM_IWD_NETWORK_INTERFACE,
+	                                       NULL, &error);
+	if (!network_proxy) {
+		g_clear_error (&error);
+		return;
+	}
+
+	name_value = g_dbus_proxy_get_cached_property (network_proxy, "Name");
+	type_value = g_dbus_proxy_get_cached_property (network_proxy, "Type");
+	if (   !name_value
+	    || !g_variant_is_of_type (name_value, G_VARIANT_TYPE_STRING)
+	    || !type_value
+	    || !g_variant_is_of_type (type_value, G_VARIANT_TYPE_STRING))
+		return;
+
+	name = g_variant_get_string (name_value, NULL);
+	type = g_variant_get_string (type_value, NULL);
+
+	/* What we get from IWD are networks, or ESSs, that may contain
+	 * multiple APs, or BSSs, each.  We don't get information about any
+	 * specific BSSs within an ESS but we can safely present each ESS
+	 * as an individual BSS to NM, which will be seen as ESSs comprising
+	 * a single BSS each.  NM won't be able to handle roaming but IWD
+	 * already does that.  We fake the BSSIDs as they don't play any
+	 * role either.
+	 */
+	bssid[0] = 0x00;
+	bssid[1] = 0x01;
+	bssid[2] = 0x02;
+	bssid[3] = ap_id >> 16;
+	bssid[4] = ap_id >> 8;
+	bssid[5] = ap_id;
+
+	/* WEP not supported */
+	if (nm_streq (type, "wep"))
+		return;
+
+	g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+	g_variant_builder_add (&builder, "{sv}", "BSSID",
+	                       g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, bssid, 6, 1));
+	g_variant_builder_add (&builder, "{sv}", "Mode",
+	                       g_variant_new_string ("infrastructure"));
+
+	rsn = vardict_from_network_type (type);
+	if (rsn)
+		g_variant_builder_add (&builder, "{sv}", "RSN", rsn);
+
+	props = g_variant_new ("a{sv}", &builder);
+
+	ap = nm_wifi_ap_new_from_properties (path, props);
+
+	nm_wifi_ap_set_ssid_arr (ap,
+	                         (const guint8 *) name,
+	                         NM_MIN (32, strlen (name)));
+
+	nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100));
+	nm_wifi_ap_set_freq (ap, 2417);
+	nm_wifi_ap_set_max_bitrate (ap, 65000);
+	g_hash_table_insert (aps, (gpointer) nm_wifi_ap_get_supplicant_path (ap), ap);
+}
+
+static void
 get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
 {
 	NMDeviceIwd *self = user_data;
@@ -242,9 +321,16 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
 	gboolean changed = FALSE;
 	GHashTableIter ap_iter;
 	gs_unref_hashtable GHashTable *new_aps = NULL;
+	/* Depending on whether we're using the Station interface or the Device
+	 * interface for compatibility with IWD <= 0.7, the return signature of
+	 * GetOrderedNetworks will be different.
+	 */
+	gboolean compat = priv->dbus_station_proxy == priv->dbus_device_proxy;
+	const char *return_sig = compat ? "(a(osns))" : "(a(on))";
+	static uint32_t ap_id = 0;
 
 	variant = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res,
-	                                      G_VARIANT_TYPE ("(a(osns))"),
+	                                      G_VARIANT_TYPE (return_sig),
 	                                      &error);
 	if (!variant) {
 		_LOGE (LOGD_WIFI, "Station.GetOrderedNetworks failed: %s",
@@ -254,60 +340,14 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data)
 
 	new_aps = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref);
 
-	g_variant_get (variant, "(a(osns))", &networks);
-
-	while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type)) {
-		GVariantBuilder builder;
-		gs_unref_variant GVariant *props = NULL;
-		GVariant *rsn;
-		static uint32_t ap_id = 0;
-		uint8_t bssid[6];
+	g_variant_get (variant, return_sig, &networks);
 
-		/*
-		 * What we get from IWD are networks, or ESSs, that may
-		 * contain multiple APs, or BSSs, each.  We don't get
-		 * information about any specific BSSs within an ESS but
-		 * we can safely present each ESS as an individual BSS to
-		 * NM, which will be seen as ESSs comprising a single BSS
-		 * each.  NM won't be able to handle roaming but IWD already
-		 * does that.  We fake the BSSIDs as they don't play any
-		 * role either.
-		 */
-		bssid[0] = 0x00;
-		bssid[1] = 0x01;
-		bssid[2] = 0x02;
-		bssid[3] = ap_id >> 16;
-		bssid[4] = ap_id >> 8;
-		bssid[5] = ap_id++;
-
-		/* WEP not supported */
-		if (!strcmp (type, "wep"))
-			continue;
-
-		g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
-		g_variant_builder_add (&builder, "{sv}", "BSSID",
-		                       g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, bssid, 6, 1));
-		g_variant_builder_add (&builder, "{sv}", "Mode",
-		                       g_variant_new_string ("infrastructure"));
-
-		rsn = vardict_from_network_type (type);
-		if (rsn)
-			g_variant_builder_add (&builder, "{sv}", "RSN", rsn);
-
-		props = g_variant_new ("a{sv}", &builder);
-
-		ap = nm_wifi_ap_new_from_properties (path, props);
-
-		nm_wifi_ap_set_ssid_arr (ap,
-		                         (const guint8 *) name,
-		                         NM_MIN (32, strlen (name)));
-
-		nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100));
-		nm_wifi_ap_set_freq (ap, 2417);
-		nm_wifi_ap_set_max_bitrate (ap, 65000);
-		g_hash_table_insert (new_aps,
-		                     (gpointer) nm_wifi_ap_get_supplicant_path (ap),
-		                     ap);
+	if (compat) {
+		while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type))
+			insert_ap_from_network (new_aps, priv->dbus_station_proxy, path, signal, ap_id++);
+	} else {
+		while (g_variant_iter_next (networks, "(&on)", &path, &signal))
+			insert_ap_from_network (new_aps, priv->dbus_station_proxy, path, signal, ap_id++);
 	}
 
 	g_variant_iter_free (networks);
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 64ab82cb..ec1150bb 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -2593,6 +2593,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
 	set_current_ap (self, ap, FALSE);
 	nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
 	                                          nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)));
+	g_object_unref (ap);
 	return NM_ACT_STAGE_RETURN_SUCCESS;
 
 done: