/* 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,
void *userdata) {
Network *network = userdata;
- int d;
+ RADVPrefixDelegation d;
assert(filename);
assert(section);
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;
}
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)
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);
if (section_line) {
prefix = hashmap_get(network->prefixes_by_section, n);
if (prefix) {
- *ret = prefix;
- prefix = NULL;
+ *ret = TAKE_PTR(prefix);
return 0;
}
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;
}
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;
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);
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;
}
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;
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);
}
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;
}
}