X Tutup
Skip to content

Commit 3df9bec

Browse files
committed
networkd: rework Domains= setting
Previously, .network files only knew a vaguely defined "Domains=" concept, for which the documentation declared it was the "DNS domain" for the network connection, without specifying what that means. With this the Domains setting is reworked, so that there are now "routing" domains and "search" domains. The former are to be used by resolved to route DNS request to specific network interfaces, the latter is to be used for searching single-label hostnames with (in addition to being used for routing). Both settings are configured in the "Domains=" setting. Normal domain names listed in it are now considered search domains (for compatibility with existing setups), while those prefixed with "~" are considered routing domains only. To route all lookups to a specific interface the routing domain "." may be used, referring to the root domain. An alternative syntax for this is the "*", as was already implemented before using the "wildcard" domain concept. This commit adds proper parsers for this new logic, and exposes this via the sd-network API. This information is not used by resolved yet, this will be added in a later commit.
1 parent 1d35b2d commit 3df9bec

File tree

13 files changed

+199
-143
lines changed

13 files changed

+199
-143
lines changed

man/systemd.network.xml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,21 +396,37 @@
396396
described in
397397
<citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
398398
This option may be specified more than once. This setting is read by
399-
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
399+
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
400400
</listitem>
401401
</varlistentry>
402402
<varlistentry>
403403
<term><varname>Domains=</varname></term>
404404
<listitem>
405-
<para>The domains used for DNS resolution over this link. This setting is read by
406-
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
405+
<para>The domains used for DNS host name resolution on this link. Takes a list of DNS domain names which
406+
are used as search suffixes for extending single-label host names (host names containing no dots) to become
407+
fully qualified domain names (FQDNs). If a single-label host name is resolved on this interface, each of
408+
the specified search domains are appended to it in turn, converting it into a fully qualified domain name,
409+
until one of them may be successfully resolved.</para>
410+
411+
<para>The specified domains are also used for routing of DNS queries: look-ups for host names ending in the
412+
domains specified here are preferably routed to the DNS servers configured for this interface. If a domain
413+
name is prefixed with <literal>~</literal>, the domain name becomes a pure "routing" domain, is used for
414+
DNS query routing purposes only and is not used in the described domain search logic. By specifying a
415+
routing domain of <literal>~.</literal> (the tilda indicating definition of a routing domain, the dot
416+
referring to the DNS root domain which is the implied suffix of all valid DNS names) it is possible to
417+
route all DNS traffic preferably to the DNS server specified for this interface. The route domain logic is
418+
particularly useful on multi-homed hosts with DNS servers serving particular private DNS zones on each
419+
interface.</para>
420+
421+
<para>This setting is read by
422+
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
407423
</listitem>
408424
</varlistentry>
409425
<varlistentry>
410426
<term><varname>NTP=</varname></term>
411427
<listitem>
412428
<para>An NTP server address. This option may be specified more than once. This setting is read by
413-
<citerefentry><refentrytitle>systemd-timesyncd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></para>
429+
<citerefentry><refentrytitle>systemd-timesyncd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
414430
</listitem>
415431
</varlistentry>
416432
<varlistentry>

src/basic/strv.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,3 +871,34 @@ int strv_extend_n(char ***l, const char *value, size_t n) {
871871
nl[k] = NULL;
872872
return -ENOMEM;
873873
}
874+
875+
int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
876+
bool b = false;
877+
char **s;
878+
int r;
879+
880+
/* Like fputs(), but for strv, and with a less stupid argument order */
881+
882+
if (!f)
883+
f = stdout;
884+
if (!separator)
885+
separator = " ";
886+
if (!space)
887+
space = &b;
888+
889+
STRV_FOREACH(s, l) {
890+
if (*space) {
891+
r = fputs(separator, f);
892+
if (r < 0)
893+
return r;
894+
}
895+
896+
r = fputs(*s, f);
897+
if (r < 0)
898+
return r;
899+
900+
*space = true;
901+
}
902+
903+
return 0;
904+
}

src/basic/strv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,5 @@ char ***strv_free_free(char ***l);
169169
char **strv_skip(char **l, size_t n);
170170

171171
int strv_extend_n(char ***l, const char *value, size_t n);
172+
173+
int fputstrv(FILE *f, char **l, const char *separator, bool *space);

src/libsystemd/sd-network/sd-network.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,14 @@ _public_ int sd_network_get_ntp(char ***ret) {
9595
return network_get_strv("NTP", ret);
9696
}
9797

98-
_public_ int sd_network_get_domains(char ***ret) {
98+
_public_ int sd_network_get_search_domains(char ***ret) {
9999
return network_get_strv("DOMAINS", ret);
100100
}
101101

102+
_public_ int sd_network_get_route_domains(char ***ret) {
103+
return network_get_strv("ROUTE_DOMAINS", ret);
104+
}
105+
102106
static int network_link_get_string(int ifindex, const char *field, char **ret) {
103107
_cleanup_free_ char *s = NULL, *p = NULL;
104108
int r;
@@ -222,10 +226,14 @@ _public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
222226
return network_link_get_strv(ifindex, "NTP", ret);
223227
}
224228

225-
_public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
229+
_public_ int sd_network_link_get_search_domains(int ifindex, char ***ret) {
226230
return network_link_get_strv(ifindex, "DOMAINS", ret);
227231
}
228232

233+
_public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
234+
return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
235+
}
236+
229237
_public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) {
230238
return network_link_get_strv(ifindex, "CARRIER_BOUND_TO", ret);
231239
}
@@ -234,26 +242,6 @@ _public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
234242
return network_link_get_strv(ifindex, "CARRIER_BOUND_BY", ret);
235243
}
236244

237-
_public_ int sd_network_link_get_wildcard_domain(int ifindex) {
238-
_cleanup_free_ char *p = NULL, *s = NULL;
239-
int r;
240-
241-
assert_return(ifindex > 0, -EINVAL);
242-
243-
if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
244-
return -ENOMEM;
245-
246-
r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
247-
if (r == -ENOENT)
248-
return -ENODATA;
249-
if (r < 0)
250-
return r;
251-
if (isempty(s))
252-
return -ENODATA;
253-
254-
return parse_boolean(s);
255-
}
256-
257245
static inline int MONITOR_TO_FD(sd_network_monitor *m) {
258246
return (int) (unsigned long) m - 1;
259247
}

src/network/networkctl.c

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static int link_status_one(
502502
sd_netlink *rtnl,
503503
sd_hwdb *hwdb,
504504
const char *name) {
505-
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
505+
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
506506
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
507507
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
508508
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
@@ -576,18 +576,8 @@ static int link_status_one(
576576
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
577577

578578
sd_network_link_get_dns(ifindex, &dns);
579-
sd_network_link_get_domains(ifindex, &domains);
580-
r = sd_network_link_get_wildcard_domain(ifindex);
581-
if (r > 0) {
582-
char *wildcard;
583-
584-
wildcard = strdup("*");
585-
if (!wildcard)
586-
return log_oom();
587-
588-
if (strv_consume(&domains, wildcard) < 0)
589-
return log_oom();
590-
}
579+
sd_network_link_get_search_domains(ifindex, &search_domains);
580+
sd_network_link_get_route_domains(ifindex, &route_domains);
591581

592582
sprintf(devid, "n%i", ifindex);
593583

@@ -655,8 +645,10 @@ static int link_status_one(
655645

656646
if (!strv_isempty(dns))
657647
dump_list(" DNS: ", dns);
658-
if (!strv_isempty(domains))
659-
dump_list(" Domain: ", domains);
648+
if (!strv_isempty(search_domains))
649+
dump_list(" Search Domains: ", search_domains);
650+
if (!strv_isempty(route_domains))
651+
dump_list(" Route Domains: ", route_domains);
660652

661653
(void) sd_network_link_get_ntp(ifindex, &ntp);
662654
if (!strv_isempty(ntp))
@@ -691,30 +683,35 @@ static int link_status(int argc, char *argv[], void *userdata) {
691683

692684
if (argc <= 1 && !arg_all) {
693685
_cleanup_free_ char *operational_state = NULL;
694-
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
686+
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains;
695687
const char *on_color_operational, *off_color_operational;
696688

697689
sd_network_get_operational_state(&operational_state);
698690
operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
699691

700-
printf("%s%s%s State: %s%s%s\n",
692+
printf("%s%s%s State: %s%s%s\n",
701693
on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational,
702694
on_color_operational, strna(operational_state), off_color_operational);
703695

704-
dump_addresses(rtnl, " Address: ", 0);
705-
dump_gateways(rtnl, hwdb, " Gateway: ", 0);
696+
dump_addresses(rtnl, " Address: ", 0);
697+
dump_gateways(rtnl, hwdb, " Gateway: ", 0);
706698

707699
sd_network_get_dns(&dns);
708700
if (!strv_isempty(dns))
709-
dump_list(" DNS: ", dns);
701+
dump_list(" DNS: ", dns);
702+
703+
sd_network_get_search_domains(&search_domains);
704+
if (!strv_isempty(search_domains))
705+
dump_list("Search Domains: ", search_domains);
706+
707+
sd_network_get_route_domains(&route_domains);
708+
if (!strv_isempty(route_domains))
709+
dump_list(" Route Domains: ", route_domains);
710710

711-
sd_network_get_domains(&domains);
712-
if (!strv_isempty(domains))
713-
dump_list(" Domain: ", domains);
714711

715712
sd_network_get_ntp(&ntp);
716713
if (!strv_isempty(ntp))
717-
dump_list(" NTP: ", ntp);
714+
dump_list(" NTP: ", ntp);
718715

719716
return 0;
720717
}

src/network/networkd-link.c

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,7 +2729,6 @@ int link_save(Link *link) {
27292729
admin_state, oper_state);
27302730

27312731
if (link->network) {
2732-
char **address, **domain;
27332732
bool space;
27342733
sd_dhcp6_lease *dhcp6_lease = NULL;
27352734

@@ -2743,12 +2742,7 @@ int link_save(Link *link) {
27432742

27442743
fputs("DNS=", f);
27452744
space = false;
2746-
STRV_FOREACH(address, link->network->dns) {
2747-
if (space)
2748-
fputc(' ', f);
2749-
fputs(*address, f);
2750-
space = true;
2751-
}
2745+
fputstrv(f, link->network->dns, NULL, &space);
27522746

27532747
if (link->network->dhcp_dns &&
27542748
link->dhcp_lease) {
@@ -2778,12 +2772,7 @@ int link_save(Link *link) {
27782772

27792773
fputs("NTP=", f);
27802774
space = false;
2781-
STRV_FOREACH(address, link->network->ntp) {
2782-
if (space)
2783-
fputc(' ', f);
2784-
fputs(*address, f);
2785-
space = true;
2786-
}
2775+
fputstrv(f, link->network->ntp, NULL, &space);
27872776

27882777
if (link->network->dhcp_ntp &&
27892778
link->dhcp_lease) {
@@ -2801,7 +2790,6 @@ int link_save(Link *link) {
28012790
if (link->network->dhcp_ntp && dhcp6_lease) {
28022791
struct in6_addr *in6_addrs;
28032792
char **hosts;
2804-
char **hostname;
28052793

28062794
r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
28072795
&in6_addrs);
@@ -2813,26 +2801,14 @@ int link_save(Link *link) {
28132801
}
28142802

28152803
r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
2816-
if (r > 0) {
2817-
STRV_FOREACH(hostname, hosts) {
2818-
if (space)
2819-
fputc(' ', f);
2820-
fputs(*hostname, f);
2821-
space = true;
2822-
}
2823-
}
2804+
if (r > 0)
2805+
fputstrv(f, hosts, NULL, &space);
28242806
}
28252807

28262808
fputc('\n', f);
28272809

28282810
fputs("DOMAINS=", f);
2829-
space = false;
2830-
STRV_FOREACH(domain, link->network->domains) {
2831-
if (space)
2832-
fputc(' ', f);
2833-
fputs(*domain, f);
2834-
space = true;
2835-
}
2811+
fputstrv(f, link->network->search_domains, NULL, &space);
28362812

28372813
if (link->network->dhcp_domains &&
28382814
link->dhcp_lease) {
@@ -2851,20 +2827,15 @@ int link_save(Link *link) {
28512827
char **domains;
28522828

28532829
r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
2854-
if (r >= 0) {
2855-
STRV_FOREACH(domain, domains) {
2856-
if (space)
2857-
fputc(' ', f);
2858-
fputs(*domain, f);
2859-
space = true;
2860-
}
2861-
}
2830+
if (r >= 0)
2831+
fputstrv(f, domains, NULL, &space);
28622832
}
28632833

28642834
fputc('\n', f);
28652835

2866-
fprintf(f, "WILDCARD_DOMAIN=%s\n",
2867-
yes_no(link->network->wildcard_domain));
2836+
fputs("ROUTE_DOMAINS=", f);
2837+
fputstrv(f, link->network->route_domains, NULL, NULL);
2838+
fputc('\n', f);
28682839

28692840
fprintf(f, "LLMNR=%s\n",
28702841
resolve_support_to_string(link->network->llmnr));

src/network/networkd-manager.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ static void print_string_set(FILE *f, const char *field, Set *s) {
830830
}
831831

832832
static int manager_save(Manager *m) {
833-
_cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
833+
_cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
834834
Link *link;
835835
Iterator i;
836836
_cleanup_free_ char *temp_path = NULL;
@@ -851,8 +851,12 @@ static int manager_save(Manager *m) {
851851
if (!ntp)
852852
return -ENOMEM;
853853

854-
domains = set_new(&string_hash_ops);
855-
if (!domains)
854+
search_domains = set_new(&string_hash_ops);
855+
if (!search_domains)
856+
return -ENOMEM;
857+
858+
route_domains = set_new(&string_hash_ops);
859+
if (!route_domains)
856860
return -ENOMEM;
857861

858862
HASHMAP_FOREACH(link, m->links, i) {
@@ -874,7 +878,11 @@ static int manager_save(Manager *m) {
874878
if (r < 0)
875879
return r;
876880

877-
r = set_put_strdupv(domains, link->network->domains);
881+
r = set_put_strdupv(search_domains, link->network->search_domains);
882+
if (r < 0)
883+
return r;
884+
885+
r = set_put_strdupv(route_domains, link->network->route_domains);
878886
if (r < 0)
879887
return r;
880888

@@ -911,7 +919,7 @@ static int manager_save(Manager *m) {
911919

912920
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
913921
if (r >= 0) {
914-
r = set_put_strdup(domains, domainname);
922+
r = set_put_strdup(search_domains, domainname);
915923
if (r < 0)
916924
return r;
917925
} else if (r != -ENODATA)
@@ -934,7 +942,8 @@ static int manager_save(Manager *m) {
934942

935943
print_string_set(f, "DNS=", dns);
936944
print_string_set(f, "NTP=", ntp);
937-
print_string_set(f, "DOMAINS=", domains);
945+
print_string_set(f, "DOMAINS=", search_domains);
946+
print_string_set(f, "ROUTE_DOMAINS=", route_domains);
938947

939948
r = fflush_and_check(f);
940949
if (r < 0)

src/network/networkd-network-gperf.gperf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Network.IPv6Token, config_parse_ipv6token,
4343
Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp)
4444
Network.Address, config_parse_address, 0, 0
4545
Network.Gateway, config_parse_gateway, 0, 0
46-
Network.Domains, config_parse_domains, 0, offsetof(Network, domains)
46+
Network.Domains, config_parse_domains, 0, 0
4747
Network.DNS, config_parse_strv, 0, offsetof(Network, dns)
4848
Network.LLMNR, config_parse_resolve_support, 0, offsetof(Network, llmnr)
4949
Network.MulticastDNS, config_parse_resolve_support, 0, offsetof(Network, mdns)

0 commit comments

Comments
 (0)
X Tutup