]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not request dynamic addressing protocols finished when at least one stati... 27826/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 29 May 2023 03:56:30 +0000 (12:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 30 May 2023 08:39:11 +0000 (17:39 +0900)
The setting IPv6AcceptRA= is defaults to yes, hence, even if a .network
file for an interface has static IP address configuration, it may takes
few seconds for the interface being configured state, as NDisc for the
interface needs to be finished. That makes wait-online.service
needlessly slow. Typically, such delay is not necessary for statically
configured networks.

Let's make the required condition slightly relaxed; if a .network file
has static IP address configurations, then let's make the matching
interface enter the 'configured' state soon after the static addresses
configured on the interface.

Note, this does not change the default for IPv6AcceptRA=, hence, NDisc
still runs on interfaces by default. So, addresses, routes, DNS servers,
and so on based on RA will be assigned on interfaces later.

Strictly speaking, this breaks backward compatibility, but the previous
behavior is not clearly documented. If a user requested both static
IPv4 address and IPv6 SLAAC address configured before an interface being
entered to the 'configured' state, then '--ipv6' for wait-online can be
used. So, the behavior change should not cause severe regression.

Closes #27779.

src/network/networkd-link.c
test/test-network/systemd-networkd-tests.py

index ec6d03ff02bcf86dc531878ab7376a6855d22562..d16090dbcd20915bd1d8570b304968bed244d731 100644 (file)
@@ -398,11 +398,6 @@ void link_check_ready(Link *link) {
         if (!link->static_addresses_configured)
                 return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__);
 
-        SET_FOREACH(a, link->addresses)
-                if (!address_is_ready(a))
-                        return (void) log_link_debug(link, "%s(): address %s is not ready.", __func__,
-                                                     IN_ADDR_PREFIX_TO_STRING(a->family, &a->in_addr, a->prefixlen));
-
         if (!link->static_address_labels_configured)
                 return (void) log_link_debug(link, "%s(): static address labels are not configured.", __func__);
 
@@ -436,6 +431,21 @@ void link_check_ready(Link *link) {
             !in6_addr_is_set(&link->ipv6ll_address))
                 return (void) log_link_debug(link, "%s(): IPv6LL is not configured yet.", __func__);
 
+        /* All static addresses must be ready. */
+        bool has_static_address = false;
+        SET_FOREACH(a, link->addresses) {
+                if (a->source != NETWORK_CONFIG_SOURCE_STATIC)
+                        continue;
+                if (!address_is_ready(a))
+                        return (void) log_link_debug(link, "%s(): static address %s is not ready.", __func__,
+                                                     IN_ADDR_PREFIX_TO_STRING(a->family, &a->in_addr, a->prefixlen));
+                has_static_address = true;
+        }
+
+        /* If at least one static address is requested, do not request that dynamic addressing protocols are finished. */
+        if (has_static_address)
+                goto ready;
+
         /* If no dynamic addressing protocol enabled, assume the interface is ready.
          * Note, ignore NDisc when ConfigureWithoutCarrier= is enabled, as IPv6AcceptRA= is enabled by default. */
         if (!link_ipv4ll_enabled(link) && !link_dhcp4_enabled(link) &&
index 8b01718d55e649379b602dbea496f8262194f2eb..2fd3f10021d2866b7a6f2a238b4bf9623d8da701 100755 (executable)
@@ -4676,6 +4676,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
                       '--dhcp-alternate-port=67,5555',
                       ipv4_range='192.168.5.110,192.168.5.119')
         self.wait_online(['veth99:routable', 'veth-peer:routable'])
+        self.wait_address('veth99', r'inet 192.168.5.11[0-9]*/24', ipv='-4')
 
         print('## ip address show dev veth99 scope global')
         output = check_output('ip address show dev veth99 scope global')