summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-06-15 09:01:42 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-10-01 09:05:08 +0200
commit55c204b9a357e917cb26b1a1742dff703223037e (patch)
treee026966f49af578d2292e6beb8824be09f7d9e92
parentbd27c110a3d6dede825efb4517d296c89b01a156 (diff)
downloadNetworkManager-55c204b9a357e917cb26b1a1742dff703223037e.tar.gz
core: add support for reading global DNS configuration from keyfile
Add to the NMConfigData object information about global DNS configuration, which is loaded from user or internal keyfile upon object construction.
-rw-r--r--src/nm-config-data.c298
-rw-r--r--src/nm-config-data.h17
-rw-r--r--src/nm-config.c20
-rw-r--r--src/nm-config.h8
-rw-r--r--src/tests/config/Makefile.am2
-rw-r--r--src/tests/config/NetworkManager.conf16
-rw-r--r--src/tests/config/global-dns-disabled.conf8
-rw-r--r--src/tests/config/global-dns-invalid.conf10
-rw-r--r--src/tests/config/test-config.c78
9 files changed, 457 insertions, 0 deletions
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index a804e61a93..b9fe9c2e4a 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -72,10 +72,25 @@ typedef struct {
char *dns_mode;
char *rc_manager;
+ NMGlobalDnsConfig *global_dns;
+
/* mutable field */
char *value_cached;
} NMConfigDataPrivate;
+struct _NMGlobalDnsDomain {
+ char *name;
+ char **servers;
+ char **options;
+};
+
+struct _NMGlobalDnsConfig {
+ char **searches;
+ char **options;
+ GHashTable *domains;
+ char **domain_list;
+ gboolean internal;
+};
enum {
PROP_0,
@@ -91,6 +106,7 @@ enum {
LAST_PROP
};
+
G_DEFINE_TYPE (NMConfigData, nm_config_data, G_TYPE_OBJECT)
#define NM_CONFIG_DATA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG_DATA, NMConfigDataPrivate))
@@ -534,6 +550,279 @@ nm_config_data_log (const NMConfigData *self, const char *prefix)
/************************************************************************/
+const char *const *
+nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns)
+{
+ g_return_val_if_fail (dns, NULL);
+
+ return (const char *const *) dns->searches;
+}
+
+const char *const *
+nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns)
+{
+ g_return_val_if_fail (dns, NULL);
+
+ return (const char *const *) dns->options;
+}
+
+guint
+nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns)
+{
+ g_return_val_if_fail (dns, 0);
+ g_return_val_if_fail (dns->domains, 0);
+
+ return g_hash_table_size (dns->domains);
+}
+
+NMGlobalDnsDomain *
+nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns, 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);
+
+ domain = g_hash_table_lookup (dns->domains, dns->domain_list[i]);
+ g_return_val_if_fail (domain, NULL);
+
+ return domain;
+}
+
+NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns, const char *name)
+{
+ g_return_val_if_fail (dns, NULL);
+ g_return_val_if_fail (dns->domains, NULL);
+ g_return_val_if_fail (name, NULL);
+
+ return g_hash_table_lookup (dns->domains, name);
+}
+
+const char *
+nm_global_dns_domain_get_name (const NMGlobalDnsDomain *domain)
+{
+ g_return_val_if_fail (domain, NULL);
+
+ return (const char *) domain->name;
+}
+
+const char *const *
+nm_global_dns_domain_get_servers (const NMGlobalDnsDomain *domain)
+{
+ g_return_val_if_fail (domain, NULL);
+
+ return (const char *const *) domain->servers;
+}
+
+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)
+{
+ return dns->internal;
+}
+
+gboolean
+nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns)
+{
+ g_return_val_if_fail (dns, TRUE);
+ g_return_val_if_fail (dns->domains, 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;
+}
+
+static void
+global_dns_domain_free (NMGlobalDnsDomain *domain)
+{
+ if (domain) {
+ g_free (domain->name);
+ g_strfreev (domain->servers);
+ g_strfreev (domain->options);
+ g_free (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);
+ }
+}
+
+NMGlobalDnsConfig *
+nm_config_data_get_global_dns_config (const NMConfigData *self)
+{
+ g_return_val_if_fail (NM_IS_CONFIG_DATA (self), NULL);
+
+ return NM_CONFIG_DATA_GET_PRIVATE (self)->global_dns;
+}
+
+static void
+global_dns_config_update_domain_list (NMGlobalDnsConfig *dns)
+{
+ guint length;
+
+ g_free (dns->domain_list);
+ dns->domain_list = (char **) g_hash_table_get_keys_as_array (dns->domains, &length);
+}
+
+static NMGlobalDnsConfig *
+load_global_dns (GKeyFile *keyfile, gboolean internal)
+{
+ NMGlobalDnsConfig *conf;
+ char *group, *domain_prefix;
+ gs_strfreev char **groups = NULL;
+ int g, i, j, domain_prefix_len;
+ gboolean default_found = FALSE;
+ char **strv;
+
+ group = internal
+ ? NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS
+ : NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS;
+ domain_prefix = internal
+ ? NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN
+ : NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN;
+ domain_prefix_len = strlen (domain_prefix);
+
+ if (!keyfile || !nm_config_keyfile_get_boolean (keyfile, group, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE, FALSE))
+ return NULL;
+
+ conf = g_malloc0 (sizeof (NMGlobalDnsConfig));
+ conf->domains = g_hash_table_new_full (g_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);
+
+ strv = g_key_file_get_string_list (keyfile, group, "options", NULL, NULL);
+ if (strv) {
+ _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ for (i = 0, j = 0; strv[i]; i++) {
+ if (_nm_utils_dns_option_validate (strv[i], NULL, NULL, TRUE, NULL))
+ strv[j++] = strv[i];
+ else
+ g_free (strv[i]);
+ }
+ strv[j] = NULL;
+ conf->options = strv;
+ }
+
+ groups = g_key_file_get_groups (keyfile, NULL);
+ for (g = 0; groups[g]; g++) {
+ char *name;
+ char **servers = NULL, **options = NULL;
+ NMGlobalDnsDomain *domain;
+
+ if ( !g_str_has_prefix (groups[g], domain_prefix)
+ || !groups[g][domain_prefix_len])
+ continue;
+
+ strv = g_key_file_get_string_list (keyfile, groups[g], "servers", NULL, NULL);
+ if (strv) {
+ _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+ for (i = 0, j = 0; strv[i]; i++) {
+ if ( nm_utils_ipaddr_valid (AF_INET, strv[i])
+ || nm_utils_ipaddr_valid (AF_INET6, strv[i]))
+ strv[j++] = strv[i];
+ else
+ g_free (strv[i]);
+ }
+ if (j) {
+ 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)
+ options = _nm_utils_strv_cleanup (strv, TRUE, TRUE, TRUE);
+
+ name = strdup (&groups[g][domain_prefix_len]);
+ domain = g_malloc0 (sizeof (NMGlobalDnsDomain));
+ domain->name = name;
+ domain->servers = servers;
+ domain->options = options;
+
+ g_hash_table_insert (conf->domains, strdup (name), domain);
+
+ if (!strcmp (name, "*"))
+ default_found = TRUE;
+ }
+
+ 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);
+ return NULL;
+ }
+
+ conf->internal = internal;
+ global_dns_config_update_domain_list (conf);
+ return conf;
+}
+
+static gboolean
+global_dns_equal (NMGlobalDnsConfig *old, NMGlobalDnsConfig *new)
+{
+ NMGlobalDnsDomain *domain_old, *domain_new;
+ gpointer key, value_old, value_new;
+ GHashTableIter iter;
+
+ if (old == new)
+ return TRUE;
+
+ if (!old || !new)
+ return FALSE;
+
+ if ( !_nm_utils_strv_equal (old->options, new->options)
+ || !_nm_utils_strv_equal (old->searches, new->searches))
+ return FALSE;
+
+ if ((!old->domains || !new->domains) && old->domains != new->domains)
+ return FALSE;
+
+ if (g_hash_table_size (old->domains) != g_hash_table_size (new->domains))
+ return FALSE;
+
+ g_hash_table_iter_init (&iter, old->domains);
+ while (g_hash_table_iter_next (&iter, &key, &value_old)) {
+ value_new = g_hash_table_lookup (new->domains, key);
+ if (!value_new)
+ return FALSE;
+
+ domain_old = value_old;
+ domain_new = value_new;
+
+ if ( !_nm_utils_strv_equal (domain_old->options, domain_new->options)
+ || !_nm_utils_strv_equal (domain_old->servers, domain_new->servers))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/************************************************************************/
+
char *
nm_config_data_get_connection_default (const NMConfigData *self,
const char *property,
@@ -683,6 +972,9 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data)
if (g_strcmp0 (nm_config_data_get_rc_manager (old_data), nm_config_data_get_rc_manager (new_data)))
changes |= NM_CONFIG_CHANGE_RC_MANAGER;
+ if (!global_dns_equal (priv_old->global_dns, priv_new->global_dns))
+ changes |= NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG;
+
return changes;
}
@@ -804,6 +1096,8 @@ finalize (GObject *gobject)
g_slist_free_full (priv->ignore_carrier, g_free);
g_slist_free_full (priv->assume_ipv6ll_only, g_free);
+ nm_global_dns_config_free (priv->global_dns);
+
if (priv->connection_infos) {
for (i = 0; priv->connection_infos[i].group_name; i++) {
g_free (priv->connection_infos[i].group_name);
@@ -858,6 +1152,10 @@ constructed (GObject *object)
priv->no_auto_default.specs_config = nm_config_get_device_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "no-auto-default", NULL);
+ priv->global_dns = load_global_dns (priv->keyfile_user, FALSE);
+ if (!priv->global_dns)
+ priv->global_dns = load_global_dns (priv->keyfile_intern, TRUE);
+
G_OBJECT_CLASS (nm_config_data_parent_class)->constructed (object);
}
diff --git a/src/nm-config-data.h b/src/nm-config-data.h
index 8b745f2eb0..0d7a6adfa6 100644
--- a/src/nm-config-data.h
+++ b/src/nm-config-data.h
@@ -76,6 +76,7 @@ typedef enum { /*< flags >*/
NM_CONFIG_CHANGE_NO_AUTO_DEFAULT = (1L << 8),
NM_CONFIG_CHANGE_DNS_MODE = (1L << 9),
NM_CONFIG_CHANGE_RC_MANAGER = (1L << 10),
+ NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG = (1L << 11),
_NM_CONFIG_CHANGE_LAST,
NM_CONFIG_CHANGE_ALL = ((_NM_CONFIG_CHANGE_LAST - 1) << 1) - 1,
@@ -89,6 +90,9 @@ typedef struct {
GObjectClass parent;
} NMConfigDataClass;
+typedef struct _NMGlobalDnsConfig NMGlobalDnsConfig;
+typedef struct _NMGlobalDnsDomain NMGlobalDnsDomain;
+
GType nm_config_data_get_type (void);
NMConfigData *nm_config_data_new (const char *config_main_file,
@@ -124,6 +128,7 @@ const char *nm_config_data_get_rc_manager (const NMConfigData *self);
gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device);
gboolean nm_config_data_get_assume_ipv6ll_only (const NMConfigData *self, NMDevice *device);
+NMGlobalDnsConfig *nm_config_data_get_global_dns_config (const NMConfigData *self);
char *nm_config_data_get_connection_default (const NMConfigData *self,
const char *property,
@@ -135,6 +140,18 @@ gboolean nm_config_data_is_intern_atomic_group (const NMConfigData *self, const
GKeyFile *nm_config_data_clone_keyfile_intern (const NMConfigData *self);
+const char *const *nm_global_dns_config_get_searches (const NMGlobalDnsConfig *dns);
+const char *const *nm_global_dns_config_get_options (const NMGlobalDnsConfig *dns);
+guint nm_global_dns_config_get_num_domains (const NMGlobalDnsConfig *dns);
+NMGlobalDnsDomain *nm_global_dns_config_get_domain (const NMGlobalDnsConfig *dns, guint i);
+NMGlobalDnsDomain *nm_global_dns_config_lookup_domain (const NMGlobalDnsConfig *dns, const char *name);
+const char *nm_global_dns_domain_get_name (const NMGlobalDnsDomain *domain);
+const char *const *nm_global_dns_domain_get_servers (const NMGlobalDnsDomain *domain);
+const char *const *nm_global_dns_domain_get_options (const NMGlobalDnsDomain *domain);
+gboolean nm_global_dns_config_is_internal (const NMGlobalDnsConfig *dns);
+gboolean nm_global_dns_config_is_empty (const NMGlobalDnsConfig *dns);
+void nm_global_dns_config_free (NMGlobalDnsConfig *conf);
+
/* private accessors */
GKeyFile *_nm_config_data_get_keyfile (const NMConfigData *self);
GKeyFile *_nm_config_data_get_keyfile_user (const NMConfigData *self);
diff --git a/src/nm-config.c b/src/nm-config.c
index 0ccb6e6af2..bf5811d480 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -1184,6 +1184,24 @@ intern_config_read (const char *filename,
}
out:
+ /*
+ * If user configuration specifies global DNS options, the DNS
+ * options in internal configuration must be deleted. Otherwise a
+ * deletion of options from user configuration may cause the
+ * internal options to appear again.
+ */
+ if (nm_config_keyfile_get_boolean (keyfile_conf, NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE, FALSE)) {
+ if (g_key_file_remove_group (keyfile_intern, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, NULL))
+ needs_rewrite = TRUE;
+ for (g = 0; groups && groups[g]; g++) {
+ if ( g_str_has_prefix (groups[g], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)
+ && groups[g][STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)]) {
+ g_key_file_remove_group (keyfile_intern, groups[g], NULL);
+ needs_rewrite = TRUE;
+ }
+ }
+ }
+
g_key_file_unref (keyfile);
if (out_needs_rewrite)
@@ -1593,6 +1611,8 @@ _change_flags_one_to_string (NMConfigChangeFlags flag)
return "dns-mode";
case NM_CONFIG_CHANGE_RC_MANAGER:
return "rc-manager";
+ case NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG:
+ return "global-dns-config";
default:
g_return_val_if_reached ("unknown");
}
diff --git a/src/nm-config.h b/src/nm-config.h
index 59fd5cf39a..c52b3dceb6 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -49,17 +49,20 @@ G_BEGIN_DECLS
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN ".intern."
#define NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION "connection"
+#define NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "global-dns-domain-"
#define NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST ".test-append-stringlist"
#define NM_CONFIG_KEYFILE_GROUP_MAIN "main"
#define NM_CONFIG_KEYFILE_GROUP_LOGGING "logging"
#define NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY "connectivity"
+#define NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS "global-dns"
#define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile"
#define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown"
#define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet"
#define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend"
+#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE "enable"
#define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was"
#define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh"
#define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed"
@@ -69,6 +72,11 @@ G_BEGIN_DECLS
#define NM_CONFIG_KEYFILE_KEYPREFIX_WAS ".was."
#define NM_CONFIG_KEYFILE_KEYPREFIX_SET ".set."
+#define NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS \
+ NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS
+#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN \
+ NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN
+
typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
struct _NMConfig {
diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am
index cc1ffb387b..6ad9876f1f 100644
--- a/src/tests/config/Makefile.am
+++ b/src/tests/config/Makefile.am
@@ -30,6 +30,8 @@ TESTS = test-config
EXTRA_DIST = \
NetworkManager.conf \
bad.conf \
+ global-dns-disabled.conf \
+ global-dns-invalid.conf \
conf.d/00-overrides.conf \
conf.d/10-more.conf \
conf.d/90-last.conf
diff --git a/src/tests/config/NetworkManager.conf b/src/tests/config/NetworkManager.conf
index a750c801ee..da7b1fd421 100644
--- a/src/tests/config/NetworkManager.conf
+++ b/src/tests/config/NetworkManager.conf
@@ -81,3 +81,19 @@ ord.key07=A-0.3.07
ord.key08=A-0.3.08
ord.key09=A-0.3.09
ord.ovw01=A-0.3.ovw01
+
+[global-dns]
+enable=yes
+searches=foo.com,bar.org
+options=debug,edns0
+
+[global-dns-domain-*]
+servers=1.1.1.1,bad,1::128
+options=opt1,opt2
+
+[global-dns-domain-example.com]
+servers=2.2.2.2
+
+# Invalid section: 'servers' key is missing
+[global-dns-domain-test.com]
+options=opt3
diff --git a/src/tests/config/global-dns-disabled.conf b/src/tests/config/global-dns-disabled.conf
new file mode 100644
index 0000000000..53ccd832e2
--- /dev/null
+++ b/src/tests/config/global-dns-disabled.conf
@@ -0,0 +1,8 @@
+[global-dns]
+enable=no
+searches=foo.com
+options=timeout:5
+
+[global-dns-domain-*]
+servers=1.2.3.4
+options=myoption
diff --git a/src/tests/config/global-dns-invalid.conf b/src/tests/config/global-dns-invalid.conf
new file mode 100644
index 0000000000..10ecc9b04c
--- /dev/null
+++ b/src/tests/config/global-dns-invalid.conf
@@ -0,0 +1,10 @@
+# Invalid configuration, since there isn't a default domain section
+
+[global-dns]
+enable=yes
+searches=foo.com
+options=timeout:5
+
+[global-dns-domain-test.com]
+servers=1.2.3.4
+options=myoption
diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c
index b021fe028a..d3b2db6920 100644
--- a/src/tests/config/test-config.c
+++ b/src/tests/config/test-config.c
@@ -244,6 +244,83 @@ test_config_override (void)
}
static void
+test_config_global_dns (void)
+{
+ NMConfig *config;
+ const NMGlobalDnsConfig *dns;
+ NMGlobalDnsDomain *domain;
+ const char *const *strv;
+
+ config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL,
+ "/no/such/dir", "", NULL);
+
+ dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config));
+ g_assert (dns);
+
+ strv = nm_global_dns_config_get_searches (dns);
+ g_assert (strv);
+ g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+ g_assert_cmpstr (strv[0], ==, "foo.com");
+ g_assert_cmpstr (strv[1], ==, "bar.org");
+
+ strv = nm_global_dns_config_get_options (dns);
+ g_assert (strv);
+ g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+ g_assert_cmpstr (strv[0], ==, "debug");
+ g_assert_cmpstr (strv[1], ==, "edns0");
+
+ g_assert_cmpuint (nm_global_dns_config_get_num_domains (dns), ==, 2);
+
+ /* Default domain */
+ domain = nm_global_dns_config_lookup_domain (dns, "*");
+ g_assert (domain);
+
+ strv = nm_global_dns_domain_get_servers (domain);
+ g_assert (strv);
+ g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+ g_assert_cmpstr (strv[0], ==, "1.1.1.1");
+ g_assert_cmpstr (strv[1], ==, "1::128");
+
+ strv = nm_global_dns_domain_get_options (domain);
+ g_assert (strv);
+ g_assert_cmpuint (g_strv_length ((char **) strv), ==, 2);
+ g_assert_cmpstr (strv[0], ==, "opt1");
+ g_assert_cmpstr (strv[1], ==, "opt2");
+
+ /* 'example.com' domain */
+ domain = nm_global_dns_config_lookup_domain (dns, "example.com");
+ g_assert (domain);
+
+ strv = nm_global_dns_domain_get_servers (domain);
+ g_assert (strv);
+ g_assert_cmpuint (g_strv_length ((char **) strv), ==, 1);
+ g_assert_cmpstr (strv[0], ==, "2.2.2.2");
+
+ strv = nm_global_dns_domain_get_options (domain);
+ g_assert (!strv || g_strv_length ((char **) strv) == 0);
+
+ /* Non-existent domain 'test.com' */
+ domain = nm_global_dns_config_lookup_domain (dns, "test.com");
+ g_assert (!domain);
+
+ g_object_unref (config);
+
+ /* Check that a file without "enable=yes" gives a NULL configuration */
+ config = setup_config (NULL, SRCDIR "/global-dns-disabled.conf", "", NULL,
+ "/no/such/dir", "", NULL);
+ dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config));
+ g_assert (!dns);
+ g_object_unref (config);
+
+ /* Check that a file without a default domain section gives a NULL configuration */
+ config = setup_config (NULL, SRCDIR "/global-dns-invalid.conf", "", NULL,
+ "/no/such/dir", "", NULL);
+ dns = nm_config_data_get_global_dns_config (nm_config_get_data_orig (config));
+ g_assert (!dns);
+ g_object_unref (config);
+}
+
+static void
test_config_no_auto_default (void)
{
NMConfig *config;
@@ -852,6 +929,7 @@ main (int argc, char **argv)
g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error);
g_test_add_func ("/config/set-values", test_config_set_values);
+ g_test_add_func ("/config/global-dns", test_config_global_dns);
g_test_add_func ("/config/signal", test_config_signal);