summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-05-12 17:16:12 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-05-12 17:16:12 +0200
commit8da3e658f7313f56928d22cfe13f9ab78cc1dd3c (patch)
tree3f51ef02d64b7b04ff6e80f4d7e6a0ae6d904773
parent860606012145b42590e389655e4e4e3fec86e1d1 (diff)
parent570d73979beb40cde22546a31ac175d04f53026d (diff)
dns: merge branch 'bg/dns-priority-bgo758772'
Introduce connection properties to change the priority of DNS entries. https://bugzilla.gnome.org/show_bug.cgi?id=758772
-rw-r--r--clients/cli/settings.c126
-rw-r--r--introspection/nm-ip4-config.xml7
-rw-r--r--introspection/nm-ip6-config.xml7
-rw-r--r--libnm-core/nm-setting-ip-config.c52
-rw-r--r--libnm-core/nm-setting-ip-config.h4
-rw-r--r--libnm-core/nm-setting-ip4-config.c11
-rw-r--r--libnm-core/nm-setting-ip6-config.c11
-rw-r--r--libnm-core/tests/test-general.c1
-rw-r--r--libnm/libnm.ver1
-rw-r--r--src/devices/nm-device.c31
-rw-r--r--src/dns-manager/nm-dns-dnsmasq.c54
-rw-r--r--src/dns-manager/nm-dns-manager.c452
-rw-r--r--src/dns-manager/nm-dns-manager.h13
-rw-r--r--src/dns-manager/nm-dns-plugin.c8
-rw-r--r--src/dns-manager/nm-dns-plugin.h22
-rw-r--r--src/dns-manager/nm-dns-unbound.c4
-rw-r--r--src/nm-ip4-config.c59
-rw-r--r--src/nm-ip4-config.h5
-rw-r--r--src/nm-ip6-config.c58
-rw-r--r--src/nm-ip6-config.h5
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c16
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c14
-rw-r--r--src/vpn-manager/nm-vpn-connection.c3
23 files changed, 647 insertions, 317 deletions
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index 1651aab226..741fac1cdc 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -272,20 +272,21 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_OPTIONS), /* 4 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 5 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 6 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 7 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 8 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 9 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 10 */
- SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID), /* 11 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT), /* 12 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 13 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 14 */
- SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_FQDN), /* 15 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 16 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 17 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DAD_TIMEOUT), /* 18 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_PRIORITY), /* 5 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 6 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 7 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 8 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 9 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 10 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 11 */
+ SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID), /* 12 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT), /* 13 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 14 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 15 */
+ SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_FQDN), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 17 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 18 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DAD_TIMEOUT), /* 19 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP4_CONFIG_ALL "name"","\
@@ -293,6 +294,7 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_DNS_OPTIONS","\
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
@@ -315,18 +317,19 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_OPTIONS), /* 4 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 5 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 6 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 7 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 8 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 9 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 10 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 11 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 12 */
- SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY), /* 13 */
- SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 14 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 15 */
- SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_PRIORITY), /* 5 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES), /* 6 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY), /* 7 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES), /* 8 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTE_METRIC), /* 9 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES), /* 10 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS), /* 11 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT), /* 12 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL), /* 13 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY), /* 14 */
+ SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 15 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 16 */
+ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 17 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP6_CONFIG_ALL "name"","\
@@ -334,6 +337,7 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_DNS_OPTIONS","\
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
@@ -1444,6 +1448,7 @@ DEFINE_GETTER (nmc_property_ipv4_get_method, NM_SETTING_IP_CONFIG_METHOD)
DEFINE_GETTER (nmc_property_ipv4_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv4_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
DEFINE_GETTER_WITH_DEFAULT (nmc_property_ipv4_get_dns_options, NM_SETTING_IP_CONFIG_DNS_OPTIONS, !nm_setting_ip_config_has_dns_options ((NMSettingIPConfig *) setting))
+DEFINE_GETTER (nmc_property_ipv4_get_dns_priority, NM_SETTING_IP_CONFIG_DNS_PRIORITY)
static char *
nmc_property_ip_get_addresses (NMSetting *setting, NmcPropertyGetType get_type)
@@ -1564,6 +1569,7 @@ DEFINE_GETTER (nmc_property_ipv6_get_method, NM_SETTING_IP_CONFIG_METHOD)
DEFINE_GETTER (nmc_property_ipv6_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv6_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
DEFINE_GETTER_WITH_DEFAULT (nmc_property_ipv6_get_dns_options, NM_SETTING_IP_CONFIG_DNS_OPTIONS, !nm_setting_ip_config_has_dns_options ((NMSettingIPConfig *) setting))
+DEFINE_GETTER (nmc_property_ipv6_get_dns_priority, NM_SETTING_IP_CONFIG_DNS_PRIORITY)
static char *
nmc_property_ipv6_get_routes (NMSetting *setting, NmcPropertyGetType get_type)
@@ -6452,6 +6458,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE_IP (4, DNS_PRIORITY),
+ nmc_property_ipv4_get_dns_priority,
+ nmc_property_set_int,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
nmc_add_prop_funcs (GLUE_IP (4, ADDRESSES),
nmc_property_ip_get_addresses,
nmc_property_ipv4_set_addresses,
@@ -6580,6 +6593,13 @@ nmc_properties_init (void)
NULL,
NULL,
NULL);
+ nmc_add_prop_funcs (GLUE_IP (6, DNS_PRIORITY),
+ nmc_property_ipv6_get_dns_priority,
+ nmc_property_set_int,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
nmc_add_prop_funcs (GLUE_IP (6, ADDRESSES),
nmc_property_ip_get_addresses,
nmc_property_ipv6_set_addresses,
@@ -8135,20 +8155,21 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 2, nmc_property_ipv4_get_dns (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_ipv4_get_dns_search (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, nmc_property_ipv4_get_dns_options (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 5, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 6, nmc_property_ipv4_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 7, nmc_property_ipv4_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 8, nmc_property_ipv4_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 9, nmc_property_ipv4_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 10, nmc_property_ipv4_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 11, nmc_property_ipv4_get_dhcp_client_id (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 12, nmc_property_ipv4_get_dhcp_timeout (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 13, nmc_property_ipv4_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 14, nmc_property_ipv4_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 15, nmc_property_ipv4_get_dhcp_fqdn (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 16, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 17, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 18, nmc_property_ipv4_get_dad_timeout (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 5, nmc_property_ipv4_get_dns_priority (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 6, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 7, nmc_property_ipv4_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 8, nmc_property_ipv4_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 9, nmc_property_ipv4_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 10, nmc_property_ipv4_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 11, nmc_property_ipv4_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 12, nmc_property_ipv4_get_dhcp_client_id (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 13, nmc_property_ipv4_get_dhcp_timeout (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 14, nmc_property_ipv4_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 15, nmc_property_ipv4_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 16, nmc_property_ipv4_get_dhcp_fqdn (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 17, nmc_property_ipv4_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 18, nmc_property_ipv4_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 19, nmc_property_ipv4_get_dad_timeout (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
@@ -8178,18 +8199,19 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 2, nmc_property_ipv6_get_dns (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_ipv6_get_dns_search (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, nmc_property_ipv6_get_dns_options (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 5, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 6, nmc_property_ipv6_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 7, nmc_property_ipv6_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 8, nmc_property_ipv6_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 9, nmc_property_ipv6_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 10, nmc_property_ipv6_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 11, nmc_property_ipv6_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 12, nmc_property_ipv6_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 13, nmc_property_ipv6_get_ip6_privacy (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 14, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 15, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
- set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 5, nmc_property_ipv6_get_dns_priority (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 6, nmc_property_ip_get_addresses (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 7, nmc_property_ipv6_get_gateway (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 8, nmc_property_ipv6_get_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 9, nmc_property_ipv6_get_route_metric (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 10, nmc_property_ipv6_get_ignore_auto_routes (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 11, nmc_property_ipv6_get_ignore_auto_dns (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 12, nmc_property_ipv6_get_never_default (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 13, nmc_property_ipv6_get_may_fail (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 14, nmc_property_ipv6_get_ip6_privacy (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 15, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY));
+ set_val_str (arr, 17, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml
index c2a0f06828..bbe7bebeae 100644
--- a/introspection/nm-ip4-config.xml
+++ b/introspection/nm-ip4-config.xml
@@ -77,6 +77,13 @@
<property name="DnsOptions" type="as" access="read"/>
<!--
+ DnsPriority:
+
+ The relative priority of DNS servers.
+ -->
+ <property name="DnsPriority" type="i" access="read"/>
+
+ <!--
WinsServers:
The Windows Internet Name Service servers associated with the connection.
diff --git a/introspection/nm-ip6-config.xml b/introspection/nm-ip6-config.xml
index 606761dd2b..a58bfffa55 100644
--- a/introspection/nm-ip6-config.xml
+++ b/introspection/nm-ip6-config.xml
@@ -77,6 +77,13 @@
<property name="DnsOptions" type="as" access="read"/>
<!--
+ DnsPriority:
+
+ The relative priority of DNS servers.
+ -->
+ <property name="DnsPriority" type="i" access="read"/>
+
+ <!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
-->
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index 1afaabca3b..c7e9b5fe4a 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -1120,6 +1120,7 @@ typedef struct {
GPtrArray *dns; /* array of IP address strings */
GPtrArray *dns_search; /* array of domain name strings */
GPtrArray *dns_options;/* array of DNS options */
+ gint dns_priority;
GPtrArray *addresses; /* array of NMIPAddress */
GPtrArray *routes; /* array of NMIPRoute */
gint64 route_metric;
@@ -1140,6 +1141,7 @@ enum {
PROP_DNS,
PROP_DNS_SEARCH,
PROP_DNS_OPTIONS,
+ PROP_DNS_PRIORITY,
PROP_ADDRESSES,
PROP_GATEWAY,
PROP_ROUTES,
@@ -1684,6 +1686,22 @@ nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_
}
/**
+ * nm_setting_ip_config_get_dns_priority:
+ * @setting: the #NMSettingIPConfig
+ *
+ * Returns: the priority of DNS servers
+ *
+ * Since: 1.4
+ **/
+gint
+nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
+
+ return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_priority;
+}
+
+/**
* nm_setting_ip_config_get_num_addresses:
* @setting: the #NMSettingIPConfig
*
@@ -2362,6 +2380,9 @@ set_property (GObject *object, guint prop_id,
}
}
break;
+ case PROP_DNS_PRIORITY:
+ priv->dns_priority = g_value_get_int (value);
+ break;
case PROP_ADDRESSES:
g_ptr_array_unref (priv->addresses);
priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value),
@@ -2434,6 +2455,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
g_value_take_boxed (value, priv->dns_options ? _nm_utils_ptrarray_to_strv (priv->dns_options) : NULL);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
case PROP_ADDRESSES:
g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses,
(NMUtilsCopyFunc) nm_ip_address_dup,
@@ -2586,6 +2610,34 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
G_PARAM_STATIC_STRINGS));
/**
+ * NMSettingIPConfig:dns-priority:
+ *
+ * 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. 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 configurations with the lowest priority
+ * value will be used.
+ *
+ * Since: 1.4
+ **/
+ g_object_class_install_property
+ (object_class, PROP_DNS_PRIORITY,
+ g_param_spec_int (NM_SETTING_IP_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* NMSettingIPConfig:addresses:
*
* Array of IP addresses.
diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h
index 79c7e63921..b18d6a9439 100644
--- a/libnm-core/nm-setting-ip-config.h
+++ b/libnm-core/nm-setting-ip-config.h
@@ -136,6 +136,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route,
#define NM_SETTING_IP_CONFIG_DNS "dns"
#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search"
#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_SETTING_IP_CONFIG_DNS_PRIORITY "dns-priority"
#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses"
#define NM_SETTING_IP_CONFIG_GATEWAY "gateway"
#define NM_SETTING_IP_CONFIG_ROUTES "routes"
@@ -219,6 +220,9 @@ gboolean nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig
const char *dns_option);
void nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_set);
+NM_AVAILABLE_IN_1_4
+gint nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting);
+
guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting);
NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting,
int idx);
diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c
index 9b479a083d..8f43def019 100644
--- a/libnm-core/nm-setting-ip4-config.c
+++ b/libnm-core/nm-setting-ip4-config.c
@@ -654,6 +654,17 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class)
* ---end---
*/
+ /* ---ifcfg-rh---
+ * property: dns-priority
+ * variable: IPV4_DNS_PRIORITY(+)
+ * description: The priority for DNS servers of this connection. Lower values have higher priority.
+ * If zero, the default value will be used (50 for VPNs, 100 for other connections).
+ * A negative value prevents DNS from other connections with greater values to be used.
+ * default: 0
+ * example: IPV4_DNS_PRIORITY=20
+ * ---end---
+ */
+
/**
* NMSettingIP4Config:dhcp-client-id:
*
diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c
index 1f0b11fc98..f583255382 100644
--- a/libnm-core/nm-setting-ip6-config.c
+++ b/libnm-core/nm-setting-ip6-config.c
@@ -556,6 +556,17 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
* ---end---
*/
+ /* ---ifcfg-rh---
+ * property: dns-priority
+ * variable: IPV6_DNS_PRIORITY(+)
+ * description: The priority for DNS servers of this connection. Lower values have higher priority.
+ * If zero, the default value will be used (50 for VPNs, 100 for other connections).
+ * A negative value prevents DNS from other connections with greater values to be used.
+ * default: 0
+ * example: IPV6_DNS_PRIORITY=20
+ * ---end---
+ */
+
/**
* NMSettingIP6Config:ip6-privacy:
*
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 0c7fd870f0..c80f55893f 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -1968,6 +1968,7 @@ test_connection_diff_a_only (void)
{ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_DAD_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A },
+ { NM_SETTING_IP_CONFIG_DNS_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A },
{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
} },
};
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index e40a8d8e2e..f8e2c4eb2d 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1061,6 +1061,7 @@ global:
libnm_1_4_0 {
global:
+ nm_setting_ip_config_get_dns_priority;
nm_vpn_editor_plugin_load;
nm_vpn_plugin_info_get_auth_dialog;
nm_vpn_plugin_info_get_service;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index ee0075956d..c709989e27 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -536,6 +536,34 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason,
/***********************************************************/
+static void
+init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
+{
+ gs_free char *value = NULL;
+ gint priority;
+
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "ipv4.dns-priority",
+ self);
+ priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0);
+ nm_ip4_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL);
+}
+
+static void
+init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config)
+{
+ gs_free char *value = NULL;
+ gint priority;
+
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "ipv6.dns-priority",
+ self);
+ priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0);
+ nm_ip6_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL);
+}
+
+/***********************************************************/
+
gboolean
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
{
@@ -4416,6 +4444,7 @@ ip4_config_merge_and_apply (NMDevice *self,
}
composite = nm_ip4_config_new (nm_device_get_ip_ifindex (self));
+ init_ip4_config_dns_priority (self, composite);
if (commit)
ensure_con_ip4_config (self);
@@ -5155,9 +5184,11 @@ ip6_config_merge_and_apply (NMDevice *self,
/* If no config was passed in, create a new one */
composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
+ init_ip6_config_dns_priority (self, composite);
if (commit)
ensure_con_ip6_config (self);
+
g_assert (composite);
/* Merge all the IP configs into the composite config */
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c
index 5c72d7bad0..6730f1c075 100644
--- a/src/dns-manager/nm-dns-dnsmasq.c
+++ b/src/dns-manager/nm-dns-dnsmasq.c
@@ -202,17 +202,15 @@ add_global_config (NMDnsDnsmasq *self, GVariantBuilder *dnsmasq_servers, const N
}
static gboolean
-add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6, gboolean split)
+add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
+ const char *iface, gboolean split)
{
const struct in6_addr *addr;
char *buf = NULL;
int nnameservers, i_nameserver, n, i;
gboolean added = FALSE;
- const char *iface;
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
-
- iface = g_object_get_data (G_OBJECT (ip6), IP_CONFIG_IFACE_TAG);
g_assert (iface);
if (split) {
@@ -264,6 +262,24 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
return TRUE;
}
+static gboolean
+add_ip_config_data (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPConfigData *data)
+{
+ if (NM_IS_IP4_CONFIG (data->config)) {
+ return add_ip4_config (self,
+ servers,
+ (NMIP4Config *) data->config,
+ data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
+ } else if (NM_IS_IP6_CONFIG (data->config)) {
+ return add_ip6_config (self,
+ servers,
+ (NMIP6Config *) data->config,
+ data->iface,
+ data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
+ } else
+ g_return_val_if_reached (FALSE);
+}
+
static void
dnsmasq_update_done (GObject *source, GAsyncResult *res, gpointer user_data)
{
@@ -429,15 +445,12 @@ start_dnsmasq (NMDnsDnsmasq *self)
static gboolean
update (NMDnsPlugin *plugin,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
- const GSList *iter;
GVariantBuilder servers;
start_dnsmasq (self);
@@ -447,28 +460,9 @@ update (NMDnsPlugin *plugin,
if (global_config)
add_global_config (self, &servers, global_config);
else {
- /* Use split DNS for VPN configs */
- for (iter = vpn_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, TRUE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, TRUE);
- }
-
- /* Now add interface configs without split DNS */
- for (iter = dev_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, FALSE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, FALSE);
- }
-
- /* And any other random configs */
- for (iter = other_configs; iter; iter = g_slist_next (iter)) {
- if (NM_IS_IP4_CONFIG (iter->data))
- add_ip4_config (self, &servers, iter->data, FALSE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- add_ip6_config (self, &servers, iter->data, FALSE);
+ while (*configs) {
+ add_ip_config_data (self, &servers, *configs);
+ configs++;
}
}
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 9cb8a0f072..67913c376e 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -110,11 +110,10 @@ NM_DEFINE_SINGLETON_INSTANCE (NMDnsManager);
/*********************************************************************************************/
typedef struct _NMDnsManagerPrivate {
- GSList *ip4_vpn_configs;
- NMIP4Config *ip4_device_config;
- GSList *ip6_vpn_configs;
- NMIP6Config *ip6_device_config;
- GSList *configs;
+ GPtrArray *configs;
+ NMDnsIPConfigData *best_conf4, *best_conf6;
+ gboolean need_sort;
+
char *hostname;
guint updates_queue;
@@ -169,6 +168,79 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConf
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG, "netconfig"),
);
+NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_config_type_to_string, NMDnsIPConfigType,
+ NM_UTILS_LOOKUP_DEFAULT_WARN ("<unknown>"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_DEFAULT, "default"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, "best"),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_VPN, "vpn"),
+);
+
+static NMDnsIPConfigData *
+ip_config_data_new (gpointer config, NMDnsIPConfigType type, const char *iface)
+{
+ NMDnsIPConfigData *data;
+
+ data = g_slice_new0 (NMDnsIPConfigData);
+ data->config = g_object_ref (config);
+ data->iface = g_strdup (iface);
+ data->type = type;
+
+ return data;
+}
+
+static void
+ip_config_data_destroy (gpointer ptr)
+{
+ NMDnsIPConfigData *data = ptr;
+
+ if (!data)
+ return;
+
+ g_object_unref (data->config);
+ g_free (data->iface);
+ g_slice_free (NMDnsIPConfigData, data);
+}
+
+static gint
+ip_config_data_compare (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b)
+{
+ gboolean a_v4, b_v4;
+ gint a_prio, b_prio;
+
+ a_v4 = NM_IS_IP4_CONFIG (a->config);
+ b_v4 = NM_IS_IP4_CONFIG (b->config);
+
+ a_prio = a_v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) a->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) a->config);
+
+ b_prio = b_v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) b->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) b->config);
+
+ /* Configurations with lower priority value first */
+ if (a_prio < b_prio)
+ return -1;
+ else if (a_prio > b_prio)
+ return 1;
+
+ /* Sort also according to type */
+ if (a->type > b->type)
+ return -1;
+ else if (a->type < b->type)
+ return 1;
+
+ return 0;
+}
+
+static gint
+ip_config_data_ptr_compare (gconstpointer a, gconstpointer b)
+{
+ const NMDnsIPConfigData *const *ptr_a = a, *const *ptr_b = b;
+
+ return ip_config_data_compare (*ptr_a, *ptr_b);
+}
+
static void
add_string_item (GPtrArray *array, const char *str)
{
@@ -253,12 +325,9 @@ merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src)
}
static void
-merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
+merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface)
{
guint32 num, num_domains, num_searches, i;
- const char *iface;
-
- iface = g_object_get_data (G_OBJECT (src), IP_CONFIG_IFACE_TAG);
num = nm_ip6_config_get_num_nameservers (src);
for (i = 0; i < num; i++) {
@@ -312,6 +381,19 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
}
}
+static void
+merge_one_ip_config_data (NMDnsManager *self,
+ NMResolvConfData *rc,
+ NMDnsIPConfigData *data)
+{
+ if (NM_IS_IP4_CONFIG (data->config))
+ merge_one_ip4_config (rc, (NMIP4Config *) data->config);
+ else if (NM_IS_IP6_CONFIG (data->config))
+ merge_one_ip6_config (rc, (NMIP6Config *) data->config, data->iface);
+ else
+ g_return_if_reached ();
+}
+
static GPid
run_netconfig (NMDnsManager *self, GError **error, gint *stdin_fd)
{
@@ -780,75 +862,29 @@ compute_hash (NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
GChecksum *sum;
- GSList *iter;
gsize len = HASH_LEN;
+ guint i;
sum = g_checksum_new (G_CHECKSUM_SHA1);
g_assert (len == g_checksum_type_get_length (G_CHECKSUM_SHA1));
if (global)
nm_global_dns_config_update_checksum (global, sum);
+ else {
+ for (i = 0; i < priv->configs->len; i++) {
+ NMDnsIPConfigData *data = priv->configs->pdata[i];
- for (iter = priv->ip4_vpn_configs; iter; iter = g_slist_next (iter))
- nm_ip4_config_hash (iter->data, sum, TRUE);
- if (priv->ip4_device_config)
- nm_ip4_config_hash (priv->ip4_device_config, sum, TRUE);
-
- for (iter = priv->ip6_vpn_configs; iter; iter = g_slist_next (iter))
- nm_ip6_config_hash (iter->data, sum, TRUE);
- if (priv->ip6_device_config)
- nm_ip6_config_hash (priv->ip6_device_config, sum, TRUE);
-
- /* add any other configs we know about */
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (NM_IN_SET (iter->data, priv->ip4_device_config,
- priv->ip6_device_config))
- continue;
-
- if (NM_IS_IP4_CONFIG (iter->data))
- nm_ip4_config_hash (NM_IP4_CONFIG (iter->data), sum, TRUE);
- else if (NM_IS_IP6_CONFIG (iter->data))
- nm_ip6_config_hash (NM_IP6_CONFIG (iter->data), sum, TRUE);
+ if (NM_IS_IP4_CONFIG (data->config))
+ nm_ip4_config_hash ((NMIP4Config *) data->config, sum, TRUE);
+ else if (NM_IS_IP6_CONFIG (data->config))
+ nm_ip6_config_hash ((NMIP6Config *) data->config, sum, TRUE);
+ }
}
g_checksum_get_digest (sum, buffer, &len);
g_checksum_free (sum);
}
-static void
-build_plugin_config_lists (NMDnsManager *self,
- GSList **out_vpn_configs,
- GSList **out_dev_configs,
- GSList **out_other_configs)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- GSList *iter;
-
- g_return_if_fail (out_vpn_configs && !*out_vpn_configs);
- g_return_if_fail (out_dev_configs && !*out_dev_configs);
- g_return_if_fail (out_other_configs && !*out_other_configs);
-
- /* Build up config lists for plugins; we use the raw configs here, not the
- * merged information that we write to resolv.conf so that the plugins can
- * still use the domain information in each config to provide split DNS if
- * they want to.
- */
- for (iter = priv->ip4_vpn_configs; iter; iter = g_slist_next (iter))
- *out_vpn_configs = g_slist_append (*out_vpn_configs, iter->data);
- for (iter = priv->ip6_vpn_configs; iter; iter = g_slist_next (iter))
- *out_vpn_configs = g_slist_append (*out_vpn_configs, iter->data);
- if (priv->ip4_device_config)
- *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip4_device_config);
- if (priv->ip6_device_config)
- *out_dev_configs = g_slist_append (*out_dev_configs, priv->ip6_device_config);
-
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (!NM_IN_SET (iter->data, priv->ip4_device_config,
- priv->ip6_device_config))
- *out_other_configs = g_slist_append (*out_other_configs, iter->data);
- }
-}
-
static gboolean
merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
{
@@ -888,7 +924,6 @@ update_dns (NMDnsManager *self,
{
NMDnsManagerPrivate *priv;
NMResolvConfData rc;
- GSList *iter;
const char *nis_domain = NULL;
char **searches = NULL;
char **options = NULL;
@@ -900,6 +935,7 @@ update_dns (NMDnsManager *self,
SpawnResult result = SR_ERROR;
NMConfigData *data;
NMGlobalDnsConfig *global_config;
+ gs_free NMDnsIPConfigData **plugin_confs = NULL;
g_return_val_if_fail (!error || !*error, FALSE);
@@ -918,6 +954,11 @@ update_dns (NMDnsManager *self,
data = nm_config_get_data (priv->config);
global_config = nm_config_data_get_global_dns_config (data);
+ if (priv->need_sort) {
+ g_ptr_array_sort (priv->configs, ip_config_data_ptr_compare);
+ priv->need_sort = FALSE;
+ }
+
/* Update hash with config we're applying */
compute_hash (self, global_config, priv->hash);
@@ -930,32 +971,40 @@ update_dns (NMDnsManager *self,
if (global_config)
merge_global_dns_config (&rc, global_config);
else {
- for (iter = priv->ip4_vpn_configs; iter; iter = g_slist_next (iter))
- merge_one_ip4_config (&rc, iter->data);
- if (priv->ip4_device_config)
- merge_one_ip4_config (&rc, priv->ip4_device_config);
-
- for (iter = priv->ip6_vpn_configs; iter; iter = g_slist_next (iter))
- merge_one_ip6_config (&rc, iter->data);
- if (priv->ip6_device_config)
- merge_one_ip6_config (&rc, priv->ip6_device_config);
-
- for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
- if (NM_IN_SET (iter->data, priv->ip4_device_config,
- priv->ip6_device_config))
- continue;
+ int prio, prev_prio = 0;
+ NMDnsIPConfigData *current;
+ gboolean skip = FALSE, v4;
+
+ plugin_confs = g_new (NMDnsIPConfigData *, priv->configs->len + 1);
+
+ for (i = 0; i < priv->configs->len; i++) {
+ current = priv->configs->pdata[i];
+ v4 = NM_IS_IP4_CONFIG (current->config);
- if (NM_IS_IP4_CONFIG (iter->data)) {
- NMIP4Config *config = NM_IP4_CONFIG (iter->data);
+ prio = v4 ?
+ nm_ip4_config_get_dns_priority ((NMIP4Config *) current->config) :
+ nm_ip6_config_get_dns_priority ((NMIP6Config *) current->config);
+
+ if (prev_prio < 0 && prio != prev_prio) {
+ skip = TRUE;
+ plugin_confs[i] = NULL;
+ }
- merge_one_ip4_config (&rc, config);
- } else if (NM_IS_IP6_CONFIG (iter->data)) {
- NMIP6Config *config = NM_IP6_CONFIG (iter->data);
+ prev_prio = prio;
- merge_one_ip6_config (&rc, config);
- } else
- g_assert_not_reached ();
+ _LOGT ("config: %8d %-7s v%c %-16s %s",
+ prio,
+ _config_type_to_string (current->type),
+ v4 ? '4' : '6',
+ current->iface,
+ skip ? "<SKIP>" : "");
+
+ if (!skip) {
+ merge_one_ip_config_data (self, &rc, current);
+ plugin_confs[i] = current;
+ }
}
+ plugin_confs[i] = NULL;
}
/* If the hostname is a FQDN ("dcbw.example.com"), then add the domain part of it
@@ -1018,7 +1067,6 @@ update_dns (NMDnsManager *self,
if (priv->plugin) {
NMDnsPlugin *plugin = priv->plugin;
const char *plugin_name = nm_dns_plugin_get_name (plugin);
- GSList *vpn_configs = NULL, *dev_configs = NULL, *other_configs = NULL;
if (nm_dns_plugin_is_caching (plugin)) {
if (no_caching) {
@@ -1029,14 +1077,9 @@ update_dns (NMDnsManager *self,
caching = TRUE;
}
- if (!global_config)
- build_plugin_config_lists (self, &vpn_configs, &dev_configs, &other_configs);
-
_LOGD ("update-dns: updating plugin %s", plugin_name);
if (!nm_dns_plugin_update (plugin,
- vpn_configs,
- dev_configs,
- other_configs,
+ (const NMDnsIPConfigData **) plugin_confs,
global_config,
priv->hostname)) {
_LOGW ("update-dns: plugin %s update failed", plugin_name);
@@ -1046,9 +1089,6 @@ update_dns (NMDnsManager *self,
*/
caching = FALSE;
}
- g_slist_free (vpn_configs);
- g_slist_free (dev_configs);
- g_slist_free (other_configs);
skip:
;
@@ -1172,38 +1212,64 @@ plugin_child_quit (NMDnsPlugin *plugin, int exit_status, gpointer user_data)
plugin_child_quit_update_dns (self);
}
-gboolean
-nm_dns_manager_add_ip4_config (NMDnsManager *self,
- const char *iface,
- NMIP4Config *config,
- NMDnsIPConfigType cfg_type)
+static void
+ip_config_dns_priority_changed (gpointer config,
+ GParamSpec *pspec,
+ NMDnsManager *self)
+{
+ NM_DNS_MANAGER_GET_PRIVATE (self)->need_sort = TRUE;
+}
+
+static gboolean
+nm_dns_manager_add_ip_config (NMDnsManager *self,
+ const char *iface,
+ gpointer config,
+ NMDnsIPConfigType cfg_type)
{
NMDnsManagerPrivate *priv;
GError *error = NULL;
+ NMDnsIPConfigData *data;
+ gboolean v4 = NM_IS_IP4_CONFIG (config);
+ guint i;
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE);
+ g_return_val_if_fail (config, FALSE);
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- g_object_set_data_full (G_OBJECT (config), IP_CONFIG_IFACE_TAG, g_strdup (iface), g_free);
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
+ if (data->config == config) {
+ if ( nm_streq (data->iface, iface)
+ && data->type == cfg_type)
+ return FALSE;
+ else {
+ g_ptr_array_remove_index_fast (priv->configs, i);
+ break;
+ }
+ }
+ }
- switch (cfg_type) {
- case NM_DNS_IP_CONFIG_TYPE_VPN:
- if (!g_slist_find (priv->ip4_vpn_configs, config)) {
- priv->ip4_vpn_configs = g_slist_append (priv->ip4_vpn_configs,
- g_object_ref (config));
+ data = ip_config_data_new (config, cfg_type, iface);
+ g_ptr_array_add (priv->configs, data);
+ g_signal_connect (config,
+ v4 ?
+ "notify::" NM_IP4_CONFIG_DNS_PRIORITY :
+ "notify::" NM_IP6_CONFIG_DNS_PRIORITY,
+ (GCallback) ip_config_dns_priority_changed, self);
+ priv->need_sort = TRUE;
+
+ if (cfg_type == NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) {
+ /* Only one best-device per IP version is allowed */
+ if (v4) {
+ if (priv->best_conf4)
+ priv->best_conf4->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT;
+ priv->best_conf4 = data;
+ } else {
+ if (priv->best_conf6)
+ priv->best_conf6->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT;
+ priv->best_conf6 = data;
}
- break;
- case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE:
- priv->ip4_device_config = config;
- /* Fall through */
- case NM_DNS_IP_CONFIG_TYPE_DEFAULT:
- if (!g_slist_find (priv->configs, config))
- priv->configs = g_slist_append (priv->configs, g_object_ref (config));
- break;
- default:
- g_return_val_if_reached (FALSE);
}
if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
@@ -1215,35 +1281,12 @@ nm_dns_manager_add_ip4_config (NMDnsManager *self,
}
gboolean
-nm_dns_manager_remove_ip4_config (NMDnsManager *self, NMIP4Config *config)
+nm_dns_manager_add_ip4_config (NMDnsManager *self,
+ const char *iface,
+ NMIP4Config *config,
+ NMDnsIPConfigType cfg_type)
{
- NMDnsManagerPrivate *priv;
- GError *error = NULL;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
-
- priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- if (g_slist_find (priv->configs, config)) {
- priv->configs = g_slist_remove (priv->configs, config);
- if (config == priv->ip4_device_config)
- priv->ip4_device_config = NULL;
- } else if (g_slist_find (priv->ip4_vpn_configs, config))
- priv->ip4_vpn_configs = g_slist_remove (priv->ip4_vpn_configs, config);
- else
- return FALSE;
-
- g_object_unref (config);
-
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
-
- g_object_set_data (G_OBJECT (config), IP_CONFIG_IFACE_TAG, NULL);
-
- return TRUE;
+ return nm_dns_manager_add_ip_config (self, iface, config, cfg_type);
}
gboolean
@@ -1252,72 +1295,55 @@ nm_dns_manager_add_ip6_config (NMDnsManager *self,
NMIP6Config *config,
NMDnsIPConfigType cfg_type)
{
+ return nm_dns_manager_add_ip_config (self, iface, config, cfg_type);
+}
+
+static gboolean
+nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config)
+{
NMDnsManagerPrivate *priv;
GError *error = NULL;
+ NMDnsIPConfigData *data;
+ guint i;
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE);
+ g_return_val_if_fail (config, FALSE);
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
- g_object_set_data_full (G_OBJECT (config), IP_CONFIG_IFACE_TAG, g_strdup (iface), g_free);
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
- switch (cfg_type) {
- case NM_DNS_IP_CONFIG_TYPE_VPN:
- if (!g_slist_find (priv->ip6_vpn_configs, config)) {
- priv->ip6_vpn_configs = g_slist_append (priv->ip6_vpn_configs,
- g_object_ref (config));
- }
- break;
- case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE:
- priv->ip6_device_config = config;
- /* Fall through */
- case NM_DNS_IP_CONFIG_TYPE_DEFAULT:
- if (!g_slist_find (priv->configs, config))
- priv->configs = g_slist_append (priv->configs, g_object_ref (config));
- break;
- default:
- g_return_val_if_reached (FALSE);
- }
+ if (data->config == config) {
+ if (config == priv->best_conf4)
+ priv->best_conf4 = NULL;
+ else if (config == priv->best_conf6)
+ priv->best_conf6 = NULL;
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
+ g_signal_handlers_disconnect_by_func (config, ip_config_dns_priority_changed, self);
+ g_ptr_array_remove_index (priv->configs, i);
+
+ if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
+ _LOGW ("could not commit DNS changes: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ return TRUE;
+ }
}
+ return FALSE;
+}
- return TRUE;
+gboolean
+nm_dns_manager_remove_ip4_config (NMDnsManager *self, NMIP4Config *config)
+{
+ return nm_dns_manager_remove_ip_config (self, config);
}
gboolean
nm_dns_manager_remove_ip6_config (NMDnsManager *self, NMIP6Config *config)
{
- NMDnsManagerPrivate *priv;
- GError *error = NULL;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (config != NULL, FALSE);
-
- priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- if (g_slist_find (priv->configs, config)) {
- priv->configs = g_slist_remove (priv->configs, config);
- if (config == priv->ip6_device_config)
- priv->ip6_device_config = NULL;
- } else if (g_slist_find (priv->ip6_vpn_configs, config))
- priv->ip6_vpn_configs = g_slist_remove (priv->ip6_vpn_configs, config);
- else
- return FALSE;
-
- g_object_unref (config);
-
- if (!priv->updates_queue && !update_dns (self, FALSE, &error)) {
- _LOGW ("could not commit DNS changes: %s", error->message);
- g_clear_error (&error);
- }
-
- g_object_set_data (G_OBJECT (config), IP_CONFIG_IFACE_TAG, NULL);
-
- return TRUE;
+ return nm_dns_manager_remove_ip_config (self, config);
}
void
@@ -1405,6 +1431,11 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func)
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
g_return_if_fail (priv->updates_queue > 0);
+ if (priv->need_sort) {
+ g_ptr_array_sort (priv->configs, ip_config_data_ptr_compare);
+ priv->need_sort = FALSE;
+ }
+
compute_hash (self, nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)), new);
changed = (memcmp (new, priv->prev_hash, sizeof (new)) != 0) ? TRUE : FALSE;
_LOGD ("(%s): DNS configuration %s", func, changed ? "changed" : "did not change");
@@ -1592,9 +1623,10 @@ nm_dns_manager_init (NMDnsManager *self)
_LOGT ("creating...");
priv->config = g_object_ref (nm_config_get ());
+ priv->configs = g_ptr_array_new_full (8, ip_config_data_destroy);
+
/* Set the initial hash */
- compute_hash (self, nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)),
- NM_DNS_MANAGER_GET_PRIVATE (self)->hash);
+ compute_hash (self, NULL, NM_DNS_MANAGER_GET_PRIVATE (self)->hash);
g_signal_connect (G_OBJECT (priv->config),
NM_CONFIG_SIGNAL_CONFIG_CHANGED,
@@ -1608,7 +1640,9 @@ dispose (GObject *object)
{
NMDnsManager *self = NM_DNS_MANAGER (object);
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+ NMDnsIPConfigData *data;
GError *error = NULL;
+ guint i;
_LOGT ("disposing");
@@ -1630,12 +1664,16 @@ dispose (GObject *object)
g_clear_object (&priv->config);
}
- g_slist_free_full (priv->configs, g_object_unref);
- priv->configs = NULL;
- g_slist_free_full (priv->ip4_vpn_configs, g_object_unref);
- priv->ip4_vpn_configs = NULL;
- g_slist_free_full (priv->ip6_vpn_configs, g_object_unref);
- priv->ip6_vpn_configs = NULL;
+ if (priv->configs) {
+ for (i = 0; i < priv->configs->len; i++) {
+ data = priv->configs->pdata[i];
+ g_signal_handlers_disconnect_by_func (data->config,
+ ip_config_dns_priority_changed,
+ self);
+ }
+ g_ptr_array_free (priv->configs, TRUE);
+ priv->configs = NULL;
+ }
G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
}
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index c170dd7a01..a82fdfc036 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -28,13 +28,24 @@
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
+G_BEGIN_DECLS
+
typedef enum {
NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0,
NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE,
NM_DNS_IP_CONFIG_TYPE_VPN
} NMDnsIPConfigType;
-G_BEGIN_DECLS
+enum {
+ NM_DNS_PRIORITY_DEFAULT_NORMAL = 100,
+ NM_DNS_PRIORITY_DEFAULT_VPN = 50,
+};
+
+typedef struct {
+ gpointer config;
+ NMDnsIPConfigType type;
+ char *iface;
+} NMDnsIPConfigData;
#define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ())
#define NM_DNS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DNS_MANAGER, NMDnsManager))
diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c
index 6ab18faa9c..38eaf060c0 100644
--- a/src/dns-manager/nm-dns-plugin.c
+++ b/src/dns-manager/nm-dns-plugin.c
@@ -74,18 +74,14 @@ static guint signals[LAST_SIGNAL] = { 0 };
gboolean
nm_dns_plugin_update (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE);
return NM_DNS_PLUGIN_GET_CLASS (self)->update (self,
- vpn_configs,
- dev_configs,
- other_configs,
+ configs,
global_config,
hostname);
}
diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h
index 7ecaa424dc..d715582cbe 100644
--- a/src/dns-manager/nm-dns-plugin.h
+++ b/src/dns-manager/nm-dns-plugin.h
@@ -20,6 +20,7 @@
#define __NETWORKMANAGER_DNS_PLUGIN_H__
#include "nm-default.h"
+#include "nm-dns-manager.h"
#include "nm-config-data.h"
@@ -33,8 +34,6 @@
#define NM_DNS_PLUGIN_FAILED "failed"
#define NM_DNS_PLUGIN_CHILD_QUIT "child-quit"
-#define IP_CONFIG_IFACE_TAG "dns-manager-iface"
-
typedef struct {
GObject parent;
} NMDnsPlugin;
@@ -44,18 +43,13 @@ typedef struct {
/* Methods */
- /* Called when DNS information is changed. 'vpn_configs' is a list of
- * NMIP4Config or NMIP6Config objects from VPN connections, while
- * 'dev_configs' is a list of NMPI4Config or NMIP6Config objects from
- * active devices. 'other_configs' represent other IP configuration that
- * may be in-use. 'global_config' is the optional global DNS
- * configuration. Configs of the same IP version are sorted in priority
- * order.
+ /* Called when DNS information is changed. 'configs' is an array
+ * of pointers to NMDnsIPConfigData sorted by priority.
+ * 'global_config' is the optional global DNS
+ * configuration.
*/
gboolean (*update) (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname);
@@ -92,9 +86,7 @@ gboolean nm_dns_plugin_is_caching (NMDnsPlugin *self);
const char *nm_dns_plugin_get_name (NMDnsPlugin *self);
gboolean nm_dns_plugin_update (NMDnsPlugin *self,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname);
diff --git a/src/dns-manager/nm-dns-unbound.c b/src/dns-manager/nm-dns-unbound.c
index 4c1af1039f..66a287fdf5 100644
--- a/src/dns-manager/nm-dns-unbound.c
+++ b/src/dns-manager/nm-dns-unbound.c
@@ -28,9 +28,7 @@ G_DEFINE_TYPE (NMDnsUnbound, nm_dns_unbound, NM_TYPE_DNS_PLUGIN)
static gboolean
update (NMDnsPlugin *plugin,
- const GSList *vpn_configs,
- const GSList *dev_configs,
- const GSList *other_configs,
+ const NMDnsIPConfigData **configs,
const NMGlobalDnsConfig *global_config,
const char *hostname)
{
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 6facff67ff..56c8a4ef3b 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -54,6 +54,7 @@ typedef struct {
int ifindex;
gint64 route_metric;
gboolean metered;
+ gint dns_priority;
} NMIP4ConfigPrivate;
struct _NMIP4Config {
@@ -96,6 +97,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config,
PROP_SEARCHES,
PROP_DNS_OPTIONS,
PROP_WINS_SERVERS,
+ PROP_DNS_PRIORITY,
);
NMIP4Config *
@@ -447,7 +449,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
{
NMIP4ConfigPrivate *priv;
guint naddresses, nroutes, nnameservers, nsearches;
- int i;
+ int i, priority;
if (!setting)
return;
@@ -546,6 +548,10 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
i++;
}
+ priority = nm_setting_ip_config_get_dns_priority (setting);
+ if (priority)
+ nm_ip4_config_set_dns_priority (config, priority);
+
g_object_thaw_notify (G_OBJECT (config));
}
@@ -655,6 +661,11 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
nm_setting_ip_config_add_dns_option (s_ip4, option);
}
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ nm_ip4_config_get_dns_priority (config),
+ NULL);
+
return NM_SETTING (s_ip4);
}
@@ -746,6 +757,10 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
nm_ip4_config_set_metered (dst, nm_ip4_config_get_metered (dst) ||
nm_ip4_config_get_metered (src));
+ /* DNS priority */
+ if (nm_ip4_config_get_dns_priority (src))
+ nm_ip4_config_set_dns_priority (dst, nm_ip4_config_get_dns_priority (src));
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -969,6 +984,10 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
nm_ip4_config_del_wins (dst, idx);
}
+ /* DNS priority */
+ if (nm_ip4_config_get_dns_priority (src) == nm_ip4_config_get_dns_priority (dst))
+ nm_ip4_config_set_dns_priority (dst, 0);
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -1210,6 +1229,12 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
has_relevant_changes = TRUE;
}
+ /* DNS priority */
+ if (src_priv->dns_priority != dst_priv->dns_priority) {
+ nm_ip4_config_set_dns_priority (dst, src_priv->dns_priority);
+ has_relevant_changes = TRUE;
+ }
+
/* mss */
if (src_priv->mss != dst_priv->mss) {
nm_ip4_config_set_mss (dst, src_priv->mss);
@@ -1333,6 +1358,7 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
for (i = 0; i < nm_ip4_config_get_num_dns_options (config); i++)
g_message (" dnsopt: %s", nm_ip4_config_get_dns_option (config, i));
+ g_message (" dnspri: %d", nm_ip4_config_get_dns_priority (config));
g_message (" mss: %"G_GUINT32_FORMAT, nm_ip4_config_get_mss (config));
g_message (" mtu: %"G_GUINT32_FORMAT, nm_ip4_config_get_mtu (config));
@@ -1923,6 +1949,27 @@ nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i)
/******************************************************************/
void
+nm_ip4_config_set_dns_priority (NMIP4Config *config, gint priority)
+{
+ NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+
+ if (priority != priv->dns_priority) {
+ priv->dns_priority = priority;
+ _notify (config, PROP_DNS_PRIORITY);
+ }
+}
+
+gint
+nm_ip4_config_get_dns_priority (const NMIP4Config *config)
+{
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+
+ return priv->dns_priority;
+}
+
+/******************************************************************/
+
+void
nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
@@ -2174,6 +2221,7 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
g_checksum_update (sum, (const guint8 *) s, strlen (s));
}
+ hash_u32 (sum, (guint32) nm_ip4_config_get_dns_priority (config));
}
/**
@@ -2405,6 +2453,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
nm_utils_g_value_set_strv (value, priv->dns_options);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
case PROP_WINS_SERVERS:
g_value_take_variant (value,
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
@@ -2505,7 +2556,11 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
-
+ obj_properties[PROP_DNS_PRIORITY] =
+ g_param_spec_int (NM_IP4_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
obj_properties[PROP_WINS_SERVERS] =
g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVERS, "", "",
G_VARIANT_TYPE ("au"),
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 6eb1aed8be..f302630a0c 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -44,6 +44,7 @@ typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
#define NM_IP4_CONFIG_DOMAINS "domains"
#define NM_IP4_CONFIG_SEARCHES "searches"
#define NM_IP4_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP4_CONFIG_DNS_PRIORITY "dns-priority"
#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
/* deprecated */
@@ -126,6 +127,10 @@ void nm_ip4_config_del_dns_option (NMIP4Config *config, guint i);
guint32 nm_ip4_config_get_num_dns_options (const NMIP4Config *config);
const char * nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i);
+/* DNS priority */
+void nm_ip4_config_set_dns_priority (NMIP4Config *config, gint priority);
+gint nm_ip4_config_get_dns_priority (const NMIP4Config *config);
+
/* MSS */
void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss);
guint32 nm_ip4_config_get_mss (const NMIP4Config *config);
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index fce06706ff..e525c10287 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -46,6 +46,7 @@ typedef struct {
guint32 mss;
int ifindex;
gint64 route_metric;
+ gint dns_priority;
} NMIP6ConfigPrivate;
struct _NMIP6Config {
@@ -83,6 +84,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config,
PROP_DOMAINS,
PROP_SEARCHES,
PROP_DNS_OPTIONS,
+ PROP_DNS_PRIORITY,
);
NMIP6Config *
@@ -433,7 +435,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
NMIP6ConfigPrivate *priv;
guint naddresses, nroutes, nnameservers, nsearches;
const char *gateway_str;
- int i;
+ int i, priority;
if (!setting)
return;
@@ -527,6 +529,10 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
i++;
}
+ priority = nm_setting_ip_config_get_dns_priority (setting);
+ if (priority)
+ nm_ip6_config_set_dns_priority (config, priority);
+
g_object_thaw_notify (G_OBJECT (config));
}
@@ -643,6 +649,10 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
nm_setting_ip_config_add_dns_option (s_ip6, option);
}
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ nm_ip6_config_get_dns_priority (config),
+ NULL);
return NM_SETTING (s_ip6);
}
@@ -710,6 +720,10 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
if (nm_ip6_config_get_mss (src))
nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src));
+ /* DNS priority */
+ if (nm_ip6_config_get_dns_priority (src))
+ nm_ip6_config_set_dns_priority (dst, nm_ip6_config_get_dns_priority (src));
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -903,6 +917,10 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
if (nm_ip6_config_get_mss (src) == nm_ip6_config_get_mss (dst))
nm_ip6_config_set_mss (dst, 0);
+ /* DNS priority */
+ if (nm_ip6_config_get_dns_priority (src) == nm_ip6_config_get_dns_priority (dst))
+ nm_ip6_config_set_dns_priority (dst, 0);
+
g_object_thaw_notify (G_OBJECT (dst));
}
@@ -1150,6 +1168,12 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
has_minor_changes = TRUE;
}
+ /* DNS priority */
+ if (src_priv->dns_priority != dst_priv->dns_priority) {
+ nm_ip6_config_set_dns_priority (dst, src_priv->dns_priority);
+ has_relevant_changes = TRUE;
+ }
+
#if NM_MORE_ASSERTS
/* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes
* regardless of config_equal. But config_equal must correspond to has_relevant_changes. */
@@ -1210,6 +1234,8 @@ nm_ip6_config_dump (const NMIP6Config *config, const char *detail)
for (i = 0; i < nm_ip6_config_get_num_dns_options (config); i++)
g_message (" dnsopt: %s", nm_ip6_config_get_dns_option (config, i));
+ g_message (" dnspri: %d", nm_ip6_config_get_dns_priority (config));
+
g_message (" mss: %"G_GUINT32_FORMAT, nm_ip6_config_get_mss (config));
g_message (" n-dflt: %d", nm_ip6_config_get_never_default (config));
}
@@ -1782,6 +1808,27 @@ nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i)
/******************************************************************/
void
+nm_ip6_config_set_dns_priority (NMIP6Config *config, gint priority)
+{
+ NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+
+ if (priority != priv->dns_priority) {
+ priv->dns_priority = priority;
+ _notify (config, PROP_DNS_PRIORITY);
+ }
+}
+
+gint
+nm_ip6_config_get_dns_priority (const NMIP6Config *config)
+{
+ const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+
+ return priv->dns_priority;
+}
+
+/******************************************************************/
+
+void
nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
@@ -1861,6 +1908,7 @@ nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only
g_checksum_update (sum, (const guint8 *) s, strlen (s));
}
+ hash_u32 (sum, (guint32) nm_ip6_config_get_dns_priority (config));
}
/**
@@ -2097,6 +2145,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_OPTIONS:
nm_utils_g_value_set_strv (value, priv->dns_options);
break;
+ case PROP_DNS_PRIORITY:
+ g_value_set_int (value, priv->dns_priority);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2192,6 +2243,11 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
G_TYPE_STRV,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_DNS_PRIORITY] =
+ g_param_spec_int (NM_IP6_CONFIG_DNS_PRIORITY, "", "",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h
index 85b75db0e1..0aba5e9ff2 100644
--- a/src/nm-ip6-config.h
+++ b/src/nm-ip6-config.h
@@ -46,6 +46,7 @@ typedef struct _NMIP6ConfigClass NMIP6ConfigClass;
#define NM_IP6_CONFIG_DOMAINS "domains"
#define NM_IP6_CONFIG_SEARCHES "searches"
#define NM_IP6_CONFIG_DNS_OPTIONS "dns-options"
+#define NM_IP6_CONFIG_DNS_PRIORITY "dns-priority"
/* deprecated */
#define NM_IP6_CONFIG_ADDRESSES "addresses"
@@ -128,6 +129,10 @@ void nm_ip6_config_del_dns_option (NMIP6Config *config, guint i);
guint32 nm_ip6_config_get_num_dns_options (const NMIP6Config *config);
const char * nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i);
+/* DNS priority */
+void nm_ip6_config_set_dns_priority (NMIP6Config *config, gint priority);
+gint nm_ip6_config_get_dns_priority (const NMIP6Config *config);
+
/* MSS */
void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss);
guint32 nm_ip6_config_get_mss (const NMIP6Config *config);
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index fe762db1d1..0596edc1ad 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -919,6 +919,7 @@ make_ip4_setting (shvarFile *ifcfg,
shvarFile *route_ifcfg;
gboolean never_default = FALSE;
gint64 timeout;
+ gint priority;
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
@@ -1141,6 +1142,13 @@ make_ip4_setting (shvarFile *ifcfg,
g_free (dns_options);
dns_options = NULL;
+ /* DNS priority */
+ priority = svGetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
+ g_object_set (s_ip4,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ priority,
+ NULL);
+
/* Static routes - route-<name> file */
route_path = utils_get_route_path (ifcfg->fileName);
@@ -1323,6 +1331,7 @@ make_ip6_setting (shvarFile *ifcfg,
char *ipv6addr, *ipv6addr_secondaries;
char **list = NULL, **iter;
guint32 i;
+ gint priority;
shvarFile *network_ifcfg;
gboolean never_default = FALSE;
gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip;
@@ -1572,6 +1581,13 @@ make_ip6_setting (shvarFile *ifcfg,
g_free (value);
g_free (dns_options);
+ /* DNS priority */
+ priority = svGetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", 10, G_MININT32, G_MAXINT32, 0);
+ g_object_set (s_ip6,
+ NM_SETTING_IP_CONFIG_DNS_PRIORITY,
+ priority,
+ NULL);
+
return NM_SETTING (s_ip6);
error:
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index c17824d6fc..96ed1f1a60 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -1970,6 +1970,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
gint32 j;
guint32 i, n, num;
gint64 route_metric;
+ gint priority;
int timeout;
GString *searches;
gboolean success = FALSE;
@@ -2281,6 +2282,12 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
svSetValueInt64 (ifcfg, "ARPING_WAIT", (timeout - 1) / 1000 + 1);
}
+ priority = nm_setting_ip_config_get_dns_priority (s_ip4);
+ if (priority)
+ svSetValueInt64 (ifcfg, "IPV4_DNS_PRIORITY", priority);
+ else
+ svSetValue (ifcfg, "IPV4_DNS_PRIORITY", NULL, FALSE);
+
success = TRUE;
out:
@@ -2440,6 +2447,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
char *addr_key;
char *tmp;
guint32 i, num, num4;
+ gint priority;
GString *searches;
NMIPAddress *addr;
const char *dns;
@@ -2606,6 +2614,12 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
g_free (tmp);
}
+ priority = nm_setting_ip_config_get_dns_priority (s_ip6);
+ if (priority)
+ svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority);
+ else
+ svSetValue (ifcfg, "IPV6_DNS_PRIORITY", NULL, FALSE);
+
/* Static routes go to route6-<dev> file */
route6_path = utils_get_route6_path (ifcfg->fileName);
if (!route6_path) {
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 084bf5d595..c235748741 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -44,6 +44,7 @@
#include "nm-config.h"
#include "nm-vpn-plugin-info.h"
#include "nm-vpn-manager.h"
+#include "nm-dns-manager.h"
#include "nmdbus-vpn-connection.h"
@@ -1364,6 +1365,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
ifindex = nm_device_get_ip_ifindex (parent_dev);
}
config = nm_ip4_config_new (ifindex);
+ nm_ip4_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
memset (&address, 0, sizeof (address));
address.plen = 24;
@@ -1497,6 +1499,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
}
config = nm_ip6_config_new (priv->ip_ifindex);
+ nm_ip6_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN);
memset (&address, 0, sizeof (address));
address.plen = 128;