]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: DHCPv6 Assign delegated prefix to LAN interface
authorSusant Sahani <ssahani@vmware.com>
Sat, 4 Apr 2020 18:07:18 +0000 (20:07 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 29 May 2020 07:20:37 +0000 (16:20 +0900)
In DHCPv6-PD environment, where WAN interface requests IPv6 via DHCPv6,
receives the address as well as delegated prefixes, with LAN interfaces
serving those delegated prefixes in their router advertisement messages.
The LAN interfaces on the router themselves do not have
the IPv6 addresses assigned by networkd from the prefix it
serves on that interface. Now this patch enables it.

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

index 1eaa452786f1a73881f18598c2534c0751425cc4..e8f3f364f1e1fb058777285f672830c5cd3f7607 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>AssignAcquiredDelegatedPrefixAddress=</varname></term>
+          <listitem>
+            <para>Takes a boolean. Specifies whether to add an address from the delegated prefixes which are received
+            from the WAN interface by the <varname>IPv6PrefixDelegation=</varname>. When true (on LAN interfce), the EUI-64
+            algorithm will be used to form an interface identifier from the delegated prefixes. Defaults to true.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>PrefixDelegationHint=</varname></term>
           <listitem>
@@ -3301,7 +3310,10 @@ DHCP=ipv6</programlisting>
 Name=enp2s0
 
 [Network]
-IPv6PrefixDelegation=dhcpv6</programlisting>
+IPv6PrefixDelegation=dhcpv6
+
+[DHCPv6]
+AssignAcquiredDelegatedPrefixAddress=yes</programlisting>
 
       <para>This will enable IPv6 PD on the interface enp1s0 as an upstream interface where the
       DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.</para>
index b3ebdc8cd7095e61d65bc6f67d11a6c03c47a36f..d0972f3593dcff329f646833d21a39f552a0ec01 100644 (file)
@@ -26,6 +26,10 @@ static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr);
 static int dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link);
 static int dhcp6_prefix_remove_all(Manager *m, Link *link);
 static bool dhcp6_link_has_dhcpv6_prefix(Link *link);
+static int dhcp6_assign_delegated_prefix(Link *link, const struct in6_addr *prefix,
+                                         uint8_t prefix_len,
+                                         uint32_t lifetime_preferred,
+                                         uint32_t lifetime_valid);
 
 static bool dhcp6_get_prefix_delegation(Link *link) {
         if (!link->network)
@@ -191,6 +195,12 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
         if (r < 0)
                 return r;
 
+        if (link->network->dhcp6_pd_assign_prefix) {
+                r = dhcp6_assign_delegated_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
+                if (r < 0)
+                        return r;
+        }
+
         return sd_radv_start(radv);
 }
 
@@ -1018,3 +1028,43 @@ static bool dhcp6_link_has_dhcpv6_prefix(Link *link) {
 
         return false;
 }
+
+static int dhcp6_assign_delegated_prefix(Link *link,
+                                         const struct in6_addr *prefix,
+                                         uint8_t prefix_len,
+                                         uint32_t lifetime_preferred,
+                                         uint32_t lifetime_valid) {
+        _cleanup_(address_freep) Address *address = NULL;
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(prefix);
+
+        if (!link->network->dhcp6_pd_assign_prefix)
+                return 0;
+
+        r = address_new(&address);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not allocate address: %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");
+
+        address->prefixlen = prefix_len;
+        address->family = AF_INET6;
+        address->cinfo.ifa_prefered = lifetime_preferred;
+        address->cinfo.ifa_valid = lifetime_valid;
+
+        link_set_state(link, LINK_STATE_CONFIGURING);
+
+        r = address_configure(address, link, address_handler, true);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Could not set addresses: %m");
+        if (r > 0)
+                link->address_messages++;
+
+        return 0;
+}
index 484705f4882f71e9f6387560739b00f73af163b2..8a549110fa14dc4405e642a8d39cd46b76258fd6 100644 (file)
@@ -1173,7 +1173,7 @@ static int link_request_set_neighbors(Link *link) {
         return 0;
 }
 
-static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(rtnl);
index e8d67e0d64fc817a604fcdf3ec21ccbae4e8143a..c793a37df74bc276c7b02f1366c5bcc5d310df97 100644 (file)
@@ -228,6 +228,7 @@ int link_request_set_routes(Link *link);
 int link_request_set_nexthop(Link *link);
 
 int link_reconfigure(Link *link, bool force);
+int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_link_ipv6_address_gen_mode);
 
index 79799e7dde58dde8ddd26be127b2c354016b4036..d318b7d891ddaa9b4d83be68627ea6bb7aced30d 100644 (file)
@@ -199,6 +199,7 @@ DHCPv6.RequestOptions,                       config_parse_dhcp_request_options,
 DHCPv6.UserClass,                            config_parse_dhcp_user_class,                             AF_INET6,                      offsetof(Network, dhcp6_user_class)
 DHCPv6.VendorClass,                          config_parse_dhcp_vendor_class,                           0,                             offsetof(Network, dhcp6_vendor_class)
 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.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 781bbaa8811fd211f9e0ab6c16426fd3a9c816ac..ae466a23101d0155ee1bea18e25793aa893a4d0e 100644 (file)
@@ -412,6 +412,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .dhcp6_use_ntp = true,
                 .dhcp6_use_dns = true,
 
+                .dhcp6_pd_assign_prefix = true,
+
                 .dhcp_server_emit_dns = true,
                 .dhcp_server_emit_ntp = true,
                 .dhcp_server_emit_sip = true,
index 45b9df647d62ade73d0e134758e1009dd56f6811..441bba127326d48405286b4f74393c4532d503c6 100644 (file)
@@ -192,6 +192,7 @@ struct Network {
         bool dhcp6_force_pd_other_information; /* Start DHCPv6 PD also when 'O'
                                                   RA flag is set, see RFC 7084,
                                                   WPD-4 */
+        bool dhcp6_pd_assign_prefix;
 
         /* Bridge Support */
         int use_bpdu;
index 178bd9aaae3e82786992da3f7d288cc24f9835d8..a1a6cdd233042038601fc6ff096046b329210405 100644 (file)
@@ -119,6 +119,7 @@ SendOption=
 RequestOptions=
 UserClass=
 VendorClass=
+AssignAcquiredDelegatedPrefixAddress=
 [Route]
 Destination=
 Protocol=