networkd/sd-network: extend operational states
Expose states 'degraded' or 'routable' if a link has a site/link-local or a routable address, respectively.
This commit is contained in:
parent
bcb7a07e0a
commit
e375dcde72
|
@ -1253,9 +1253,9 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
|
|||
if (r < 0)
|
||||
/* if we got a message without operstate, take it to mean
|
||||
the state was unchanged */
|
||||
operstate = link->operstate;
|
||||
operstate = link->kernel_operstate;
|
||||
|
||||
if ((link->flags == flags) && (link->operstate == operstate))
|
||||
if ((link->flags == flags) && (link->kernel_operstate == operstate))
|
||||
return 0;
|
||||
|
||||
if (link->flags != flags) {
|
||||
|
@ -1299,13 +1299,13 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
|
|||
unknown_flags_removed);
|
||||
}
|
||||
|
||||
carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
|
||||
carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
|
||||
link_has_carrier(flags, operstate);
|
||||
carrier_lost = link_has_carrier(link->flags, link->operstate) &&
|
||||
carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
|
||||
!link_has_carrier(flags, operstate);
|
||||
|
||||
link->flags = flags;
|
||||
link->operstate = operstate;
|
||||
link->kernel_operstate = operstate;
|
||||
|
||||
link_save(link);
|
||||
|
||||
|
@ -1663,7 +1663,7 @@ static int link_configure(Link *link) {
|
|||
}
|
||||
}
|
||||
|
||||
if (link_has_carrier(link->flags, link->operstate)) {
|
||||
if (link_has_carrier(link->flags, link->kernel_operstate)) {
|
||||
r = link_acquire_conf(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1750,7 +1750,13 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
|
|||
|
||||
r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
|
||||
if (r < 0) {
|
||||
log_warning_link(link, "rtnl: recevied address with invalid prefixlen, ignoring");
|
||||
log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_addr_get_scope(message, &address->scope);
|
||||
if (r < 0) {
|
||||
log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1986,10 +1992,39 @@ static void serialize_addresses(FILE *f, const char *key, Address *address) {
|
|||
fputs("\n", f);
|
||||
}
|
||||
|
||||
static void link_update_operstate(Link *link) {
|
||||
|
||||
assert(link);
|
||||
|
||||
if (link->kernel_operstate == IF_OPER_DORMANT)
|
||||
link->operstate = LINK_OPERSTATE_DORMANT;
|
||||
else if (link_has_carrier(link->flags, link->kernel_operstate)) {
|
||||
Address *address;
|
||||
uint8_t scope = RT_SCOPE_NOWHERE;
|
||||
|
||||
/* if we have carrier, check what addresses we have */
|
||||
LIST_FOREACH(addresses, address, link->addresses) {
|
||||
if (address->scope < scope)
|
||||
scope = address->scope;
|
||||
}
|
||||
|
||||
if (scope < RT_SCOPE_SITE)
|
||||
/* universally accessible addresses found */
|
||||
link->operstate = LINK_OPERSTATE_ROUTABLE;
|
||||
else if (scope < RT_SCOPE_HOST)
|
||||
/* only link or site local addresses found */
|
||||
link->operstate = LINK_OPERSTATE_DEGRADED;
|
||||
else
|
||||
/* no useful addresses found */
|
||||
link->operstate = LINK_OPERSTATE_CARRIER;
|
||||
} else
|
||||
link->operstate = LINK_OPERSTATE_UNKNOWN;
|
||||
}
|
||||
|
||||
int link_save(Link *link) {
|
||||
_cleanup_free_ char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *admin_state, *oper_state = "unknown";
|
||||
const char *admin_state, *oper_state;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
@ -1997,6 +2032,8 @@ int link_save(Link *link) {
|
|||
assert(link->lease_file);
|
||||
assert(link->manager);
|
||||
|
||||
link_update_operstate(link);
|
||||
|
||||
r = manager_save(link->manager);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -2009,10 +2046,8 @@ int link_save(Link *link) {
|
|||
admin_state = link_state_to_string(link->state);
|
||||
assert(admin_state);
|
||||
|
||||
if (link->operstate == IF_OPER_DORMANT)
|
||||
oper_state = "dormant";
|
||||
else if (link_has_carrier(link->flags, link->operstate))
|
||||
oper_state = "carrier";
|
||||
oper_state = link_operstate_to_string(link->operstate);
|
||||
assert(oper_state);
|
||||
|
||||
r = fopen_temporary(link->state_file, &f, &temp_path);
|
||||
if (r < 0)
|
||||
|
@ -2074,3 +2109,13 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
|||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||
|
||||
static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
|
||||
[LINK_OPERSTATE_UNKNOWN] = "unknown",
|
||||
[LINK_OPERSTATE_DORMANT] = "dormant",
|
||||
[LINK_OPERSTATE_CARRIER] = "carrier",
|
||||
[LINK_OPERSTATE_DEGRADED] = "degraded",
|
||||
[LINK_OPERSTATE_ROUTABLE] = "routable",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
|
||||
|
|
|
@ -424,8 +424,8 @@ int manager_save(Manager *m) {
|
|||
Iterator i;
|
||||
_cleanup_free_ char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *oper_state = "unknown";
|
||||
bool dormant = false, carrier = false;
|
||||
LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
|
||||
const char *operstate_str;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
@ -435,16 +435,12 @@ int manager_save(Manager *m) {
|
|||
if (link->flags & IFF_LOOPBACK)
|
||||
continue;
|
||||
|
||||
if (link_has_carrier(link->flags, link->operstate))
|
||||
carrier = true;
|
||||
else if (link->operstate == IF_OPER_DORMANT)
|
||||
dormant = true;
|
||||
if (link->operstate > operstate)
|
||||
operstate = link->operstate;
|
||||
}
|
||||
|
||||
if (carrier)
|
||||
oper_state = "carrier";
|
||||
else if (dormant)
|
||||
oper_state = "dormant";
|
||||
operstate_str = link_operstate_to_string(operstate);
|
||||
assert(operstate_str);
|
||||
|
||||
r = fopen_temporary(m->state_file, &f, &temp_path);
|
||||
if (r < 0)
|
||||
|
@ -454,7 +450,7 @@ int manager_save(Manager *m) {
|
|||
|
||||
fprintf(f,
|
||||
"# This is private data. Do not parse.\n"
|
||||
"OPER_STATE=%s\n", oper_state);
|
||||
"OPER_STATE=%s\n", operstate_str);
|
||||
|
||||
fflush(f);
|
||||
|
||||
|
|
|
@ -212,6 +212,16 @@ typedef enum LinkState {
|
|||
_LINK_STATE_INVALID = -1
|
||||
} LinkState;
|
||||
|
||||
typedef enum LinkOperationalState {
|
||||
LINK_OPERSTATE_UNKNOWN,
|
||||
LINK_OPERSTATE_DORMANT,
|
||||
LINK_OPERSTATE_CARRIER,
|
||||
LINK_OPERSTATE_DEGRADED,
|
||||
LINK_OPERSTATE_ROUTABLE,
|
||||
_LINK_OPERSTATE_MAX,
|
||||
_LINK_OPERSTATE_INVALID = -1
|
||||
} LinkOperationalState;
|
||||
|
||||
struct Link {
|
||||
Manager *manager;
|
||||
|
||||
|
@ -224,11 +234,12 @@ struct Link {
|
|||
struct udev_device *udev_device;
|
||||
|
||||
unsigned flags;
|
||||
uint8_t operstate;
|
||||
uint8_t kernel_operstate;
|
||||
|
||||
Network *network;
|
||||
|
||||
LinkState state;
|
||||
LinkOperationalState operstate;
|
||||
|
||||
unsigned addr_messages;
|
||||
unsigned route_messages;
|
||||
|
@ -423,6 +434,9 @@ bool link_has_carrier(unsigned flags, uint8_t operstate);
|
|||
const char* link_state_to_string(LinkState s) _const_;
|
||||
LinkState link_state_from_string(const char *s) _pure_;
|
||||
|
||||
const char* link_operstate_to_string(LinkOperationalState s) _const_;
|
||||
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
|
||||
#define _cleanup_link_unref_ _cleanup_(link_unrefp)
|
||||
|
||||
|
|
|
@ -61,14 +61,14 @@ _SD_BEGIN_DECLARATIONS;
|
|||
int sd_network_get_link_state(unsigned index, char **state);
|
||||
|
||||
/* Get operatinal state from ifindex.
|
||||
* Possible states: unknown, dormant, carrier
|
||||
* Possible states: unknown, dormant, carrier, degraded, routable
|
||||
* Possible return codes:
|
||||
* -ENODATA: networkd is not aware of the link
|
||||
*/
|
||||
int sd_network_get_link_operational_state(unsigned index, char **state);
|
||||
|
||||
/* Get overall opeartional state
|
||||
* Possible states: unknown, dormant, carrier
|
||||
* Possible states: unknown, dormant, carrier, degraded, routable
|
||||
* Possible return codes:
|
||||
* -ENODATA: networkd is not aware of any links
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue