networkd: Parse DNS IPv6 information for Router Advertisement
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Mon, 14 Aug 2017 09:53:10 +0000 (12:53 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Thu, 7 Sep 2017 06:51:26 +0000 (09:51 +0300)
Parse DNS IPv6 addresses and DNS server lifetime from .network files
so that they can be included in Router Advertisement RDNSS options.

RDNSS address and lifetime information is added to the
[IPv6PrefixDelegation] section according to the following syntax:

DNS=2001:db8::a:b 2001:db8::c:d
DNSLifetimeSec=1042

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

index 54385b5..804affd 100644 (file)
@@ -144,6 +144,8 @@ IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec,
 IPv6PrefixDelegation.Managed,           config_parse_bool,                              0,                             offsetof(Network, router_managed)
 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.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
 IPv6Prefix.AddressAutoconfiguration,    config_parse_prefix_flags,                      0,                             0
index 77acee1..026f318 100644 (file)
@@ -26,6 +26,7 @@
 #include "dns-domain.h"
 #include "fd-util.h"
 #include "hostname-util.h"
+#include "in-addr-util.h"
 #include "network-internal.h"
 #include "networkd-manager.h"
 #include "networkd-network.h"
@@ -1008,6 +1009,58 @@ int config_parse_dhcp_server_dns(
         return 0;
 }
 
+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) {
+
+        Network *n = data;
+        const char *p = rvalue;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        for (;;) {
+                _cleanup_free_ char *w = NULL;
+                union in_addr_union a;
+
+                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;
+
+                if (in_addr_from_string(AF_INET6, w, &a) >= 0) {
+                        struct in6_addr *m;
+
+                        m = realloc(n->router_dns, (n->n_router_dns + 1) * sizeof(struct in6_addr));
+                        if (!m)
+                                return log_oom();
+
+                        m[n->n_router_dns++] = a.in6;
+                        n->router_dns = m;
+
+                } else
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
+
+        }
+
+        return 0;
+}
+
 int config_parse_dhcp_server_ntp(
                 const char *unit,
                 const char *filename,
index d55e6f7..1c0b947 100644 (file)
@@ -164,6 +164,9 @@ struct Network {
         uint8_t router_preference;
         bool router_managed;
         bool router_other_information;
+        usec_t router_dns_lifetime_usec;
+        struct in6_addr *router_dns;
+        unsigned n_router_dns;
 
         /* Bridge Support */
         bool use_bpdu;
@@ -265,6 +268,7 @@ int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename,
 int config_parse_hostname(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_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_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);