Skip to content

Commit

Permalink
network: rewrite dynamic addressing protocol checkers in link_check_r…
Browse files Browse the repository at this point in the history
…eady()

Notable change is,
- UseAddress=no in [DHCPv6],
- Assign=no in [DHCPPrefixDelegation], and
- UseAutonomousPrefix=no in [IPv6AcceptRA]
are gracefully handled now.
  • Loading branch information
yuwata committed May 30, 2023
1 parent e4086f7 commit 5f950e5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 41 deletions.
23 changes: 23 additions & 0 deletions src/network/networkd-address.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,29 @@ bool address_is_ready(const Address *a) {
return true;
}

bool link_check_addresses_ready(Link *link, NetworkConfigSource source) {
Address *a;
bool has = false;

assert(link);

/* Check if all addresses on the interface are ready. If there is no address, this will return false. */

SET_FOREACH(a, link->addresses) {
if (source >= 0 && a->source != source)
continue;
if (address_is_marked(a))
continue;
if (!address_exists(a))
continue;
if (!address_is_ready(a))
return false;
has = true;
}

return has;
}

void link_mark_addresses(Link *link, NetworkConfigSource source) {
Address *a;

Expand Down
1 change: 1 addition & 0 deletions src/network/networkd-address.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ int address_remove(Address *address);
int address_remove_and_drop(Address *address);
int address_dup(const Address *src, Address **ret);
bool address_is_ready(const Address *a);
bool link_check_addresses_ready(Link *link, NetworkConfigSource source);
void address_set_broadcast(Address *a, Link *link);

DEFINE_SECTION_CLEANUP_FUNCTIONS(Address, address_free);
Expand Down
80 changes: 39 additions & 41 deletions src/network/networkd-link.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,47 +436,45 @@ 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__);

bool has_dynamic_address = false;
SET_FOREACH(a, link->addresses) {
if (address_is_marked(a))
continue;
if (!address_exists(a))
continue;
if (IN_SET(a->source,
NETWORK_CONFIG_SOURCE_IPV4LL,
NETWORK_CONFIG_SOURCE_DHCP4,
NETWORK_CONFIG_SOURCE_DHCP6,
NETWORK_CONFIG_SOURCE_DHCP_PD,
NETWORK_CONFIG_SOURCE_NDISC)) {
has_dynamic_address = true;
break;
}
}

if ((link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) ||
(link_dhcp_pd_is_enabled(link) && link->network->dhcp_pd_assign)) && !has_dynamic_address)
/* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */
return (void) log_link_debug(link, "%s(): DHCPv4, DHCPv6, DHCP-PD 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_ipv4ll_enabled(link) || link_dhcp4_enabled(link) ||
link_dhcp6_enabled(link) || link_dhcp_pd_is_enabled(link) ||
(!link->network->configure_without_carrier && link_ipv6_accept_ra_enabled(link))) {

if (!link->ipv4ll_address_configured && !link->dhcp4_configured &&
!link->dhcp6_configured && !link->dhcp_pd_configured && !link->ndisc_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(): IPv4LL:%s DHCPv4:%s DHCPv6:%s DHCP-PD:%s NDisc:%s",
__func__,
yes_no(link->ipv4ll_address_configured),
yes_no(link->dhcp4_configured),
yes_no(link->dhcp6_configured),
yes_no(link->dhcp_pd_configured),
yes_no(link->ndisc_configured));
}

/* 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) &&
!link_dhcp6_enabled(link) && !link_dhcp_pd_is_enabled(link) &&
(link->network->configure_without_carrier || !link_ipv6_accept_ra_enabled(link)))
goto ready;

bool ipv4ll_ready =
link_ipv4ll_enabled(link) && link->ipv4ll_address_configured &&
link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_IPV4LL);
bool dhcp4_ready =
link_dhcp4_enabled(link) && link->dhcp4_configured &&
link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP4);
bool dhcp6_ready =
link_dhcp6_enabled(link) && link->dhcp6_configured &&
(!link->network->dhcp6_use_address ||
link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP6));
bool dhcp_pd_ready =
link_dhcp_pd_is_enabled(link) && link->dhcp_pd_configured &&
(!link->network->dhcp_pd_assign ||
link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_DHCP_PD));
bool ndisc_ready =
link_ipv6_accept_ra_enabled(link) && link->ndisc_configured &&
(!link->network->ipv6_accept_ra_use_autonomous_prefix ||
link_check_addresses_ready(link, NETWORK_CONFIG_SOURCE_NDISC));

/* At least one dynamic addressing protocol is finished. */
if (!ipv4ll_ready && !dhcp4_ready && !dhcp6_ready && !dhcp_pd_ready && !ndisc_ready)
return (void) log_link_debug(link, "%s(): dynamic addressing protocols are enabled but none of them finished yet.", __func__);

log_link_debug(link, "%s(): IPv4LL:%s DHCPv4:%s DHCPv6:%s DHCP-PD:%s NDisc:%s",
__func__,
yes_no(ipv4ll_ready),
yes_no(dhcp4_ready),
yes_no(dhcp6_ready),
yes_no(dhcp_pd_ready),
yes_no(ndisc_ready));

ready:
link_set_state(link, LINK_STATE_CONFIGURED);
}

Expand Down

0 comments on commit 5f950e5

Please sign in to comment.