From 9e7d91ed97a008a47e347d99b02de376d55d3449 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 29 May 2023 12:56:30 +0900 Subject: [PATCH] network: do not request dynamic addressing protocols finished when at least one static address is configured 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 | 20 +++++++++++++++----- test/test-network/systemd-networkd-tests.py | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ec6d03ff02b..d16090dbcd2 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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) && diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 8b01718d55e..2fd3f10021d 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -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') -- 2.47.3