]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-radv.c
network: drop sections contain invalid settings in network_verify()
[thirdparty/systemd.git] / src / network / networkd-radv.c
index 1cc89f3b0ad541a0a61acbec793d963c27635388..8cb14b588cfbd5a7ab4f0c4e93e9697f5219c0e8 100644 (file)
@@ -1,21 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 /***
-  This file is part of systemd.
-
-  Copyright (C) 2017 Intel Corporation. All rights reserved.
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+  Copyright © 2017 Intel Corporation. All rights reserved.
 ***/
 
 #include <netinet/icmp6.h>
 #include "parse-util.h"
 #include "sd-radv.h"
 #include "string-util.h"
+#include "string-table.h"
+#include "strv.h"
+
+static const char * const radv_prefix_delegation_table[_RADV_PREFIX_DELEGATION_MAX] = {
+        [RADV_PREFIX_DELEGATION_NONE] = "no",
+        [RADV_PREFIX_DELEGATION_STATIC] = "static",
+        [RADV_PREFIX_DELEGATION_DHCP6] = "dhcpv6",
+        [RADV_PREFIX_DELEGATION_BOTH] = "yes",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(
+                radv_prefix_delegation,
+                RADVPrefixDelegation,
+                RADV_PREFIX_DELEGATION_BOTH);
 
 int config_parse_router_prefix_delegation(
                 const char *unit,
@@ -41,7 +40,7 @@ int config_parse_router_prefix_delegation(
                 void *userdata) {
 
         Network *network = userdata;
-        int d;
+        RADVPrefixDelegation d;
 
         assert(filename);
         assert(section);
@@ -49,21 +48,14 @@ int config_parse_router_prefix_delegation(
         assert(rvalue);
         assert(data);
 
-        if (streq(rvalue, "static"))
-                network->router_prefix_delegation = RADV_PREFIX_DELEGATION_STATIC;
-        else if (streq(rvalue, "dhcpv6"))
-                network->router_prefix_delegation = RADV_PREFIX_DELEGATION_DHCP6;
-        else {
-                d = parse_boolean(rvalue);
-                if (d > 0)
-                        network->router_prefix_delegation = RADV_PREFIX_DELEGATION_BOTH;
-                else
-                        network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
-
-                if (d < 0)
-                        log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router prefix delegation '%s' is invalid, ignoring assignment: %m", rvalue);
+        d = radv_prefix_delegation_from_string(rvalue);
+        if (d < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Invalid router prefix delegation '%s', ignoring assignment.", rvalue);
+                return 0;
         }
 
+        network->router_prefix_delegation = d;
+
         return 0;
 }
 
@@ -111,13 +103,14 @@ void prefix_free(Prefix *prefix) {
                                        prefix->section);
         }
 
+        network_config_section_free(prefix->section);
         prefix->radv_prefix = sd_radv_prefix_unref(prefix->radv_prefix);
 
         free(prefix);
 }
 
 int prefix_new(Prefix **ret) {
-        Prefix *prefix = NULL;
+        _cleanup_(prefix_freep) Prefix *prefix = NULL;
 
         prefix = new0(Prefix, 1);
         if (!prefix)
@@ -131,10 +124,10 @@ int prefix_new(Prefix **ret) {
         return 0;
 }
 
-int prefix_new_static(Network *network, const char *filename,
-                      unsigned section_line, Prefix **ret) {
-        _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
-        _cleanup_prefix_free_ Prefix *prefix = NULL;
+static int prefix_new_static(Network *network, const char *filename,
+                             unsigned section_line, Prefix **ret) {
+        _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
+        _cleanup_(prefix_freep) Prefix *prefix = NULL;
         int r;
 
         assert(network);
@@ -149,8 +142,7 @@ int prefix_new_static(Network *network, const char *filename,
                 if (section_line) {
                         prefix = hashmap_get(network->prefixes_by_section, n);
                         if (prefix) {
-                                *ret = prefix;
-                                prefix = NULL;
+                                *ret = TAKE_PTR(prefix);
 
                                 return 0;
                         }
@@ -161,22 +153,23 @@ int prefix_new_static(Network *network, const char *filename,
         if (r < 0)
                 return r;
 
+        prefix->network = network;
+        LIST_APPEND(prefixes, network->static_prefixes, prefix);
+        network->n_static_prefixes++;
+
         if (filename) {
-                prefix->section = n;
-                n = NULL;
+                prefix->section = TAKE_PTR(n);
 
-                r = hashmap_put(network->prefixes_by_section, prefix->section,
-                                prefix);
+                r = hashmap_ensure_allocated(&network->prefixes_by_section, &network_config_hash_ops);
                 if (r < 0)
                         return r;
-        }
 
-        prefix->network = network;
-        LIST_APPEND(prefixes, network->static_prefixes, prefix);
-        network->n_static_prefixes++;
+                r = hashmap_put(network->prefixes_by_section, prefix->section, prefix);
+                if (r < 0)
+                        return r;
+        }
 
-        *ret = prefix;
-        prefix = NULL;
+        *ret = TAKE_PTR(prefix);
 
         return 0;
 }
@@ -193,7 +186,7 @@ int config_parse_prefix(const char *unit,
                 void *userdata) {
 
         Network *network = userdata;
-        _cleanup_prefix_free_ Prefix *p = NULL;
+        _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
         uint8_t prefixlen = 64;
         union in_addr_union in6addr;
         int r;
@@ -235,7 +228,7 @@ int config_parse_prefix_flags(const char *unit,
                               void *data,
                               void *userdata) {
         Network *network = userdata;
-        _cleanup_prefix_free_ Prefix *p = NULL;
+        _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
         int r, val;
 
         assert(filename);
@@ -279,7 +272,7 @@ int config_parse_prefix_lifetime(const char *unit,
                                  void *data,
                                  void *userdata) {
         Network *network = userdata;
-        _cleanup_prefix_free_ Prefix *p = NULL;
+        _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
         usec_t usec;
         int r;
 
@@ -398,8 +391,9 @@ static int radv_set_dns(Link *link, Link *uplink) {
 }
 
 static int radv_set_domains(Link *link, Link *uplink) {
-        char **search_domains;
+        OrderedSet *search_domains;
         usec_t lifetime_usec;
+        _cleanup_free_ char **s = NULL; /* just free() because the strings are owned by the set */
 
         if (!link->network->router_emit_domains)
                 return 0;
@@ -430,9 +424,13 @@ static int radv_set_domains(Link *link, Link *uplink) {
         return 0;
 
  set_domains:
+        s = ordered_set_get_strv(search_domains);
+        if (!s)
+                return log_oom();
+
         return sd_radv_set_dnssl(link->radv,
                                  DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
-                                 search_domains);
+                                 s);
 
 }
 
@@ -501,9 +499,16 @@ int radv_configure(Link *link) {
         if (IN_SET(link->network->router_prefix_delegation,
                    RADV_PREFIX_DELEGATION_STATIC,
                    RADV_PREFIX_DELEGATION_BOTH)) {
+
                 LIST_FOREACH(prefixes, p, link->network->static_prefixes) {
                         r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
-                        if (r != -EEXIST && r < 0)
+                        if (r == -EEXIST)
+                                continue;
+                        if (r == -ENOEXEC) {
+                                log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
+                                continue;
+                        }
+                        if (r < 0)
                                 return r;
                 }
         }