diff --git a/NEWS b/NEWS
index ca30fd033..a9a0ea12f 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,14 @@ The API is subject to change and not guaranteed to be compatible
with the later release.
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
+* Introduce new "rc-manager=auto" setting and make it the default,
+ unless a different default is chosen at compile time.
+ This mode tries to detect "systemd-resolved", "resolvconf", and "netconfig"
+ and chooses the mode that seems most suitable depending on build
+ setting and runtime detection.
+ "resolvconf" and "netconfig" are only considered iff NetworkManager
+ was built with the respective options enabled.
+
=============================================
NetworkManager-1.26
Overview of changes since NetworkManager-1.24
diff --git a/configure.ac b/configure.ac
index d6842670a..8f8b9338f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -891,14 +891,15 @@ AC_SUBST(NM_CONFIG_DEFAULT_MAIN_DHCP, $config_dhcp_default)
AC_ARG_WITH(resolvconf, AS_HELP_STRING([--with-resolvconf=yes|no|path], [Enable resolvconf support]))
AC_ARG_WITH(netconfig, AS_HELP_STRING([--with-netconfig=yes|no], [Enable SUSE netconfig support]))
-AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
+AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=auto|symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
if test "$config_dns_rc_manager_default" != "" -a \
+ "$config_dns_rc_manager_default" != auto -a \
"$config_dns_rc_manager_default" != file -a \
"$config_dns_rc_manager_default" != symlink -a \
"$config_dns_rc_manager_default" != netconfig -a \
"$config_dns_rc_manager_default" != resolvconf; then
AC_MSG_WARN([Unknown --with-config-dns-rc-manager-default=$config_dns_rc_manager_default setting.])
- config_dns_rc_manager_default=
+ config_dns_rc_manager_default=auto
fi
# Use netconfig by default on SUSE
AS_IF([test -z "$with_netconfig" -a -f /etc/SuSE-release], with_netconfig=yes)
@@ -912,9 +913,6 @@ if test "$with_resolvconf" = "yes"; then
AC_MSG_ERROR(cannot find resolvconf in path. Set the path explicitly via --with-resolvconf=PATH.)
fi
fi
-if test "$with_resolvconf" != "no"; then
- AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=resolvconf)
-fi
if test "$with_netconfig" = "yes"; then
AC_PATH_PROGS(with_netconfig, netconfig, yes, /sbin:/usr/sbin:/usr/local/sbin)
@@ -922,11 +920,6 @@ if test "$with_netconfig" = "yes"; then
AC_MSG_ERROR(cannot find netconfig in path. Set the path explicitly via --with-netconfig=PATH.)
fi
fi
-if test "$with_netconfig" != "no"; then
- AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=netconfig)
-fi
-
-AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=symlink)
if test "$with_resolvconf" != "no"; then
AC_DEFINE_UNQUOTED(RESOLVCONF_PATH, "$with_resolvconf", [Path to resolvconf])
diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec
index 20001c6fd..343e29199 100644
--- a/contrib/fedora/rpm/NetworkManager.spec
+++ b/contrib/fedora/rpm/NetworkManager.spec
@@ -115,7 +115,11 @@
%if 0%{?fedora} || 0%{?rhel} > 7
%global logging_backend_default journal
+%if 0%{?fedora} || 0%{?rhel} > 8
+%global dns_rc_manager_default auto
+%else
%global dns_rc_manager_default symlink
+%endif
%else
%global logging_backend_default syslog
%global dns_rc_manager_default file
@@ -641,6 +645,8 @@ This tool is still experimental.
%endif
-Ddist_version=%{version}-%{release} \
-Dconfig_plugins_default=%{config_plugins_default} \
+ -Dresolvconf=no \
+ -Dnetconfig=no \
-Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \
-Dconfig_logging_backend_default=%{logging_backend_default} \
-Djson_validation=true
@@ -779,6 +785,8 @@ intltoolize --automake --copy --force
%endif
--with-dist-version=%{version}-%{release} \
--with-config-plugins-default=%{config_plugins_default} \
+ --with-resolvconf=no \
+ --with-netconfig=no \
--with-config-dns-rc-manager-default=%{dns_rc_manager_default} \
--with-config-logging-backend-default=%{logging_backend_default} \
--enable-json-validation
diff --git a/contrib/fedora/rpm/build_clean.sh b/contrib/fedora/rpm/build_clean.sh
index 776e4c4df..e7afdb4f2 100755
--- a/contrib/fedora/rpm/build_clean.sh
+++ b/contrib/fedora/rpm/build_clean.sh
@@ -158,7 +158,7 @@ if [[ $NO_DIST != 1 ]]; then
--enable-polkit=yes \
--with-nm-cloud-setup=yes \
--with-config-dhcp-default=internal \
- --with-config-dns-rc-manager-default=symlink \
+ --with-config-dns-rc-manager-default=auto \
|| die "Error autogen.sh"
if [[ $QUICK == 1 ]]; then
make dist -j 7 || die "Error make dist"
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index aac80a087..ce61c8216 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -309,7 +309,8 @@ no-auto-default=*
default: NetworkManager will update
/etc/resolv.conf to reflect the nameservers
- provided by currently active connections.
+ provided by currently active connections. The rc-manager
+ setting (below) controls how this is done.
dnsmasq: NetworkManager will run
dnsmasq as a local caching nameserver, using "Conditional Forwarding"
if you are connected to a VPN, and then update
@@ -349,37 +350,57 @@ no-auto-default=*
rc-manager
- Set the resolv.conf
- management mode. The default value depends on NetworkManager build
- options, and this version of NetworkManager was build with a default of
- "&NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;".
- Regardless of this setting, NetworkManager will
- always write resolv.conf to its runtime state directory
- &nmrundir;/resolv.conf.
+
+ Set the resolv.conf
+ management mode. This option is about how NetworkManager writes to
+ /etc/resolv.conf, if at all.
+ The default value depends on NetworkManager build
+ options, and this version of NetworkManager was build with a default of
+ "&NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;".
+ Regardless of this setting, NetworkManager will
+ always write its version of resolv.conf to its runtime state directory
+ as &nmrundir;/resolv.conf.
+
+ If you configure dns=none or make /etc/resolv.conf
+ immutable with chattr +i, NetworkManager will ignore this setting and
+ always choose unmanaged (below).
+
+ auto: if systemd-resolved plugin is configured via
+ the dns setting or if it gets detected as main DNS plugin,
+ NetworkManager will update systemd-resolved without touching /etc/resolv.conf.
+ Alternatively, if resolvconf or netconfig are enabled
+ at compile time and the respective binary is found, NetworkManager will automatically use it.
+ Note that if you install or uninstall these binaries, you need to reload the
+ rc-manager setting with SIGHUP or
+ systemctl reload NetworkManager. As last fallback
+ it uses the symlink option (see next).
+
symlink: If /etc/resolv.conf is
- a regular file, NetworkManager will replace the file on update. If
- /etc/resolv.conf is instead a symlink, NetworkManager
- will leave it alone. Unless the symlink points to the internal file
- &nmrundir;/resolv.conf,
- in which case the symlink will be updated to emit an inotify notification.
- This allows the user to conveniently instruct NetworkManager not
- to manage /etc/resolv.conf by replacing it with
- a symlink.
+ a regular file or does not exist, NetworkManager will write the file directly.
+ If /etc/resolv.conf is instead a symlink, NetworkManager
+ will leave it alone. Unless the symlink points to the internal file
+ &nmrundir;/resolv.conf,
+ in which case the symlink will be updated to emit an inotify notification.
+ This allows the user to conveniently instruct NetworkManager not
+ to manage /etc/resolv.conf by replacing it with
+ a symlink.
+
file: NetworkManager will write
- /etc/resolv.conf as file. If it finds
- a symlink to an existing target, it will follow the symlink and
- update the target instead. In no case will an existing symlink
- be replaced by a file. Note that older versions of NetworkManager
- behaved differently and would replace dangling symlinks with a
- plain file.
+ /etc/resolv.conf as regular file. If it finds
+ a symlink to an existing target, it will follow the symlink and
+ update the target instead. In no case will an existing symlink
+ be replaced by a file. Note that older versions of NetworkManager
+ behaved differently and would replace dangling symlinks with a
+ plain file.
+
resolvconf: NetworkManager will run
- resolvconf to update the DNS configuration.
+ resolvconf to update the DNS configuration.
netconfig: NetworkManager will run
- netconfig to update the DNS configuration.
+ netconfig to update the DNS configuration.
unmanaged: don't touch
- /etc/resolv.conf.
+ /etc/resolv.conf.
none: deprecated alias for
- symlink.
+ symlink.
diff --git a/meson_options.txt b/meson_options.txt
index d6306711e..5bfa3b151 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -49,7 +49,7 @@ option('ifupdown', type: 'boolean', value: false, description: 'enable ifupdown
# handlers for resolv.conf
option('resolvconf', type: 'string', value: '', description: 'Enable resolvconf support')
option('netconfig', type: 'string', value: '', description: 'Enable SUSE netconfig support')
-option('config_dns_rc_manager_default', type: 'combo', choices: ['symlink', 'file', 'netconfig', 'resolvconf'], value: 'symlink', description: 'Configure default value for main.rc-manager setting')
+option('config_dns_rc_manager_default', type: 'combo', choices: ['auto', 'symlink', 'file', 'netconfig', 'resolvconf'], value: 'auto', description: 'Configure default value for main.rc-manager setting')
# dhcp clients
option('dhclient', type: 'string', value: '', description: 'Enable dhclient support')
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index 9108911cb..bc1b32f86 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -42,10 +42,16 @@
#ifndef RESOLVCONF_PATH
#define RESOLVCONF_PATH "/sbin/resolvconf"
+#define HAS_RESOLVCONF 0
+#else
+#define HAS_RESOLVCONF 1
#endif
#ifndef NETCONFIG_PATH
#define NETCONFIG_PATH "/sbin/netconfig"
+#define HAS_NETCONFIG 0
+#else
+#define HAS_NETCONFIG 1
#endif
/*****************************************************************************/
@@ -182,6 +188,7 @@ domain_is_routing (const char *domain)
static
NM_UTILS_LOOKUP_STR_DEFINE (_rc_manager_to_string, NMDnsManagerResolvConfManager,
NM_UTILS_LOOKUP_DEFAULT_WARN (NULL),
+ NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO, "auto"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN, "unknown"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, "unmanaged"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE, "immutable"),
@@ -1900,6 +1907,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO:
break;
}
}
@@ -1999,6 +2007,7 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
gboolean param_changed = FALSE;
gboolean plugin_changed = FALSE;
gboolean systemd_resolved_changed = FALSE;
+ gboolean rc_manager_was_auto = FALSE;
mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
systemd_resolved = nm_config_data_get_systemd_resolved (nm_config_get_data (priv->config));
@@ -2014,7 +2023,9 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
again:
if (!man) {
/* nop */
- } else if (NM_IN_STRSET (man, "symlink", "none"))
+ } else if (nm_streq (man, "auto"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO;
+ else if (NM_IN_STRSET (man, "symlink", "none"))
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
else if (nm_streq (man, "file"))
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
@@ -2031,7 +2042,7 @@ again:
man, ""NM_CONFIG_DEFAULT_MAIN_RC_MANAGER);
}
man = ""NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;
- rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO;
goto again;
}
}
@@ -2070,6 +2081,31 @@ again:
plugin_changed = TRUE;
}
+ if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO) {
+ rc_manager_was_auto = TRUE;
+ if (nm_streq (mode, "systemd-resolved"))
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
+ else if ( HAS_RESOLVCONF
+ && g_file_test (RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) {
+ /* We detect /sbin/resolvconf only at this stage. That means, if you install
+ * or uninstall openresolv afterwards, you need to reload the DNS settings
+ * (with SIGHUP or `systemctl reload NetworkManager.service`).
+ *
+ * We only accept resolvconf if NetworkManager was built with --with-resolvconf.
+ * For example, on Fedora the systemd package provides a compat resolvconf
+ * implementation for systemd-resolved. But using that never makes sense, because
+ * there we either use full systemd-resolved mode or not. In no case does it
+ * make sense to call that resolvconf implementation. */
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
+ } else if ( HAS_NETCONFIG
+ && g_file_test (NETCONFIG_PATH, G_FILE_TEST_IS_EXECUTABLE)) {
+ /* Like for resolvconf, we detect only once. We only autoenable this
+ * option, if NetworkManager was built with netconfig explicitly enabled. */
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
+ } else
+ rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
+ }
+
/* 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 (systemd_resolved) {
@@ -2096,10 +2132,11 @@ again:
}
if (param_changed || plugin_changed || systemd_resolved_changed) {
- _LOGI ("init: dns=%s%s rc-manager=%s%s%s%s",
+ _LOGI ("init: dns=%s%s rc-manager=%s%s%s%s%s",
mode,
(systemd_resolved ? ",systemd-resolved" : ""),
_rc_manager_to_string (rc_manager),
+ rc_manager_was_auto ? " (auto)" : "",
NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=",
nm_dns_plugin_get_name (priv->plugin), "", ""));
}
diff --git a/src/dns/nm-dns-manager.h b/src/dns/nm-dns-manager.h
index 2a0c9deee..d82a68d15 100644
--- a/src/dns/nm-dns-manager.h
+++ b/src/dns/nm-dns-manager.h
@@ -88,12 +88,20 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: do not touch /etc/resolv.conf
* (but still write the internal copy -- unless it is symlinked by
* /etc/resolv.conf)
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO: if /etc/resolv.conf is marked
+ * as an immutable file, use "unmanaged" and don't touch /etc/resolv.conf.
+ * Otherwise, if "systemd-resolved" is enabled (or detected), configure systemd-resolved via D-Bus
+ * and don't touch /etc/resolv.conf.
+ * Otherwise, if "resolvconf" application is found, use it.
+ * As last resort, fallback to "symlink" which writes to /etc/resolv.conf
+ * if (and only if) the file is missing or not a symlink.
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: similar to "unmanaged",
* but indicates that resolv.conf cannot be modified.
- * @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes resolv.conf
- * by symlinking it to the run state directory.
- * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like SYMLINK, but instead of
- * symlinking /etc/resolv.conf, write it as a file.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes /etc/resolv.conf
+ * if the file is missing or not a symlink. An existing symlink is
+ * left untouched.
+ * @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Write to /etc/resolv.conf directly.
+ * If it is a file, write it as file, otherwise follow symlinks.
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
through resolvconf
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
@@ -103,6 +111,7 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
*/
typedef enum {
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN,
+ NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO,
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,