summary refs log tree commit diff
path: root/src/devices
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-05-11 17:08:25 +0200
committerMichael Biebl <biebl@debian.org>2016-05-11 17:08:25 +0200
commit73e152af6e3fb4f5848bfb8394484026ff119003 (patch)
treed5a8b37778d3a95c51511451b38b6a329b94cb41 /src/devices
parent78c3b8801ecf4975e5da1af3b10ae20dd2d876de (diff)
Imported Upstream version 1.2.2 upstream/1.2.2
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c2
-rw-r--r--src/devices/nm-device-ethernet.c37
-rw-r--r--src/devices/nm-device-factory.c10
-rw-r--r--src/devices/nm-device.c139
-rw-r--r--src/devices/wwan/nm-modem-broadband.c23
-rw-r--r--src/devices/wwan/nm-modem.c3
6 files changed, 142 insertions, 72 deletions
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index a009746d..5ee22f93 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -788,7 +788,7 @@ static void
 adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
 {
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
-	GError *error;
+	GError *error = NULL;
 	GVariant *v;
 
 	priv->adapter5 = g_dbus_proxy_new_for_bus_finish (res, &error);
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 6225ae7b..d27f7dca 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -194,16 +194,21 @@ _update_s390_subchannels (NMDeviceEthernet *self)
 		} else if (   !strcmp (item, "layer2")
 		           || !strcmp (item, "portname")
 		           || !strcmp (item, "portno")) {
-			char *path, *value;
+			gs_free char *path = NULL, *value = NULL;
+
 			path = g_strdup_printf ("%s/%s", parent_path, item);
 			value = nm_platform_sysctl_get (NM_PLATFORM_GET, path);
-			if (value && *value)
-				g_hash_table_insert (priv->s390_options, g_strdup (item), g_strdup (value));
-			else
+
+			if (   !strcmp (item, "portname")
+			    && !g_strcmp0 (value, "no portname required")) {
+				/* Do nothing */
+			} else if (value && *value) {
+				g_hash_table_insert (priv->s390_options, g_strdup (item), value);
+				value = NULL;
+			} else
 				_LOGW (LOGD_DEVICE | LOGD_HW, "error reading %s", path);
-			g_free (path);
-			g_free (value);
 		}
+
 		if (error) {
 			_LOGW (LOGD_DEVICE | LOGD_HW, "%s", error->message);
 			g_clear_error (&error);
@@ -1433,7 +1438,9 @@ new_default_connection (NMDevice *self)
 	const GSList *connections;
 	NMSetting *setting;
 	const char *hw_address;
-	char *defname, *uuid;
+	gs_free char *defname = NULL;
+	gs_free char *uuid = NULL;
+	gs_free char *machine_id = NULL;
 
 	if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
 		return NULL;
@@ -1448,7 +1455,19 @@ new_default_connection (NMDevice *self)
 
 	connections = nm_connection_provider_get_connections (nm_connection_provider_get ());
 	defname = nm_device_ethernet_utils_get_default_wired_name (connections);
-	uuid = nm_utils_uuid_generate ();
+	if (!defname)
+		return NULL;
+
+	machine_id = nm_utils_machine_id_read ();
+
+	/* Create a stable UUID. The UUID is also the Network_ID for stable-privacy addr-gen-mode,
+	 * thus when it changes we will also generate different IPv6 addresses. */
+	uuid = _nm_utils_uuid_generate_from_strings ("default-wired",
+	                                             machine_id ?: "",
+	                                             defname,
+	                                             hw_address,
+	                                             NULL);
+
 	g_object_set (setting,
 	              NM_SETTING_CONNECTION_ID, defname,
 	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
@@ -1457,8 +1476,6 @@ new_default_connection (NMDevice *self)
 	              NM_SETTING_CONNECTION_UUID, uuid,
 	              NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
 	              NULL);
-	g_free (uuid);
-	g_free (defname);
 
 	/* Lock the connection to the device */
 	setting = nm_setting_wired_new ();
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c
index 482eb185..7873756f 100644
--- a/src/devices/nm-device-factory.c
+++ b/src/devices/nm-device-factory.c
@@ -512,20 +512,20 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
 			continue;
 		}
 
+		/* after loading glib types from the plugin, we cannot unload the library anymore.
+		 * Make it resident. */
+		g_module_make_resident (plugin);
+
 		factory = create_func (&error);
 		if (!factory) {
 			nm_log_warn (LOGD_HW, "(%s): failed to initialize device factory: %s",
 			             item, NM_G_ERROR_MSG (error));
 			g_clear_error (&error);
-			g_module_close (plugin);
 			continue;
 		}
 		g_clear_error (&error);
 
-		if (_add_factory (factory, TRUE, g_module_name (plugin), callback, user_data))
-			g_module_make_resident (plugin);
-		else
-			g_module_close (plugin);
+		_add_factory (factory, TRUE, g_module_name (plugin), callback, user_data);
 
 		g_object_unref (factory);
 	}
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 08cf6dce..8472ff80 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1276,7 +1276,7 @@ void
 nm_device_update_dynamic_ip_setup (NMDevice *self)
 {
 	NMDevicePrivate *priv;
-	GError *error;
+	GError *error = NULL;
 	gconstpointer addr;
 	size_t addr_length;
 
@@ -1887,6 +1887,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
 	g_return_if_fail (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT));
 	g_return_if_fail (priv->ip_ifindex <= 0);
 	g_return_if_fail (priv->ip_iface == NULL);
+	g_return_if_fail (!priv->queued_ip4_config_id);
+	g_return_if_fail (!priv->queued_ip6_config_id);
 
 	_LOGD (LOGD_DEVICE, "start setup of %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), plink ? plink->ifindex : 0);
 
@@ -3382,6 +3384,15 @@ activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int famil
 	act_data->id = new_id;
 }
 
+static gboolean
+activation_source_is_scheduled (NMDevice *self, ActivationHandleFunc func, int family)
+{
+	ActivationHandleData *act_data;
+
+	act_data = activation_source_get_by_family (self, family, NULL);
+	return act_data->func == func;
+}
+
 /*****************************************************************************/
 
 static gboolean
@@ -4456,6 +4467,8 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
 		                    NULL,
 		                    NULL,
 		                    NULL);
+
+		nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE);
 	}
 }
 
@@ -5187,6 +5200,8 @@ dhcp6_lease_change (NMDevice *self)
 		                    settings_connection,
 		                    nm_device_get_applied_connection (self),
 		                    self, NULL, NULL, NULL);
+
+		nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE);
 	}
 }
 
@@ -6827,30 +6842,6 @@ activate_stage5_ip4_config_commit (NMDevice *self)
 	check_ip_done (self);
 }
 
-static void
-queued_ip4_config_change_clear (NMDevice *self)
-{
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-
-	if (priv->queued_ip4_config_id) {
-		_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
-		g_source_remove (priv->queued_ip4_config_id);
-		priv->queued_ip4_config_id = 0;
-	}
-}
-
-static void
-queued_ip6_config_change_clear (NMDevice *self)
-{
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-
-	if (priv->queued_ip6_config_id) {
-		_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
-		g_source_remove (priv->queued_ip6_config_id);
-		priv->queued_ip6_config_id = 0;
-	}
-}
-
 void
 nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *config)
 {
@@ -6863,7 +6854,6 @@ nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *conf
 	if (config)
 		priv->dev_ip4_config = g_object_ref (config);
 
-	queued_ip4_config_change_clear (self);
 	activation_source_schedule (self, activate_stage5_ip4_config_commit, AF_INET);
 }
 
@@ -7109,7 +7099,9 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 
 	priv->ip4_state =  IP_NONE;
-	queued_ip4_config_change_clear (self);
+
+	if (nm_clear_g_source (&priv->queued_ip4_config_id))
+		_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
 
 	dhcp4_cleanup (self, cleanup_type, FALSE);
 	arp_cleanup (self);
@@ -7123,7 +7115,9 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 
 	priv->ip6_state = IP_NONE;
-	queued_ip6_config_change_clear (self);
+
+	if (nm_clear_g_source (&priv->queued_ip6_config_id))
+		_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
 
 	dhcp6_cleanup (self, cleanup_type, FALSE);
 	linklocal6_cleanup (self);
@@ -7169,22 +7163,25 @@ _hash_check_invalid_keys_impl (GHashTable *hash, const char *setting_name, GErro
 
 		g_hash_table_iter_init (&iter, hash);
 		while (g_hash_table_iter_next (&iter, (gpointer *) &k, NULL)) {
-			for (i = 0; argv[i]; i++) {
-				if (!strcmp (argv[i], k)) {
-					first_invalid_key = k;
-					break;
-				}
-			}
-			if (first_invalid_key)
+			if (_nm_utils_strv_find_first ((char **) argv, -1, k) < 0) {
+				first_invalid_key = k;
 				break;
+			}
+		}
+		if (setting_name) {
+			g_set_error (error,
+			             NM_DEVICE_ERROR,
+			             NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
+			             "Can't reapply changes to '%s.%s' setting",
+			             setting_name,
+			             first_invalid_key);
+		} else {
+			g_set_error (error,
+			             NM_DEVICE_ERROR,
+			             NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
+			             "Can't reapply any changes to '%s' setting",
+			             first_invalid_key);
 		}
-		g_set_error (error,
-		             NM_DEVICE_ERROR,
-		             NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
-		             "Can't reapply changes to '%s%s%s' setting",
-		             setting_name ? : "",
-		             setting_name ? "." : "",
-		             first_invalid_key ? : "<UNKNOWN>");
 		g_return_val_if_fail (first_invalid_key, FALSE);
 		return FALSE;
 	}
@@ -7305,9 +7302,16 @@ reapply_connection (NMDevice *self,
 	                               NM_SETTING_CONNECTION_SETTING_NAME))
 		return FALSE;
 
+	/* whitelist allowed properties from "connection" setting which are allowed to differ.
+	 *
+	 * This includes UUID, there is no principal problem with reapplying a connection
+	 * and changing it's UUID. In fact, disallowing it makes it cumbersome for the user
+	 * to reapply any connection but the original settings-connection. */
 	if (!_hash_check_invalid_keys (diffs ? g_hash_table_lookup (diffs, NM_SETTING_CONNECTION_SETTING_NAME) : NULL,
 	                               NM_SETTING_CONNECTION_SETTING_NAME,
 	                               error,
+	                               NM_SETTING_CONNECTION_ID,
+	                               NM_SETTING_CONNECTION_UUID,
 	                               NM_SETTING_CONNECTION_ZONE,
 	                               NM_SETTING_CONNECTION_METERED))
 		return FALSE;
@@ -7336,6 +7340,7 @@ reapply_connection (NMDevice *self,
 		con_old = applied_clone  = nm_simple_connection_new_clone (applied);
 		con_new = applied;
 		nm_connection_replace_settings_from_connection (applied, connection);
+		nm_connection_clear_secrets (applied);
 	} else
 		con_old = con_new = applied;
 
@@ -8779,6 +8784,19 @@ update_ip4_config (NMDevice *self, gboolean initial)
 	gboolean capture_resolv_conf;
 	NMDnsManagerResolvConfMode resolv_conf_mode;
 
+	/* If a commit is scheduled, this function would potentially interfere with
+	 * it changing IP configurations before they are applied. Postpone the
+	 * update in such case.
+	 */
+	if (   !initial
+	    && activation_source_is_scheduled (self,
+	                                       activate_stage5_ip4_config_commit,
+	                                       AF_INET)) {
+		priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
+		_LOGT (LOGD_DEVICE, "IP4 update was postponed");
+		return;
+	}
+
 	ifindex = nm_device_get_ip_ifindex (self);
 	if (!ifindex)
 		return;
@@ -8857,6 +8875,19 @@ update_ip6_config (NMDevice *self, gboolean initial)
 	gboolean capture_resolv_conf;
 	NMDnsManagerResolvConfMode resolv_conf_mode;
 
+	/* If a commit is scheduled, this function would potentially interfere with
+	 * it changing IP configurations before they are applied. Postpone the
+	 * update in such case.
+	 */
+	if (   !initial
+	    && activation_source_is_scheduled (self,
+	                                       activate_stage5_ip6_config_commit,
+	                                       AF_INET6)) {
+		priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
+		_LOGT (LOGD_DEVICE, "IP6 update was postponed");
+		return;
+	}
+
 	ifindex = nm_device_get_ip_ifindex (self);
 	if (!ifindex)
 		return;
@@ -8922,8 +8953,12 @@ nm_device_capture_initial_config (NMDevice *self)
 static gboolean
 queued_ip4_config_change (gpointer user_data)
 {
-	NMDevice *self = NM_DEVICE (user_data);
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+	NMDevice *self = user_data;
+	NMDevicePrivate *priv;
+
+	g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
+
+	priv = NM_DEVICE_GET_PRIVATE (self);
 
 	/* Wait for any queued state changes */
 	if (priv->queued_state.id)
@@ -8942,11 +8977,15 @@ queued_ip4_config_change (gpointer user_data)
 static gboolean
 queued_ip6_config_change (gpointer user_data)
 {
-	NMDevice *self = NM_DEVICE (user_data);
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+	NMDevice *self = user_data;
+	NMDevicePrivate *priv;
 	GSList *iter;
 	gboolean need_ipv6ll = FALSE;
 
+	g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE);
+
+	priv = NM_DEVICE_GET_PRIVATE (self);
+
 	/* Wait for any queued state changes */
 	if (priv->queued_state.id)
 		return TRUE;
@@ -11201,6 +11240,10 @@ dispose (GObject *object)
 
 	_LOGD (LOGD_DEVICE, "disposing");
 
+	platform = nm_platform_get ();
+	g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
+	g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
+
 	g_slist_free_full (priv->arping.dad_list, (GDestroyNotify) nm_arping_manager_destroy);
 	priv->arping.dad_list = NULL;
 
@@ -11241,10 +11284,6 @@ dispose (GObject *object)
 
 	_clear_queued_act_request (priv);
 
-	platform = nm_platform_get ();
-	g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self);
-	g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self);
-
 	nm_clear_g_source (&priv->device_link_changed_id);
 	nm_clear_g_source (&priv->device_ip_link_changed_id);
 
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index 9539fefd..1a6e6b25 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -310,6 +310,10 @@ connect_ready (MMModemSimple *simple_iface,
 	NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN;
 
 	self->priv->bearer = mm_modem_simple_connect_finish (simple_iface, res, &error);
+
+	if (!ctx)
+		return;
+
 	if (!self->priv->bearer) {
 		if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) ||
 		    (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) &&
@@ -377,9 +381,17 @@ connect_ready (MMModemSimple *simple_iface,
 static void
 send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
 {
-    GError *error = NULL;
+	gs_free_error GError *error = NULL;
+
+	mm_sim_send_pin_finish (sim, result, &error);
+
+	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+		return;
+
+	if (!self->priv->ctx || self->priv->ctx->step != CONNECT_STEP_UNLOCK)
+		return;
 
-    if (!mm_sim_send_pin_finish (sim, result, &error)) {
+	if (error) {
 		if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) ||
 		    (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) &&
 		     mm_modem_get_unlock_required (self->priv->modem_iface) == MM_MODEM_LOCK_SIM_PIN)) {
@@ -387,9 +399,8 @@ send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self)
 		} else {
 			g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error));
 		}
-		g_error_free (error);
 		return;
-    }
+	}
 
 	self->priv->ctx->step++;
 	connect_context_step (self);
@@ -1079,14 +1090,16 @@ simple_disconnect_ready (MMModemSimple *modem_iface,
 }
 
 static void
-disconnect (NMModem *self,
+disconnect (NMModem *modem,
             gboolean warn,
             GCancellable *cancellable,
             GAsyncReadyCallback callback,
             gpointer user_data)
 {
+	NMModemBroadband *self = NM_MODEM_BROADBAND (modem);
 	DisconnectContext *ctx;
 
+	connect_context_clear (self);
 	ctx = g_slice_new (DisconnectContext);
 	ctx->self = g_object_ref (self);
 	ctx->result = g_simple_async_result_new (G_OBJECT (self),
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
index 804a6d9c..a6c77007 100644
--- a/src/devices/wwan/nm-modem.c
+++ b/src/devices/wwan/nm-modem.c
@@ -1187,6 +1187,7 @@ nm_modem_device_state_changed (NMModem *self,
 	case NM_DEVICE_STATE_UNMANAGED:
 	case NM_DEVICE_STATE_UNAVAILABLE:
 	case NM_DEVICE_STATE_FAILED:
+	case NM_DEVICE_STATE_DISCONNECTED:
 		if (priv->act_request) {
 			cancel_get_secrets (self);
 			g_object_unref (priv->act_request);
@@ -1195,7 +1196,7 @@ nm_modem_device_state_changed (NMModem *self,
 
 		if (was_connected) {
 			/* Don't bother warning on FAILED since the modem is already gone */
-			if (new_state == NM_DEVICE_STATE_FAILED)
+			if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED)
 				warn = FALSE;
 			/* First cleanup */
 			NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL);