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.
This commit is contained in:
Yu Watanabe
2023-05-30 17:39:11 +09:00
parent 195b83edf8
commit 9e7d91ed97
2 changed files with 16 additions and 5 deletions
+15 -5
View 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) &&
@@ -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')