From: Yu Watanabe Date: Sat, 15 Jun 2019 23:58:39 +0000 (+0900) Subject: network: split operational states into carrier and address states X-Git-Tag: v243-rc1~260^2~5 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=commitdiff_plain;h=1678fbb3c5016504a628dc90a45b3f8fbe4fc55d;ds=sidebyside network: split operational states into carrier and address states This should not change any behavior. The new states will be exposed by later commits. --- diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h index 6936fd536b9..601d00146a4 100644 --- a/src/libsystemd/sd-network/network-util.h +++ b/src/libsystemd/sd-network/network-util.h @@ -20,5 +20,24 @@ typedef enum LinkOperationalState { _LINK_OPERSTATE_INVALID = -1 } LinkOperationalState; +typedef enum LinkCarrierState { + LINK_CARRIER_STATE_OFF = LINK_OPERSTATE_OFF, + LINK_CARRIER_STATE_NO_CARRIER = LINK_OPERSTATE_NO_CARRIER, + LINK_CARRIER_STATE_DORMANT = LINK_OPERSTATE_DORMANT, + LINK_CARRIER_STATE_DEGRADED_CARRIER = LINK_OPERSTATE_DEGRADED_CARRIER, + LINK_CARRIER_STATE_CARRIER = LINK_OPERSTATE_CARRIER, + LINK_CARRIER_STATE_ENSLAVED = LINK_OPERSTATE_ENSLAVED, + _LINK_CARRIER_STATE_MAX, + _LINK_CARRIER_STATE_INVALID = -1 +} LinkCarrierState; + +typedef enum LinkAddressState { + LINK_ADDRESS_STATE_OFF, + LINK_ADDRESS_STATE_DEGRADED, + LINK_ADDRESS_STATE_ROUTABLE, + _LINK_ADDRESS_STATE_MAX, + _LINK_ADDRESS_STATE_INVALID = -1 +} LinkAddressState; + const char* link_operstate_to_string(LinkOperationalState s) _const_; LinkOperationalState link_operstate_from_string(const char *s) _pure_; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 56e36b7d6b5..46ebc2b5971 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -360,63 +360,85 @@ static void link_update_master_operstate(Link *link, NetDev *netdev) { void link_update_operstate(Link *link, bool also_update_master) { LinkOperationalState operstate; + LinkCarrierState carrier_state; + LinkAddressState address_state; + uint8_t scope = RT_SCOPE_NOWHERE; + Address *address; Iterator i; assert(link); if (link->kernel_operstate == IF_OPER_DORMANT) - operstate = LINK_OPERSTATE_DORMANT; + carrier_state = LINK_CARRIER_STATE_DORMANT; else if (link_has_carrier(link)) { - Address *address; - uint8_t scope = RT_SCOPE_NOWHERE; - - /* if we have carrier, check what addresses we have */ - SET_FOREACH(address, link->addresses, i) { - if (!address_is_ready(address)) - continue; - - if (address->scope < scope) - scope = address->scope; - } - - /* for operstate we also take foreign addresses into account */ - SET_FOREACH(address, link->addresses_foreign, i) { - if (!address_is_ready(address)) - continue; - - if (address->scope < scope) - scope = address->scope; - } - - if (scope < RT_SCOPE_SITE) - /* universally accessible addresses found */ - operstate = LINK_OPERSTATE_ROUTABLE; - else if (scope < RT_SCOPE_HOST) - /* only link or site local addresses found */ - operstate = LINK_OPERSTATE_DEGRADED; + if (link_is_enslaved(link)) + carrier_state = LINK_CARRIER_STATE_ENSLAVED; else - /* no useful addresses found */ - operstate = LINK_OPERSTATE_CARRIER; + carrier_state = LINK_CARRIER_STATE_CARRIER; } else if (link->flags & IFF_UP) - operstate = LINK_OPERSTATE_NO_CARRIER; + carrier_state = LINK_CARRIER_STATE_NO_CARRIER; else - operstate = LINK_OPERSTATE_OFF; + carrier_state = LINK_CARRIER_STATE_OFF; - if (IN_SET(operstate, LINK_OPERSTATE_DEGRADED, LINK_OPERSTATE_CARRIER) && - link_is_enslaved(link)) - operstate = LINK_OPERSTATE_ENSLAVED; - - if (operstate >= LINK_OPERSTATE_CARRIER) { + if (carrier_state >= LINK_CARRIER_STATE_CARRIER) { Link *slave; SET_FOREACH(slave, link->slaves, i) { link_update_operstate(slave, false); - if (slave->operstate < LINK_OPERSTATE_CARRIER) - operstate = LINK_OPERSTATE_DEGRADED_CARRIER; + if (slave->carrier_state < LINK_CARRIER_STATE_CARRIER) + carrier_state = LINK_CARRIER_STATE_DEGRADED_CARRIER; } } + SET_FOREACH(address, link->addresses, i) { + if (!address_is_ready(address)) + continue; + + if (address->scope < scope) + scope = address->scope; + } + + /* for operstate we also take foreign addresses into account */ + SET_FOREACH(address, link->addresses_foreign, i) { + if (!address_is_ready(address)) + continue; + + if (address->scope < scope) + scope = address->scope; + } + + if (scope < RT_SCOPE_SITE) + /* universally accessible addresses found */ + address_state = LINK_ADDRESS_STATE_ROUTABLE; + else if (scope < RT_SCOPE_HOST) + /* only link or site local addresses found */ + address_state = LINK_ADDRESS_STATE_DEGRADED; + else + /* no useful addresses found */ + address_state = LINK_ADDRESS_STATE_OFF; + + /* Mapping of address and carrier state vs operational state + * carrier state + * | off | no-carrier | dormant | degraded-carrier | carrier | enslaved + * ------------------------------------------------------------------------------ + * off | off | no-carrier | dormant | degraded-carrier | carrier | enslaved + * address_state degraded | off | no-carrier | dormant | degraded-carrier | degraded | enslaved + * routable | off | no-carrier | dormant | degraded-carrier | routable | routable + */ + + if (carrier_state < LINK_CARRIER_STATE_CARRIER || address_state == LINK_ADDRESS_STATE_OFF) + operstate = (LinkOperationalState) carrier_state; + else if (address_state == LINK_ADDRESS_STATE_ROUTABLE) + operstate = LINK_OPERSTATE_ROUTABLE; + else if (carrier_state == LINK_CARRIER_STATE_CARRIER) + operstate = LINK_OPERSTATE_DEGRADED; + else + operstate = LINK_OPERSTATE_ENSLAVED; + + link->carrier_state = carrier_state; + link->address_state = address_state; + if (link->operstate != operstate) { link->operstate = operstate; link_send_changed(link, "OperationalState", NULL); diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 05b88356cfd..ac1532c066f 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -60,6 +60,8 @@ typedef struct Link { LinkState state; LinkOperationalState operstate; + LinkCarrierState carrier_state; + LinkAddressState address_state; unsigned address_messages; unsigned address_label_messages;