summary refs log tree commit diff
path: root/src/nm-config-data.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-06-04 00:07:45 +0200
committerMichael Biebl <biebl@debian.org>2018-06-04 00:07:45 +0200
commit04bc9e1cd3544445d883ad29ea108c1645c8e7b7 (patch)
treed10c354b1b980ca8a7b9e48ec9019e8ed88bde2b /src/nm-config-data.c
parentee9c73a923909e23a649407be77e25235d769e25 (diff)
New upstream version 1.11.4 upstream/1.11.4
Diffstat (limited to 'src/nm-config-data.c')
-rw-r--r--src/nm-config-data.c308
1 files changed, 194 insertions, 114 deletions
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 00e5c635..813ef9c8 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -54,7 +54,7 @@ struct _NMGlobalDnsConfig {
 	char **searches;
 	char **options;
 	GHashTable *domains;
-	char **domain_list;
+	const char **domain_list;
 	gboolean internal;
 };
 
@@ -238,7 +238,7 @@ nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default)
 	if (!list && allow_default) {
 		gs_unref_keyfile GKeyFile *kf = nm_config_create_keyfile ();
 
-		/* let keyfile split the default string according to it's own escaping rules. */
+		/* let keyfile split the default string according to its own escaping rules. */
 		g_key_file_set_value (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS);
 		list = g_key_file_get_string_list (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NULL, NULL);
 	}
@@ -705,54 +705,53 @@ nm_config_data_log (const NMConfigData *self,
 
 /*****************************************************************************/
 
-const char *const *
-nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns)
+const char *const*
+nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns_config)
 {
-	g_return_val_if_fail (dns, NULL);
+	g_return_val_if_fail (dns_config, NULL);
 
-	return (const char *const *) dns->searches;
+	return (const char *const*) dns_config->searches;
 }
 
 const char *const *
-nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns_config)
 {
-	g_return_val_if_fail (dns, NULL);
+	g_return_val_if_fail (dns_config, NULL);
 
-	return (const char *const *) dns->options;
+	return (const char *const*) dns_config->options;
 }
 
 guint
-nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns_config)
 {
-	g_return_val_if_fail (dns, 0);
-	g_return_val_if_fail (dns->domains, 0);
+	g_return_val_if_fail (dns_config, 0);
 
-	return g_hash_table_size (dns->domains);
+	return dns_config->domains ? g_hash_table_size (dns_config->domains) : 0;
 }
 
 NMGlobalDnsDomain *
-nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns, guint i)
+nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns_config, guint i)
 {
 	NMGlobalDnsDomain *domain;
 
-	g_return_val_if_fail (dns, NULL);
-	g_return_val_if_fail (dns->domains, NULL);
-	g_return_val_if_fail (dns->domain_list, NULL);
-	g_return_val_if_fail (i < g_strv_length (dns->domain_list), NULL);
+	g_return_val_if_fail (dns_config, NULL);
+	g_return_val_if_fail (dns_config->domains, NULL);
+	g_return_val_if_fail (i < g_hash_table_size (dns_config->domains), NULL);
 
-	domain = g_hash_table_lookup (dns->domains, dns->domain_list[i]);
-	g_return_val_if_fail (domain, NULL);
+	nm_assert (NM_PTRARRAY_LEN (dns_config->domain_list) == g_hash_table_size (dns_config->domains));
 
+	domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
+
+	nm_assert (domain);
 	return domain;
 }
 
-NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns, const char *name)
+NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns_config, const char *name)
 {
-	g_return_val_if_fail (dns, NULL);
-	g_return_val_if_fail (dns->domains, NULL);
+	g_return_val_if_fail (dns_config, NULL);
 	g_return_val_if_fail (name, NULL);
 
-	return g_hash_table_lookup (dns->domains, name);
+	return dns_config->domains ? g_hash_table_lookup (dns_config->domains, name) : NULL;
 }
 
 const char *
@@ -775,55 +774,73 @@ const char *const *
 nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain)
 {
 	g_return_val_if_fail (domain, NULL);
+
 	return (const char *const *) domain->options;
 }
 
 gboolean
-nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns_config)
 {
-	return dns->internal;
+	return dns_config->internal;
 }
 
 gboolean
-nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns)
+nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns_config)
 {
-	g_return_val_if_fail (dns, TRUE);
-	g_return_val_if_fail (dns->domains, TRUE);
+	g_return_val_if_fail (dns_config, TRUE);
 
-	return    (!dns->searches || g_strv_length (dns->searches) == 0)
-	       && (!dns->options || g_strv_length (dns->options) == 0)
-	       && g_hash_table_size (dns->domains) == 0;
+	return    !dns_config->searches
+	       && !dns_config->options
+	       && !dns_config->domain_list;
 }
 
 void
-nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns, GChecksum *sum)
+nm_global_dns_config_update_checksum (const NMGlobalDnsConfig *dns_config, GChecksum *sum)
 {
 	NMGlobalDnsDomain *domain;
-	GList *keys, *key;
-	guint i;
+	guint i, j;
+	guint8 v8;
 
-	g_return_if_fail (dns);
-	g_return_if_fail (dns->domains);
+	g_return_if_fail (dns_config);
 	g_return_if_fail (sum);
 
-	for (i = 0; dns->searches && dns->searches[i]; i++)
-		g_checksum_update (sum, (guchar *) dns->searches[i], strlen (dns->searches[i]));
-	for (i = 0; dns->options && dns->options[i]; i++)
-		g_checksum_update (sum, (guchar *) dns->options[i], strlen (dns->options[i]));
+	v8 = NM_HASH_COMBINE_BOOLS (guint8,
+	                            !dns_config->searches,
+	                            !dns_config->options,
+	                            !dns_config->domain_list);
+	g_checksum_update (sum, (guchar *) &v8, 1);
+
+	if (dns_config->searches) {
+		for (i = 0; dns_config->searches[i]; i++)
+			g_checksum_update (sum, (guchar *) dns_config->searches[i], strlen (dns_config->searches[i]) + 1);
+	}
+	if (dns_config->options) {
+		for (i = 0; dns_config->options[i]; i++)
+			g_checksum_update (sum, (guchar *) dns_config->options[i], strlen (dns_config->options[i]) + 1);
+	}
+
+	if (dns_config->domain_list) {
+		for (i = 0; dns_config->domain_list[i]; i++) {
+			domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
+			nm_assert (domain);
 
-	keys = g_list_sort (g_hash_table_get_keys (dns->domains), (GCompareFunc) strcmp);
-	for (key = keys; key; key = g_list_next (key)) {
+			v8 = NM_HASH_COMBINE_BOOLS (guint8,
+			                            !domain->servers,
+			                            !domain->options);
+			g_checksum_update (sum, (guchar *) &v8, 1);
 
-		domain = g_hash_table_lookup (dns->domains, key->data);
-		g_assert (domain != NULL);
-		g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name));
+			g_checksum_update (sum, (guchar *) domain->name, strlen (domain->name) + 1);
 
-		for (i = 0; domain->servers && domain->servers[i]; i++)
-			g_checksum_update (sum, (guchar *) domain->servers[i], strlen (domain->servers[i]));
-		for (i = 0; domain->options && domain->options[i]; i++)
-			g_checksum_update (sum, (guchar *) domain->options[i], strlen (domain->options[i]));
+			if (domain->servers) {
+				for (j = 0; domain->servers[j]; j++)
+					g_checksum_update (sum, (guchar *) domain->servers[j], strlen (domain->servers[j]) + 1);
+			}
+			if (domain->options) {
+				for (j = 0; domain->options[j]; j++)
+					g_checksum_update (sum, (guchar *) domain->options[j], strlen (domain->options[j]) + 1);
+			}
+		}
 	}
-	g_list_free (keys);
 }
 
 static void
@@ -838,14 +855,15 @@ global_dns_domain_free (NMGlobalDnsDomain  *domain)
 }
 
 void
-nm_global_dns_config_free (NMGlobalDnsConfig *conf)
-{
-	if (conf) {
-		g_strfreev (conf->searches);
-		g_strfreev (conf->options);
-		g_free (conf->domain_list);
-		g_hash_table_unref (conf->domains);
-		g_free (conf);
+nm_global_dns_config_free (NMGlobalDnsConfig *dns_config)
+{
+	if (dns_config) {
+		g_strfreev (dns_config->searches);
+		g_strfreev (dns_config->options);
+		g_free (dns_config->domain_list);
+		if (dns_config->domains)
+			g_hash_table_unref (dns_config->domains);
+		g_free (dns_config);
 	}
 }
 
@@ -858,18 +876,22 @@ nm_config_data_get_global_dns_config (const NMConfigData *self)
 }
 
 static void
-global_dns_config_update_domain_list (NMGlobalDnsConfig *dns)
+global_dns_config_seal_domains (NMGlobalDnsConfig *dns_config)
 {
-	guint length;
+	nm_assert (dns_config);
+	nm_assert (dns_config->domains);
+	nm_assert (!dns_config->domain_list);
 
-	g_free (dns->domain_list);
-	dns->domain_list = (char **) g_hash_table_get_keys_as_array (dns->domains, &length);
+	if (g_hash_table_size (dns_config->domains) == 0)
+		nm_clear_pointer (&dns_config->domains, g_hash_table_unref);
+	else
+		dns_config->domain_list = nm_utils_strdict_get_keys (dns_config->domains, TRUE, NULL);
 }
 
 static NMGlobalDnsConfig *
 load_global_dns (GKeyFile *keyfile, gboolean internal)
 {
-	NMGlobalDnsConfig *conf;
+	NMGlobalDnsConfig *dns_config;
 	char *group, *domain_prefix;
 	gs_strfreev char **groups = NULL;
 	int g, i, j, domain_prefix_len;
@@ -887,13 +909,18 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
 	if (!nm_config_keyfile_has_global_dns_config (keyfile, internal))
 		return NULL;
 
-	conf = g_malloc0 (sizeof (NMGlobalDnsConfig));
-	conf->domains = g_hash_table_new_full (nm_str_hash, g_str_equal,
-	                                       g_free, (GDestroyNotify) global_dns_domain_free);
+	dns_config = g_malloc0 (sizeof (NMGlobalDnsConfig));
+	dns_config->domains = g_hash_table_new_full (nm_str_hash, g_str_equal,
+	                                             g_free, (GDestroyNotify) global_dns_domain_free);
 
 	strv = g_key_file_get_string_list (keyfile, group, "searches", NULL, NULL);
-	if (strv)
-		conf->searches = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+	if (strv) {
+		_nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+		if (!strv[0])
+			g_free (strv);
+		else
+			dns_config->searches = strv;
+	}
 
 	strv = g_key_file_get_string_list (keyfile, group, "options", NULL, NULL);
 	if (strv) {
@@ -904,8 +931,12 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
 			else
 				g_free (strv[i]);
 		}
-		strv[j] = NULL;
-		conf->options = strv;
+		if (j == 0)
+			g_free (strv);
+		else {
+			strv[j] = NULL;
+			dns_config->options = strv;
+		}
 	}
 
 	groups = g_key_file_get_groups (keyfile, NULL);
@@ -928,20 +959,23 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
 				else
 					g_free (strv[i]);
 			}
-			if (j) {
+			if (j == 0)
+				g_free (strv);
+			else {
 				strv[j] = NULL;
 				servers = strv;
 			}
-			else
-				g_free (strv);
 		}
 
 		if (!servers)
 			continue;
 
 		strv = g_key_file_get_string_list (keyfile, groups[g], "options", NULL, NULL);
-		if (strv)
+		if (strv) {
 			options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+			if (!options[0])
+				nm_clear_g_free (&options);
+		}
 
 		name = strdup (&groups[g][domain_prefix_len]);
 		domain = g_malloc0 (sizeof (NMGlobalDnsDomain));
@@ -949,7 +983,7 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
 		domain->servers = servers;
 		domain->options = options;
 
-		g_hash_table_insert (conf->domains, strdup (name), domain);
+		g_hash_table_insert (dns_config->domains, strdup (name), domain);
 
 		if (!strcmp (name, "*"))
 			default_found = TRUE;
@@ -958,59 +992,60 @@ load_global_dns (GKeyFile *keyfile, gboolean internal)
 	if (!default_found) {
 		nm_log_dbg (LOGD_CORE, "%s global DNS configuration is missing default domain, ignore it",
 		            internal ? "internal" : "user");
-		nm_global_dns_config_free (conf);
+		nm_global_dns_config_free (dns_config);
 		return NULL;
 	}
 
-	conf->internal = internal;
-	global_dns_config_update_domain_list (conf);
-	return conf;
+	dns_config->internal = internal;
+	global_dns_config_seal_domains (dns_config);
+	return dns_config;
 }
 
-
 void
-nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns, GValue *value)
+nm_global_dns_config_to_dbus (const NMGlobalDnsConfig *dns_config, GValue *value)
 {
 	GVariantBuilder conf_builder, domains_builder, domain_builder;
-	NMGlobalDnsDomain *domain;
-	GHashTableIter iter;
+	guint i;
 
 	g_variant_builder_init (&conf_builder, G_VARIANT_TYPE ("a{sv}"));
-	if (!dns)
+	if (!dns_config)
 		goto out;
 
-	if (dns->searches) {
+	if (dns_config->searches) {
 		g_variant_builder_add (&conf_builder, "{sv}", "searches",
-		                       g_variant_new_strv ((const char *const *) dns->searches, -1));
+		                       g_variant_new_strv ((const char *const *) dns_config->searches, -1));
 	}
 
-	if (dns->options) {
+	if (dns_config->options) {
 		g_variant_builder_add (&conf_builder, "{sv}", "options",
-		                       g_variant_new_strv ((const char *const *) dns->options, -1));
+		                       g_variant_new_strv ((const char *const *) dns_config->options, -1));
 	}
 
 	g_variant_builder_init (&domains_builder, G_VARIANT_TYPE ("a{sv}"));
+	if (dns_config->domain_list) {
+		for (i = 0; dns_config->domain_list[i]; i++) {
+			NMGlobalDnsDomain *domain;
 
-	g_hash_table_iter_init (&iter, dns->domains);
-	while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &domain)) {
+			domain = g_hash_table_lookup (dns_config->domains, dns_config->domain_list[i]);
 
-		g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
+			g_variant_builder_init (&domain_builder, G_VARIANT_TYPE ("a{sv}"));
 
-		if (domain->servers) {
-			g_variant_builder_add (&domain_builder, "{sv}", "servers",
-			                       g_variant_new_strv ((const char *const *) domain->servers, -1));
-		}
-		if (domain->options) {
-			g_variant_builder_add (&domain_builder, "{sv}", "options",
-			                       g_variant_new_strv ((const char *const *) domain->options, -1));
-		}
+			if (domain->servers) {
+				g_variant_builder_add (&domain_builder, "{sv}", "servers",
+				                       g_variant_new_strv ((const char *const *) domain->servers, -1));
+			}
+			if (domain->options) {
+				g_variant_builder_add (&domain_builder, "{sv}", "options",
+				                       g_variant_new_strv ((const char *const *) domain->options, -1));
+			}
 
-		g_variant_builder_add (&domains_builder, "{sv}", domain->name,
-		                       g_variant_builder_end (&domain_builder));
+			g_variant_builder_add (&domains_builder, "{sv}", domain->name,
+			                       g_variant_builder_end (&domain_builder));
+		}
 	}
-
 	g_variant_builder_add (&conf_builder, "{sv}", "domains",
 	                       g_variant_builder_end (&domains_builder));
+
 out:
 	g_value_take_variant (value, g_variant_builder_end (&conf_builder));
 }
@@ -1044,15 +1079,20 @@ global_dns_domain_from_dbus (char *name, GVariant *variant)
 				else
 					g_free (strv[i]);
 			}
-			if (j) {
+			if (j == 0)
+				g_free (strv);
+			else {
 				strv[j] = NULL;
+				g_strfreev (domain->servers);
 				domain->servers = strv;
-			} else
-				g_free (strv);
+			}
 		} else if (   !g_strcmp0 (key, "options")
 		           && g_variant_is_of_type (val, G_VARIANT_TYPE ("as"))) {
 			strv = g_variant_dup_strv (val, NULL);
+			g_strfreev (domain->options);
 			domain->options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+			if (!domain->options[0])
+				nm_clear_g_free (&domain->options);
 		}
 
 		g_variant_unref (val);
@@ -1111,11 +1151,12 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
 				else
 					g_free (strv[i]);
 			}
-
-			if (strv)
+			if (j == 0)
+				g_free (strv);
+			else {
 				strv[j] = NULL;
-
-			dns_config->options = strv;
+				dns_config->options = strv;
+			}
 		} else if (   !g_strcmp0 (key, "domains")
 		           && g_variant_is_of_type (val, G_VARIANT_TYPE ("a{sv}"))) {
 			NMGlobalDnsDomain *domain;
@@ -1145,7 +1186,7 @@ nm_global_dns_config_from_dbus (const GValue *value, GError **error)
 		return NULL;
 	}
 
-	global_dns_config_update_domain_list (dns_config);
+	global_dns_config_seal_domains (dns_config);
 	return dns_config;
 }
 
@@ -1196,6 +1237,8 @@ _match_section_infos_lookup (const MatchSectionInfo *match_section_infos,
                              GKeyFile *keyfile,
                              const char *property,
                              NMDevice *device,
+                             const NMPlatformLink *pllink,
+                             const char *match_device_type,
                              char **out_value)
 {
 	if (!match_section_infos)
@@ -1216,9 +1259,15 @@ _match_section_infos_lookup (const MatchSectionInfo *match_section_infos,
 		if (!value && !match_section_infos->stop_match)
 			continue;
 
-		match = TRUE;
-		if (match_section_infos->match_device.has)
-			match = device && nm_device_spec_match_list (device, match_section_infos->match_device.spec);
+		if (match_section_infos->match_device.has) {
+			if (device)
+				match = nm_device_spec_match_list (device, match_section_infos->match_device.spec);
+			else if (pllink)
+				match = nm_match_spec_device_by_pllink (pllink, match_device_type, match_section_infos->match_device.spec, FALSE);
+			else
+				match = FALSE;
+		} else
+			match = TRUE;
 
 		if (match) {
 			*out_value = value;
@@ -1248,6 +1297,35 @@ nm_config_data_get_device_config (const NMConfigData *self,
 	                                               priv->keyfile,
 	                                               property,
 	                                               device,
+	                                               NULL,
+	                                               NULL,
+	                                               &value);
+	NM_SET_OUT (has_match, !!connection_info);
+	return value;
+}
+
+char *
+nm_config_data_get_device_config_by_pllink (const NMConfigData *self,
+                                            const char *property,
+                                            const NMPlatformLink *pllink,
+                                            const char *match_device_type,
+                                            gboolean *has_match)
+{
+	const NMConfigDataPrivate *priv;
+	const MatchSectionInfo *connection_info;
+	char *value = NULL;
+
+	g_return_val_if_fail (self, NULL);
+	g_return_val_if_fail (property && *property, NULL);
+
+	priv = NM_CONFIG_DATA_GET_PRIVATE (self);
+
+	connection_info = _match_section_infos_lookup (&priv->device_infos[0],
+	                                               priv->keyfile,
+	                                               property,
+	                                               NULL,
+	                                               pllink,
+	                                               match_device_type,
 	                                               &value);
 	NM_SET_OUT (has_match, !!connection_info);
 	return value;
@@ -1287,6 +1365,8 @@ nm_config_data_get_connection_default (const NMConfigData *self,
 	                             priv->keyfile,
 	                             property,
 	                             device,
+	                             NULL,
+	                             NULL,
 	                             &value);
 	return value;
 }