diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-12 17:16:12 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-12 17:16:12 +0200 |
commit | 8da3e658f7313f56928d22cfe13f9ab78cc1dd3c (patch) | |
tree | 3f51ef02d64b7b04ff6e80f4d7e6a0ae6d904773 | |
parent | 860606012145b42590e389655e4e4e3fec86e1d1 (diff) | |
parent | 570d73979beb40cde22546a31ac175d04f53026d (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.c | 126 | ||||
-rw-r--r-- | introspection/nm-ip4-config.xml | 7 | ||||
-rw-r--r-- | introspection/nm-ip6-config.xml | 7 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-config.c | 52 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-config.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip4-config.c | 11 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip6-config.c | 11 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 1 | ||||
-rw-r--r-- | libnm/libnm.ver | 1 | ||||
-rw-r--r-- | src/devices/nm-device.c | 31 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-dnsmasq.c | 54 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-manager.c | 452 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-manager.h | 13 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-plugin.c | 8 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-plugin.h | 22 | ||||
-rw-r--r-- | src/dns-manager/nm-dns-unbound.c | 4 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 59 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 5 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 58 | ||||
-rw-r--r-- | src/nm-ip6-config.h | 5 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 16 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 14 | ||||
-rw-r--r-- | src/vpn-manager/nm-vpn-connection.c | 3 |
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; |