]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: honor M or O flag in RA even if IPv6AcceptRA.DHCPv6Cleint=always
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 16 Nov 2020 07:25:43 +0000 (16:25 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 16 Nov 2020 09:59:24 +0000 (18:59 +0900)
Follow-up for ac24e418d9bc988ecf114c464701b35934948178.

The original motivation of the commit and RFE #15339 is to start dhcpv6
client in managed mode when neither M nor O flag is set in the RA.
But, previously, if the setting is set to "always", then the DHCPv6
client is always started in managed mode even if O flag is set in the
RA. Such the behavior breaks RFC 7084.

man/systemd.network.xml
src/network/networkd-ndisc.c

index 9edf009c085142d77e2d2ab4062bd871218f672f..6229e206150ecc97628fc444d1239ef3553651b8 100644 (file)
@@ -2086,9 +2086,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
         <varlistentry>
           <term><varname>DHCPv6Client=</varname></term>
           <listitem>
-            <para>Takes a boolean, or the special value <literal>always</literal>. When true (the default), the DHCPv6 client will be started when the
-            RA has the managed or other information flag. If set to <literal>always</literal>, the DHCPv6 client will be started even if there is no
-            managed or other information flag in the RA.</para>
+            <para>Takes a boolean, or the special value <literal>always</literal>. When true or
+            <literal>always</literal>, the DHCPv6 client will be started when the RA has the managed or
+            other information flag. If set to <literal>always</literal>, the DHCPv6 client will also be
+            started in managed mode when neither managed nor other information flag is set in the RA.
+            Defaults to true.</para>
           </listitem>
         </varlistentry>
       </variablelist>
index f4bea080701a152b854e6f3cce39d619cd703d93..d2aa3db175fc79da8cf6407cfbc1c982ce6126bb 100644 (file)
@@ -1163,13 +1163,17 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to get RA flags: %m");
 
-        if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) && link->network->ipv6_accept_ra_start_dhcp6_client)) {
+        if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) &&
+             link->network->ipv6_accept_ra_start_dhcp6_client != IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO) ||
+            link->network->ipv6_accept_ra_start_dhcp6_client == IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS) {
 
-                if (link->network->ipv6_accept_ra_start_dhcp6_client == IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS)
-                        r = dhcp6_request_address(link, false);
-                else
+                if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))
                         /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
                         r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
+                else
+                        /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode
+                         * even if router does not have M or O flag. */
+                        r = dhcp6_request_address(link, false);
                 if (r < 0 && r != -EBUSY)
                         return log_link_error_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
                 else