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);