diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 865b46f403..ee464ffff4 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -547,6 +547,17 @@
name servers limited to a specific link.
+
+ DNSDefaultRoute=
+
+ Takes a boolean argument. If true, this link's configured DNS servers are used for resolving domain
+ names that do not match any link's configured Domains= setting. If false, this link's
+ configured DNS servers are never used for such domains, and are exclusively used for resolving names that
+ match at least one of the domains configured on this link. If not specified defaults to an automatic mode:
+ queries not matching any link's configured domains will be routed to this link if it has no routing-only
+ domains configured.
+
+
NTP=
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index d73e85cf25..e2851df31a 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -3929,6 +3929,8 @@ int link_save(Link *link) {
resolve_support_to_string(link->network->llmnr));
fprintf(f, "MDNS=%s\n",
resolve_support_to_string(link->network->mdns));
+ if (link->network->dns_default_route >= 0)
+ fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->network->dns_default_route));
if (link->network->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
fprintf(f, "DNS_OVER_TLS=%s\n",
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 48d8ae52fa..5d8aede593 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -58,6 +58,7 @@ Network.Address, config_parse_address,
Network.Gateway, config_parse_gateway, 0, 0
Network.Domains, config_parse_domains, 0, 0
Network.DNS, config_parse_dns, 0, 0
+Network.DNSDefaultRoute, config_parse_tristate, 0, offsetof(Network, dns_default_route)
Network.LLMNR, config_parse_resolve_support, 0, offsetof(Network, llmnr)
Network.MulticastDNS, config_parse_resolve_support, 0, offsetof(Network, mdns)
Network.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Network, dns_over_tls_mode)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 16a48a8a6d..ccc1c3ce89 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -168,6 +168,7 @@ int network_load_one(Manager *manager, const char *filename) {
.lldp_mode = LLDP_MODE_ROUTERS_ONLY,
+ .dns_default_route = -1,
.llmnr = RESOLVE_SUPPORT_YES,
.mdns = RESOLVE_SUPPORT_NO,
.dnssec_mode = _DNSSEC_MODE_INVALID,
@@ -657,7 +658,6 @@ int config_parse_domains(
* routing domain, unconditionally. */
is_route = true;
domain = "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
-
} else {
r = dns_name_normalize(domain, 0, &normalized);
if (r < 0) {
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 3a72c5bd9a..f6e62cdd79 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -260,17 +260,20 @@ struct Network {
Hashmap *prefixes_by_section;
Hashmap *rules_by_section;
+ /* All kinds of DNS configuration */
struct in_addr_data *dns;
unsigned n_dns;
-
- char **search_domains, **route_domains, **ntp, **bind_carrier;
-
+ char **search_domains, **route_domains;
+ int dns_default_route;
ResolveSupport llmnr;
ResolveSupport mdns;
DnssecMode dnssec_mode;
DnsOverTlsMode dns_over_tls_mode;
Set *dnssec_negative_trust_anchors;
+ char **ntp;
+ char **bind_carrier;
+
LIST_FIELDS(Network, networks);
};
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index cab87bf98f..209132f239 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -159,6 +159,7 @@ InvertRule=
RouterPreference=
DNSLifetimeSec=
DNS=
+DNSDefaultRoute=
RouterLifetimeSec=
Domains=
EmitDNS=