summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-09-25 04:10:34 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-10-07 01:24:12 +0900
commitf5960e0ab5e4ffa985e8f08308ccadfcb4d4f748 (patch)
tree9927be9200ea951a51aba763370ab4fdd85462fe
parent140bf8dacca4d462fe5c71fa57f98458828f813d (diff)
downloadsystemd-f5960e0ab5e4ffa985e8f08308ccadfcb4d4f748.tar.gz
network: extend Token= setting in [DHCPv6PrefixDelegation]
Now the setting supports the same syntax as the one in the [IPv6AcceptRA] section.
-rw-r--r--man/systemd.network.xml8
-rw-r--r--src/network/networkd-address-generation.c5
-rw-r--r--src/network/networkd-address-generation.h1
-rw-r--r--src/network/networkd-dhcp6.c54
-rw-r--r--src/network/networkd-network-gperf.gperf2
-rw-r--r--src/network/networkd-network.c1
-rw-r--r--src/network/networkd-network.h2
7 files changed, 41 insertions, 32 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 1d811a6867..1459ba83d9 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2158,11 +2158,9 @@ Table=1234</programlisting></para>
<term><varname>Token=</varname></term>
<listitem>
<para>Specifies an optional address generation mode for assigning an address in each
- delegated prefix. Takes an IPv6 address. When set, the lower bits of the supplied address is
- combined with the upper bits of each delegatad prefix received from the WAN interface by the
- DHCPv6 Prefix Delegation to form a complete address. When <varname>Assign=</varname> is
- disabled, this setting is ignored. When unset, the EUI-64 algorithm will be used to form
- addresses. Defaults to unset.</para>
+ delegated prefix. This accepts the same syntax as <varname>Token=</varname> in the
+ [IPv6AcceptRA] section. If <varname>Assign=</varname> is set to false, then this setting will
+ be ignored. Defaults to unset, which means the EUI-64 algorithm will be used.</para>
</listitem>
</varlistentry>
diff --git a/src/network/networkd-address-generation.c b/src/network/networkd-address-generation.c
index 800a96d351..bea765a3b0 100644
--- a/src/network/networkd-address-generation.c
+++ b/src/network/networkd-address-generation.c
@@ -20,6 +20,7 @@
#define RESERVED_SUBNET_ANYCAST_ADDRESSES ((const struct in6_addr) { .s6_addr = { 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 } })
#define RESERVED_SUBNET_ANYCAST_PREFIXLEN 57
+#define DHCP6PD_APP_ID SD_ID128_MAKE(fb,b9,37,ca,4a,ed,4a,4d,b0,70,7f,aa,71,c0,c9,85)
#define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e)
typedef enum AddressGenerationType {
@@ -227,6 +228,10 @@ static int generate_addresses(
return 0;
}
+int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret) {
+ return generate_addresses(link, link->network->dhcp6_pd_tokens, &DHCP6PD_APP_ID, prefix, 64, ret);
+}
+
int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret) {
return generate_addresses(link, link->network->ndisc_tokens, &NDISC_APP_ID, prefix, prefixlen, ret);
}
diff --git a/src/network/networkd-address-generation.h b/src/network/networkd-address-generation.h
index fc0eaa2fe8..7e8b01e0a8 100644
--- a/src/network/networkd-address-generation.h
+++ b/src/network/networkd-address-generation.h
@@ -9,6 +9,7 @@ typedef struct Link Link;
void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret);
+int dhcp6_pd_generate_addresses(Link *link, const struct in6_addr *prefix, Set **ret);
int ndisc_generate_addresses(Link *link, const struct in6_addr *prefix, uint8_t prefixlen, Set **ret);
CONFIG_PARSER_PROTOTYPE(config_parse_address_generation_type);
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index c6911e14a0..8827d33c2a 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -362,8 +362,8 @@ static int dhcp6_pd_request_address(
uint32_t lifetime_preferred,
uint32_t lifetime_valid) {
- _cleanup_(address_freep) Address *address = NULL;
- Address *existing;
+ _cleanup_set_free_ Set *addresses = NULL;
+ struct in6_addr *a;
int r;
assert(link);
@@ -373,35 +373,39 @@ static int dhcp6_pd_request_address(
if (!link->network->dhcp6_pd_assign)
return 0;
- r = address_new(&address);
+ r = dhcp6_pd_generate_addresses(link, prefix, &addresses);
if (r < 0)
- return log_link_error_errno(link, r, "Failed to allocate address for DHCPv6 delegated prefix: %m");
+ return log_link_warning_errno(link, r, "Failed to generate addresses for acquired DHCPv6 delegated prefix: %m");
- if (in6_addr_is_set(&link->network->dhcp6_pd_token)) {
- memcpy(address->in_addr.in6.s6_addr, prefix->s6_addr, 8);
- memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.s6_addr + 8, 8);
- } else
- generate_eui64_address(link, prefix, &address->in_addr.in6);
+ SET_FOREACH(a, addresses) {
+ _cleanup_(address_freep) Address *address = NULL;
+ Address *existing;
- address->source = NETWORK_CONFIG_SOURCE_DHCP6PD;
- address->prefixlen = 64;
- address->family = AF_INET6;
- address->cinfo.ifa_prefered = lifetime_preferred;
- address->cinfo.ifa_valid = lifetime_valid;
- SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address);
- address->route_metric = link->network->dhcp6_pd_route_metric;
+ r = address_new(&address);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to allocate address for DHCPv6 delegated prefix: %m");
- log_dhcp6_pd_address(link, address);
+ address->source = NETWORK_CONFIG_SOURCE_DHCP6PD;
+ address->family = AF_INET6;
+ address->in_addr.in6 = *a;
+ address->prefixlen = 64;
+ address->cinfo.ifa_prefered = lifetime_preferred;
+ address->cinfo.ifa_valid = lifetime_valid;
+ SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address);
+ address->route_metric = link->network->dhcp6_pd_route_metric;
- if (address_get(link, address, &existing) < 0)
- link->dhcp6_pd_configured = false;
- else
- address_unmark(existing);
+ log_dhcp6_pd_address(link, address);
- r = link_request_address(link, TAKE_PTR(address), true, &link->dhcp6_pd_messages,
- dhcp6_pd_address_handler, NULL);
- if (r < 0)
- return log_link_error_errno(link, r, "Failed to request DHCPv6 delegated prefix address: %m");
+ if (address_get(link, address, &existing) < 0)
+ link->dhcp6_pd_configured = false;
+ else
+ address_unmark(existing);
+
+ r = link_request_address(link, TAKE_PTR(address), true, &link->dhcp6_pd_messages,
+ dhcp6_pd_address_handler, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to request DHCPv6 delegated prefix address: %m");
+ }
return 0;
}
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index ce7e6c089e..c8b1521d90 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -329,7 +329,7 @@ DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp6_pd_subnet_id,
DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp6_pd_announce)
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address)
-DHCPv6PrefixDelegation.Token, config_parse_in_addr_non_null, AF_INET6, offsetof(Network, dhcp6_pd_token)
+DHCPv6PrefixDelegation.Token, config_parse_address_generation_type, 0, offsetof(Network, dhcp6_pd_tokens)
DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric)
IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 98a9cccc03..afbb9d61db 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -708,6 +708,7 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_server_send_vendor_options);
ordered_hashmap_free(network->dhcp6_client_send_options);
ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
+ set_free(network->dhcp6_pd_tokens);
set_free(network->ndisc_tokens);
return mfree(network);
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 81b7797e6e..ff9d1338fd 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -244,7 +244,7 @@ struct Network {
bool dhcp6_pd_manage_temporary_address;
int64_t dhcp6_pd_subnet_id;
uint32_t dhcp6_pd_route_metric;
- struct in6_addr dhcp6_pd_token;
+ Set *dhcp6_pd_tokens;
/* Bridge Support */
int use_bpdu;