network: extend Token= setting in [DHCPv6PrefixDelegation]

Now the setting supports the same syntax as the one in the [IPv6AcceptRA]
section.
This commit is contained in:
Yu Watanabe 2021-09-25 04:10:34 +09:00
parent 140bf8dacc
commit f5960e0ab5
7 changed files with 41 additions and 32 deletions

View file

@ -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>

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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;