networkd: Parse DNS search domain information for Router Advertisement
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Wed, 16 Aug 2017 10:29:51 +0000 (13:29 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 15 Sep 2017 07:34:57 +0000 (10:34 +0300)
Parse DNS search domains from .network files so that they are included
in Router Advertisement DNSSL options.

DNS search domains are added to the [IPv6PrefixDelegation] section using
the following syntax:

    Domains=foo.example.com bar.example.com

If IDNA libraries are enabled in systemd, international domain names
are supported.

src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index f01e78a..274d2a8 100644 (file)
@@ -152,6 +152,7 @@ IPv6PrefixDelegation.Managed,           config_parse_bool,
 IPv6PrefixDelegation.OtherInformation,  config_parse_bool,                              0,                             offsetof(Network, router_other_information)
 IPv6PrefixDelegation.RouterPreference,  config_parse_router_preference,                 0,                             0
 IPv6PrefixDelegation.DNS,               config_parse_radv_dns,                          0,                             0
+IPv6PrefixDelegation.Domains,           config_parse_radv_search_domains,               0,                             0
 IPv6PrefixDelegation.DNSLifetimeSec,    config_parse_sec,                               0,                             offsetof(Network, router_dns_lifetime_usec)
 IPv6Prefix.Prefix,                      config_parse_prefix,                            0,                             0
 IPv6Prefix.OnLink,                      config_parse_prefix_flags,                      0,                             0
index 1694b1e..f2da314 100644 (file)
@@ -35,6 +35,7 @@
 #include "stat-util.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "strv.h"
 #include "util.h"
 
 static void network_config_hash_func(const void *p, struct siphash *state) {
@@ -1127,6 +1128,55 @@ int config_parse_radv_dns(
         return 0;
 }
 
+int config_parse_radv_search_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) {
+
+        Network *n = data;
+        const char *p = rvalue;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        for (;;) {
+                _cleanup_free_ char *w = NULL;
+                _cleanup_free_ char *idna = NULL;
+
+                r = extract_first_word(&p, &w, NULL, 0);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
+                        return 0;
+                }
+                if (r == 0)
+                        break;
+
+                r = dns_name_apply_idna(w, &idna);
+                if (r > 0) {
+                        r = strv_push(&n->router_search_domains, idna);
+                        if (r >= 0)
+                                idna = NULL;
+                } else if (r == 0) {
+                        r = strv_push(&n->router_search_domains, w);
+                        if (r >= 0)
+                                w = NULL;
+                }
+        }
+
+        return 0;
+}
+
 int config_parse_dhcp_server_ntp(
                 const char *unit,
                 const char *filename,
index 7af3171..11f5bb1 100644 (file)
@@ -169,6 +169,7 @@ struct Network {
         usec_t router_dns_lifetime_usec;
         struct in6_addr *router_dns;
         unsigned n_router_dns;
+        char **router_search_domains;
 
         /* Bridge Support */
         bool use_bpdu;
@@ -275,6 +276,7 @@ int config_parse_hostname(const char *unit, const char *filename, unsigned line,
 int config_parse_timezone(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_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_radv_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_radv_search_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);
 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);