networkd: optinally use DHCP lease domain info for routing only
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Jan 2016 21:27:01 +0000 (22:27 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 Jan 2016 13:42:04 +0000 (14:42 +0100)
This changes the UseDomains= setting of .network files to take an optional third value "route", in addition to the
boolean values. If set, the passed domain information is used for routing rules only, but not for the search path
logic.

man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index be88d66..f88751b 100644 (file)
         <varlistentry>
           <term><varname>UseDomains=</varname></term>
           <listitem>
-            <para>When true (not the default), the domain name
-            received from the DHCP server will be used for DNS
-            resolution over this link. When a name cannot be resolved
-            as specified, the domain name will be used a suffix and
-            name resolution of that will be attempted.</para>
-
-            <para>This corresponds to the <option>domain</option>
-            option in <citerefentry project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-            and should not be enabled on untrusted networks.</para>
+            <para>Takes a boolean argument, or a the special value <literal>route</literal>. When true, the domain name
+            received from the DHCP server will be used as DNS search domain over this link, similar to the effect of
+            the <option>Domains=</option> setting. If set to <literal>route</literal>, the domain name received from
+            the DHCP server will be used for routing DNS queries only, but not for searching, similar to the effect of
+            the <option>Domains=</option> setting when the argument is prefixed with <literal>~</literal>. Defaults to
+            false.</para>
+
+            <para>It is recommended to enable this option only on trusted networks, as setting this affects resolution
+            of all host names, in particular to single-label names. It is generally safer to use the supplied domain
+            only as routing domain, rather than as search domain, in order to not have it affect local resolution of
+            single-label names.</para>
+
+            <para>When set to true, this setting corresponds to the <option>domain</option> option in <citerefentry
+            project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
index b0e0c4f..bf13544 100644 (file)
@@ -2731,6 +2731,8 @@ int link_save(Link *link) {
         if (link->network) {
                 bool space;
                 sd_dhcp6_lease *dhcp6_lease = NULL;
+                const char *dhcp_domainname = NULL;
+                char **dhcp6_domains = NULL;
 
                 if (link->dhcp6_client) {
                         r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
@@ -2807,34 +2809,42 @@ int link_save(Link *link) {
 
                 fputc('\n', f);
 
-                fputs("DOMAINS=", f);
-                fputstrv(f, link->network->search_domains, NULL, &space);
-
-                if (link->network->dhcp_use_domains &&
-                    link->dhcp_lease) {
-                        const char *domainname;
+                if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
+                        if (link->dhcp_lease)
+                                (void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
 
-                        r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
-                        if (r >= 0) {
-                                if (space)
-                                        fputc(' ', f);
-                                fputs(domainname, f);
-                                space = true;
-                        }
+                        if (dhcp6_lease)
+                                (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
                 }
 
-                if (link->network->dhcp_use_domains && dhcp6_lease) {
-                        char **domains;
+                fputs("DOMAINS=", f);
+                fputstrv(f, link->network->search_domains, NULL, &space);
 
-                        r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
-                        if (r >= 0)
-                                fputstrv(f, domains, NULL, &space);
+                if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES && dhcp_domainname) {
+                        if (space)
+                                fputc(' ', f);
+                        fputs(dhcp_domainname, f);
+                        space = true;
                 }
 
+                if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES && dhcp6_domains)
+                        fputstrv(f, dhcp6_domains, NULL, &space);
+
                 fputc('\n', f);
 
                 fputs("ROUTE_DOMAINS=", f);
                 fputstrv(f, link->network->route_domains, NULL, NULL);
+
+                if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE && dhcp_domainname) {
+                        if (space)
+                                fputc(' ', f);
+                        fputs(dhcp_domainname, f);
+                        space = true;
+                }
+
+                if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE && dhcp6_domains)
+                        fputstrv(f, dhcp6_domains, NULL, &space);
+
                 fputc('\n', f);
 
                 fprintf(f, "LLMNR=%s\n",
index 0701dd0..723a92b 100644 (file)
@@ -916,12 +916,17 @@ static int manager_save(Manager *m) {
                                 return r;
                 }
 
-                if (link->network->dhcp_use_domains) {
+                if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                         const char *domainname;
 
                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
                         if (r >= 0) {
-                                r = ordered_set_put_strdup(search_domains, domainname);
+
+                                if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES)
+                                        r = ordered_set_put_strdup(search_domains, domainname);
+                                else
+                                        r = ordered_set_put_strdup(route_domains, domainname);
+
                                 if (r < 0)
                                         return r;
                         } else if (r != -ENODATA)
index 89b2819..409df17 100644 (file)
@@ -72,7 +72,7 @@ DHCP.UseDNS,                            config_parse_bool,
 DHCP.UseNTP,                            config_parse_bool,                              0,                             offsetof(Network, dhcp_use_ntp)
 DHCP.UseMTU,                            config_parse_bool,                              0,                             offsetof(Network, dhcp_use_mtu)
 DHCP.UseHostname,                       config_parse_bool,                              0,                             offsetof(Network, dhcp_use_hostname)
-DHCP.UseDomains,                        config_parse_bool,                              0,                             offsetof(Network, dhcp_use_domains)
+DHCP.UseDomains,                        config_parse_dhcp_use_domains,                  0,                             offsetof(Network, dhcp_use_domains)
 DHCP.UseRoutes,                         config_parse_bool,                              0,                             offsetof(Network, dhcp_use_routes)
 DHCP.SendHostname,                      config_parse_bool,                              0,                             offsetof(Network, dhcp_send_hostname)
 DHCP.Hostname,                          config_parse_hostname,                          0,                             offsetof(Network, dhcp_hostname)
@@ -104,6 +104,6 @@ Network.IPv4LL,                         config_parse_ipv4ll,
 DHCPv4.UseDNS,                          config_parse_bool,                              0,                             offsetof(Network, dhcp_use_dns)
 DHCPv4.UseMTU,                          config_parse_bool,                              0,                             offsetof(Network, dhcp_use_mtu)
 DHCPv4.UseHostname,                     config_parse_bool,                              0,                             offsetof(Network, dhcp_use_hostname)
-DHCP.UseDomainName,                     config_parse_bool,                              0,                             offsetof(Network, dhcp_use_domains)
-DHCPv4.UseDomainName,                   config_parse_bool,                              0,                             offsetof(Network, dhcp_use_domains)
+DHCP.UseDomainName,                     config_parse_dhcp_use_domains,                  0,                             offsetof(Network, dhcp_use_domains)
+DHCPv4.UseDomainName,                   config_parse_dhcp_use_domains,                  0,                             offsetof(Network, dhcp_use_domains)
 DHCPv4.CriticalConnection,              config_parse_bool,                              0,                             offsetof(Network, dhcp_critical)
index 2a28ff2..e1a8111 100644 (file)
@@ -1005,3 +1005,13 @@ int config_parse_dnssec_negative_trust_anchors(
 
         return 0;
 }
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse DHCP use domains setting");
+
+static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = {
+        [DHCP_USE_DOMAINS_NO] = "no",
+        [DHCP_USE_DOMAINS_ROUTE] = "route",
+        [DHCP_USE_DOMAINS_YES] = "yes",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains, DHCPUseDomains, DHCP_USE_DOMAINS_YES);
index c8e705f..626dfbd 100644 (file)
@@ -52,6 +52,14 @@ typedef enum IPv6PrivacyExtensions {
         _IPV6_PRIVACY_EXTENSIONS_INVALID = -1,
 } IPv6PrivacyExtensions;
 
+typedef enum DHCPUseDomains {
+        DHCP_USE_DOMAINS_NO,
+        DHCP_USE_DOMAINS_YES,
+        DHCP_USE_DOMAINS_ROUTE,
+        _DHCP_USE_DOMAINS_MAX,
+        _DHCP_USE_DOMAINS_INVALID = -1,
+} DHCPUseDomains;
+
 struct Network {
         Manager *manager;
 
@@ -84,7 +92,7 @@ struct Network {
         bool dhcp_use_ntp;
         bool dhcp_use_mtu;
         bool dhcp_use_hostname;
-        bool dhcp_use_domains;
+        DHCPUseDomains dhcp_use_domains;
         bool dhcp_send_hostname;
         bool dhcp_broadcast;
         bool dhcp_critical;
@@ -174,6 +182,7 @@ int config_parse_timezone(const char *unit, const char *filename, unsigned line,
 int config_parse_dhcp_server_dns(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_dhcp_server_ntp(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_dnssec_negative_trust_anchors(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_dhcp_use_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 /* Legacy IPv4LL support */
 int config_parse_ipv4ll(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -187,3 +196,6 @@ int network_object_find(sd_bus *bus, const char *path, const char *interface, vo
 
 const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_;
 IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_;
+
+const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
+DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;