diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 9bad97b07b8..dfae8119e73 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -267,15 +267,8 @@
when determining whether the system is online (including when running
systemd-networkd-wait-online). When no, the network is
ignored when determining the online state. When a minimum operational state and an optional
- maximum operational state are set, yes is implied, and this controls the
- minimum and maximum operational state required for the network interface to be considered
- online.
-
- When yes is specified for a CAN device,
- systemd-networkd-wait-online deems that the interface is online when its
- operational state becomes carrier. For an interface with other type, e.g.
- ether, the interface is deened online when its online state is
- degraded or routable.
+ maximum operational state are set, systemd-networkd-wait-online deems that the
+ interface is online when the operational state is in the specified range.
Defaults to yes when ActivationPolicy= is not
set, or set to up, always-up, or
@@ -290,6 +283,44 @@
skipped automatically by systemd-networkd-wait-online if
RequiredForOnline=no.
+ The boolean value yes is translated as follows;
+
+
+
+
+ carrier,
+
+
+
+
+
+
+ degraded-carrier with RequiredFamilyForOnline=any,
+
+
+
+
+
+
+ enslaved,
+
+
+
+
+
+
+ degraded.
+
+
+
+
+
+
+ This setting can be overridden by the command line option for
+ systemd-networkd-wait-online. See
+ systemd-networkd-wait-online.service8
+ for more details.
+
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 194d31eafe8..621f8592061 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -76,16 +76,48 @@ void link_required_operstate_for_online(Link *link, LinkOperationalStateRange *r
assert(ret);
if (link->network && operational_state_range_is_valid(&link->network->required_operstate_for_online))
+ /* If explicitly specified, use it as is. */
*ret = link->network->required_operstate_for_online;
else if (link->iftype == ARPHRD_CAN)
+ /* CAN devices do not support addressing, hence defaults to 'carrier'. */
*ret = (const LinkOperationalStateRange) {
.min = LINK_OPERSTATE_CARRIER,
.max = LINK_OPERSTATE_CARRIER,
};
+ else if (link->network && link->network->bond)
+ /* Bonding slaves do not support addressing. */
+ *ret = (const LinkOperationalStateRange) {
+ .min = LINK_OPERSTATE_ENSLAVED,
+ .max = LINK_OPERSTATE_ENSLAVED,
+ };
+ else if (STRPTR_IN_SET(link->kind, "batadv", "bond", "bridge", "vrf"))
+ /* Some of slave interfaces may be offline. */
+ *ret = (const LinkOperationalStateRange) {
+ .min = LINK_OPERSTATE_DEGRADED_CARRIER,
+ .max = LINK_OPERSTATE_ROUTABLE,
+ };
else
*ret = LINK_OPERSTATE_RANGE_DEFAULT;
}
+AddressFamily link_required_family_for_online(Link *link) {
+ assert(link);
+
+ if (link->network && link->network->required_family_for_online >= 0)
+ return link->network->required_family_for_online;
+
+ if (link->network && operational_state_range_is_valid(&link->network->required_operstate_for_online))
+ /* If RequiredForOnline= is explicitly specified, defaults to no. */
+ return ADDRESS_FAMILY_NO;
+
+ if (STRPTR_IN_SET(link->kind, "batadv", "bond", "bridge", "vrf"))
+ /* As the minimum required operstate for master interfaces is 'degraded-carrier',
+ * we should request an address assigned to the link for backward compatibility. */
+ return ADDRESS_FAMILY_YES;
+
+ return ADDRESS_FAMILY_NO;
+}
+
bool link_ipv6_enabled(Link *link) {
assert(link);
@@ -1877,7 +1909,7 @@ void link_update_operstate(Link *link, bool also_update_master) {
online_state = LINK_ONLINE_STATE_OFFLINE;
else {
- AddressFamily required_family = link->network->required_family_for_online;
+ AddressFamily required_family = link_required_family_for_online(link);
bool needs_ipv4 = required_family & ADDRESS_FAMILY_IPV4;
bool needs_ipv6 = required_family & ADDRESS_FAMILY_IPV6;
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 985670fcd2f..d81b45bd643 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -260,3 +260,4 @@ int link_flags_to_string_alloc(uint32_t flags, char **ret);
const char *kernel_operstate_to_string(int t) _const_;
void link_required_operstate_for_online(Link *link, LinkOperationalStateRange *ret);
+AddressFamily link_required_family_for_online(Link *link);
diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c
index 5b2e8a2de4f..859a28aa59f 100644
--- a/src/network/networkd-state-file.c
+++ b/src/network/networkd-state-file.c
@@ -637,7 +637,7 @@ static int link_save(Link *link) {
link_operstate_to_string(st.min), link_operstate_to_string(st.max));
fprintf(f, "REQUIRED_FAMILY_FOR_ONLINE=%s\n",
- link_required_address_family_to_string(link->network->required_family_for_online));
+ link_required_address_family_to_string(link_required_family_for_online(link)));
fprintf(f, "ACTIVATION_POLICY=%s\n",
activation_policy_to_string(link->network->activation_policy));