]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: DHCPv6 - Add support to set token on the LAN interface
authorSusant Sahani <ssahani@vmware.com>
Wed, 10 Jun 2020 02:57:35 +0000 (04:57 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 17 Jun 2020 05:20:48 +0000 (14:20 +0900)
This patch adds support to set a token on the LAN interface for
the acquired delegated prefixes for the DHCPv6 to generate address.

man/systemd.network.xml
src/network/networkd-dhcp6.c
src/network/networkd-dhcp6.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index ae93a39eb462dcb5b925dd9f281fed4763e025f3..851570e723ff330434ed2e48527d0aaa55442aac 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+        <term><varname>AssignAcquiredDelegatedPrefixToken=</varname></term>
+          <listitem>
+            <para>Specifies an optional address generation mode for <varname>AssignAcquiredDelegatedPrefixAddress=</varname>.
+            Takes an IPv6 address. When set, the lower bits of the supplied address are combined with the upper bits of a
+            delegatad prefix received from the WAN interface by the <varname>IPv6PrefixDelegation=</varname> prefixes to
+            form a complete address.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>PrefixDelegationHint=</varname></term>
           <listitem>
index f86fdc2103611f1af4f18c710f6cde21416c8cac..f0766f0af7644b9e58cd7e39233f45128168fc33 100644 (file)
@@ -55,23 +55,25 @@ static int dhcp6_get_preferred_delegated_prefix(
                 const struct in6_addr *pd_prefix,
                 uint8_t pd_prefix_len,
                 struct in6_addr *ret_addr) {
-        int r;
-        union in_addr_union pd_prefix_union = {
-                .in6 = *pd_prefix,
-        };
-        int64_t subnet_id = link->network->router_prefix_subnet_id;
-
-        assert(pd_prefix_len <= 64);
 
+        int64_t subnet_id = link->network->router_prefix_subnet_id;
         uint8_t prefix_bits = 64 - pd_prefix_len;
         uint64_t n_prefixes = UINT64_C(1) << prefix_bits;
         _cleanup_free_ char *assigned_buf = NULL;
-
+        union in_addr_union pd_prefix_union = {
+                .in6 = *pd_prefix,
+        };
         /* We start off with the original PD prefix we have been assigned and
          * iterate from there */
         union in_addr_union prefix = {
                 .in6 = *pd_prefix,
         };
+        int r;
+
+        assert(pd_prefix_len <= 64);
+        assert(manager);
+        assert(link);
+        assert(link->network);
 
         if (subnet_id >= 0) {
                 /* If the link has a preference for a particular subnet id try to allocate that */
@@ -222,11 +224,11 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, Lin
 }
 
 int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) {
-        int r;
-        sd_dhcp6_lease *lease;
+        uint32_t lifetime_preferred, lifetime_valid;
         union in_addr_union pd_prefix;
         uint8_t pd_prefix_len;
-        uint32_t lifetime_preferred, lifetime_valid;
+        sd_dhcp6_lease *lease;
+        int r;
 
         r = sd_dhcp6_client_get_lease(client, &lease);
         if (r < 0)
@@ -275,17 +277,17 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link,
                                       uint32_t lifetime_preferred,
                                       uint32_t lifetime_valid,
                                       bool assign_preferred_subnet_id) {
-        Iterator i;
-        Link *link;
+
+        _cleanup_free_ char *assigned_buf = NULL, *buf = NULL;
         Manager *manager = dhcp6_link->manager;
         union in_addr_union prefix = {
                 .in6 = *pd_prefix,
         };
+        bool pool_depleted = false;
         uint64_t n_prefixes;
-        _cleanup_free_ char *buf = NULL;
-        _cleanup_free_ char *assigned_buf = NULL;
+        Iterator i;
+        Link *link;
         int r;
-        bool pool_depleted = false;
 
         assert(manager);
         assert(pd_prefix_len <= 64);
@@ -364,11 +366,11 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link
 }
 
 static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) {
-        int r;
-        sd_dhcp6_lease *lease;
+        uint32_t lifetime_preferred, lifetime_valid;
         union in_addr_union pd_prefix;
+        sd_dhcp6_lease *lease;
         uint8_t pd_prefix_len;
-        uint32_t lifetime_preferred, lifetime_valid;
+        int r;
 
         r = sd_dhcp6_client_get_lease(client, &lease);
         if (r < 0)
@@ -1045,6 +1047,7 @@ static int dhcp6_assign_delegated_prefix(Link *link,
                                          uint8_t prefix_len,
                                          uint32_t lifetime_preferred,
                                          uint32_t lifetime_valid) {
+
         _cleanup_(address_freep) Address *address = NULL;
         int r;
 
@@ -1057,12 +1060,17 @@ static int dhcp6_assign_delegated_prefix(Link *link,
 
         r = address_new(&address);
         if (r < 0)
-                return log_link_error_errno(link, r, "Could not allocate address: %m");
+                return log_link_error_errno(link, r, "Failed to allocate address for DHCPv6 delegated prefix: %m");
 
         address->in_addr.in6 = *prefix;
-        r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to generate EUI64 address for DHCPv6 acquired delegated prefix: %m");
+
+        if (!in_addr_is_null(AF_INET6, &link->network->dhcp6_delegation_prefix_token))
+                memcpy(&address->in_addr.in6.s6_addr + 8, &link->network->dhcp6_delegation_prefix_token.in6.s6_addr + 8, 8);
+        else {
+                r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
+                if (r < 0)
+                        return log_link_warning_errno(link, r, "Failed to generate EUI64 address for acquired DHCPv6 delegated prefix: %m");
+        }
 
         address->prefixlen = prefix_len;
         address->family = AF_INET6;
@@ -1073,7 +1081,7 @@ static int dhcp6_assign_delegated_prefix(Link *link,
 
         r = address_configure(address, link, address_handler, true);
         if (r < 0)
-                return log_link_warning_errno(link, r, "Could not set addresses: %m");
+                return log_link_warning_errno(link, r, "Failed to set acquired DHCPv6 delegated prefix address: %m");
         if (r > 0)
                 link->address_messages++;
 
@@ -1126,6 +1134,7 @@ int config_parse_dhcp6_mud_url(
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         _cleanup_free_ char *unescaped = NULL;
         Network *network = data;
         int r;
@@ -1155,3 +1164,44 @@ int config_parse_dhcp6_mud_url(
 
         return free_and_replace(network->dhcp6_mudurl, unescaped);
 }
+
+int config_parse_dhcp6_delegated_prefix_token(
+                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 = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                network->dhcp6_delegation_prefix_token = IN_ADDR_NULL;
+                return 0;
+        }
+
+        r = in_addr_from_string(AF_INET6, rvalue, &network->dhcp6_delegation_prefix_token);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r,
+                           "Failed to parse DHCPv6 %s, ignoring: %s", lvalue, rvalue);
+                return 0;
+        }
+
+        if (in_addr_is_null(AF_INET6, &network->dhcp6_delegation_prefix_token)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0,
+                           "DHCPv6 %s cannot be the ANY address, ignoring: %s", lvalue, rvalue);
+                return 0;
+        }
+
+        return 0;
+}
index e7c180897bff86047b738bb0feea41bd7066be5e..913410fe77b16f7f78724b43518248c87c4a83a6 100644 (file)
@@ -16,3 +16,4 @@ int dhcp6_prefix_remove(Manager *m, struct in6_addr *addr);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_delegated_prefix_token);
index 5c2a4d36a11bbe6e731816f4c1bb65af1ca07cc1..84ea5d552e9997367cce109c4b2884010ac25c88 100644 (file)
@@ -203,6 +203,7 @@ DHCPv6.VendorClass,                          config_parse_dhcp_vendor_class,
 DHCPv6.SendVendorOption,                     config_parse_dhcp_send_option,                            AF_INET6,                      offsetof(Network, dhcp6_client_send_vendor_options)
 DHCPv6.ForceDHCPv6PDOtherInformation,        config_parse_bool,                                        0,                             offsetof(Network, dhcp6_force_pd_other_information)
 DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool,                                        0,                             offsetof(Network, dhcp6_pd_assign_prefix)
+DHCPv6.AssignAcquiredDelegatedPrefixToken,   config_parse_dhcp6_delegated_prefix_token,                0,                             0
 DHCPv6.PrefixDelegationHint,                 config_parse_dhcp6_pd_hint,                               0,                             0
 DHCPv6.WithoutRA,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp6_without_ra)
 DHCPv6.SendOption,                           config_parse_dhcp_send_option,                            AF_INET6,                      offsetof(Network, dhcp6_client_send_options)
index 590162286221609f35bbefcc52fdff3a35daa952..00ecac6ca9421d60d3499eac5c38c01b06cdcc3e 100644 (file)
@@ -201,6 +201,7 @@ struct Network {
                                                   RA flag is set, see RFC 7084,
                                                   WPD-4 */
         bool dhcp6_pd_assign_prefix;
+        union in_addr_union dhcp6_delegation_prefix_token;
 
         /* Bridge Support */
         int use_bpdu;
index 478b574418efbc1206c8651e28f5229c7cf78afc..a6ef817360fc018ab33f4d8918ba06c86bfa7921 100644 (file)
@@ -120,6 +120,7 @@ RequestOptions=
 UserClass=
 VendorClass=
 AssignAcquiredDelegatedPrefixAddress=
+AssignAcquiredDelegatedPrefixToken=
 SendVendorOption=
 RouteMetric=
 [Route]