From 16d5c8222b1dcb2d4fbf30808d40bf4192a8aac4 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Tue, 10 May 2016 08:54:25 +0200 Subject: [PATCH 01/10] dns: don't use the global configuration to compute initial hash If the initial hash includes the global configuration, every update attempt will be skipped because the configuration never changes, and resolv.conf will never be updated. Instead, use a NULL global configuration to compute the hash and force an initial update. --- src/dns-manager/nm-dns-manager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 9cb8a0f072..7b23244aee 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -1593,8 +1593,7 @@ nm_dns_manager_init (NMDnsManager *self) priv->config = g_object_ref (nm_config_get ()); /* 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, From 8e6d442477c4c67672da62f1a7100c9951e85a86 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 6 May 2016 10:34:40 +0200 Subject: [PATCH 02/10] dns: use a single array for all configurations In a following commit configurations will be ordered by their priority; arrange them in a single array to make this simpler. Also, instead of using g_object_set_data() to store metadata, introduce a NMDnsIPConfigData structure. --- src/dns-manager/nm-dns-manager.c | 382 ++++++++++++++++--------------- src/dns-manager/nm-dns-manager.h | 4 +- 2 files changed, 205 insertions(+), 181 deletions(-) diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 7b23244aee..9892ec3959 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -109,12 +109,17 @@ NM_DEFINE_SINGLETON_INSTANCE (NMDnsManager); /*********************************************************************************************/ +typedef struct { + gpointer config; + NMDnsIPConfigType type; + char *iface; +} NMDnsIPConfigData; + 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 +174,62 @@ 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 (""), + 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; + + /* Plugins still receive plain config, attach iface through object data */ + g_object_set_data_full (G_OBJECT (config), + IP_CONFIG_IFACE_TAG, + g_strdup (iface), + g_free); + + return data; +} + +static void +ip_config_data_destroy (gpointer ptr) +{ + NMDnsIPConfigData *data = ptr; + + g_object_set_data (G_OBJECT (data->config), IP_CONFIG_IFACE_TAG, NULL); + 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) +{ + 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 +314,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 +370,24 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src) } } +static void +merge_one_ip_config_data (NMDnsManager *self, + NMResolvConfData *rc, + NMDnsIPConfigData *data) +{ + _LOGT ("merge config: [ %-7s v%c %s ]", + _config_type_to_string (data->type), + NM_IS_IP4_CONFIG (data->config) ? '4' : '6', + data->iface); + + 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,35 +856,23 @@ 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); @@ -822,7 +886,7 @@ build_plugin_config_lists (NMDnsManager *self, GSList **out_other_configs) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); - GSList *iter; + guint i; g_return_if_fail (out_vpn_configs && !*out_vpn_configs); g_return_if_fail (out_dev_configs && !*out_dev_configs); @@ -833,19 +897,22 @@ build_plugin_config_lists (NMDnsManager *self, * 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 (i = 0; i < priv->configs->len; i++) { + NMDnsIPConfigData *data = priv->configs->pdata[i]; - 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); + switch (data->type) { + case NM_DNS_IP_CONFIG_TYPE_VPN: + *out_vpn_configs = g_slist_append (*out_vpn_configs, data->config); + break; + case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE: + *out_dev_configs = g_slist_append (*out_dev_configs, data->config); + break; + case NM_DNS_IP_CONFIG_TYPE_DEFAULT: + *out_other_configs = g_slist_append (*out_other_configs, data->config); + break; + default: + g_return_if_reached (); + } } } @@ -888,7 +955,6 @@ update_dns (NMDnsManager *self, { NMDnsManagerPrivate *priv; NMResolvConfData rc; - GSList *iter; const char *nis_domain = NULL; char **searches = NULL; char **options = NULL; @@ -918,6 +984,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 +1001,8 @@ 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; - - if (NM_IS_IP4_CONFIG (iter->data)) { - NMIP4Config *config = NM_IP4_CONFIG (iter->data); - - merge_one_ip4_config (&rc, config); - } else if (NM_IS_IP6_CONFIG (iter->data)) { - NMIP6Config *config = NM_IP6_CONFIG (iter->data); - - merge_one_ip6_config (&rc, config); - } else - g_assert_not_reached (); - } + for (i = 0; i < priv->configs->len; i++) + merge_one_ip_config_data (self, &rc, priv->configs->pdata[i]); } /* If the hostname is a FQDN ("dcbw.example.com"), then add the domain part of it @@ -1172,38 +1219,51 @@ 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 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); - - 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)); + 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; + } + } + } + + data = ip_config_data_new (config, cfg_type, iface); + g_ptr_array_add (priv->configs, data); + 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 +1275,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 @@ -1251,73 +1288,55 @@ nm_dns_manager_add_ip6_config (NMDnsManager *self, const char *iface, 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)); + if (data->config == config) { + if (config == priv->best_conf4) + priv->best_conf4 = NULL; + else if (config == priv->best_conf6) + priv->best_conf6 = NULL; + + 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; } - 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); } + return FALSE; +} - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { - _LOGW ("could not commit DNS changes: %s", error->message); - g_clear_error (&error); - } - - 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 +1424,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,6 +1616,8 @@ 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, NULL, NM_DNS_MANAGER_GET_PRIVATE (self)->hash); @@ -1629,12 +1655,10 @@ 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) { + 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..ed92345ba2 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -28,14 +28,14 @@ #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 - #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)) #define NM_DNS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_DNS_MANAGER, NMDnsManagerClass)) From e53aa0dcffc5b722669652f10671a2bc5fbe4fa0 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 7 May 2016 10:22:04 +0200 Subject: [PATCH 03/10] dns: pass config data array to plugins Export NMDnsIPConfigData to DNS plugins and use it to pass additional information about configurations. --- src/dns-manager/nm-dns-dnsmasq.c | 54 ++++++++++++------------- src/dns-manager/nm-dns-manager.c | 67 ++++---------------------------- src/dns-manager/nm-dns-manager.h | 6 +++ src/dns-manager/nm-dns-plugin.c | 8 +--- src/dns-manager/nm-dns-plugin.h | 22 ++++------- src/dns-manager/nm-dns-unbound.c | 4 +- 6 files changed, 47 insertions(+), 114 deletions(-) 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 9892ec3959..0d636c0f14 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -109,12 +109,6 @@ NM_DEFINE_SINGLETON_INSTANCE (NMDnsManager); /*********************************************************************************************/ -typedef struct { - gpointer config; - NMDnsIPConfigType type; - char *iface; -} NMDnsIPConfigData; - typedef struct _NMDnsManagerPrivate { GPtrArray *configs; NMDnsIPConfigData *best_conf4, *best_conf6; @@ -191,12 +185,6 @@ ip_config_data_new (gpointer config, NMDnsIPConfigType type, const char *iface) data->iface = g_strdup (iface); data->type = type; - /* Plugins still receive plain config, attach iface through object data */ - g_object_set_data_full (G_OBJECT (config), - IP_CONFIG_IFACE_TAG, - g_strdup (iface), - g_free); - return data; } @@ -205,7 +193,9 @@ ip_config_data_destroy (gpointer ptr) { NMDnsIPConfigData *data = ptr; - g_object_set_data (G_OBJECT (data->config), IP_CONFIG_IFACE_TAG, NULL); + if (!data) + return; + g_object_unref (data->config); g_free (data->iface); g_slice_free (NMDnsIPConfigData, data); @@ -879,43 +869,6 @@ compute_hash (NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer 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); - guint i; - - 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 (i = 0; i < priv->configs->len; i++) { - NMDnsIPConfigData *data = priv->configs->pdata[i]; - - switch (data->type) { - case NM_DNS_IP_CONFIG_TYPE_VPN: - *out_vpn_configs = g_slist_append (*out_vpn_configs, data->config); - break; - case NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE: - *out_dev_configs = g_slist_append (*out_dev_configs, data->config); - break; - case NM_DNS_IP_CONFIG_TYPE_DEFAULT: - *out_other_configs = g_slist_append (*out_other_configs, data->config); - break; - default: - g_return_if_reached (); - } - } -} - static gboolean merge_global_dns_config (NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) { @@ -1065,7 +1018,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) { @@ -1076,14 +1028,11 @@ 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); + g_ptr_array_add (priv->configs, NULL); + if (!nm_dns_plugin_update (plugin, - vpn_configs, - dev_configs, - other_configs, + (const NMDnsIPConfigData **) priv->configs->pdata, global_config, priv->hostname)) { _LOGW ("update-dns: plugin %s update failed", plugin_name); @@ -1093,9 +1042,7 @@ update_dns (NMDnsManager *self, */ caching = FALSE; } - g_slist_free (vpn_configs); - g_slist_free (dev_configs); - g_slist_free (other_configs); + g_ptr_array_remove_index (priv->configs, priv->configs->len - 1); skip: ; diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h index ed92345ba2..72dc4e3cb4 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -36,6 +36,12 @@ typedef enum { NM_DNS_IP_CONFIG_TYPE_VPN } NMDnsIPConfigType; +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)) #define NM_DNS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_DNS_MANAGER, NMDnsManagerClass)) 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) { From bdd0e7fec0a2af12331b815bfaf3de182ed6eebb Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 23 Apr 2016 15:57:04 +0200 Subject: [PATCH 04/10] libnm-core: add dns-priority to NMSettingIPConfig --- libnm-core/nm-setting-ip-config.c | 52 +++++++++++++++++++++++++++++++ libnm-core/nm-setting-ip-config.h | 4 +++ libnm-core/tests/test-general.c | 1 + libnm/libnm.ver | 1 + 4 files changed, 58 insertions(+) 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, @@ -1683,6 +1685,22 @@ nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_ g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); } +/** + * 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, @@ -2585,6 +2609,34 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) G_PARAM_READWRITE | 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: * 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/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; From c5f17531b9e72f94d840d6a517dd20d8a6fd8e59 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 23 Apr 2016 15:57:07 +0200 Subject: [PATCH 05/10] ifcfg-rh: add support for DNS priority --- libnm-core/nm-setting-ip4-config.c | 11 +++++++++++ libnm-core/nm-setting-ip6-config.c | 11 +++++++++++ src/settings/plugins/ifcfg-rh/reader.c | 16 ++++++++++++++++ src/settings/plugins/ifcfg-rh/writer.c | 14 ++++++++++++++ 4 files changed, 52 insertions(+) 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/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- 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- file */ route6_path = utils_get_route6_path (ifcfg->fileName); if (!route6_path) { From d5855ed8075c89b961516bc23bfe1ecafab49771 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 23 Apr 2016 15:57:11 +0200 Subject: [PATCH 06/10] cli: add support for DNS priority --- clients/cli/settings.c | 126 ++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 52 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 */ From f09f5e1ec84b1e8b0e6231f72655f6446ae4646a Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 23 Apr 2016 15:57:14 +0200 Subject: [PATCH 07/10] core: add DNS priority to NMIP4Config --- introspection/nm-ip4-config.xml | 7 ++++ src/nm-ip4-config.c | 59 +++++++++++++++++++++++++++++++-- src/nm-ip4-config.h | 5 +++ 3 files changed, 69 insertions(+), 2 deletions(-) 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 @@ -76,6 +76,13 @@ --> + + + + + +