diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index e743e6d2a0..eb6eaf3ce2 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2605,6 +2605,18 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix
+
+ UseDNR=
+
+ When true, designated resolvers advertised by the DHCP server will be used as encrypted
+ DNS servers. See RFC 9463.
+
+ Defaults to unset, and the value for UseDNS= will be used.
+
+
+
+
+
UseMTU=
@@ -3131,6 +3143,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix
UseDNS=
+ UseDNR=
UseNTP=
UseHostname=
UseDomains=
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 0a784553d0..4d3f429a30 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1557,6 +1557,13 @@ static int dhcp4_configure(Link *link) {
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for SIP server: %m");
}
+
+ if (network_dhcp_use_dnr(link->network)) {
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_V4_DNR);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for DNR: %m");
+ }
+
if (link->network->dhcp_use_captive_portal) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL);
if (r < 0)
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 9f23542493..89be7e8ae2 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -228,6 +228,7 @@ NextHop.Group, config_parse_nexthop_group,
DHCPv4.RequestAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_request_address)
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCPv4.UseDNS, config_parse_tristate, 0, offsetof(Network, dhcp_use_dns)
+DHCPv4.UseDNR, config_parse_tristate, 0, offsetof(Network, dhcp_use_dnr)
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
DHCPv4.UseNTP, config_parse_tristate, 0, offsetof(Network, dhcp_use_ntp)
DHCPv4.RoutesToNTP, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_ntp)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 8ccf215a71..873894d82c 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -388,6 +388,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp_use_sip = true,
.dhcp_use_captive_portal = true,
.dhcp_use_dns = -1,
+ .dhcp_use_dnr = -1,
.dhcp_routes_to_dns = true,
.dhcp_use_domains = _USE_DOMAINS_INVALID,
.dhcp_use_hostname = true,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 66a8328e29..1a92257059 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -153,6 +153,7 @@ struct Network {
int dhcp_ipv6_only_mode;
int dhcp_use_rapid_commit;
int dhcp_use_dns;
+ int dhcp_use_dnr;
bool dhcp_routes_to_dns;
int dhcp_use_ntp;
bool dhcp_routes_to_ntp;
@@ -420,6 +421,10 @@ int network_load(Manager *manager, OrderedHashmap **networks);
int network_reload(Manager *manager);
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename);
int network_verify(Network *network);
+static inline int network_dhcp_use_dnr(Network *network) {
+ assert(network);
+ return network->dhcp_use_dnr < 0 ? network->dhcp_use_dns : network->dhcp_use_dnr;
+}
int manager_build_dhcp_pd_subnet_ids(Manager *manager);