summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/nm-device-bond.c3
-rw-r--r--src/devices/nm-device-ethernet.c4
-rw-r--r--src/devices/nm-device-private.h4
-rw-r--r--src/devices/nm-device.c375
-rw-r--r--src/devices/nm-device.h15
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c6
-rw-r--r--src/devices/wifi/nm-device-wifi.c303
-rw-r--r--src/devices/wifi/nm-wifi-ap.c61
-rw-r--r--src/devices/wifi/nm-wifi-ap.h7
-rw-r--r--src/devices/wwan/nm-modem-broadband.c4
-rw-r--r--src/devices/wwan/nm-modem.c9
-rw-r--r--src/dhcp/nm-dhcp-dhclient-utils.c4
-rw-r--r--src/dhcp/tests/test-dhcp-dhclient.c1
-rw-r--r--src/dns/nm-dns-manager.c4
-rw-r--r--src/nm-active-connection.c2
-rw-r--r--src/nm-config-data.c2
-rw-r--r--src/nm-config-data.h2
-rw-r--r--src/nm-config.c1
-rw-r--r--src/nm-core-utils.c3
-rw-r--r--src/nm-manager.c24
-rw-r--r--src/nm-manager.h2
-rw-r--r--src/nm-policy.c6
-rw-r--r--src/nm-rfkill-manager.c2
-rw-r--r--src/platform/nm-platform.c22
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c9
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c2
-rw-r--r--src/supplicant/nm-supplicant-interface.c92
-rw-r--r--src/systemd/src/basic/siphash24.c7
-rw-r--r--src/systemd/src/basic/time-util.c2
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-option.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c2
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-lease.c2
-rw-r--r--src/tests/test-general.c4
-rw-r--r--src/vpn/nm-vpn-connection.c4
35 files changed, 493 insertions, 503 deletions
diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
index 5dba19d9..34d34eb4 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -169,7 +169,8 @@ update_connection (NMDevice *device, NMConnection *connection)
 		const char *defvalue = nm_setting_bond_get_option_default (s_bond, *options);
 		char *p;
 
-		if (_nm_setting_bond_get_option_type (s_bond, *options) == NM_BOND_OPTION_TYPE_BOTH) {
+		if (   value
+		    && _nm_setting_bond_get_option_type (s_bond, *options) == NM_BOND_OPTION_TYPE_BOTH) {
 			p = strchr (value, ' ');
 			if (p)
 				*p = '\0';
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 327e54a8..5df16df0 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -1171,7 +1171,7 @@ dcb_state (NMDevice *device, gboolean timeout)
 			break;
 		}
 		_LOGD (LOGD_DCB, "dcb_state() preconfig down falling through");
-		/* carrier never went down? fall through */
+		/* fall through */
 	case DCB_WAIT_CARRIER_PRECONFIG_UP:
 		if (timeout || carrier) {
 			_LOGD (LOGD_DCB, "dcb_state() preconfig up configuring DCB");
@@ -1195,7 +1195,7 @@ dcb_state (NMDevice *device, gboolean timeout)
 			break;
 		}
 		_LOGD (LOGD_DCB, "dcb_state() postconfig down falling through");
-		/* carrier never went down? fall through */
+		/* fall through */
 	case DCB_WAIT_CARRIER_POSTCONFIG_UP:
 		if (timeout || carrier) {
 			_LOGD (LOGD_DCB, "dcb_state() postconfig up starting IP");
diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h
index c6d2a931..2023feb5 100644
--- a/src/devices/nm-device-private.h
+++ b/src/devices/nm-device-private.h
@@ -91,10 +91,6 @@ gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release);
 
 void nm_device_recheck_available_connections (NMDevice *device);
 
-void nm_device_queued_state_clear (NMDevice *device);
-
-NMDeviceState nm_device_queued_state_peek (NMDevice *device);
-
 gboolean nm_device_get_enslaved (NMDevice *device);
 
 NMDevice *nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 1fcf965c..2a2d276d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -73,9 +73,64 @@ _LOG_DECLARE_SELF (NMDevice);
 #include "introspection/org.freedesktop.NetworkManager.Device.h"
 #include "introspection/org.freedesktop.NetworkManager.Device.Statistics.h"
 
-G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
+/*****************************************************************************/
 
-#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE)
+#define DHCP_RESTART_TIMEOUT   120
+#define DHCP_NUM_TRIES_MAX     3
+#define DEFAULT_AUTOCONNECT    TRUE
+
+/*****************************************************************************/
+
+typedef void (*ActivationHandleFunc) (NMDevice *self);
+
+typedef struct {
+	ActivationHandleFunc func;
+	guint id;
+} ActivationHandleData;
+
+typedef enum {
+	CLEANUP_TYPE_KEEP,
+	CLEANUP_TYPE_REMOVED,
+	CLEANUP_TYPE_DECONFIGURE,
+} CleanupType;
+
+typedef enum {
+	IP_NONE = 0,
+	IP_WAIT,
+	IP_CONF,
+	IP_DONE,
+	IP_FAIL
+} IpState;
+
+typedef struct {
+	NMDevice *slave;
+	gulong watch_id;
+	bool slave_is_enslaved;
+	bool configure;
+} SlaveInfo;
+
+typedef struct {
+	NMDevice *device;
+	guint idle_add_id;
+	int ifindex;
+} DeleteOnDeactivateData;
+
+typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean);
+
+typedef struct {
+	ArpingCallback callback;
+	NMDevice *device;
+	NMIP4Config **configs;
+} ArpingData;
+
+typedef enum {
+	HW_ADDR_TYPE_UNSET = 0,
+	HW_ADDR_TYPE_PERMANENT,
+	HW_ADDR_TYPE_EXPLICIT,
+	HW_ADDR_TYPE_GENERATED,
+} HwAddrType;
+
+/*****************************************************************************/
 
 enum {
 	STATE_CHANGED,
@@ -136,82 +191,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
 	PROP_RX_BYTES,
 );
 
-#define DEFAULT_AUTOCONNECT TRUE
-
-/*****************************************************************************/
-
-#define PENDING_ACTION_DHCP4 "dhcp4"
-#define PENDING_ACTION_DHCP6 "dhcp6"
-#define PENDING_ACTION_AUTOCONF6 "autoconf6"
-
-#define DHCP_RESTART_TIMEOUT   120
-#define DHCP_NUM_TRIES_MAX     3
-
-typedef void (*ActivationHandleFunc) (NMDevice *self);
-
-typedef struct {
-	ActivationHandleFunc func;
-	guint id;
-} ActivationHandleData;
-
-typedef enum {
-	CLEANUP_TYPE_KEEP,
-	CLEANUP_TYPE_REMOVED,
-	CLEANUP_TYPE_DECONFIGURE,
-} CleanupType;
-
-typedef enum {
-	IP_NONE = 0,
-	IP_WAIT,
-	IP_CONF,
-	IP_DONE,
-	IP_FAIL
-} IpState;
-
-typedef struct {
-	NMDeviceState state;
-	NMDeviceStateReason reason;
-	guint id;
-} QueuedState;
-
-typedef struct {
-	NMDevice *slave;
-	gulong watch_id;
-	bool slave_is_enslaved;
-	bool configure;
-} SlaveInfo;
-
-typedef struct {
-	NMLogDomain log_domain;
-	guint timeout;
-	guint watch;
-	GPid pid;
-	const char *binary;
-	const char *address;
-	guint deadline;
-} PingInfo;
-
-typedef struct {
-	NMDevice *device;
-	guint idle_add_id;
-	int ifindex;
-} DeleteOnDeactivateData;
-
-typedef void (*ArpingCallback) (NMDevice *, NMIP4Config **, gboolean);
-
-typedef struct {
-	ArpingCallback callback;
-	NMDevice *device;
-	NMIP4Config **configs;
-} ArpingData;
-
-typedef enum {
-	HW_ADDR_TYPE_UNSET = 0,
-	HW_ADDR_TYPE_PERMANENT,
-	HW_ADDR_TYPE_EXPLICIT,
-	HW_ADDR_TYPE_GENERATED,
-} HwAddrType;
-
 typedef struct _NMDevicePrivate {
 	bool in_state_changed;
 
@@ -220,7 +199,13 @@ typedef struct _NMDevicePrivate {
 
 	NMDeviceState state;
 	NMDeviceStateReason state_reason;
-	QueuedState   queued_state;
+	struct {
+		guint id;
+
+		/* The @state/@reason is only valid, when @id is set. */
+		NMDeviceState state;
+		NMDeviceStateReason reason;
+	} queued_state;
 	guint queued_ip4_config_id;
 	guint queued_ip6_config_id;
 	GSList *pending_actions;
@@ -238,7 +223,8 @@ typedef struct _NMDevicePrivate {
 		const guint8 hw_addr_len; /* read-only */
 		guint8 hw_addr_len_;
 	};
-	guint8 /*HwAddrType*/ hw_addr_type;
+
+	HwAddrType hw_addr_type:5;
 
 	bool          real:1;
 
@@ -358,7 +344,15 @@ typedef struct _NMDevicePrivate {
 		guint           num_tries_left;
 	} dhcp4;
 
-	PingInfo        gw_ping;
+	struct {
+		NMLogDomain log_domain;
+		guint timeout;
+		guint watch;
+		GPid pid;
+		const char *binary;
+		const char *address;
+		guint deadline;
+	} gw_ping;
 
 	/* dnsmasq stuff for shared connections */
 	NMDnsMasqManager *dnsmasq_manager;
@@ -451,6 +445,12 @@ typedef struct _NMDevicePrivate {
 
 } NMDevicePrivate;
 
+G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
+
+#define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE)
+
+/*****************************************************************************/
+
 static void nm_device_set_proxy_config (NMDevice *self, GHashTable *options);
 
 static gboolean nm_device_set_ip4_config (NMDevice *self,
@@ -489,7 +489,7 @@ static void _set_state_full (NMDevice *self,
                              NMDeviceState state,
                              NMDeviceStateReason reason,
                              gboolean quitting);
-
+static void queued_state_clear (NMDevice *device);
 static gboolean queued_ip4_config_change (gpointer user_data);
 static gboolean queued_ip6_config_change (gpointer user_data);
 static void ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data);
@@ -504,36 +504,27 @@ static void _cancel_activation (NMDevice *self);
 
 /*****************************************************************************/
 
-#define QUEUED_PREFIX "queued state change to "
-
-static const char *state_table[] = {
-	[NM_DEVICE_STATE_UNKNOWN]      = QUEUED_PREFIX "unknown",
-	[NM_DEVICE_STATE_UNMANAGED]    = QUEUED_PREFIX "unmanaged",
-	[NM_DEVICE_STATE_UNAVAILABLE]  = QUEUED_PREFIX "unavailable",
-	[NM_DEVICE_STATE_DISCONNECTED] = QUEUED_PREFIX "disconnected",
-	[NM_DEVICE_STATE_PREPARE]      = QUEUED_PREFIX "prepare",
-	[NM_DEVICE_STATE_CONFIG]       = QUEUED_PREFIX "config",
-	[NM_DEVICE_STATE_NEED_AUTH]    = QUEUED_PREFIX "need-auth",
-	[NM_DEVICE_STATE_IP_CONFIG]    = QUEUED_PREFIX "ip-config",
-	[NM_DEVICE_STATE_IP_CHECK]     = QUEUED_PREFIX "ip-check",
-	[NM_DEVICE_STATE_SECONDARIES]  = QUEUED_PREFIX "secondaries",
-	[NM_DEVICE_STATE_ACTIVATED]    = QUEUED_PREFIX "activated",
-	[NM_DEVICE_STATE_DEACTIVATING] = QUEUED_PREFIX "deactivating",
-	[NM_DEVICE_STATE_FAILED]       = QUEUED_PREFIX "failed",
-};
-
-static const char *
-queued_state_to_string (NMDeviceState state)
-{
-	if ((gsize) state < G_N_ELEMENTS (state_table))
-		return state_table[state];
-	return state_table[NM_DEVICE_STATE_UNKNOWN];
-}
+NM_UTILS_LOOKUP_STR_DEFINE_STATIC (queued_state_to_string, NMDeviceState,
+	NM_UTILS_LOOKUP_DEFAULT  (                              NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNKNOWN,      NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNMANAGED,    NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNAVAILABLE,  NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DISCONNECTED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_PREPARE,      NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_CONFIG,       NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_NEED_AUTH,    NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CONFIG,    NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CHECK,     NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_SECONDARIES,  NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_ACTIVATED,    NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DEACTIVATING, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"),
+	NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_FAILED,       NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"),
+);
 
 static const char *
 state_to_string (NMDeviceState state)
 {
-	return queued_state_to_string (state) + strlen (QUEUED_PREFIX);
+	return queued_state_to_string (state) + NM_STRLEN (NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE);
 }
 
 NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason,
@@ -1932,8 +1923,9 @@ carrier_changed (NMDevice *self, gboolean carrier)
 		}
 	} else {
 		if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) {
-			if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED)
-				nm_device_queued_state_clear (self);
+			if (   priv->queued_state.id
+			    && priv->queued_state.state >= NM_DEVICE_STATE_DISCONNECTED)
+				queued_state_clear (self);
 		} else {
 			nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE,
 			                       NM_DEVICE_STATE_REASON_CARRIER);
@@ -1989,7 +1981,7 @@ nm_device_set_carrier (NMDevice *self, gboolean carrier)
 		klass->carrier_changed (self, TRUE);
 
 		if (nm_clear_g_source (&priv->carrier_wait_id)) {
-			nm_device_remove_pending_action (self, "carrier wait", TRUE);
+			nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE);
 			_carrier_wait_check_queued_act_request (self);
 		}
 	} else if (   state <= NM_DEVICE_STATE_DISCONNECTED
@@ -3921,6 +3913,9 @@ recheck_available (gpointer user_data)
 		priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE;
 	}
 
+	if (priv->recheck_available.call_id == 0)
+		nm_device_remove_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, TRUE);
+
 	return G_SOURCE_REMOVE;
 }
 
@@ -3933,8 +3928,12 @@ nm_device_queue_recheck_available (NMDevice *self,
 
 	priv->recheck_available.available_reason = available_reason;
 	priv->recheck_available.unavailable_reason = unavailable_reason;
-	if (!priv->recheck_available.call_id)
+	if (!priv->recheck_available.call_id) {
 		priv->recheck_available.call_id = g_idle_add (recheck_available, self);
+		nm_device_add_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE,
+		                              FALSE /* cannot assert, because of how recheck_available() first clears
+		                                       the call-id and postpones removing the pending-action. */);
+	}
 }
 
 void
@@ -4971,7 +4970,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
 		/* Stop any ongoing DHCP transaction on this device */
 		nm_clear_g_signal_handler (priv->dhcp4.client, &priv->dhcp4.state_sigid);
 
-		nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+		nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE);
 
 		if (   cleanup_type == CLEANUP_TYPE_DECONFIGURE
 		    || cleanup_type == CLEANUP_TYPE_REMOVED)
@@ -5199,7 +5198,7 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
 	                    NULL,
 	                    NULL);
 
-	nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE);
 
 	return TRUE;
 }
@@ -5340,7 +5339,7 @@ dhcp4_state_changed (NMDhcpClient *client,
 		/* Ignore expiry before we even have a lease (NAK, old lease, etc) */
 		if (priv->ip4_state == IP_CONF)
 			break;
-		/* Fall through */
+		/* fall through */
 	case NM_DHCP_STATE_DONE:
 	case NM_DHCP_STATE_FAIL:
 		dhcp4_fail (self, FALSE);
@@ -5424,7 +5423,7 @@ dhcp4_start (NMDevice *self,
 	                                            G_CALLBACK (dhcp4_state_changed),
 	                                            self);
 
-	nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE);
+	nm_device_add_pending_action (self, NM_PENDING_ACTION_DHCP4, TRUE);
 
 	/* DHCP devices will be notified by the DHCP manager when stuff happens */
 	return NM_ACT_STAGE_RETURN_POSTPONE;
@@ -5726,7 +5725,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
 		g_clear_object (&priv->dhcp6.client);
 	}
 
-	nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE);
 
 	if (priv->dhcp6.config) {
 		nm_exported_object_clear_and_unexport (&priv->dhcp6.config);
@@ -5970,7 +5969,7 @@ dhcp6_lease_change (NMDevice *self)
 	                    nm_device_get_applied_connection (self),
 	                    self, NULL, NULL, NULL);
 
-	nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE);
 
 	return TRUE;
 }
@@ -6159,7 +6158,7 @@ dhcp6_state_changed (NMDhcpClient *client,
 		 */
 		if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF)
 			break;
-		/* Otherwise, fall through */
+		/* fall through */
 	case NM_DHCP_STATE_FAIL:
 		dhcp6_fail (self, FALSE);
 		break;
@@ -6256,7 +6255,7 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason)
 	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	if (!nm_setting_ip_config_get_may_fail (s_ip6) ||
 	    !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP))
-		nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE);
+		nm_device_add_pending_action (self, NM_PENDING_ACTION_DHCP6, TRUE);
 
 	if (wait_for_ll) {
 		NMActStageReturn ret;
@@ -7031,7 +7030,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr)
 	}
 
 	if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection)))
-		nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE);
+		nm_device_add_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, TRUE);
 
 	/* ensure link local is ready... */
 	ret = linklocal6_start (self);
@@ -7053,7 +7052,7 @@ addrconf6_cleanup (NMDevice *self)
 	nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_changed_id);
 	nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_timeout_id);
 
-	nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, FALSE);
 
 	g_clear_object (&priv->ac_ip6_config);
 	g_clear_object (&priv->ndisc);
@@ -7921,7 +7920,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
 
 	arp_announce (self);
 
-	nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE);
 
 	/* Enter the IP_CHECK state if this is the first method to complete */
 	_set_ip_state (self, AF_INET, IP_DONE);
@@ -8058,8 +8057,8 @@ activate_stage5_ip6_config_commit (NMDevice *self)
 				return;
 			}
 		}
-		nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
-		nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE);
+		nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE);
+		nm_device_remove_pending_action (self, NM_PENDING_ACTION_AUTOCONF6, FALSE);
 
 		/* Start IPv6 forwarding if we need it */
 		method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
@@ -9745,7 +9744,7 @@ carrier_wait_timeout (gpointer user_data)
 	NMDevice *self = NM_DEVICE (user_data);
 
 	NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0;
-	nm_device_remove_pending_action (self, "carrier wait", TRUE);
+	nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE);
 
 	_carrier_wait_check_queued_act_request (self);
 
@@ -9827,7 +9826,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
 	 */
 	if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) {
 		if (!nm_clear_g_source (&priv->carrier_wait_id))
-			nm_device_add_pending_action (self, "carrier wait", TRUE);
+			nm_device_add_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, TRUE);
 		priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self);
 	}
 
@@ -10336,7 +10335,7 @@ device_ipx_changed (NMPlatform *platform,
 			priv->dad6_failed_addrs = g_slist_append (priv->dad6_failed_addrs,
 			                                          g_memdup (addr, sizeof (NMPlatformIP6Address)));
 		}
-		/* fallthrough */
+		/* fall through */
 	case NMP_OBJECT_TYPE_IP6_ROUTE:
 		if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
 			priv->queued_ip6_config_pending = TRUE;
@@ -11241,7 +11240,9 @@ nm_device_supports_vlans (NMDevice *self)
 /**
  * nm_device_add_pending_action():
  * @self: the #NMDevice to add the pending action to
- * @action: a static string that identifies the action
+ * @action: a static string that identifies the action. The string instance must
+ *   stay valid until the pending action is removed (that is, the string is
+ *   not cloned, but ownership stays with the caller).
  * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending.
  * Otherwise, ignore duplicate scheduling of the same action silently.
  *
@@ -11276,7 +11277,7 @@ nm_device_add_pending_action (NMDevice *self, const char *action, gboolean asser
 		count++;
 	}
 
-	priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action));
+	priv->pending_actions = g_slist_prepend (priv->pending_actions, (char *) action);
 	count++;
 
 	_LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action);
@@ -11290,7 +11291,7 @@ nm_device_add_pending_action (NMDevice *self, const char *action, gboolean asser
 /**
  * nm_device_remove_pending_action():
  * @self: the #NMDevice to remove the pending action from
- * @action: a static string that identifies the action
+ * @action: a string that identifies the action.
  * @assert_is_pending: if %TRUE, assert that the @action is pending.
  * If %FALSE, don't do anything if the current action is not pending and
  * return %FALSE.
@@ -11317,7 +11318,6 @@ nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean as
 			_LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'",
 			       count + g_slist_length (iter->next), /* length excluding 'iter' */
 			       action);
-			g_free (iter->data);
 			priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter);
 			if (priv->pending_actions == NULL)
 				_notify (self, PROP_HAS_PENDING_ACTION);
@@ -11383,8 +11383,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
 		                                      NULL);
 	}
 
-	/* Clear any queued transitions */
-	nm_device_queued_state_clear (self);
+	queued_state_clear (self);
 
 	_cleanup_ip4_pre (self, cleanup_type);
 	_cleanup_ip6_pre (self, cleanup_type);
@@ -11889,8 +11888,7 @@ _set_state_full (NMDevice *self,
 	priv->state = state;
 	priv->state_reason = reason;
 
-	/* Clear any queued transitions */
-	nm_device_queued_state_clear (self);
+	queued_state_clear (self);
 
 	dispatcher_cleanup (self);
 	if (priv->deactivating_cancellable)
@@ -12202,33 +12200,32 @@ nm_device_state_changed (NMDevice *self,
 }
 
 static gboolean
-queued_set_state (gpointer user_data)
+queued_state_set (gpointer user_data)
 {
 	NMDevice *self = NM_DEVICE (user_data);
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 	NMDeviceState new_state;
 	NMDeviceStateReason new_reason;
 
-	if (priv->queued_state.id) {
-		_LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)",
-		       state_to_string (priv->queued_state.state),
-		       priv->queued_state.id);
+	nm_assert (priv->queued_state.id);
 
-		/* Clear queued state struct before triggering state change, since
-		 * the state change may queue another state.
-		 */
-		priv->queued_state.id = 0;
-		new_state = priv->queued_state.state;
-		new_reason = priv->queued_state.reason;
-		nm_device_queued_state_clear (self);
+	_LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s",
+	       state_to_string (priv->queued_state.state),
+	       reason_to_string (priv->queued_state.reason),
+	       priv->queued_state.id,
+	       "change state");
 
-		nm_device_state_changed (self, new_state, new_reason);
-		nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE);
-	} else {
-		g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN);
-		g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE);
-	}
-	return FALSE;
+	/* Clear queued state struct before triggering state change, since
+	 * the state change may queue another state.
+	 */
+	priv->queued_state.id = 0;
+	new_state = priv->queued_state.state;
+	new_reason = priv->queued_state.reason;
+
+	nm_device_state_changed (self, new_state, new_reason);
+	nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE);
+
+	return G_SOURCE_REMOVE;
 }
 
 void
@@ -12242,8 +12239,16 @@ nm_device_queue_state (NMDevice *self,
 
 	priv = NM_DEVICE_GET_PRIVATE (self);
 
-	if (priv->queued_state.id && priv->queued_state.state == state)
+	if (priv->queued_state.id && priv->queued_state.state == state) {
+		_LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s%s%s%s",
+		       state_to_string (priv->queued_state.state),
+		       reason_to_string (priv->queued_state.reason),
+		       priv->queued_state.id,
+		       "ignore queuing same state change",
+		       NM_PRINT_FMT_QUOTED (priv->queued_state.reason != reason,
+		                            " (reason differs: ", reason_to_string (reason), ")", ""));
 		return;
+	}
 
 	/* Add pending action for the new state before clearing the queued states, so
 	 * that we don't accidently pop all pending states and reach 'startup complete'  */
@@ -12251,45 +12256,41 @@ nm_device_queue_state (NMDevice *self,
 
 	/* We should only ever have one delayed state transition at a time */
 	if (priv->queued_state.id) {
-		_LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)",
+		_LOGW (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s",
 		       state_to_string (priv->queued_state.state),
-		       reason_to_string (priv->queued_state.reason));
-		nm_device_queued_state_clear (self);
+		       reason_to_string (priv->queued_state.reason),
+		       priv->queued_state.id,
+		       "replace previously queued state change");
+		nm_clear_g_source (&priv->queued_state.id);
+		nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
 	}
 
 	priv->queued_state.state = state;
 	priv->queued_state.reason = reason;
-	priv->queued_state.id = g_idle_add (queued_set_state, self);
-
-	_LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)",
-	       state_to_string (state), reason_to_string (reason),
-	       priv->queued_state.id);
-}
-
-NMDeviceState
-nm_device_queued_state_peek (NMDevice *self)
-{
-	NMDevicePrivate *priv;
-
-	g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN);
-
-	priv = NM_DEVICE_GET_PRIVATE (self);
+	priv->queued_state.id = g_idle_add (queued_state_set, self);
 
-	return priv->queued_state.id ? priv->queued_state.state : NM_DEVICE_STATE_UNKNOWN;
+	_LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s",
+	       state_to_string (state),
+	       reason_to_string (reason),
+	       priv->queued_state.id,
+	       "queue state change");
 }
 
-void
-nm_device_queued_state_clear (NMDevice *self)
+static void
+queued_state_clear (NMDevice *self)
 {
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 
-	if (priv->queued_state.id) {
-		_LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)",
-		       priv->queued_state.id);
-		nm_clear_g_source (&priv->queued_state.id);
-		nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
-	}
-	memset (&priv->queued_state, 0, sizeof (priv->queued_state));
+	if (!priv->queued_state.id)
+		return;
+
+	_LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s",
+	       state_to_string (priv->queued_state.state),
+	       reason_to_string (priv->queued_state.reason),
+	       priv->queued_state.id,
+	       "clear queued state change");
+	nm_clear_g_source (&priv->queued_state.id);
+	nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE);
 }
 
 NMDeviceState
@@ -12584,7 +12585,9 @@ nm_device_hw_addr_is_explict (NMDevice *self)
 	g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
 
 	priv = NM_DEVICE_GET_PRIVATE (self);
-	return !NM_IN_SET (priv->hw_addr_type, HW_ADDR_TYPE_PERMANENT, HW_ADDR_TYPE_UNSET);
+	return !NM_IN_SET ((HwAddrType) priv->hw_addr_type,
+	                   HW_ADDR_TYPE_PERMANENT,
+	                   HW_ADDR_TYPE_UNSET);
 }
 
 static gboolean
@@ -13143,7 +13146,7 @@ finalize (GObject *object)
 	g_free (priv->hw_addr);
 	g_free (priv->hw_addr_perm);
 	g_free (priv->hw_addr_initial);
-	g_slist_free_full (priv->pending_actions, g_free);
+	g_slist_free (priv->pending_actions);
 	g_slist_free_full (priv->dad6_failed_addrs, g_free);
 	g_clear_pointer (&priv->physical_port_id, g_free);
 	g_free (priv->udi);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 311b5a2c..e512f2ca 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -30,6 +30,21 @@
 #include "nm-rfkill-manager.h"
 #include "NetworkManagerUtils.h"
 
+
+#define NM_PENDING_ACTION_AUTOACTIVATE              "autoactivate"
+#define NM_PENDING_ACTION_DHCP4                     "dhcp4"
+#define NM_PENDING_ACTION_DHCP6                     "dhcp6"
+#define NM_PENDING_ACTION_AUTOCONF6                 "autoconf6"
+#define NM_PENDING_ACTION_RECHECK_AVAILABLE         "recheck-available"
+#define NM_PENDING_ACTION_CARRIER_WAIT              "carrier-wait"
+#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT    "waiting-for-supplicant"
+#define NM_PENDING_ACTION_WIFI_SCAN                 "wifi-scan"
+#define NM_PENDING_ACTION_WAITING_FOR_COMPANION     "waiting-for-companion"
+
+#define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-"
+#define NM_PENDING_ACTIONPREFIX_ACTIVATION          "activation-"
+
+
 /* Properties */
 #define NM_DEVICE_UDI              "udi"
 #define NM_DEVICE_IFACE            "interface"
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index e0258523..0fdccb8a 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -377,7 +377,7 @@ device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data)
 		nm_device_queue_recheck_available (NM_DEVICE (self),
 		                                   NM_DEVICE_STATE_REASON_NONE,
 		                                   NM_DEVICE_STATE_REASON_NONE);
-		nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
+		nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE);
 	}
 }
 
@@ -399,7 +399,7 @@ find_companion (NMDeviceOlpcMesh *self)
 	if (priv->companion)
 		return;
 
-	nm_device_add_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
+	nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE);
 
 	/* Try to find the companion if it's already known to the NMManager */
 	for (list = nm_manager_get_devices (priv->manager); list ; list = g_slist_next (list)) {
@@ -407,7 +407,7 @@ find_companion (NMDeviceOlpcMesh *self)
 			nm_device_queue_recheck_available (NM_DEVICE (self),
 			                                   NM_DEVICE_STATE_REASON_NONE,
 			                                   NM_DEVICE_STATE_REASON_NONE);
-			nm_device_remove_pending_action (NM_DEVICE (self), "waiting for companion", TRUE);
+			nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE);
 			break;
 		}
 	}
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index ed5d2c62..188ed54e 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -95,6 +95,7 @@ typedef struct {
 	bool              enabled:1; /* rfkilled or not */
 	bool              requested_scan:1;
 	bool              ssid_found:1;
+	bool              is_scanning:1;
 
 	gint32            last_scan;
 	gint32            scheduled_scan_time;
@@ -182,7 +183,7 @@ static void supplicant_iface_notify_current_bss (NMSupplicantInterface *iface,
                                                  GParamSpec *pspec,
                                                  NMDeviceWifi *self);
 
-static void request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options);
+static void request_wireless_scan (NMDeviceWifi *self, gboolean force_if_scanning, GVariant *scan_options);
 
 static void ap_add_remove (NMDeviceWifi *self,
                            guint signum,
@@ -196,18 +197,34 @@ static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset);
 /*****************************************************************************/
 
 static void
-constructed (GObject *object)
+_ap_dump (NMDeviceWifi *self,
+          const NMWifiAP *ap,
+          const char *prefix,
+          gint32 now_s)
+{
+	char buf[1024];
+
+	buf[0] = '\0';
+	_LOGD (LOGD_WIFI_SCAN, "wifi-ap: %-7s %s",
+	       prefix,
+	       nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_s));
+}
+
+static void
+_notify_scanning (NMDeviceWifi *self)
 {
-	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+	gboolean scanning;
 
-	G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object);
+	scanning =    priv->sup_iface
+	           && nm_supplicant_interface_get_scanning (priv->sup_iface);
 
-	if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP)
-		_LOGI (LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode");
+	if (scanning == priv->is_scanning)
+		return;
 
-	/* Connect to the supplicant manager */
-	priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ());
+	_LOGD (LOGD_WIFI, "wifi-scan: scanning-state: %s", scanning ? "scanning" : "idle");
+	priv->is_scanning = scanning;
+	_notify (self, PROP_SCANNING);
 }
 
 static gboolean
@@ -239,7 +256,7 @@ supplicant_interface_acquire (NMDeviceWifi *self)
 	}
 
 	if (nm_supplicant_interface_get_state (priv->sup_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY)
-		nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", FALSE);
+		nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, FALSE);
 
 	g_signal_connect (priv->sup_iface,
 	                  NM_SUPPLICANT_INTERFACE_STATE,
@@ -262,7 +279,7 @@ supplicant_interface_acquire (NMDeviceWifi *self)
 	                  G_CALLBACK (supplicant_iface_scan_done_cb),
 	                  self);
 	g_signal_connect (priv->sup_iface,
-	                  "notify::scanning",
+	                  "notify::"NM_SUPPLICANT_INTERFACE_SCANNING,
 	                  G_CALLBACK (supplicant_iface_notify_scanning_cb),
 	                  self);
 	g_signal_connect (priv->sup_iface,
@@ -270,6 +287,8 @@ supplicant_interface_acquire (NMDeviceWifi *self)
 	                  G_CALLBACK (supplicant_iface_notify_current_bss),
 	                  self);
 
+	_notify_scanning (self);
+
 	return TRUE;
 }
 
@@ -286,9 +305,9 @@ _requested_scan_set (NMDeviceWifi *self, gboolean value)
 
 	priv->requested_scan = value;
 	if (value)
-		nm_device_add_pending_action ((NMDevice *) self, "scan", TRUE);
+		nm_device_add_pending_action ((NMDevice *) self, NM_PENDING_ACTION_WIFI_SCAN, TRUE);
 	else
-		nm_device_remove_pending_action ((NMDevice *) self, "scan", TRUE);
+		nm_device_remove_pending_action ((NMDevice *) self, NM_PENDING_ACTION_WIFI_SCAN, TRUE);
 }
 
 static void
@@ -306,8 +325,8 @@ supplicant_interface_release (NMDeviceWifi *self)
 
 	/* Reset the scan interval to be pretty frequent when disconnected */
 	priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP;
-	_LOGD (LOGD_WIFI_SCAN, "reset scanning interval to %d seconds",
-	       priv->scan_interval);
+	_LOGD (LOGD_WIFI, "wifi-scan: reset interval to %u seconds",
+	       (unsigned) priv->scan_interval);
 
 	nm_clear_g_source (&priv->ap_dump_id);
 
@@ -320,6 +339,8 @@ supplicant_interface_release (NMDeviceWifi *self)
 
 		g_clear_object (&priv->sup_iface);
 	}
+
+	_notify_scanning (self);
 }
 
 static NMWifiAP *
@@ -541,7 +562,7 @@ deactivate (NMDevice *device)
 
 	/* Ensure we trigger a scan after deactivating a Hotspot */
 	if (old_mode == NM_802_11_MODE_AP)
-		request_wireless_scan (self, NULL);
+		request_wireless_scan (self, FALSE, NULL);
 }
 
 static void
@@ -1165,7 +1186,7 @@ request_scan_cb (NMDevice *device,
 
 	priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
-	request_wireless_scan (self, new_scan_options);
+	request_wireless_scan (self, FALSE, new_scan_options);
 	g_dbus_method_invocation_return_value (context, NULL);
 }
 
@@ -1400,21 +1421,22 @@ ssids_options_to_ptrarray (GVariant *value)
 }
 
 static void
-request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
+request_wireless_scan (NMDeviceWifi *self, gboolean force_if_scanning, GVariant *scan_options)
 {
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 	gboolean backoff = FALSE;
 	GPtrArray *ssids = NULL;
+	gboolean new_scan_requested = FALSE;
 
 	nm_clear_g_source (&priv->pending_scan_id);
 
-	if (priv->requested_scan) {
+	if (!force_if_scanning && priv->requested_scan) {
 		/* There's already a scan in progress */
 		return;
 	}
 
 	if (check_scanning_allowed (self)) {
-		_LOGD (LOGD_WIFI_SCAN, "scanning requested");
+		_LOGD (LOGD_WIFI, "wifi-scan: scanning requested");
 
 		if (scan_options) {
 			GVariant *val = g_variant_lookup_value (scan_options, "ssids", NULL);
@@ -1423,14 +1445,14 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
 				if (g_variant_is_of_type (val, G_VARIANT_TYPE ("aay")))
 					ssids = ssids_options_to_ptrarray (val);
 				else
-					_LOGD (LOGD_WIFI_SCAN, "ignoring invalid 'ssids' scan option");
+					_LOGD (LOGD_WIFI, "wifi-scan: ignoring invalid 'ssids' scan option");
 				g_variant_unref (val);
 			}
 		}
 		if (!ssids)
 			ssids = build_hidden_probe_list (self);
 
-		if (nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN)) {
+		if (_LOGD_ENABLED (LOGD_WIFI)) {
 			if (ssids) {
 				const GByteArray *ssid;
 				guint i;
@@ -1441,12 +1463,12 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
 					foo = ssid->len > 0
 					      ? nm_utils_ssid_to_utf8 (ssid->data, ssid->len)
 					      : NULL;
-					_LOGD (LOGD_WIFI_SCAN, "(%d) probe scanning SSID '%s'",
-					            i, foo ? foo : "<hidden>");
+					_LOGD (LOGD_WIFI, "wifi-scan: (%u) probe scanning SSID %s%s%s",
+					       i, NM_PRINT_FMT_QUOTED (foo, "\"", foo, "\"", "<hidden>"));
 					g_free (foo);
 				}
 			} else
-				_LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan");
+				_LOGD (LOGD_WIFI, "wifi-scan: no SSIDs to probe scan");
 		}
 
 		_hw_addr_set_scanning (self, FALSE);
@@ -1455,12 +1477,16 @@ request_wireless_scan (NMDeviceWifi *self, GVariant *scan_options)
 			/* success */
 			backoff = TRUE;
 			_requested_scan_set (self, TRUE);
+			new_scan_requested = TRUE;
 		}
 
 		if (ssids)
 			g_ptr_array_unref (ssids);
 	} else
-		_LOGD (LOGD_WIFI_SCAN, "scan requested but not allowed at this time");
+		_LOGD (LOGD_WIFI, "wifi-scan: scanning requested but not allowed at this time");
+
+	if (!new_scan_requested)
+		_requested_scan_set (self, FALSE);
 
 	schedule_scan (self, backoff);
 }
@@ -1472,7 +1498,7 @@ request_wireless_scan_periodic (gpointer user_data)
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
 	priv->pending_scan_id = 0;
-	request_wireless_scan (self, NULL);
+	request_wireless_scan (self, FALSE, NULL);
 	return G_SOURCE_REMOVE;
 }
 
@@ -1519,7 +1545,7 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff)
 			priv->scan_interval = 5;
 		}
 
-		_LOGD (LOGD_WIFI_SCAN, "scheduled scan in %d seconds (interval now %d seconds)",
+		_LOGD (LOGD_WIFI, "wifi-scan: scheduled in %d seconds (interval now %d seconds)",
 		       next_scan, priv->scan_interval);
 	}
 }
@@ -1531,7 +1557,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
 {
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
-	_LOGD (LOGD_WIFI_SCAN, "scan %s", success ? "successful" : "failed");
+	_LOGD (LOGD_WIFI, "wifi-scan: scan-done callback: %s", success ? "successful" : "failed");
 
 	priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
 	schedule_scan (self, success);
@@ -1549,17 +1575,22 @@ ap_list_dump (gpointer user_data)
 {
 	NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-	gs_free NMWifiAP **list = NULL;
-	gsize i;
 
 	priv->ap_dump_id = 0;
-	_LOGD (LOGD_WIFI_SCAN, "APs: [now:%u last:%u next:%u]",
-	       nm_utils_get_monotonic_timestamp_s (),
-	       priv->last_scan,
-	       priv->scheduled_scan_time);
-	list = ap_list_get_sorted (self, TRUE);
-	for (i = 0; list[i]; i++)
-		nm_wifi_ap_dump (list[i], "dump    ", nm_device_get_iface (NM_DEVICE (self)));
+
+	if (_LOGD_ENABLED (LOGD_WIFI_SCAN)) {
+		gs_free NMWifiAP **list = NULL;
+		gsize i;
+		gint32 now_s = nm_utils_get_monotonic_timestamp_s ();
+
+		_LOGD (LOGD_WIFI_SCAN, "APs: [now:%u last:%u next:%u]",
+		       now_s,
+		       priv->last_scan,
+		       priv->scheduled_scan_time);
+		list = ap_list_get_sorted (self, TRUE);
+		for (i = 0; list[i]; i++)
+			_ap_dump (self, list[i], "dump", now_s);
+	}
 	return G_SOURCE_REMOVE;
 }
 
@@ -1568,10 +1599,9 @@ schedule_ap_list_dump (NMDeviceWifi *self)
 {
 	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
 
-	if (!nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN))
-		return;
-	nm_clear_g_source (&priv->ap_dump_id);
-	priv->ap_dump_id = g_timeout_add_seconds (1, ap_list_dump, self);
+	if (   !priv->ap_dump_id
+	    && _LOGD_ENABLED (LOGD_WIFI_SCAN))
+		priv->ap_dump_id = g_timeout_add_seconds (1, ap_list_dump, self);
 }
 
 static void
@@ -1633,7 +1663,7 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
 
 	ap = nm_wifi_ap_new_from_properties (object_path, properties);
 	if (!ap) {
-		_LOGD (LOGD_WIFI_SCAN, "invalid AP properties received for %s", object_path);
+		_LOGD (LOGD_WIFI, "invalid AP properties received for %s", object_path);
 		return;
 	}
 
@@ -1646,21 +1676,21 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
 		ssid = nm_wifi_ap_get_ssid (ap);
 		if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) {
 			/* Yay, matched it, no longer treat as hidden */
-			_LOGD (LOGD_WIFI_SCAN, "matched hidden AP %s => '%s'",
+			_LOGD (LOGD_WIFI, "matched hidden AP %s => '%s'",
 			       nm_wifi_ap_get_address (ap), nm_utils_escape_ssid (ssid->data, ssid->len));
 		} else {
 			/* Didn't have an entry for this AP in the database */
-			_LOGD (LOGD_WIFI_SCAN, "failed to match hidden AP %s",
+			_LOGD (LOGD_WIFI, "failed to match hidden AP %s",
 			       nm_wifi_ap_get_address (ap));
 		}
 	}
 
 	found_ap = get_ap_by_supplicant_path (self, object_path);
 	if (found_ap) {
-		nm_wifi_ap_dump (ap, "updated ", nm_device_get_iface (NM_DEVICE (self)));
+		_ap_dump (self, ap, "updated", 0);
 		nm_wifi_ap_update_from_properties (found_ap, object_path, properties);
 	} else {
-		nm_wifi_ap_dump (ap, "added   ", nm_device_get_iface (NM_DEVICE (self)));
+		_ap_dump (self, ap, "added", 0);
 		ap_add_remove (self, ACCESS_POINT_ADDED, ap, TRUE);
 	}
 
@@ -1695,7 +1725,7 @@ supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
 
 	ap = get_ap_by_supplicant_path (self, object_path);
 	if (ap) {
-		nm_wifi_ap_dump (ap, "updated ", nm_device_get_iface (NM_DEVICE (self)));
+		_ap_dump (self, ap, "updated", 0);
 		nm_wifi_ap_update_from_properties (ap, object_path, properties);
 		schedule_ap_list_dump (self);
 	}
@@ -1723,7 +1753,7 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface,
 			 */
 			nm_wifi_ap_set_fake (ap, TRUE);
 		} else {
-			nm_wifi_ap_dump (ap, "removed ", nm_device_get_iface (NM_DEVICE (self)));
+			_ap_dump (self, ap, "removed", 0);
 			ap_add_remove (self, ACCESS_POINT_REMOVED, ap, TRUE);
 			schedule_ap_list_dump (self);
 		}
@@ -2022,7 +2052,6 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
 	NMDevice *device = NM_DEVICE (self);
 	NMDeviceState devstate;
 	gboolean scanning;
-	gboolean recheck_available = FALSE;
 
 	if (new_state == old_state)
 		return;
@@ -2042,11 +2071,13 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
 
 	switch (new_state) {
 	case NM_SUPPLICANT_INTERFACE_STATE_READY:
-		_LOGD (LOGD_WIFI_SCAN, "supplicant ready");
-		recheck_available = TRUE;
+		_LOGD (LOGD_WIFI, "supplicant ready");
+		nm_device_queue_recheck_available (NM_DEVICE (device),
+		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
+		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
 		priv->scan_interval = SCAN_INTERVAL_MIN;
 		if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
-			nm_device_remove_pending_action (device, "waiting for supplicant", TRUE);
+			nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
 		break;
 	case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
 		remove_supplicant_interface_error_handler (self);
@@ -2104,11 +2135,13 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
 		}
 		break;
 	case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
-		recheck_available = TRUE;
+		nm_device_queue_recheck_available (NM_DEVICE (device),
+		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
+		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
 		cleanup_association_attempt (self, FALSE);
 
 		if (old_state < NM_SUPPLICANT_INTERFACE_STATE_READY)
-			nm_device_remove_pending_action (device, "waiting for supplicant", TRUE);
+			nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE);
 
 		/* If the device is already in UNAVAILABLE state then the state change
 		 * is a NOP and the interface won't be re-acquired in the device state
@@ -2122,23 +2155,19 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
 			_LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up");
 		break;
 	case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE:
-		_requested_scan_set (self, FALSE);
-		request_wireless_scan (self, NULL);
+		/* we would clear _requested_scan_set() and trigger a new scan.
+		 * However, we don't want to cancel the current pending action, so force
+		 * a new scan request. */
+		request_wireless_scan (self, TRUE, NULL);
 		break;
 	default:
 		break;
 	}
 
-	if (recheck_available) {
-		nm_device_queue_recheck_available (NM_DEVICE (device),
-		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
-		                                   NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
-	}
-
 	/* Signal scanning state changes */
 	if (   new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
 	    || old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
-		_notify (self, PROP_SCANNING);
+		_notify_scanning (self);
 }
 
 static void
@@ -2176,17 +2205,11 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface,
                                      GParamSpec *pspec,
                                      NMDeviceWifi *self)
 {
-	NMDeviceState state;
-	gboolean scanning;
-
-	scanning = nm_supplicant_interface_get_scanning (iface);
-	_LOGD (LOGD_WIFI_SCAN, "now %s", scanning ? "scanning" : "idle");
-
-	_notify (self, PROP_SCANNING);
+	_notify_scanning (self);
 
 	/* Run a quick update of current AP when coming out of a scan */
-	state = nm_device_get_state (NM_DEVICE (self));
-	if (!scanning && state == NM_DEVICE_STATE_ACTIVATED)
+	if (   !NM_DEVICE_WIFI_GET_PRIVATE (self)->is_scanning
+	    && nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED)
 		periodic_update (self);
 }
 
@@ -3011,7 +3034,7 @@ device_state_changed (NMDevice *device,
 	case NM_DEVICE_STATE_DISCONNECTED:
 		/* Kick off a scan to get latest results */
 		priv->scan_interval = SCAN_INTERVAL_MIN;
-		request_wireless_scan (self, NULL);
+		request_wireless_scan (self, FALSE, NULL);
 		break;
 	default:
 		break;
@@ -3085,64 +3108,6 @@ set_enabled (NMDevice *device, gboolean enabled)
 
 /*****************************************************************************/
 
-NMDevice *
-nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities)
-{
-	return g_object_new (NM_TYPE_DEVICE_WIFI,
-	                     NM_DEVICE_IFACE, iface,
-	                     NM_DEVICE_TYPE_DESC, "802.11 WiFi",
-	                     NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
-	                     NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI,
-	                     NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
-	                     NM_DEVICE_WIFI_CAPABILITIES, (guint) capabilities,
-	                     NULL);
-}
-
-static void
-nm_device_wifi_init (NMDeviceWifi *self)
-{
-	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
-	priv->mode = NM_802_11_MODE_INFRA;
-	priv->aps = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-static void
-dispose (GObject *object)
-{
-	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
-	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
-	nm_clear_g_source (&priv->periodic_source_id);
-
-	wifi_secrets_cancel (self);
-
-	cleanup_association_attempt (self, TRUE);
-	supplicant_interface_release (self);
-	cleanup_supplicant_failures (self);
-
-	g_clear_object (&priv->sup_mgr);
-
-	remove_all_aps (self);
-
-	G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
-	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
-	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
-	nm_assert (g_hash_table_size (priv->aps) == 0);
-
-	g_hash_table_unref (priv->aps);
-
-	g_free (priv->hw_addr_scan);
-
-	G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
-}
-
 static void
 get_property (GObject *object, guint prop_id,
               GValue *value, GParamSpec *pspec)
@@ -3172,7 +3137,7 @@ get_property (GObject *object, guint prop_id,
 		nm_utils_g_value_set_object_path (value, priv->current_ap);
 		break;
 	case PROP_SCANNING:
-		g_value_set_boolean (value, nm_supplicant_interface_get_scanning (priv->sup_iface));
+		g_value_set_boolean (value, priv->is_scanning);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3198,6 +3163,80 @@ set_property (GObject *object, guint prop_id,
 	}
 }
 
+/*****************************************************************************/
+
+static void
+nm_device_wifi_init (NMDeviceWifi *self)
+{
+	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+	priv->mode = NM_802_11_MODE_INFRA;
+	priv->aps = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+constructed (GObject *object)
+{
+	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
+	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+	G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object);
+
+	if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP)
+		_LOGI (LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode");
+
+	/* Connect to the supplicant manager */
+	priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ());
+}
+
+NMDevice *
+nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities)
+{
+	return g_object_new (NM_TYPE_DEVICE_WIFI,
+	                     NM_DEVICE_IFACE, iface,
+	                     NM_DEVICE_TYPE_DESC, "802.11 WiFi",
+	                     NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
+	                     NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI,
+	                     NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
+	                     NM_DEVICE_WIFI_CAPABILITIES, (guint) capabilities,
+	                     NULL);
+}
+
+static void
+dispose (GObject *object)
+{
+	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
+	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+	nm_clear_g_source (&priv->periodic_source_id);
+
+	wifi_secrets_cancel (self);
+
+	cleanup_association_attempt (self, TRUE);
+	supplicant_interface_release (self);
+	cleanup_supplicant_failures (self);
+
+	g_clear_object (&priv->sup_mgr);
+
+	remove_all_aps (self);
+
+	G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+	NMDeviceWifi *self = NM_DEVICE_WIFI (object);
+	NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+
+	nm_assert (g_hash_table_size (priv->aps) == 0);
+
+	g_hash_table_unref (priv->aps);
+
+	g_free (priv->hw_addr_scan);
+
+	G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
+}
 
 static void
 nm_device_wifi_class_init (NMDeviceWifiClass *klass)
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index 9d8ba42c..96e9d19c 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -206,16 +206,19 @@ void
 nm_wifi_ap_set_address (NMWifiAP *ap, const char *addr)
 {
 	NMWifiAPPrivate *priv;
+	guint8 addr_buf[ETH_ALEN];
 
 	g_return_if_fail (NM_IS_WIFI_AP (ap));
-	g_return_if_fail (addr != NULL);
-	g_return_if_fail (nm_utils_hwaddr_valid (addr, ETH_ALEN));
+	if (   !addr
+	    || !nm_utils_hwaddr_aton (addr, addr_buf, sizeof (addr_buf)))
+		g_return_if_reached ();
 
 	priv = NM_WIFI_AP_GET_PRIVATE (ap);
 
-	if (!priv->address || !nm_utils_hwaddr_matches (addr, -1, priv->address, -1)) {
+	if (   !priv->address
+	    || !nm_utils_hwaddr_matches (addr_buf, sizeof (addr_buf), priv->address, -1)) {
 		g_free (priv->address);
-		priv->address = g_strdup (addr);
+		priv->address = nm_utils_hwaddr_ntoa (addr_buf, sizeof (addr_buf));
 		_notify (ap, PROP_HW_ADDRESS);
 	}
 }
@@ -572,50 +575,44 @@ add_group_ciphers (NMWifiAP *ap, NMSettingWirelessSecurity *sec)
 		nm_wifi_ap_set_rsn_flags (ap, priv->rsn_flags | flags);
 }
 
-static char
-mode_to_char (NMWifiAP *self)
-{
-	NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self);
-
-	if (priv->mode == NM_802_11_MODE_ADHOC)
-		return '*';
-	if (priv->hotspot)
-		return '#';
-	if (priv->fake)
-		return '-';
-	return ' ';
-}
-
-void
-nm_wifi_ap_dump (NMWifiAP *self,
-                 const char *prefix,
-                 const char *ifname)
+const char *
+nm_wifi_ap_to_string (const NMWifiAP *self,
+                      char *str_buf,
+                      gulong buf_len,
+                      gint32 now_s)
 {
-	NMWifiAPPrivate *priv;
+	const NMWifiAPPrivate *priv;
 	const char *supplicant_id = "-";
 	guint32 chan;
+	char b1[200];
 
-	g_return_if_fail (NM_IS_WIFI_AP (self));
+	g_return_val_if_fail (NM_IS_WIFI_AP (self), NULL);
 
 	priv = NM_WIFI_AP_GET_PRIVATE (self);
 	chan = nm_utils_wifi_freq_to_channel (priv->freq);
 	if (priv->supplicant_path)
 		supplicant_id = strrchr (priv->supplicant_path, '/');
 
-	nm_log_dbg (LOGD_WIFI_SCAN, "%s[%s%c] %-32s[%s%u %3u%% %c W:%04X R:%04X] [%3u] %s%s",
-	            prefix,
+	g_snprintf (str_buf, buf_len,
+	            "%17s %-32s [ %c %3u %3u%% %c W:%04X R:%04X ] %3us %s",
 	            priv->address ?: "(none)",
-	            mode_to_char (self),
-	            priv->ssid ? nm_utils_escape_ssid (priv->ssid->data, priv->ssid->len) : "(none)",
-	            chan > 99 ? "" : (chan > 9 ? " " : "  "),
+	            nm_sprintf_buf (b1, "%s%s%s",
+	                            NM_PRINT_FMT_QUOTED (priv->ssid, "\"", nm_utils_escape_ssid (priv->ssid->data, priv->ssid->len), "\"", "(none)")),
+	            (priv->mode == NM_802_11_MODE_ADHOC
+	                 ? '*'
+	                 : (priv->hotspot
+	                        ? '#'
+	                        : (priv->fake
+	                               ? 'f'
+	                               : 'a'))),
 	            chan,
 	            priv->strength,
-	            priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : ' ',
+	            priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_',
 	            priv->wpa_flags & 0xFFFF,
 	            priv->rsn_flags & 0xFFFF,
-	            priv->last_seen > 0 ? (nm_utils_get_monotonic_timestamp_s () - priv->last_seen) : -1,
-	            ifname,
+	            priv->last_seen > 0 ? ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_s ()) - priv->last_seen) : -1,
 	            supplicant_id);
+	return str_buf;
 }
 
 static guint
diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h
index 5a2a2e58..a68aece8 100644
--- a/src/devices/wifi/nm-wifi-ap.h
+++ b/src/devices/wifi/nm-wifi-ap.h
@@ -89,8 +89,9 @@ gboolean          nm_wifi_ap_get_fake                 (const NMWifiAP *ap);
 void              nm_wifi_ap_set_fake                 (NMWifiAP *ap,
                                                        gboolean fake);
 
-void              nm_wifi_ap_dump                     (NMWifiAP *self,
-                                                       const char *prefix,
-                                                       const char *ifname);
+const char       *nm_wifi_ap_to_string                (const NMWifiAP *self,
+                                                       char *str_buf,
+                                                       gulong buf_len,
+                                                       gint32 now_s);
 
 #endif /* __NM_WIFI_AP_H__ */
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index e1fc4546..7dfd38c5 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -489,7 +489,6 @@ connect_context_step (NMModemBroadband *self)
 		}
 		ctx->step++;
 		/* fall through */
-
 	case CONNECT_STEP_WAIT_FOR_READY: {
 		GError *error = NULL;
 
@@ -527,9 +526,8 @@ connect_context_step (NMModemBroadband *self)
 		}
 
 		ctx->step++;
-		/* fall through */
 	}
-
+		/* fall through */
 	case CONNECT_STEP_CONNECT:
 		if (ctx->ip_types_i < ctx->ip_types->len) {
 			NMModemIPType current;
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
index 04c95a2b..1dec0dd1 100644
--- a/src/devices/wwan/nm-modem.c
+++ b/src/devices/wwan/nm-modem.c
@@ -1127,8 +1127,7 @@ deactivate_step (DeactivateContext *ctx)
 	switch (ctx->step) {
 	case DEACTIVATE_CONTEXT_STEP_FIRST:
 		ctx->step++;
-		/* Fall down */
-
+		/* fall through */
 	case DEACTIVATE_CONTEXT_STEP_CLEANUP:
 		/* Make sure we keep a ref to the PPP manager if there is one */
 		if (priv->ppp_manager)
@@ -1136,8 +1135,7 @@ deactivate_step (DeactivateContext *ctx)
 		/* Run cleanup */
 		NM_MODEM_GET_CLASS (ctx->self)->deactivate_cleanup (ctx->self, ctx->device);
 		ctx->step++;
-		/* Fall down */
-
+		/* fall through */
 	case DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP:
 		/* If we have a PPP manager, stop it */
 		if (ctx->ppp_manager) {
@@ -1148,8 +1146,7 @@ deactivate_step (DeactivateContext *ctx)
 			return;
 		}
 		ctx->step++;
-		/* Fall down */
-
+		/* fall through */
 	case DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT:
 		/* Disconnect asynchronously */
 		NM_MODEM_GET_CLASS (ctx->self)->disconnect (ctx->self,
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c
index 8cc25ab5..f36451b2 100644
--- a/src/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c
@@ -245,6 +245,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
 {
 	GString *new_contents;
 	GPtrArray *fqdn_opts, *reqs;
+	gboolean reset_reqlist = FALSE;
 	int i;
 
 	g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL);
@@ -302,6 +303,7 @@ nm_dhcp_dhclient_create_config (const char *interface,
 				in_req = TRUE;
 				p += strlen (REQ_TAG);
 				g_ptr_array_set_size (reqs, 0);
+				reset_reqlist = TRUE;
 			}
 
 			/* Save all request options for later use */
@@ -345,6 +347,8 @@ nm_dhcp_dhclient_create_config (const char *interface,
 		add_request (reqs, "ntp-servers");
 	}
 
+	if (reset_reqlist)
+		g_string_append (new_contents, "request; # override dhclient defaults\n");
 	/* And add it to the dhclient configuration */
 	for (i = 0; i < reqs->len; i++)
 		g_string_append_printf (new_contents, "also request %s;\n", (char *) reqs->pdata[i]);
diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c
index 82f0c080..f4cf9c9f 100644
--- a/src/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/dhcp/tests/test-dhcp-dhclient.c
@@ -511,6 +511,7 @@ static const char *existing_req_expected = \
 	"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
 	"option wpad code 252 = string;\n"
 	"\n"
+	"request; # override dhclient defaults\n"
 	"also request another-thing;\n"
 	"also request yet-another-thing;\n"
 	"also request rfc3442-classless-static-routes;\n"
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index dfd2fce1..55e04180 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -1566,7 +1566,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
 	case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN:
 	case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE:
 		nm_assert_not_reached ();
-		/* fall-through */
+		/* fall through */
 	case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED:
 		return NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
 	default:
@@ -1586,7 +1586,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
 			case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED:
 			case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE:
 				nm_assert_not_reached ();
-				/* fall-through */
+				/* fall through */
 			case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
 			case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
 			case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 38aadd27..068bc85e 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -567,7 +567,7 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
 		                  G_CALLBACK (device_metered_changed), self);
 
 		if (!priv->assumed) {
-			priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self);
+			priv->pending_activation_id = g_strdup_printf (NM_PENDING_ACTIONPREFIX_ACTIVATION"%p", (void *)self);
 			nm_device_add_pending_action (device, priv->pending_activation_id, TRUE);
 		}
 	} else {
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 0d554e55..68e66971 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -246,7 +246,7 @@ nm_config_data_get_connectivity_uri (const NMConfigData *self)
 	return NM_CONFIG_DATA_GET_PRIVATE (self)->connectivity.uri;
 }
 
-const guint
+guint
 nm_config_data_get_connectivity_interval (const NMConfigData *self)
 {
 	g_return_val_if_fail (self, 0);
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index b5e3c674..d7d14a61 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -160,7 +160,7 @@ gint nm_config_data_get_value_boolean (const NMConfigData *self, const char *gro
 
 char **nm_config_data_get_plugins (const NMConfigData *config_data, gboolean allow_default);
 const char *nm_config_data_get_connectivity_uri (const NMConfigData *config_data);
-const guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data);
+guint nm_config_data_get_connectivity_interval (const NMConfigData *config_data);
 const char *nm_config_data_get_connectivity_response (const NMConfigData *config_data);
 
 const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data);
diff --git a/src/nm-config.c b/src/nm-config.c
index bc8a3ea5..c68a8429 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -1046,6 +1046,7 @@ _string_append_val (GString *str, const char *value)
 		case '#':
 		case ':':
 			g_string_append_c (str, '+');
+			/* fall through */
 		default:
 			g_string_append_c (str, *value);
 		}
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 631540a1..c9bb220c 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -4100,6 +4100,9 @@ nm_utils_file_set_contents (const gchar *filename,
 	g_return_val_if_fail (!error || !*error, FALSE);
 	g_return_val_if_fail (length >= -1, FALSE);
 
+	if (length == -1)
+		length = strlen (contents);
+
 	tmp_name = g_strdup_printf ("%s.XXXXXX", filename);
 	fd = g_mkstemp_full (tmp_name, O_RDWR, mode);
 	if (fd < 0) {
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 0c1d36e1..7dfaa5ab 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -3126,8 +3126,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
 		 * decides to go unmanaged while we're activating (perhaps because other slaves
 		 * go away leaving him with no kids).
 		 */
-		nm_device_set_unmanaged_by_flags (master_device, NM_UNMANAGED_EXTERNAL_DOWN,
-		                                  NM_UNMAN_FLAG_OP_FORGET, NM_DEVICE_STATE_REASON_USER_REQUESTED);
+		if (master_device) {
+			nm_device_set_unmanaged_by_flags (master_device, NM_UNMANAGED_EXTERNAL_DOWN,
+			                                  NM_UNMAN_FLAG_OP_FORGET, NM_DEVICE_STATE_REASON_USER_REQUESTED);
+		}
 
 		nm_active_connection_set_master (active, master_ac);
 		_LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s",
@@ -3877,20 +3879,12 @@ error:
 
 gboolean
 nm_manager_deactivate_connection (NMManager *manager,
-                                  const char *connection_path,
+                                  NMActiveConnection *active,
                                   NMDeviceStateReason reason,
                                   GError **error)
 {
-	NMActiveConnection *active;
 	gboolean success = FALSE;
 
-	active = active_connection_get_by_path (manager, connection_path);
-	if (!active) {
-		g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
-		                     "The connection was not active.");
-		return FALSE;
-	}
-
 	if (NM_IS_VPN_CONNECTION (active)) {
 		NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
 
@@ -3934,6 +3928,7 @@ deactivate_net_auth_done_cb (NMAuthChain *chain,
 
 	path = nm_auth_chain_get_data (chain, "path");
 	result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL);
+	active = active_connection_get_by_path (self, path);
 
 	if (auth_error) {
 		_LOGD (LOGD_CORE, "Disconnect request failed: %s", auth_error->message);
@@ -3945,16 +3940,19 @@ deactivate_net_auth_done_cb (NMAuthChain *chain,
 		error = g_error_new_literal (NM_MANAGER_ERROR,
 		                             NM_MANAGER_ERROR_PERMISSION_DENIED,
 		                             "Not authorized to deactivate connections");
+	} else if (!active) {
+		error = g_error_new_literal (NM_MANAGER_ERROR,
+		                             NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
+		                             "The connection was not active.");
 	} else {
 		/* success; deactivation allowed */
 		if (!nm_manager_deactivate_connection (self,
-		                                       path,
+		                                       active,
 		                                       NM_DEVICE_STATE_REASON_USER_REQUESTED,
 		                                       &error))
 			nm_assert (error);
 	}
 
-	active = active_connection_get_by_path (self, path);
 	if (active) {
 		nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE,
 		                            nm_active_connection_get_settings_connection (active),
diff --git a/src/nm-manager.h b/src/nm-manager.h
index 13cae375..c69fc9e1 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -115,7 +115,7 @@ NMActiveConnection *nm_manager_activate_connection     (NMManager *manager,
                                                         GError **error);
 
 gboolean            nm_manager_deactivate_connection   (NMManager *manager,
-                                                        const char *connection_path,
+                                                        NMActiveConnection *active,
                                                         NMDeviceStateReason reason,
                                                         GError **error);
 
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 266bc5b1..a2ff2945 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -943,7 +943,7 @@ activate_data_free (ActivateData *data)
 {
 	NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (data->policy);
 
-	nm_device_remove_pending_action (data->device, "autoactivate", TRUE);
+	nm_device_remove_pending_action (data->device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE);
 	priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
 
 	if (data->autoactivate_id)
@@ -1253,7 +1253,7 @@ schedule_activate_check (NMPolicy *self, NMDevice *device)
 			return;
 	}
 
-	nm_device_add_pending_action (device, "autoactivate", TRUE);
+	nm_device_add_pending_action (device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE);
 
 	data = g_slice_new0 (ActivateData);
 	data->policy = self;
@@ -2024,7 +2024,7 @@ _deactivate_if_active (NMManager *manager, NMSettingsConnection *connection)
 		if (nm_active_connection_get_settings_connection (ac) == connection &&
 		    (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
 			if (!nm_manager_deactivate_connection (manager,
-			                                       nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac)),
+			                                       ac,
 			                                       NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
 			                                       &error)) {
 				_LOGW (LOGD_DEVICE, "connection '%s' disappeared, but error deactivating it: (%d) %s",
diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c
index 36afd35e..09a32965 100644
--- a/src/nm-rfkill-manager.c
+++ b/src/nm-rfkill-manager.c
@@ -262,7 +262,7 @@ killswitch_find_by_name (NMRfkillManager *self, const char *name)
 	return NULL;
 }
 
-static const RfKillType
+static RfKillType
 rfkill_type_to_enum (const char *str)
 {
 	g_return_val_if_fail (str != NULL, RFKILL_TYPE_UNKNOWN);
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 8b22ced2..a9014b36 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -2864,6 +2864,18 @@ ip4_addr_subnets_build_index (const GArray *addresses, gboolean consider_flags)
 	return subnets;
 }
 
+/**
+ * ip4_addr_subnets_is_secondary:
+ * @address: an address
+ * @subnets: the hash table mapping subnets to addresses
+ * @addresses: array of addresses in the hash table
+ * @out_addr_list: array of addresses belonging to the same subnet
+ *
+ * Checks whether @address is secondary and returns in @out_addr_list the list of addresses
+ * belonging to the same subnet, if it contains other elements.
+ *
+ * Returns: %TRUE if the address is secondary, %FALSE otherwise
+ */
 static gboolean
 ip4_addr_subnets_is_secondary (const NMPlatformIP4Address *address, GHashTable *subnets, const GArray *addresses, GPtrArray **out_addr_list)
 {
@@ -2876,13 +2888,13 @@ ip4_addr_subnets_is_secondary (const NMPlatformIP4Address *address, GHashTable *
 	nm_assert (p);
 	if (!_ptr_inside_ip4_addr_array (addresses, p)) {
 		addr_list = p;
-		if (addr_list->pdata[0] != address) {
-			NM_SET_OUT (out_addr_list, addr_list);
+		NM_SET_OUT (out_addr_list, addr_list);
+		if (addr_list->pdata[0] != address)
 			return TRUE;
-		}
-	} else
+	} else {
 		nm_assert ((gconstpointer) address == p);
-	NM_SET_OUT (out_addr_list, NULL);
+		NM_SET_OUT (out_addr_list, NULL);
+	}
 	return FALSE;
 }
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index b64cad35..46bd2de1 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -3387,7 +3387,7 @@ make_wireless_setting (shvarFile *ifcfg,
 	const char *cvalue;
 	char *value = NULL;
 	gint64 chan = 0;
-	NMSettingMacRandomization mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
+	NMSettingMacRandomization mac_randomization;
 	NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
 
 	s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
@@ -3587,7 +3587,7 @@ make_wireless_setting (shvarFile *ifcfg,
 		}
 		g_free (value);
 	} else
-		mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
+		mac_randomization = NM_SETTING_MAC_RANDOMIZATION_DEFAULT;
 
 	g_object_set (s_wireless,
 	              NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION,
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 90a8e7ac..fa8013b0 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -941,17 +941,16 @@ write_wireless_setting (NMConnection *connection,
 		break;
 	}
 
-	svUnsetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION");
 	switch (nm_setting_wireless_get_mac_address_randomization (s_wireless)) {
-	case NM_SETTING_MAC_RANDOMIZATION_DEFAULT:
-		svSetValueString (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "default");
+	case NM_SETTING_MAC_RANDOMIZATION_NEVER:
+		svSetValueString (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "never");
 		break;
 	case NM_SETTING_MAC_RANDOMIZATION_ALWAYS:
 		svSetValueString (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "always");
 		break;
+	case NM_SETTING_MAC_RANDOMIZATION_DEFAULT:
 	default:
-	case NM_SETTING_MAC_RANDOMIZATION_NEVER:
-		svSetValueString (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "never");
+		svSetValueString (ifcfg, "MAC_ADDRESS_RANDOMIZATION", "default");
 		break;
 	}
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 1a8439f6..f467d864 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -8998,7 +8998,7 @@ int main (int argc, char **argv)
 	nmtst_add_test_func (TPATH "wifi/read-mac-random-always",   test_read_wifi_mac_random,  "always",  GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_ALWAYS));
 	nmtst_add_test_func (TPATH "wifi/read-mac-random-never",    test_read_wifi_mac_random,  "never",   GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER));
 	nmtst_add_test_func (TPATH "wifi/read-mac-random-default",  test_read_wifi_mac_random,  "default", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
-	nmtst_add_test_func (TPATH "wifi/read-mac-random-missing",  test_read_wifi_mac_random,  "missing", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER));
+	nmtst_add_test_func (TPATH "wifi/read-mac-random-missing",  test_read_wifi_mac_random,  "missing", GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_DEFAULT));
 
 	nmtst_add_test_func (TPATH "wifi/write-mac-random-always",  test_write_wifi_mac_random, "always",  GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_ALWAYS),  "always");
 	nmtst_add_test_func (TPATH "wifi/write-mac-random-never",   test_write_wifi_mac_random, "never",   GINT_TO_POINTER (NM_SETTING_MAC_RANDOMIZATION_NEVER),   "never");
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index deaac779..f932fe8b 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -67,7 +67,6 @@ typedef struct {
 	gboolean       has_credreq;  /* Whether querying 802.1x credentials is supported */
 	NMSupplicantFeature fast_support;
 	NMSupplicantFeature ap_support;   /* Lightweight AP mode support */
-	NMSupplicantFeature mac_randomization_support;
 	guint32        max_scan_ssids;
 	guint32        ready_count;
 
@@ -353,7 +352,7 @@ nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
 {
 	NMSupplicantInterfacePrivate *priv;
 
-	g_return_val_if_fail (self != NULL, FALSE);
+	g_return_val_if_fail (self, FALSE);
 
 	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
 	if (priv->scanning)
@@ -520,25 +519,6 @@ nm_supplicant_interface_set_fast_support (NMSupplicantInterface *self,
 }
 
 static void
-set_preassoc_scan_mac_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
-{
-	NMSupplicantInterface *self;
-	gs_unref_variant GVariant *variant = NULL;
-	gs_free_error GError *error = NULL;
-
-	variant = _nm_dbus_proxy_call_finish (proxy, result,
-	                                      G_VARIANT_TYPE ("()"),
-	                                      &error);
-	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-		return;
-
-	self = NM_SUPPLICANT_INTERFACE (user_data);
-	if (error)
-		_LOGW ("failed to enable scan MAC address randomization (%s)", error->message);
-	iface_check_ready (self);
-}
-
-static void
 iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 {
 	NMSupplicantInterface *self;
@@ -562,24 +542,6 @@ iface_introspect_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data
 		/* The ProbeRequest method only exists if AP mode has been enabled */
 		if (strstr (data, "ProbeRequest"))
 			priv->ap_support = NM_SUPPLICANT_FEATURE_YES;
-
-		if (strstr (data, "PreassocMacAddr")) {
-			priv->mac_randomization_support = NM_SUPPLICANT_FEATURE_YES;
-
-			/* Turn on MAC randomization during scans by default */
-			priv->ready_count++;
-			g_dbus_proxy_call (priv->iface_proxy,
-			                   DBUS_INTERFACE_PROPERTIES ".Set",
-			                   g_variant_new ("(ssv)",
-			                                  WPAS_DBUS_IFACE_INTERFACE,
-			                                  "PreassocMacAddr",
-			                                  g_variant_new_string ("0")),
-			                   G_DBUS_CALL_FLAGS_NONE,
-			                   -1,
-			                   priv->init_cancellable,
-			                   (GAsyncReadyCallback) set_preassoc_scan_mac_cb,
-			                   self);
-		}
 	}
 
 	iface_check_ready (self);
@@ -600,8 +562,6 @@ wpas_iface_scan_done (GDBusProxy *proxy,
 	/* Cache last scan completed time */
 	priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
 
-	g_signal_emit (self, signals[SCAN_DONE], 0, success);
-
 	/* Emit NEW_BSS so that wifi device has the APs (in case it removed them) */
 	g_hash_table_iter_init (&iter, priv->bss_proxies);
 	while (g_hash_table_iter_next (&iter, (gpointer) &bss_path, (gpointer) &bss_proxy)) {
@@ -615,6 +575,8 @@ wpas_iface_scan_done (GDBusProxy *proxy,
 			}
 		}
 	}
+
+	g_signal_emit (self, signals[SCAN_DONE], 0, success);
 }
 
 static void
@@ -790,8 +752,7 @@ on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_
 	                   (GAsyncReadyCallback) iface_check_netreply_cb,
 	                   self);
 
-	if (priv->ap_support == NM_SUPPLICANT_FEATURE_UNKNOWN ||
-	    priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_UNKNOWN) {
+	if (priv->ap_support == NM_SUPPLICANT_FEATURE_UNKNOWN) {
 		/* If the global supplicant capabilities property is not present, we can
 		 * fall back to checking whether the ProbeRequest method is supported.  If
 		 * neither of these works we have no way of determining if AP mode is
@@ -1226,33 +1187,6 @@ add_network (NMSupplicantInterface *self)
 }
 
 static void
-set_mac_randomization_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
-{
-	NMSupplicantInterface *self;
-	NMSupplicantInterfacePrivate *priv;
-	gs_unref_variant GVariant *reply = NULL;
-	gs_free_error GError *error = NULL;
-
-	reply = g_dbus_proxy_call_finish (proxy, result, &error);
-	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-		return;
-
-	self = NM_SUPPLICANT_INTERFACE (user_data);
-	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
-	if (!reply) {
-		g_dbus_error_strip_remote_error (error);
-		_LOGW ("couldn't send MAC randomization mode to the supplicant interface: %s",
-		       error->message);
-		emit_error_helper (self, error);
-		return;
-	}
-
-	_LOGT ("config: set MAC randomization to 0");
-	add_network (self);
-}
-
-static void
 set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 {
 	NMSupplicantInterface *self;
@@ -1278,21 +1212,7 @@ set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 	_LOGI ("config: set interface ap_scan to %d",
 	       nm_supplicant_config_get_ap_scan (priv->cfg));
 
-	if (priv->mac_randomization_support == NM_SUPPLICANT_FEATURE_YES) {
-		/* Enable/disable association MAC address randomization */
-		g_dbus_proxy_call (priv->iface_proxy,
-		                   DBUS_INTERFACE_PROPERTIES ".Set",
-		                   g_variant_new ("(ssv)",
-		                                  WPAS_DBUS_IFACE_INTERFACE,
-		                                  "MacAddr",
-		                                  g_variant_new_string ("0")),
-		                   G_DBUS_CALL_FLAGS_NONE,
-		                   -1,
-		                   priv->assoc_cancellable,
-		                   (GAsyncReadyCallback) set_mac_randomization_cb,
-		                   self);
-	} else
-		add_network (self);
+	add_network (self);
 }
 
 gboolean
@@ -1349,7 +1269,6 @@ scan_request_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 		return;
 
 	self = NM_SUPPLICANT_INTERFACE (user_data);
-
 	if (error) {
 		if (_nm_dbus_error_has_name (error, "fi.w1.wpa_supplicant1.Interface.ScanError"))
 			_LOGD ("could not get scan request result: %s", error->message);
@@ -1358,7 +1277,6 @@ scan_request_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
 			_LOGW ("could not get scan request result: %s", error->message);
 		}
 	}
-	g_signal_emit (self, signals[SCAN_DONE], 0, error ? FALSE : TRUE);
 }
 
 gboolean
diff --git a/src/systemd/src/basic/siphash24.c b/src/systemd/src/basic/siphash24.c
index 4db444f5..e4b1cb10 100644
--- a/src/systemd/src/basic/siphash24.c
+++ b/src/systemd/src/basic/siphash24.c
@@ -129,18 +129,25 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
         switch (left) {
                 case 7:
                         state->padding |= ((uint64_t) in[6]) << 48;
+                        /* fall through */
                 case 6:
                         state->padding |= ((uint64_t) in[5]) << 40;
+                        /* fall through */
                 case 5:
                         state->padding |= ((uint64_t) in[4]) << 32;
+                        /* fall through */
                 case 4:
                         state->padding |= ((uint64_t) in[3]) << 24;
+                        /* fall through */
                 case 3:
                         state->padding |= ((uint64_t) in[2]) << 16;
+                        /* fall through */
                 case 2:
                         state->padding |= ((uint64_t) in[1]) <<  8;
+                        /* fall through */
                 case 1:
                         state->padding |= ((uint64_t) in[0]);
+                        /* fall through */
                 case 0:
                         break;
         }
diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c
index f6de8ca5..fa488787 100644
--- a/src/systemd/src/basic/time-util.c
+++ b/src/systemd/src/basic/time-util.c
@@ -1277,7 +1277,7 @@ bool clock_supported(clockid_t clock) {
                 if (!clock_boottime_supported())
                         return false;
 
-                /* fall through, after checking the cached value for CLOCK_BOOTTIME. */
+                /* fall through */
 
         default:
                 /* For everything else, check properly */
diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
index ee63142c..3a77e34d 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
@@ -341,7 +341,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
 
 int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
         size_t pos = 0, idx = 0;
-        _cleanup_free_ char **names = NULL;
+        _cleanup_strv_free_ char **names = NULL;
         int r;
 
         assert_return(optlen > 1, -ENODATA);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 4615cb40..fa508d68 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -1003,7 +1003,7 @@ static int client_receive_message(
                         break;
                 }
 
-                /* fall through for Soliciation Rapid Commit option check */
+                /* fall through */ /* for Soliciation Rapid Commit option check */
         case DHCP6_STATE_REQUEST:
         case DHCP6_STATE_RENEW:
         case DHCP6_STATE_REBIND:
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
index 5419048f..63a813aa 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
@@ -228,7 +228,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
         if (r < 0)
                 return 0;
 
-        free(lease->domains);
+        strv_free(lease->domains);
         lease->domains = domains;
         lease->domains_count = r;
 
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 53c9c0d8..81d8e05c 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -1291,7 +1291,7 @@ test_nm_utils_strbuf_append (void)
 					nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]);
 					break;
 				}
-				/* fall-through */
+				/* fall through */
 			case 1:
 				nm_utils_strbuf_append_str (&t_buf, &t_len, str);
 				break;
@@ -1300,7 +1300,7 @@ test_nm_utils_strbuf_append (void)
 					nm_utils_strbuf_append (&t_buf, &t_len, "%c", str[0]);
 					break;
 				}
-				/* fall-through */
+				/* fall through */
 			case 3:
 				nm_utils_strbuf_append (&t_buf, &t_len, "%s", str);
 				break;
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index fb9aae8a..3d4536e7 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -637,7 +637,7 @@ _set_vpn_state (NMVpnConnection *self,
 		/* Tear down and clean up the connection */
 		call_plugin_disconnect (self);
 		vpn_cleanup (self, parent_dev);
-		/* Fall through */
+		/* fall through */
 	default:
 		priv->secrets_idx = SECRETS_REQ_SYSTEM;
 		break;
@@ -1514,7 +1514,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
 			switch (g_variant_n_children (v)) {
 			case 5:
 				g_variant_get_child (v, 4, "u", &route.pref_src);
-				/* fallthrough */
+				/* fall through */
 			case 4:
 				g_variant_get_child (v, 0, "u", &route.network);
 				g_variant_get_child (v, 1, "u", &plen);