diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2018-07-03 14:35:32 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2018-07-03 16:12:28 +0200 |
commit | 31981d7f2d6002b529c82d407b8d0914bbefb1cc (patch) | |
tree | 4471d5b5ae57baa813f5a2cefcbe691b1df92b20 | |
parent | 2ee76c88c10c109d7607501033097a0a762f9687 (diff) | |
download | NetworkManager-lr/always-systemd-resolve.tar.gz |
dns: default to always loading nm-dns-systemd-resolvelr/always-systemd-resolve
If the primary plugin is different, create an instance of the
systemd-resolve plugin alongside it to keep systemd-resolve up to date.
If for whatever reasons don't want NetworkManager to push the DNS data
it discovers to systemd-resolved, the functionality can be disabled
with:
[main]
dns-=systemd-resolve
-rw-r--r-- | src/dns/nm-dns-manager.c | 52 | ||||
-rw-r--r-- | src/nm-config-data.c | 32 | ||||
-rw-r--r-- | src/nm-config-data.h | 2 | ||||
-rw-r--r-- | src/nm-config.c | 5 | ||||
-rw-r--r-- | src/nm-config.h | 2 |
5 files changed, 77 insertions, 16 deletions
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index a29fd81f4e..febf82ab45 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -122,6 +122,7 @@ typedef struct { NMDnsManagerResolvConfManager rc_manager; char *mode; + NMDnsPlugin *sd_resolve_plugin; NMDnsPlugin *plugin; NMConfig *config; @@ -1390,6 +1391,16 @@ update_dns (NMDnsManager *self, &searches, &options, &nameservers, &nis_servers, &nis_domain); + if (priv->plugin || priv->sd_resolve_plugin) + rebuild_domain_lists (self); + + if (priv->sd_resolve_plugin) { + nm_dns_plugin_update (priv->sd_resolve_plugin, + global_config, + _ip_config_lst_head (self), + priv->hostname); + } + /* Let any plugins do their thing first */ if (priv->plugin) { NMDnsPlugin *plugin = priv->plugin; @@ -1405,7 +1416,6 @@ update_dns (NMDnsManager *self, } _LOGD ("update-dns: updating plugin %s", plugin_name); - rebuild_domain_lists (self); if (!nm_dns_plugin_update (plugin, global_config, _ip_config_lst_head (self), @@ -1417,15 +1427,17 @@ update_dns (NMDnsManager *self, */ caching = FALSE; } - /* Clear the generated search list as it points to - * strings owned by IP configurations and we can't - * guarantee they stay alive. */ - clear_domain_lists (self); skip: ; } + /* Clear the generated search list as it points to + * strings owned by IP configurations and we can't + * guarantee they stay alive. */ + clear_domain_lists (self); + clear_domain_lists (self); + /* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf * to ensure that the glibc resolver doesn't try to round-robin nameservers, * but only uses the local caching nameserver. @@ -1921,10 +1933,15 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); NMDnsManagerResolvConfManager rc_manager; - const char *mode; + gs_strfreev char **dns_mode; + const char *mode = NULL; + gboolean want_sd_resolve = FALSE; gboolean param_changed = FALSE, plugin_changed = FALSE; - mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); + dns_mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); + mode = dns_mode[0]; + if (mode) + want_sd_resolve = nm_streq0 (dns_mode[1], "systemd-resolved"); if (nm_streq0 (mode, "none")) rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; @@ -1970,6 +1987,7 @@ again: plugin_changed = TRUE; } mode = "systemd-resolved"; + want_sd_resolve = FALSE; } else if (nm_streq0 (mode, "dnsmasq")) { if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) { _clear_plugin (self); @@ -1992,6 +2010,20 @@ again: plugin_changed = TRUE; } + /* The systemd-resolved plugin is special. We typically always want to keep + * systemd-resolved up to date even if the configured plugin is different. */ + if (want_sd_resolve) { + if (!priv->sd_resolve_plugin) { + priv->sd_resolve_plugin = nm_dns_systemd_resolved_new (); + plugin_changed = TRUE; + } + } else { + if (priv->sd_resolve_plugin) { + g_clear_object (&priv->sd_resolve_plugin); + plugin_changed = TRUE; + } + } + if (plugin_changed && priv->plugin) { g_signal_connect (priv->plugin, NM_DNS_PLUGIN_FAILED, G_CALLBACK (plugin_failed), self); g_signal_connect (priv->plugin, NM_DNS_PLUGIN_CHILD_QUIT, G_CALLBACK (plugin_child_quit), self); @@ -2013,8 +2045,9 @@ again: } if (param_changed || plugin_changed) { - _LOGI ("init: dns=%s, rc-manager=%s%s%s%s", - mode, _rc_manager_to_string (rc_manager), + _LOGI ("init: dns=%s%s rc-manager=%s%s%s%s", + mode, (want_sd_resolve ? ",systemd-resolved" : ""), + _rc_manager_to_string (rc_manager), NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=", nm_dns_plugin_get_name (priv->plugin), "", "")); } @@ -2275,6 +2308,7 @@ dispose (GObject *object) if (priv->config) g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); + g_clear_object (&priv->sd_resolve_plugin); _clear_plugin (self); priv->best_ip_config_4 = NULL; diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 813ef9c8a6..c09ba595ec 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -106,7 +106,6 @@ typedef struct { GSList *ignore_carrier; GSList *assume_ipv6ll_only; - char *dns_mode; char *rc_manager; NMGlobalDnsConfig *global_dns; @@ -306,12 +305,25 @@ nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevic || nm_device_spec_match_list (device, priv->no_auto_default.specs_config); } -const char * +char ** nm_config_data_get_dns_mode (const NMConfigData *self) { + const NMConfigDataPrivate *priv; + char **list; + g_return_val_if_fail (self, NULL); - return NM_CONFIG_DATA_GET_PRIVATE (self)->dns_mode; + priv = NM_CONFIG_DATA_GET_PRIVATE (self); + + list = g_key_file_get_string_list (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NULL, NULL); + if (!list) { + gs_unref_keyfile GKeyFile *kf = nm_config_create_keyfile (); + + /* let keyfile split the default string according to its own escaping rules. */ + g_key_file_set_value (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NM_CONFIG_DEFAULT_MAIN_DNS); + list = g_key_file_get_string_list (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NULL, NULL); + } + return _nm_utils_strv_cleanup (list, TRUE, TRUE, TRUE); } const char * @@ -597,6 +609,7 @@ static const struct { const char *value; } default_values[] = { { NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS }, + { NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NM_CONFIG_DEFAULT_MAIN_DNS }, { NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NM_CONFIG_DEFAULT_MAIN_RC_MANAGER }, { NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT }, { NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_DEFAULT_MAIN_DHCP }, @@ -1461,6 +1474,15 @@ _slist_str_equals (GSList *a, GSList *b) return !a && !b; } +static gboolean +_dns_mode_equals (NMConfigData *old_data, NMConfigData *new_data) +{ + gs_strfreev char **old_dns_mode = nm_config_data_get_dns_mode (old_data); + gs_strfreev char **new_dns_mode = nm_config_data_get_dns_mode (new_data); + + return _nm_utils_strv_equal (old_dns_mode, new_dns_mode); +} + NMConfigChangeFlags nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) { @@ -1493,7 +1515,7 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) || !_slist_str_equals (priv_old->no_auto_default.specs_config, priv_new->no_auto_default.specs_config)) changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT; - if (g_strcmp0 (nm_config_data_get_dns_mode (old_data), nm_config_data_get_dns_mode (new_data))) + if (!_dns_mode_equals (old_data, new_data)) changes |= NM_CONFIG_CHANGE_DNS_MODE; if (g_strcmp0 (nm_config_data_get_rc_manager (old_data), nm_config_data_get_rc_manager (new_data))) @@ -1638,7 +1660,6 @@ constructed (GObject *object) priv->connectivity.interval = _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXUINT, NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL); g_free (str); - priv->dns_mode = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NULL)); priv->rc_manager = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NULL)); priv->ignore_carrier = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier", NULL); @@ -1713,7 +1734,6 @@ finalize (GObject *gobject) g_slist_free_full (priv->no_auto_default.specs_config, g_free); g_strfreev (priv->no_auto_default.arr); - g_free (priv->dns_mode); g_free (priv->rc_manager); g_slist_free_full (priv->ignore_carrier, g_free); diff --git a/src/nm-config-data.h b/src/nm-config-data.h index 650fbe1480..3917670383 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -168,7 +168,7 @@ int nm_config_data_get_autoconnect_retries_default (const NMConfigData *config_d const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data); gboolean nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevice *device); -const char *nm_config_data_get_dns_mode (const NMConfigData *self); +char **nm_config_data_get_dns_mode (const NMConfigData *self); const char *nm_config_data_get_rc_manager (const NMConfigData *self); gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device); diff --git a/src/nm-config.c b/src/nm-config.c index d4682ed6da..0e8076eff7 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -670,6 +670,7 @@ static gboolean _setting_is_string_list (const char *group, const char *key) { return _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins") + || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "dns") || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG) || _IS (NM_CONFIG_KEYFILE_GROUP_LOGGING, "domains") || g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST); @@ -788,6 +789,10 @@ read_config (GKeyFile *keyfile, gboolean is_base_config, const char *dirname, co g_key_file_set_value (keyfile, group, base_key, NM_CONFIG_DEFAULT_MAIN_PLUGINS); old_val = g_key_file_get_string_list (keyfile, group, base_key, NULL, NULL); } + if (nm_streq (group, NM_CONFIG_KEYFILE_GROUP_MAIN) && nm_streq (base_key, "dns")) { + g_key_file_set_value (keyfile, group, base_key, NM_CONFIG_DEFAULT_MAIN_DNS); + old_val = g_key_file_get_string_list (keyfile, group, base_key, NULL, NULL); + } } } else { gs_free char *old_sval = nm_config_keyfile_get_value (keyfile, group, base_key, NM_CONFIG_GET_VALUE_TYPE_SPEC); diff --git a/src/nm-config.h b/src/nm-config.h index 5d027ce06e..45939cd150 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -38,6 +38,8 @@ /* Signals */ #define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed" +#define NM_CONFIG_DEFAULT_MAIN_DNS "default,systemd-resolved" + #define NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL 300 #define NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */ |