summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2018-07-03 14:35:32 +0200
committerLubomir Rintel <lkundrak@v3.sk>2018-07-03 16:12:28 +0200
commit31981d7f2d6002b529c82d407b8d0914bbefb1cc (patch)
tree4471d5b5ae57baa813f5a2cefcbe691b1df92b20
parent2ee76c88c10c109d7607501033097a0a762f9687 (diff)
downloadNetworkManager-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.c52
-rw-r--r--src/nm-config-data.c32
-rw-r--r--src/nm-config-data.h2
-rw-r--r--src/nm-config.c5
-rw-r--r--src/nm-config.h2
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 */