diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 7eaa4cb2a1..617b94bdf7 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -800,6 +800,10 @@ ipv6.ip6-privacy=0
connection.mdns
If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is "no" (0) and for all other plugins also "no" (0).
+
+ connection.dns-over-tls
+ If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is global setting and for all other plugins "no" (0).
+
connection.stable-id
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 9197124d9a..3c20aa5051 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -1198,6 +1198,29 @@ _prop_get_connection_llmnr(NMDevice *self)
NM_SETTING_CONNECTION_LLMNR_DEFAULT);
}
+static NMSettingConnectionDnsOverTls
+_prop_get_connection_dns_over_tls(NMDevice *self)
+{
+ NMConnection * connection;
+ NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT;
+
+ g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
+
+ connection = nm_device_get_applied_connection(self);
+ if (connection)
+ dns_over_tls = nm_setting_connection_get_dns_over_tls(
+ nm_connection_get_setting_connection(connection));
+ if (dns_over_tls != NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT)
+ return dns_over_tls;
+
+ return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
+ NM_CON_DEFAULT("connection.dns-over-tls"),
+ self,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS_NO,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS_YES,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
+}
+
static guint32
_prop_get_ipvx_route_table(NMDevice *self, int addr_family)
{
@@ -8996,6 +9019,7 @@ ensure_con_ip_config(NMDevice *self, int addr_family)
nm_connection_get_setting_ip4_config(connection),
_prop_get_connection_mdns(self),
_prop_get_connection_llmnr(self),
+ _prop_get_connection_dns_over_tls(self),
nm_device_get_route_table(self, addr_family),
nm_device_get_route_metric(self, addr_family));
} else {
@@ -9500,6 +9524,7 @@ dhcp4_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_data, NM
nm_connection_get_setting_ip4_config(connection),
NM_SETTING_CONNECTION_MDNS_DEFAULT,
NM_SETTING_CONNECTION_LLMNR_DEFAULT,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT,
nm_device_get_route_table(self, AF_INET),
nm_device_get_route_metric(self, AF_INET));
@@ -11314,6 +11339,7 @@ act_stage3_ip_config_start(NMDevice * self,
nm_connection_get_setting_ip4_config(connection),
NM_SETTING_CONNECTION_MDNS_DEFAULT,
NM_SETTING_CONNECTION_LLMNR_DEFAULT,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT,
nm_device_get_route_table(self, AF_INET),
nm_device_get_route_metric(self, AF_INET));
configs = g_new0(NMIP4Config *, 2);
@@ -12500,6 +12526,7 @@ nm_device_reactivate_ip_config(NMDevice * self,
s_ip_new,
_prop_get_connection_mdns(self),
_prop_get_connection_llmnr(self),
+ _prop_get_connection_dns_over_tls(self),
nm_device_get_route_table(self, AF_INET),
nm_device_get_route_metric(self, AF_INET));
} else {
@@ -12633,7 +12660,8 @@ can_reapply_change(NMDevice * self,
NM_SETTING_CONNECTION_METERED,
NM_SETTING_CONNECTION_LLDP,
NM_SETTING_CONNECTION_MDNS,
- NM_SETTING_CONNECTION_LLMNR);
+ NM_SETTING_CONNECTION_LLMNR,
+ NM_SETTING_CONNECTION_DNS_OVER_TLS);
}
if (NM_IN_STRSET(setting_name,
diff --git a/src/core/dns/nm-dns-systemd-resolved.c b/src/core/dns/nm-dns-systemd-resolved.c
index 938b7dc0f2..a55746b6c9 100644
--- a/src/core/dns/nm-dns-systemd-resolved.c
+++ b/src/core/dns/nm-dns-systemd-resolved.c
@@ -286,14 +286,15 @@ free_pending_updates(NMDnsSystemdResolved *self)
static gboolean
prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
{
- GVariantBuilder dns;
- GVariantBuilder domains;
- NMCListElem * elem;
- NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
- NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
- const char * mdns_arg = NULL, *llmnr_arg = NULL;
- gboolean has_config = FALSE;
- gboolean has_default_route = FALSE;
+ GVariantBuilder dns;
+ GVariantBuilder domains;
+ NMCListElem * elem;
+ NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
+ NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
+ NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT;
+ const char * mdns_arg = NULL, *llmnr_arg = NULL, *dns_over_tls_arg = NULL;
+ gboolean has_config = FALSE;
+ gboolean has_default_route = FALSE;
g_variant_builder_init(&dns, G_VARIANT_TYPE("(ia(iay))"));
g_variant_builder_add(&dns, "i", ic->ifindex);
@@ -315,6 +316,8 @@ prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
if (NM_IS_IP4_CONFIG(ip_config)) {
mdns = NM_MAX(mdns, nm_ip4_config_mdns_get(NM_IP4_CONFIG(ip_config)));
llmnr = NM_MAX(llmnr, nm_ip4_config_llmnr_get(NM_IP4_CONFIG(ip_config)));
+ dns_over_tls =
+ NM_MAX(dns_over_tls, nm_ip4_config_dns_over_tls_get(NM_IP4_CONFIG(ip_config)));
}
}
@@ -353,7 +356,24 @@ prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
}
nm_assert(llmnr_arg);
- if (!nm_str_is_empty(mdns_arg) || !nm_str_is_empty(llmnr_arg))
+ switch (dns_over_tls) {
+ case NM_SETTING_CONNECTION_DNS_OVER_TLS_NO:
+ dns_over_tls_arg = "no";
+ break;
+ case NM_SETTING_CONNECTION_DNS_OVER_TLS_OPPORTUNISTIC:
+ dns_over_tls_arg = "opportunistic";
+ break;
+ case NM_SETTING_CONNECTION_DNS_OVER_TLS_YES:
+ dns_over_tls_arg = "yes";
+ break;
+ case NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT:
+ dns_over_tls_arg = "";
+ break;
+ }
+ nm_assert(dns_over_tls_arg);
+
+ if (!nm_str_is_empty(mdns_arg) || !nm_str_is_empty(llmnr_arg)
+ || !nm_str_is_empty(dns_over_tls_arg))
has_config = TRUE;
_request_item_append(self, "SetLinkDomains", ic->ifindex, g_variant_builder_end(&domains));
@@ -370,6 +390,10 @@ prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
ic->ifindex,
g_variant_new("(is)", ic->ifindex, llmnr_arg ?: ""));
_request_item_append(self, "SetLinkDNS", ic->ifindex, g_variant_builder_end(&dns));
+ _request_item_append(self,
+ "SetLinkDNSOverTLS",
+ ic->ifindex,
+ g_variant_new("(is)", ic->ifindex, dns_over_tls_arg ?: ""));
return has_config;
}
diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c
index a622b05379..90398dcc07 100644
--- a/src/core/nm-ip4-config.c
+++ b/src/core/nm-ip4-config.c
@@ -287,27 +287,28 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMIP4Config,
PROP_DNS_PRIORITY, );
typedef struct {
- bool metered : 1;
- bool never_default : 1;
- guint32 mtu;
- int ifindex;
- NMIPConfigSource mtu_source;
- int dns_priority;
- NMSettingConnectionMdns mdns;
- NMSettingConnectionLlmnr llmnr;
- GArray * nameservers;
- GPtrArray * domains;
- GPtrArray * searches;
- GPtrArray * dns_options;
- GArray * nis;
- char * nis_domain;
- GArray * wins;
- GVariant * address_data_variant;
- GVariant * addresses_variant;
- GVariant * route_data_variant;
- GVariant * routes_variant;
- NMDedupMultiIndex * multi_idx;
- const NMPObject * best_default_route;
+ bool metered : 1;
+ bool never_default : 1;
+ guint32 mtu;
+ int ifindex;
+ NMIPConfigSource mtu_source;
+ int dns_priority;
+ NMSettingConnectionMdns mdns;
+ NMSettingConnectionLlmnr llmnr;
+ NMSettingConnectionDnsOverTls dns_over_tls;
+ GArray * nameservers;
+ GPtrArray * domains;
+ GPtrArray * searches;
+ GPtrArray * dns_options;
+ GArray * nis;
+ char * nis_domain;
+ GArray * wins;
+ GVariant * address_data_variant;
+ GVariant * addresses_variant;
+ GVariant * route_data_variant;
+ GVariant * routes_variant;
+ NMDedupMultiIndex * multi_idx;
+ const NMPObject * best_default_route;
union {
NMIPConfigDedupMultiIdxType idx_ip4_addresses_;
NMDedupMultiIdxType idx_ip4_addresses;
@@ -747,12 +748,13 @@ nm_ip4_config_commit(const NMIP4Config * self,
}
void
-nm_ip4_config_merge_setting(NMIP4Config * self,
- NMSettingIPConfig * setting,
- NMSettingConnectionMdns mdns,
- NMSettingConnectionLlmnr llmnr,
- guint32 route_table,
- guint32 route_metric)
+nm_ip4_config_merge_setting(NMIP4Config * self,
+ NMSettingIPConfig * setting,
+ NMSettingConnectionMdns mdns,
+ NMSettingConnectionLlmnr llmnr,
+ NMSettingConnectionDnsOverTls dns_over_tls,
+ guint32 route_table,
+ guint32 route_metric)
{
guint naddresses, nroutes, nnameservers, nsearches;
int i, priority;
@@ -868,6 +870,7 @@ nm_ip4_config_merge_setting(NMIP4Config * self,
nm_ip4_config_mdns_set(self, mdns);
nm_ip4_config_llmnr_set(self, llmnr);
+ nm_ip4_config_dns_over_tls_set(self, dns_over_tls);
nm_ip4_config_set_never_default(self, nm_setting_ip_config_get_never_default(setting));
@@ -1112,6 +1115,10 @@ nm_ip4_config_merge(NMIP4Config * dst,
/* LLMNR */
nm_ip4_config_llmnr_set(dst,
NM_MAX(nm_ip4_config_llmnr_get(src), nm_ip4_config_llmnr_get(dst)));
+ /* dns_over_tls */
+ nm_ip4_config_dns_over_tls_set(
+ dst,
+ NM_MAX(nm_ip4_config_dns_over_tls_get(src), nm_ip4_config_dns_over_tls_get(dst)));
g_object_thaw_notify(G_OBJECT(dst));
}
@@ -1357,6 +1364,10 @@ nm_ip4_config_subtract(NMIP4Config * dst,
if (nm_ip4_config_llmnr_get(src) == nm_ip4_config_llmnr_get(dst))
nm_ip4_config_llmnr_set(dst, NM_SETTING_CONNECTION_LLMNR_DEFAULT);
+ /* dns_over_tls */
+ if (nm_ip4_config_dns_over_tls_get(src) == nm_ip4_config_dns_over_tls_get(dst))
+ nm_ip4_config_dns_over_tls_set(dst, NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
+
g_object_thaw_notify(G_OBJECT(dst));
}
@@ -1466,6 +1477,7 @@ skip_routes:
/* ignore WINS */
/* ignore mdns */
/* ignore LLMNR */
+ /* ignore dns_over_tls */
if (update_dst)
g_object_thaw_notify(G_OBJECT(dst));
@@ -1777,6 +1789,11 @@ nm_ip4_config_replace(NMIP4Config *dst, const NMIP4Config *src, gboolean *releva
has_relevant_changes = TRUE;
}
+ if (src_priv->dns_over_tls != dst_priv->dns_over_tls) {
+ dst_priv->dns_over_tls = src_priv->dns_over_tls;
+ has_relevant_changes = TRUE;
+ }
+
/* DNS priority */
if (src_priv->dns_priority != dst_priv->dns_priority) {
nm_ip4_config_set_dns_priority(dst, src_priv->dns_priority);
@@ -2521,6 +2538,18 @@ nm_ip4_config_llmnr_set(NMIP4Config *self, NMSettingConnectionLlmnr llmnr)
NM_IP4_CONFIG_GET_PRIVATE(self)->llmnr = llmnr;
}
+NMSettingConnectionDnsOverTls
+nm_ip4_config_dns_over_tls_get(const NMIP4Config *self)
+{
+ return NM_IP4_CONFIG_GET_PRIVATE(self)->dns_over_tls;
+}
+
+void
+nm_ip4_config_dns_over_tls_set(NMIP4Config *self, NMSettingConnectionDnsOverTls dns_over_tls)
+{
+ NM_IP4_CONFIG_GET_PRIVATE(self)->dns_over_tls = dns_over_tls;
+}
+
/*****************************************************************************/
NMIPConfigFlags
@@ -2901,6 +2930,10 @@ nm_ip4_config_hash(const NMIP4Config *self, GChecksum *sum, gboolean dns_only)
if (val != NM_SETTING_CONNECTION_LLMNR_DEFAULT)
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
+ val = nm_ip4_config_dns_over_tls_get(self);
+ if (val != NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT)
+ g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
+
/* FIXME(ip-config-checksum): the DNS priority should be considered relevant
* and added into the checksum as well, but this can't be done right now
* because in the DNS manager we rely on the fact that an empty
@@ -3095,14 +3128,15 @@ nm_ip4_config_init(NMIP4Config *self)
nm_ip_config_dedup_multi_idx_type_init((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
NMP_OBJECT_TYPE_IP4_ROUTE);
- priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
- priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
- priv->nameservers = g_array_new(FALSE, FALSE, sizeof(guint32));
- priv->domains = g_ptr_array_new_with_free_func(g_free);
- priv->searches = g_ptr_array_new_with_free_func(g_free);
- priv->dns_options = g_ptr_array_new_with_free_func(g_free);
- priv->nis = g_array_new(FALSE, TRUE, sizeof(guint32));
- priv->wins = g_array_new(FALSE, TRUE, sizeof(guint32));
+ priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
+ priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
+ priv->dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT;
+ priv->nameservers = g_array_new(FALSE, FALSE, sizeof(guint32));
+ priv->domains = g_ptr_array_new_with_free_func(g_free);
+ priv->searches = g_ptr_array_new_with_free_func(g_free);
+ priv->dns_options = g_ptr_array_new_with_free_func(g_free);
+ priv->nis = g_array_new(FALSE, TRUE, sizeof(guint32));
+ priv->wins = g_array_new(FALSE, TRUE, sizeof(guint32));
}
NMIP4Config *
diff --git a/src/core/nm-ip4-config.h b/src/core/nm-ip4-config.h
index 326b884def..2eb193b2be 100644
--- a/src/core/nm-ip4-config.h
+++ b/src/core/nm-ip4-config.h
@@ -124,12 +124,13 @@ gboolean nm_ip4_config_commit(const NMIP4Config * self,
NMPlatform * platform,
NMIPRouteTableSyncMode route_table_sync);
-void nm_ip4_config_merge_setting(NMIP4Config * self,
- NMSettingIPConfig * setting,
- NMSettingConnectionMdns mdns,
- NMSettingConnectionLlmnr llmnr,
- guint32 route_table,
- guint32 route_metric);
+void nm_ip4_config_merge_setting(NMIP4Config * self,
+ NMSettingIPConfig * setting,
+ NMSettingConnectionMdns mdns,
+ NMSettingConnectionLlmnr llmnr,
+ NMSettingConnectionDnsOverTls dns_over_tls,
+ guint32 route_table,
+ guint32 route_metric);
NMSetting *nm_ip4_config_create_setting(const NMIP4Config *self);
void nm_ip4_config_merge(NMIP4Config * dst,
@@ -161,6 +162,8 @@ NMSettingConnectionMdns nm_ip4_config_mdns_get(const NMIP4Config *self);
void nm_ip4_config_mdns_set(NMIP4Config *self, NMSettingConnectionMdns mdns);
NMSettingConnectionLlmnr nm_ip4_config_llmnr_get(const NMIP4Config *self);
void nm_ip4_config_llmnr_set(NMIP4Config *self, NMSettingConnectionLlmnr llmnr);
+NMSettingConnectionDnsOverTls nm_ip4_config_dns_over_tls_get(const NMIP4Config *self);
+void nm_ip4_config_dns_over_tls_set(NMIP4Config *self, NMSettingConnectionDnsOverTls dns_over_tls);
void nm_ip4_config_set_config_flags(NMIP4Config *self, NMIPConfigFlags flags, NMIPConfigFlags mask);
NMIPConfigFlags nm_ip4_config_get_config_flags(const NMIP4Config *self);
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
index d06ca46adc..d2034278c0 100644
--- a/src/core/vpn/nm-vpn-connection.c
+++ b/src/core/vpn/nm-vpn-connection.c
@@ -1659,6 +1659,7 @@ nm_vpn_connection_ip4_config_get(NMVpnConnection *self, GVariant *dict)
s_ip,
nm_setting_connection_get_mdns(s_con),
nm_setting_connection_get_llmnr(s_con),
+ nm_setting_connection_get_dns_over_tls(s_con),
route_table,
route_metric);