]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: extend Token= setting in [DHCPv6PrefixDelegation]
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 24 Sep 2021 19:10:34 +0000 (04:10 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 6 Oct 2021 16:24:12 +0000 (01:24 +0900)
Now the setting supports the same syntax as the one in the [IPv6AcceptRA]
section.

man/systemd.network.xml
src/network/networkd-address-generation.c
src/network/networkd-address-generation.h
src/network/networkd-dhcp6.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index 1d811a68678b6a008a68dbefeab876ef92a0b28f..1459ba83d9b545b44c3e8f43a91b693bc8bc6d27 100644 (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>
 
index 800a96d351aa8477dd114ad143034bb41c8de54c..bea765a3b0db11a2d145521a84baab4e10c23b50 100644 (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);
 }
index fc0eaa2fe8ac40b904e3a6d86645c5de1d7819ac..7e8b01e0a85a1cd5af955fa3e11236349b90db93 100644 (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);
index c6911e14a05c34d4ee289f5bdb061b04cf099a52..8827d33c2a671b1b1a7c1fef1bef2711f6b17bd8 100644 (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;
 }
index ce7e6c089eac38eac52ce422f573185be082764d..c8b1521d903277a6d08e121780207824f76b77f1 100644 (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)
index 98a9cccc03dd0bbd202207716f24f30fa874c60b..afbb9d61db4aaa7c2379c078d9d10d25545783c9 100644 (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);
index 81b7797e6ed0757d8ecd91537c198dbfd1932751..ff9d1338fdad58a07a8a9c7e21d9ac49f3e0c7d6 100644 (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;