summary refs log tree commit diff
path: root/libnm-core/nm-connection.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
committerMichael Biebl <biebl@debian.org>2020-04-11 21:28:04 +0200
commit1e5977b62f896e844b548c3007ace9e1dfa7f9ed (patch)
tree7a7416ed410e72b6200f3d860fd315ec11cc106b /libnm-core/nm-connection.c
parentb012fa6e1d808e0736c009799c62d835cbfcc1dd (diff)
New upstream version 1.23.90 upstream/1.23.90
Diffstat (limited to 'libnm-core/nm-connection.c')
-rw-r--r--libnm-core/nm-connection.c146
1 files changed, 53 insertions, 93 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 4146fd55..5f18b651 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -887,6 +887,7 @@ static gboolean
 _supports_addr_family (NMConnection *self, int family)
 {
 	const char *connection_type = nm_connection_get_connection_type (self);
+	NMSettingConnection *s_con;
 
 	g_return_val_if_fail (connection_type, TRUE);
 	if (strcmp (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0)
@@ -895,6 +896,9 @@ _supports_addr_family (NMConnection *self, int family)
 		return FALSE;
 	if (strcmp (connection_type, NM_SETTING_6LOWPAN_SETTING_NAME) == 0)
 		return family == AF_INET6 || family == AF_UNSPEC;
+	if (   (s_con = nm_connection_get_setting_connection (self))
+	    && (nm_streq0 (nm_setting_connection_get_slave_type (s_con), NM_SETTING_VRF_SETTING_NAME)))
+		return TRUE;
 
 	return !nm_setting_connection_get_master (nm_connection_get_setting_connection (self));
 }
@@ -995,7 +999,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
 
 				if (   inet_pton (AF_INET6, token, &i6_token) == 1
 				    && _nm_utils_inet6_is_token (&i6_token)) {
-					nm_utils_inet6_ntop (&i6_token, normalized);
+					_nm_utils_inet6_ntop (&i6_token, normalized);
 					if (g_strcmp0 (token, normalized)) {
 						g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, normalized, NULL);
 						changed = TRUE;
@@ -1232,6 +1236,7 @@ _normalize_ovs_interface_type (NMConnection *self)
 		return FALSE;
 
 	v = _nm_setting_ovs_interface_verify_interface_type (s_ovs_interface,
+	                                                     nm_setting_ovs_interface_get_interface_type (s_ovs_interface),
 	                                                     self,
 	                                                     TRUE,
 	                                                     &modified,
@@ -1400,24 +1405,19 @@ nm_connection_verify (NMConnection *connection, GError **error)
 NMSettingVerifyResult
 _nm_connection_verify (NMConnection *connection, GError **error)
 {
-	NMConnectionPrivate *priv;
-	NMSettingConnection *s_con;
 	NMSettingIPConfig *s_ip4, *s_ip6;
 	NMSettingProxy *s_proxy;
-	GHashTableIter iter;
-	gpointer value;
-	GSList *all_settings = NULL, *setting_i;
+	gs_free NMSetting **settings = NULL;
 	gs_free_error GError *normalizable_error = NULL;
 	NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS;
+	guint i;
 
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
 	g_return_val_if_fail (!error || !*error, NM_SETTING_VERIFY_ERROR);
 
-	priv = NM_CONNECTION_GET_PRIVATE (connection);
-
-	/* First, make sure there's at least 'connection' setting */
-	s_con = nm_connection_get_setting_connection (connection);
-	if (!s_con) {
+	settings = nm_connection_get_settings (connection, NULL);
+	if (   !settings
+	    || !NM_IS_SETTING_CONNECTION (settings[0])) {
 		g_set_error_literal (error,
 		                     NM_CONNECTION_ERROR,
 		                     NM_CONNECTION_ERROR_MISSING_SETTING,
@@ -1426,25 +1426,13 @@ _nm_connection_verify (NMConnection *connection, GError **error)
 		return NM_SETTING_VERIFY_ERROR;
 	}
 
-	/* Build up the list of settings */
-	g_hash_table_iter_init (&iter, priv->settings);
-	while (g_hash_table_iter_next (&iter, NULL, &value)) {
-		/* Order NMSettingConnection so that it will be verified first.
-		 * The reason is, that errors in this setting might be more fundamental
-		 * and should be checked and reported with higher priority.
-		 */
-		if (value == s_con)
-			all_settings = g_slist_append (all_settings, value);
-		else
-			all_settings = g_slist_prepend (all_settings, value);
-	}
-	all_settings = g_slist_reverse (all_settings);
-
-	/* Now, run the verify function of each setting */
-	for (setting_i = all_settings; setting_i; setting_i = setting_i->next) {
+	for (i = 0; settings[i]; i++) {
 		GError *verify_error = NULL;
 		NMSettingVerifyResult verify_result;
 
+		nm_assert (NM_IS_SETTING (settings[i]));
+		nm_assert (NM_IS_SETTING_CONNECTION (settings[i]) == (i == 0));
+
 		/* verify all settings. We stop if we find the first non-normalizable
 		 * @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue
 		 * but remember the error to return it to the user.
@@ -1452,7 +1440,7 @@ _nm_connection_verify (NMConnection *connection, GError **error)
 		 * @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type,
 		 * we remember it instead (to return it as output).
 		 **/
-		verify_result = _nm_setting_verify (NM_SETTING (setting_i->data), connection, &verify_error);
+		verify_result = _nm_setting_verify (settings[i], connection, &verify_error);
 		if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE ||
 		    verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) {
 			if (   verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR
@@ -1467,13 +1455,11 @@ _nm_connection_verify (NMConnection *connection, GError **error)
 			}
 		} else if (verify_result != NM_SETTING_VERIFY_SUCCESS) {
 			g_propagate_error (error, verify_error);
-			g_slist_free (all_settings);
 			g_return_val_if_fail (verify_result == NM_SETTING_VERIFY_ERROR, NM_SETTING_VERIFY_ERROR);
 			return NM_SETTING_VERIFY_ERROR;
 		}
 		g_clear_error (&verify_error);
 	}
-	g_slist_free (all_settings);
 
 	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	s_ip6 = nm_connection_get_setting_ip6_config (connection);
@@ -1928,7 +1914,7 @@ nm_connection_update_secrets (NMConnection *connection,
 		                                             error);
 		g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection);
 
-		g_clear_pointer (&setting_dict, g_variant_unref);
+		nm_clear_pointer (&setting_dict, g_variant_unref);
 
 		if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) {
 			nm_assert (!error || *error);
@@ -2262,39 +2248,33 @@ nm_connection_to_dbus_full (NMConnection *connection,
                             NMConnectionSerializationFlags flags,
                             const NMConnectionSerializationOptions *options)
 {
-	NMConnectionPrivate *priv;
 	GVariantBuilder builder;
-	GHashTableIter iter;
-	gpointer data;
-	GVariant *setting_dict, *ret;
+	gboolean any = FALSE;
+	gs_free NMSetting **settings = NULL;
+	guint settings_len;
+	guint i;
 
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	priv = NM_CONNECTION_GET_PRIVATE (connection);
 
-	g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION);
-
-	/* Add each setting's hash to the main hash */
-
-	/* FIXME: the order of serialized settings must be stable. */
-
-	g_hash_table_iter_init (&iter, priv->settings);
-	while (g_hash_table_iter_next (&iter, NULL, &data)) {
-		NMSetting *setting = NM_SETTING (data);
+	settings = nm_connection_get_settings (connection, &settings_len);
+	for (i = 0; i < settings_len; i++) {
+		NMSetting *setting = settings[i];
+		GVariant *setting_dict;
 
 		setting_dict = _nm_setting_to_dbus (setting, connection, flags, options);
-		if (setting_dict)
-			g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_dict);
+		if (!setting_dict)
+			continue;
+		if (!any) {
+			any = TRUE;
+			g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION);
+		}
+		g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_dict);
 	}
 
-	ret = g_variant_builder_end (&builder);
-
-	/* Don't send empty hashes */
-	if (g_variant_n_children (ret) == 0) {
-		g_variant_unref (ret);
-		ret = NULL;
-	}
+	if (!any)
+		return NULL;
 
-	return ret;
+	return g_variant_builder_end (&builder);
 }
 
 /**
@@ -2318,16 +2298,21 @@ nm_connection_is_type (NMConnection *connection, const char *type)
 }
 
 static int
-_for_each_sort (NMSetting **p_a, NMSetting **p_b, void *unused)
+_get_settings_sort (gconstpointer p_a, gconstpointer p_b, gpointer unused)
 {
-	NMSetting *a = *p_a;
-	NMSetting *b = *p_b;
-	int c;
+	NMSetting *a = *((NMSetting **) p_a);
+	NMSetting *b = *((NMSetting **) p_b);
+
+	nm_assert (NM_IS_SETTING (a));
+	nm_assert (NM_IS_SETTING (b));
+	nm_assert (a != b);
+	nm_assert (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b));
+
+	NM_CMP_RETURN (_nm_setting_compare_priority (a, b));
+	NM_CMP_DIRECT_STRCMP (nm_setting_get_name (a), nm_setting_get_name (b));
 
-	c = _nm_setting_compare_priority (a, b);
-	if (c != 0)
-		return c;
-	return strcmp (nm_setting_get_name (a), nm_setting_get_name (b));
+	nm_assert_not_reached ();
+	return 0;
 }
 
 /**
@@ -2350,38 +2335,12 @@ NMSetting **
 nm_connection_get_settings (NMConnection *connection,
                             guint *out_length)
 {
-	NMConnectionPrivate *priv;
-	NMSetting **arr;
-	GHashTableIter iter;
-	NMSetting *setting;
-	guint i, size;
-
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
 
-	priv = NM_CONNECTION_GET_PRIVATE (connection);
-
-	size = g_hash_table_size (priv->settings);
-
-	if (!size) {
-		NM_SET_OUT (out_length, 0);
-		return NULL;
-	}
-
-	arr = g_new (NMSetting *, size + 1);
-
-	g_hash_table_iter_init (&iter, priv->settings);
-	for (i = 0; g_hash_table_iter_next (&iter, NULL, (gpointer *) &setting); i++)
-		arr[i] = setting;
-	nm_assert (i == size);
-	arr[size] = NULL;
-
-	/* sort the settings. This has an effect on the order in which keyfile
-	 * prints them. */
-	if (size > 1)
-		g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
-
-	NM_SET_OUT (out_length, size);
-	return arr;
+	return (NMSetting **) nm_utils_hash_values_to_array (NM_CONNECTION_GET_PRIVATE (connection)->settings,
+	                                                     _get_settings_sort,
+	                                                     NULL,
+	                                                     out_length);
 }
 
 /**
@@ -2694,6 +2653,7 @@ nm_connection_is_virtual (NMConnection *connection)
 	                        NM_SETTING_TEAM_SETTING_NAME,
 	                        NM_SETTING_TUN_SETTING_NAME,
 	                        NM_SETTING_VLAN_SETTING_NAME,
+	                        NM_SETTING_VRF_SETTING_NAME,
 	                        NM_SETTING_VXLAN_SETTING_NAME,
 	                        NM_SETTING_WIREGUARD_SETTING_NAME))
 		return TRUE;