summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-01-10 11:23:33 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2018-01-12 08:32:20 +0100
commitda373e629bd71c76e2f12ba1b38b20f7ad41c1ae (patch)
tree366077c977e923d52d6e287c2fdc8dd8b254f027
parent6e78d7edd19123f898b4da137777fbb9f319efa9 (diff)
downloadNetworkManager-bg/dns-domains-pt1-bgo746422.tar.gz
dns: introduce routing domainsbg/dns-domains-pt1-bgo746422
Similarly to what systemd-resolved does, introduce the concept of "routing" domain, which is a domain in the search list that is used only to decide the interface over which a query must be forwarded, but is not used to complete unqualified host names. Routing domains are those starting with a tilde ('~') before the actual domain name. Domains without the initial tilde are used both for completing unqualified names and for the routing decision.
-rw-r--r--clients/common/settings-docs.c.in4
-rw-r--r--libnm-core/nm-setting-ip-config.c5
-rw-r--r--src/dns/nm-dns-dnsmasq.c8
-rw-r--r--src/dns/nm-dns-manager.c36
-rw-r--r--src/dns/nm-dns-systemd-resolved.c21
-rw-r--r--src/nm-core-utils.c15
-rw-r--r--src/nm-core-utils.h2
7 files changed, 64 insertions, 27 deletions
diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in
index 1f3a1a62be..5da6423c66 100644
--- a/clients/common/settings-docs.c.in
+++ b/clients/common/settings-docs.c.in
@@ -218,7 +218,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("Intra-connection DNS priority. The relative priority to be used when determining the order of DNS servers in resolv.conf. A lower value means that servers will be on top of the file. Zero selects the default value, which is 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. For that, just specify the DNS servers in the desired order. When multiple devices have configurations with the same priority, the one with an active default route will be preferred. Note that when using dns=dnsmasq the order is meaningless since dnsmasq forwards queries to all known servers at the same time. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least a negative priority, only DNS servers from connections with the lowest priority value will be used.")
-#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.")
@@ -238,7 +238,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("Intra-connection DNS priority. The relative priority to be used when determining the order of DNS servers in resolv.conf. A lower value means that servers will be on top of the file. Zero selects the default value, which is 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. For that, just specify the DNS servers in the desired order. When multiple devices have configurations with the same priority, the one with an active default route will be preferred. Note that when using dns=dnsmasq the order is meaningless since dnsmasq forwards queries to all known servers at the same time. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least a negative priority, only DNS servers from connections with the lowest priority value will be used.")
-#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.")
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index 888ec7559d..45539becb8 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -2930,7 +2930,10 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
/**
* NMSettingIPConfig:dns-search:
*
- * Array of DNS search domains.
+ * Array of DNS search domains. Domains starting with a tilde ('~')
+ * are considered 'routing' domains and are used only to decide the
+ * interface over which a query must be forwarded; they are not used
+ * to complete unqualified host names.
**/
g_object_class_install_property
(object_class, PROP_DNS_SEARCH,
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c
index c18aaba0da..9719020c33 100644
--- a/src/dns/nm-dns-dnsmasq.c
+++ b/src/dns/nm-dns-dnsmasq.c
@@ -219,7 +219,7 @@ add_ip_config (NMDnsDnsmasq *self,
char ip_addr_to_string_buf[IP_ADDR_TO_STRING_BUFLEN];
char **domains, **iter;
gboolean iface_resolved = FALSE;
- const char *iface = NULL;
+ const char *iface = NULL, *domain;
addr_family = nm_ip_config_get_addr_family (ip_config);
g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6));
@@ -247,21 +247,23 @@ add_ip_config (NMDnsDnsmasq *self,
/* searches are preferred over domains */
n = nm_ip_config_get_num_searches (ip_config);
for (i = 0; i < n; i++) {
+ domain = nm_utils_parse_dns_domain (nm_ip_config_get_search (ip_config, i), NULL);
add_dnsmasq_nameserver (self,
servers,
ip_addr_to_string_buf,
- nm_ip_config_get_search (ip_config, i));
+ domain);
added = TRUE;
}
if (n == 0) {
/* If not searches, use any domains */
n = nm_ip_config_get_num_domains (ip_config);
+ domain = nm_utils_parse_dns_domain (nm_ip_config_get_domain (ip_config, i), NULL);
for (i = 0; i < n; i++) {
add_dnsmasq_nameserver (self,
servers,
ip_addr_to_string_buf,
- nm_ip_config_get_domain (ip_config, i));
+ domain);
added = TRUE;
}
}
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index 1e5af33e45..e5d83cdc05 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -180,7 +180,7 @@ static void _ip_config_dns_priority_changed (gpointer config,
/*****************************************************************************/
static gboolean
-domain_is_valid (const gchar *domain, gboolean check_public_suffix)
+domain_is_valid (const char *domain, gboolean check_public_suffix)
{
if (*domain == '\0')
return FALSE;
@@ -191,6 +191,12 @@ domain_is_valid (const gchar *domain, gboolean check_public_suffix)
return TRUE;
}
+static gboolean
+domain_is_routing (const char *domain)
+{
+ return domain[0] == '~';
+}
+
/*****************************************************************************/
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConfManager,
@@ -377,7 +383,8 @@ add_dns_option_item (GPtrArray *array, const char *str)
}
static void
-add_dns_domains (GPtrArray *array, const NMIPConfig *ip_config, gboolean dup)
+add_dns_domains (GPtrArray *array, const NMIPConfig *ip_config,
+ gboolean include_routing, gboolean dup)
{
guint num_domains, num_searches, i;
const char *str;
@@ -387,14 +394,20 @@ add_dns_domains (GPtrArray *array, const NMIPConfig *ip_config, gboolean dup)
for (i = 0; i < num_searches; i++) {
str = nm_ip_config_get_search (ip_config, i);
- if (domain_is_valid (str, FALSE))
- add_string_item (array, str, dup);
+ if (!include_routing && domain_is_routing (str))
+ continue;
+ if (!domain_is_valid (nm_utils_parse_dns_domain (str, NULL), FALSE))
+ continue;
+ add_string_item (array, str, dup);
}
if (num_domains > 1 || !num_searches) {
for (i = 0; i < num_domains; i++) {
str = nm_ip_config_get_domain (ip_config, i);
- if (domain_is_valid (str, FALSE))
- add_string_item (array, str, dup);
+ if (!include_routing && domain_is_routing (str))
+ continue;
+ if (!domain_is_valid (nm_utils_parse_dns_domain (str, NULL), FALSE))
+ continue;
+ add_string_item (array, str, dup);
}
}
}
@@ -439,7 +452,7 @@ merge_one_ip_config (NMResolvConfData *rc,
add_string_item (rc->nameservers, buf, TRUE);
}
- add_dns_domains (rc->searches, ip_config, TRUE);
+ add_dns_domains (rc->searches, ip_config, FALSE, TRUE);
num = nm_ip_config_get_num_dns_options (ip_config);
for (i = 0; i < num; i++) {
@@ -967,8 +980,11 @@ merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
options = nm_global_dns_config_get_options (global_conf);
for (i = 0; searches && searches[i]; i++) {
- if (domain_is_valid (searches[i], FALSE))
- add_string_item (rc->searches, searches[i], TRUE);
+ if (domain_is_routing (searches[i]))
+ continue;
+ if (!domain_is_valid (searches[i], FALSE))
+ continue;
+ add_string_item (rc->searches, searches[i], TRUE);
}
for (i = 0; options && options[i]; i++)
@@ -1954,7 +1970,7 @@ _get_config_variant (NMDnsManager *self)
else
g_ptr_array_set_size (array_domains, 0);
- add_dns_domains (array_domains, ip_config, FALSE);
+ add_dns_domains (array_domains, ip_config, TRUE, FALSE);
if (array_domains->len) {
g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as"));
for (i = 0; i < array_domains->len; i++) {
diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c
index 7ebd3e7e26..a6035fa4b1 100644
--- a/src/dns/nm-dns-systemd-resolved.c
+++ b/src/dns/nm-dns-systemd-resolved.c
@@ -144,7 +144,8 @@ update_add_ip_config (NMDnsSystemdResolved *self,
int addr_family;
gsize addr_size;
guint i, n;
- gboolean route_only;
+ gboolean is_routing;
+ const char *domain;
addr_family = nm_ip_config_get_addr_family (config);
addr_size = nm_utils_addr_family_to_size (addr_family);
@@ -161,25 +162,23 @@ update_add_ip_config (NMDnsSystemdResolved *self,
g_variant_builder_close (dns);
}
- /* If this link is never the default (e.g. only used for resources on this
- * network) add a routing domain. */
- route_only = addr_family == AF_INET
- ? !nm_ip4_config_best_default_route_get (NM_IP4_CONFIG (config))
- : !nm_ip6_config_best_default_route_get (NM_IP6_CONFIG (config));
-
n = nm_ip_config_get_num_searches (config);
if (n > 0) {
for (i = 0; i < n; i++) {
+ domain = nm_utils_parse_dns_domain (nm_ip_config_get_search (config, i),
+ &is_routing);
g_variant_builder_add (domains, "(sb)",
- nm_ip_config_get_search (config, i),
- route_only);
+ domain,
+ is_routing);
}
} else {
n = nm_ip_config_get_num_domains (config);
for (i = 0; i < n; i++) {
+ domain = nm_utils_parse_dns_domain (nm_ip_config_get_domain (config, i),
+ &is_routing);
g_variant_builder_add (domains, "(sb)",
- nm_ip_config_get_domain (config, i),
- route_only);
+ domain,
+ is_routing);
}
}
}
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 197fa49ba9..2cb34de7a2 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -4329,6 +4329,21 @@ nm_utils_format_con_diff_for_audit (GHashTable *diff)
return g_string_free (str, FALSE);
}
+const char *
+nm_utils_parse_dns_domain (const char *domain, gboolean *is_routing)
+{
+ g_return_val_if_fail (domain, NULL);
+ g_return_val_if_fail (domain[0], NULL);
+
+ if (domain[0] == '~') {
+ domain++;
+ NM_SET_OUT (is_routing, TRUE);
+ } else
+ NM_SET_OUT (is_routing, FALSE);
+
+ return domain;
+}
+
/*****************************************************************************/
NM_UTILS_ENUM2STR_DEFINE (nm_icmpv6_router_pref_to_string, NMIcmpv6RouterPref,
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 7078153e99..2f6585e717 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -448,4 +448,6 @@ const char *nm_activation_type_to_string (NMActivationType activation_type);
/*****************************************************************************/
+const char *nm_utils_parse_dns_domain (const char *domain, gboolean *is_routing);
+
#endif /* __NM_CORE_UTILS_H__ */