summaryrefslogtreecommitdiffstats
path: root/src/network/networkd-radv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-radv.c')
-rw-r--r--src/network/networkd-radv.c257
1 files changed, 183 insertions, 74 deletions
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index fdbf7cac62..25321aefed 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -6,6 +6,7 @@
#include <netinet/icmp6.h>
#include <arpa/inet.h>
+#include "dns-domain.h"
#include "networkd-address.h"
#include "networkd-manager.h"
#include "networkd-radv.h"
@@ -15,80 +16,6 @@
#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,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- Network *network = userdata;
- RADVPrefixDelegation d;
-
- assert(filename);
- assert(section);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- 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;
-}
-
-int config_parse_router_preference(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 *network = userdata;
-
- assert(filename);
- assert(section);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (streq(rvalue, "high"))
- network->router_preference = SD_NDISC_PREFERENCE_HIGH;
- else if (STR_IN_SET(rvalue, "medium", "normal", "default"))
- network->router_preference = SD_NDISC_PREFERENCE_MEDIUM;
- else if (streq(rvalue, "low"))
- network->router_preference = SD_NDISC_PREFERENCE_LOW;
- else
- log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue);
-
- return 0;
-}
-
void prefix_free(Prefix *prefix) {
if (!prefix)
return;
@@ -515,3 +442,185 @@ int radv_configure(Link *link) {
return radv_emit_dns(link);
}
+
+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 = reallocarray(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_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, *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) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to apply IDNA to domain name '%s', ignoring: %m", w);
+ continue;
+ } else if (r == 0)
+ /* transfer ownership to simplify subsequent operations */
+ idna = TAKE_PTR(w);
+
+ r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops);
+ if (r < 0)
+ return r;
+
+ r = ordered_set_consume(n->router_search_domains, TAKE_PTR(idna));
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+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,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Network *network = userdata;
+ RADVPrefixDelegation d;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ 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;
+}
+
+int config_parse_router_preference(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 *network = userdata;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (streq(rvalue, "high"))
+ network->router_preference = SD_NDISC_PREFERENCE_HIGH;
+ else if (STR_IN_SET(rvalue, "medium", "normal", "default"))
+ network->router_preference = SD_NDISC_PREFERENCE_MEDIUM;
+ else if (streq(rvalue, "low"))
+ network->router_preference = SD_NDISC_PREFERENCE_LOW;
+ else
+ log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue);
+
+ return 0;
+}