summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-06-16 08:58:39 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-06-16 23:17:23 +0900
commit1678fbb3c5016504a628dc90a45b3f8fbe4fc55d (patch)
treee3fc2f5e4a8cf0f6961a16c8a1d5ba693d6b9f87
parent46606fdda920a630e1f40f25135b7e26e4f58a0c (diff)
downloadsystemd-1678fbb3c5016504a628dc90a45b3f8fbe4fc55d.tar.gz
network: split operational states into carrier and address states
This should not change any behavior. The new states will be exposed by later commits.
-rw-r--r--src/libsystemd/sd-network/network-util.h19
-rw-r--r--src/network/networkd-link.c100
-rw-r--r--src/network/networkd-link.h2
3 files changed, 82 insertions, 39 deletions
diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h
index 6936fd536b..601d00146a 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 56e36b7d6b..46ebc2b597 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 05b88356cf..ac1532c066 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;