]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: always check dynamic address assignments before entering configured state 19894/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Jun 2021 11:34:17 +0000 (20:34 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Jun 2021 23:51:16 +0000 (08:51 +0900)
Previously (v248 or earlier), even if no static address is configured,
the link did not enter configured state, as e.g. Link::static_addresses_configured
is false until the link gained its carrier.
But, after the commit 1187fc337577cecd685d331eeab656be186ba3b2, the
situation was changed. Static addresses, routes, and etc are requested even
if the link does not have its carrier, and thus the link enters configured
state when no static address and etc are specified.

This makes the link does not enter configured state before it gains its
carrier when at least one of dynamic address assignment protocols (e.g.
DHCP) except for NDISC is enabled.

Note that, unfortunately, netplan always enables ConfigureWithoutCarrier=
for all virtual devices, e.g. bridge. See,
https://github.com/canonical/netplan/commit/978e20f902f6b92a46dc6e0050e2172e834e4617
So, we need to support e.g. the following strange config:
```
[Netowkr]
ConfigureWithoutCarrier=yes
DHCP=yes
```

Fixes #19855.

src/network/networkd-link.c

index 911fb9b302c2581d1b99f3df261aa5a101ddc1d1..f198baa8770c81f45b642f619adfc257e069a2f1 100644 (file)
@@ -469,46 +469,49 @@ void link_check_ready(Link *link) {
         if (!link->sr_iov_configured)
                 return (void) log_link_debug(link, "%s(): SR-IOV is not configured.", __func__);
 
-        if (link_has_carrier(link) || !link->network->configure_without_carrier) {
-                bool has_ndisc_address = false;
-                NDiscAddress *n;
-
-                if (link_ipv6ll_enabled(link) && !in6_addr_is_set(&link->ipv6ll_address))
-                        return (void) log_link_debug(link, "%s(): IPv6LL is not configured yet.", __func__);
-
-                SET_FOREACH(n, link->ndisc_addresses)
-                        if (!n->marked) {
-                                has_ndisc_address = true;
-                                break;
-                        }
+        /* IPv6LL is assigned after the link gains its carrier. */
+        if (!link->network->configure_without_carrier &&
+            link_ipv6ll_enabled(link) &&
+            !in6_addr_is_set(&link->ipv6ll_address))
+                return (void) log_link_debug(link, "%s(): IPv6LL is not configured yet.", __func__);
+
+        bool has_ndisc_address = false;
+        NDiscAddress *n;
+        SET_FOREACH(n, link->ndisc_addresses)
+                if (!n->marked) {
+                        has_ndisc_address = true;
+                        break;
+                }
 
-                if ((link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) || link_ipv4ll_enabled(link)) &&
-                    !link->dhcp_address && set_isempty(link->dhcp6_addresses) && !has_ndisc_address &&
+        if ((link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) || link_ipv4ll_enabled(link)) &&
+            !link->dhcp_address && set_isempty(link->dhcp6_addresses) && !has_ndisc_address &&
+            !link->ipv4ll_address_configured)
+                /* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */
+                return (void) log_link_debug(link, "%s(): DHCP4, DHCP6 or IPv4LL is enabled but no dynamic address is assigned yet.", __func__);
+
+        /* Ignore NDisc when ConfigureWithoutCarrier= is enabled, as IPv6AcceptRA= is enabled by default. */
+        if (link_dhcp4_enabled(link) || link_dhcp6_enabled(link) || link_dhcp6_pd_is_enabled(link) ||
+            (!link->network->configure_without_carrier && link_ipv6_accept_ra_enabled(link)) ||
+            link_ipv4ll_enabled(link)) {
+
+                if (!link->dhcp4_configured &&
+                    !(link->dhcp6_address_configured && link->dhcp6_route_configured) &&
+                    !(link->dhcp6_pd_address_configured && link->dhcp6_pd_route_configured) &&
+                    !(link->ndisc_addresses_configured && link->ndisc_routes_configured) &&
                     !link->ipv4ll_address_configured)
-                        /* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */
-                        return (void) log_link_debug(link, "%s(): DHCP4, DHCP6 or IPv4LL is enabled but no dynamic address is assigned yet.", __func__);
-
-                if (link_dhcp4_enabled(link) || link_dhcp6_enabled(link) || link_dhcp6_pd_is_enabled(link) ||
-                    link_ipv6_accept_ra_enabled(link) || link_ipv4ll_enabled(link)) {
-                        if (!link->dhcp4_configured &&
-                            !(link->dhcp6_address_configured && link->dhcp6_route_configured) &&
-                            !(link->dhcp6_pd_address_configured && link->dhcp6_pd_route_configured) &&
-                            !(link->ndisc_addresses_configured && link->ndisc_routes_configured) &&
-                            !link->ipv4ll_address_configured)
-                                /* When DHCP[46], NDisc, or IPv4LL is enabled, at least one protocol must be finished. */
-                                return (void) log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__);
-
-                        log_link_debug(link, "%s(): dhcp4:%s ipv4ll:%s dhcp6_addresses:%s dhcp_routes:%s dhcp_pd_addresses:%s dhcp_pd_routes:%s ndisc_addresses:%s ndisc_routes:%s",
-                                       __func__,
-                                       yes_no(link->dhcp4_configured),
-                                       yes_no(link->ipv4ll_address_configured),
-                                       yes_no(link->dhcp6_address_configured),
-                                       yes_no(link->dhcp6_route_configured),
-                                       yes_no(link->dhcp6_pd_address_configured),
-                                       yes_no(link->dhcp6_pd_route_configured),
-                                       yes_no(link->ndisc_addresses_configured),
-                                       yes_no(link->ndisc_routes_configured));
-                }
+                        /* When DHCP[46], NDisc, or IPv4LL is enabled, at least one protocol must be finished. */
+                        return (void) log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__);
+
+                log_link_debug(link, "%s(): dhcp4:%s ipv4ll:%s dhcp6_addresses:%s dhcp_routes:%s dhcp_pd_addresses:%s dhcp_pd_routes:%s ndisc_addresses:%s ndisc_routes:%s",
+                               __func__,
+                               yes_no(link->dhcp4_configured),
+                               yes_no(link->ipv4ll_address_configured),
+                               yes_no(link->dhcp6_address_configured),
+                               yes_no(link->dhcp6_route_configured),
+                               yes_no(link->dhcp6_pd_address_configured),
+                               yes_no(link->dhcp6_pd_route_configured),
+                               yes_no(link->ndisc_addresses_configured),
+                               yes_no(link->ndisc_routes_configured));
         }
 
         link_set_state(link, LINK_STATE_CONFIGURED);