From 6a1af3d4caca8f902068a97440ed31a643c2a033 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 27 May 2019 05:35:02 +0900 Subject: [PATCH 1/9] network: split out DBus related prototypes to networkd-link-bus.h --- src/network/meson.build | 1 + src/network/networkd-link-bus.c | 3 ++- src/network/networkd-link-bus.h | 15 +++++++++++++++ src/network/networkd-link.c | 2 ++ src/network/networkd-link.h | 6 ------ src/network/networkd-manager.c | 1 + src/network/networkd-speed-meter.c | 1 + 7 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 src/network/networkd-link-bus.h diff --git a/src/network/meson.build b/src/network/meson.build index 959421fc5c..4eda3abef1 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -63,6 +63,7 @@ sources = files(''' networkd-ipv6-proxy-ndp.c networkd-ipv6-proxy-ndp.h networkd-link-bus.c + networkd-link-bus.h networkd-link.c networkd-link.h networkd-lldp-rx.c diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 2f414cb116..0f2ffd4e86 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -3,6 +3,7 @@ #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-util.h" +#include "networkd-link-bus.h" #include "networkd-link.h" #include "networkd-manager.h" #include "parse-util.h" @@ -65,7 +66,7 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_END }; -static char *link_bus_path(Link *link) { +char *link_bus_path(Link *link) { _cleanup_free_ char *ifindex = NULL; char *p; int r; diff --git a/src/network/networkd-link-bus.h b/src/network/networkd-link-bus.h new file mode 100644 index 0000000000..3cc3de46c6 --- /dev/null +++ b/src/network/networkd-link-bus.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "sd-bus.h" + +#include "macro.h" + +typedef struct Link Link; + +extern const sd_bus_vtable link_vtable[]; + +char *link_bus_path(Link *link); +int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); +int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +int link_send_changed(Link *link, const char *property, ...) _sentinel_; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 67c0903fa6..56e36b7d6b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -20,6 +20,8 @@ #include "network-internal.h" #include "networkd-can.h" #include "networkd-ipv6-proxy-ndp.h" +#include "networkd-link-bus.h" +#include "networkd-link.h" #include "networkd-lldp-tx.h" #include "networkd-manager.h" #include "networkd-ndisc.h" diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 80fc4baee6..05b88356cf 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -183,12 +183,6 @@ int link_stop_clients(Link *link, bool may_keep_dhcp); const char* link_state_to_string(LinkState s) _const_; LinkState link_state_from_string(const char *s) _pure_; -extern const sd_bus_vtable link_vtable[]; - -int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); -int link_send_changed(Link *link, const char *property, ...) _sentinel_; - uint32_t link_get_vrf_table(Link *link); uint32_t link_get_dhcp_route_table(Link *link); uint32_t link_get_ipv6_accept_ra_route_table(Link *link); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 92e3b0a0f1..d2e5b5de59 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -21,6 +21,7 @@ #include "local-addresses.h" #include "netlink-util.h" #include "network-internal.h" +#include "networkd-link-bus.h" #include "networkd-manager.h" #include "networkd-speed-meter.h" #include "ordered-set.h" diff --git a/src/network/networkd-speed-meter.c b/src/network/networkd-speed-meter.c index 5fd30f3df8..c4fc56b019 100644 --- a/src/network/networkd-speed-meter.c +++ b/src/network/networkd-speed-meter.c @@ -5,6 +5,7 @@ #include "sd-event.h" #include "sd-netlink.h" +#include "networkd-link-bus.h" #include "networkd-link.h" #include "networkd-manager.h" #include "networkd-speed-meter.h" From aa3108f6b21109425e4aa2313d2a0aa14eed5674 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Jun 2019 09:14:36 +0900 Subject: [PATCH 2/9] network: introduce link_send_changed_strv() It will be used in later commits. --- src/network/networkd-link-bus.c | 18 ++++++++++++------ src/network/networkd-link-bus.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 0f2ffd4e86..cbd6fa3676 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -145,17 +145,15 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void return 1; } -int link_send_changed(Link *link, const char *property, ...) { +int link_send_changed_strv(Link *link, char **properties) { _cleanup_free_ char *p = NULL; - char **l; assert(link); assert(link->manager); + assert(properties); if (!link->manager->bus) - return 0; /* replace with assert when we have kdbus */ - - l = strv_from_stdarg_alloca(property); + return 0; p = link_bus_path(link); if (!p) @@ -165,5 +163,13 @@ int link_send_changed(Link *link, const char *property, ...) { link->manager->bus, p, "org.freedesktop.network1.Link", - l); + properties); +} + +int link_send_changed(Link *link, const char *property, ...) { + char **properties; + + properties = strv_from_stdarg_alloca(property); + + return link_send_changed_strv(link, properties); } diff --git a/src/network/networkd-link-bus.h b/src/network/networkd-link-bus.h index 3cc3de46c6..d5e0807d9d 100644 --- a/src/network/networkd-link-bus.h +++ b/src/network/networkd-link-bus.h @@ -12,4 +12,5 @@ extern const sd_bus_vtable link_vtable[]; char *link_bus_path(Link *link); int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); +int link_send_changed_strv(Link *link, char **properties); int link_send_changed(Link *link, const char *property, ...) _sentinel_; From 46606fdda920a630e1f40f25135b7e26e4f58a0c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 10 Jun 2019 05:15:53 +0900 Subject: [PATCH 3/9] network: introduce manager_send_changed_strv() --- src/network/networkd-manager-bus.c | 19 ++++++++++++------- src/network/networkd-manager.h | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c index 8c527837f8..e339c9ce8f 100644 --- a/src/network/networkd-manager-bus.c +++ b/src/network/networkd-manager-bus.c @@ -15,19 +15,24 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_END }; -int manager_send_changed(Manager *manager, const char *property, ...) { - char **l; - +int manager_send_changed_strv(Manager *manager, char **properties) { assert(manager); + assert(properties); if (!manager->bus) - return 0; /* replace by assert when we have kdbus */ - - l = strv_from_stdarg_alloca(property); + return 0; return sd_bus_emit_properties_changed_strv( manager->bus, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", - l); + properties); +} + +int manager_send_changed(Manager *manager, const char *property, ...) { + char **l; + + l = strv_from_stdarg_alloca(property); + + return manager_send_changed_strv(manager, l); } diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 281e9cbac4..60d3bed34f 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -83,6 +83,7 @@ int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, vo int manager_rtnl_process_route(sd_netlink *nl, sd_netlink_message *message, void *userdata); int manager_rtnl_process_rule(sd_netlink *nl, sd_netlink_message *message, void *userdata); +int manager_send_changed_strv(Manager *m, char **properties); int manager_send_changed(Manager *m, const char *property, ...) _sentinel_; void manager_dirty(Manager *m); From 1678fbb3c5016504a628dc90a45b3f8fbe4fc55d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Jun 2019 08:58:39 +0900 Subject: [PATCH 4/9] network: split operational states into carrier and address states This should not change any behavior. The new states will be exposed by later commits. --- src/libsystemd/sd-network/network-util.h | 19 +++++ src/network/networkd-link.c | 100 ++++++++++++++--------- src/network/networkd-link.h | 2 + 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; From 35c5a9cae40b4edb47c66bd7b743499f23e6c347 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Jun 2019 09:03:25 +0900 Subject: [PATCH 5/9] network: expose carrier and address states over dbus Previously, when a bridge or bonding interface is in degraded-carrier state, then we cannot judge the interface has addresses or not. By using the new states, dbus clients can distinguish such situation. --- src/libsystemd/sd-network/network-util.c | 19 +++++++++++++++++ src/libsystemd/sd-network/network-util.h | 6 ++++++ src/network/networkd-link-bus.c | 6 +++++- src/network/networkd-link-bus.h | 4 ++++ src/network/networkd-link.c | 27 ++++++++++++++++++++---- 5 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c index f46a3ff788..8daa15fdcb 100644 --- a/src/libsystemd/sd-network/network-util.c +++ b/src/libsystemd/sd-network/network-util.c @@ -32,3 +32,22 @@ static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState); + +static const char* const link_carrier_state_table[_LINK_CARRIER_STATE_MAX] = { + [LINK_CARRIER_STATE_OFF] = "off", + [LINK_CARRIER_STATE_NO_CARRIER] = "no-carrier", + [LINK_CARRIER_STATE_DORMANT] = "dormant", + [LINK_CARRIER_STATE_DEGRADED_CARRIER] = "degraded-carrier", + [LINK_CARRIER_STATE_CARRIER] = "carrier", + [LINK_CARRIER_STATE_ENSLAVED] = "enslaved", +}; + +DEFINE_STRING_TABLE_LOOKUP(link_carrier_state, LinkCarrierState); + +static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = { + [LINK_ADDRESS_STATE_OFF] = "off", + [LINK_ADDRESS_STATE_DEGRADED] = "degraded", + [LINK_ADDRESS_STATE_ROUTABLE] = "routable", +}; + +DEFINE_STRING_TABLE_LOOKUP(link_address_state, LinkAddressState); diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h index 601d00146a..a19435393d 100644 --- a/src/libsystemd/sd-network/network-util.h +++ b/src/libsystemd/sd-network/network-util.h @@ -41,3 +41,9 @@ typedef enum LinkAddressState { const char* link_operstate_to_string(LinkOperationalState s) _const_; LinkOperationalState link_operstate_from_string(const char *s) _pure_; + +const char* link_carrier_state_to_string(LinkCarrierState s) _const_; +LinkCarrierState link_carrier_state_from_string(const char *s) _pure_; + +const char* link_address_state_to_string(LinkAddressState s) _const_; +LinkAddressState link_address_state_from_string(const char *s) _pure_; diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index cbd6fa3676..f44818b65f 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -9,7 +9,9 @@ #include "parse-util.h" #include "strv.h" -static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); +BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); +BUS_DEFINE_PROPERTY_GET_ENUM(property_get_carrier_state, link_carrier_state, LinkCarrierState); +BUS_DEFINE_PROPERTY_GET_ENUM(property_get_address_state, link_address_state, LinkAddressState); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState); static int property_get_bit_rates( @@ -60,6 +62,8 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Link, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("BitRates", "(dd)", property_get_bit_rates, 0, 0), diff --git a/src/network/networkd-link-bus.h b/src/network/networkd-link-bus.h index d5e0807d9d..58005a4bbe 100644 --- a/src/network/networkd-link-bus.h +++ b/src/network/networkd-link-bus.h @@ -14,3 +14,7 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); int link_send_changed_strv(Link *link, char **properties); int link_send_changed(Link *link, const char *property, ...) _sentinel_; + +int property_get_operational_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int property_get_carrier_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int property_get_address_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 46ebc2b597..6cf88f071e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -362,7 +362,9 @@ void link_update_operstate(Link *link, bool also_update_master) { LinkOperationalState operstate; LinkCarrierState carrier_state; LinkAddressState address_state; + _cleanup_strv_free_ char **p = NULL; uint8_t scope = RT_SCOPE_NOWHERE; + bool changed = false; Address *address; Iterator i; @@ -436,15 +438,32 @@ void link_update_operstate(Link *link, bool also_update_master) { else operstate = LINK_OPERSTATE_ENSLAVED; - link->carrier_state = carrier_state; - link->address_state = address_state; + if (link->carrier_state != carrier_state) { + link->carrier_state = carrier_state; + changed = true; + if (strv_extend(&p, "CarrierState") < 0) + log_oom(); + } + + if (link->address_state != address_state) { + link->address_state = address_state; + changed = true; + if (strv_extend(&p, "AddressState") < 0) + log_oom(); + } if (link->operstate != operstate) { link->operstate = operstate; - link_send_changed(link, "OperationalState", NULL); - link_dirty(link); + changed = true; + if (strv_extend(&p, "OperationalState") < 0) + log_oom(); } + if (p) + link_send_changed_strv(link, p); + if (changed) + link_dirty(link); + if (also_update_master && link->network) { link_update_master_operstate(link, link->network->bond); link_update_master_operstate(link, link->network->bridge); From 7f3c07ada6fce33e8cac141da40f2f5bd5ff2170 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 10 Jun 2019 05:22:25 +0900 Subject: [PATCH 6/9] network: also introduce two new manager states --- src/network/networkd-manager-bus.c | 5 +++-- src/network/networkd-manager.c | 33 ++++++++++++++++++++++++++++-- src/network/networkd-manager.h | 2 ++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c index e339c9ce8f..622bfa01d2 100644 --- a/src/network/networkd-manager-bus.c +++ b/src/network/networkd-manager-bus.c @@ -2,15 +2,16 @@ #include "alloc-util.h" #include "bus-util.h" +#include "networkd-link-bus.h" #include "networkd-manager.h" #include "strv.h" -static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); - const sd_bus_vtable manager_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_VTABLE_END }; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index d2e5b5de59..39a6b17c10 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1078,8 +1078,11 @@ static int manager_save(Manager *m) { Link *link; Iterator i; _cleanup_free_ char *temp_path = NULL; + _cleanup_strv_free_ char **p = NULL; _cleanup_fclose_ FILE *f = NULL; LinkOperationalState operstate = LINK_OPERSTATE_OFF; + LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; + LinkAddressState address_state = LINK_ADDRESS_STATE_OFF; const char *operstate_str; int r; @@ -1110,6 +1113,12 @@ static int manager_save(Manager *m) { if (link->operstate > operstate) operstate = link->operstate; + if (link->carrier_state > carrier_state) + carrier_state = link->carrier_state; + + if (link->address_state > address_state) + address_state = link->address_state; + if (!link->network) continue; @@ -1181,6 +1190,9 @@ static int manager_save(Manager *m) { } } + if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED) + carrier_state = LINK_CARRIER_STATE_CARRIER; + operstate_str = link_operstate_to_string(operstate); assert(operstate_str); @@ -1214,9 +1226,26 @@ static int manager_save(Manager *m) { if (m->operational_state != operstate) { m->operational_state = operstate; - r = manager_send_changed(m, "OperationalState", NULL); + if (strv_extend(&p, "OperationalState") < 0) + log_oom(); + } + + if (m->carrier_state != carrier_state) { + m->carrier_state = carrier_state; + if (strv_extend(&p, "CarrierState") < 0) + log_oom(); + } + + if (m->address_state != address_state) { + m->address_state = address_state; + if (strv_extend(&p, "AddressState") < 0) + log_oom(); + } + + if (p) { + r = manager_send_changed_strv(m, p); if (r < 0) - log_error_errno(r, "Could not emit changed OperationalState: %m"); + log_error_errno(r, "Could not emit changed properties: %m"); } m->dirty = false; diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 60d3bed34f..9685da07e3 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -33,6 +33,8 @@ struct Manager { char *state_file; LinkOperationalState operational_state; + LinkCarrierState carrier_state; + LinkAddressState address_state; Hashmap *links; Hashmap *netdevs; From 3cf7a9807e7165af1e76e5e04cad70e49883ec24 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 16 Jun 2019 09:27:19 +0900 Subject: [PATCH 7/9] network: drop unused manager_send_changed() --- src/network/networkd-manager-bus.c | 8 -------- src/network/networkd-manager.h | 1 - 2 files changed, 9 deletions(-) diff --git a/src/network/networkd-manager-bus.c b/src/network/networkd-manager-bus.c index 622bfa01d2..a40220d108 100644 --- a/src/network/networkd-manager-bus.c +++ b/src/network/networkd-manager-bus.c @@ -29,11 +29,3 @@ int manager_send_changed_strv(Manager *manager, char **properties) { "org.freedesktop.network1.Manager", properties); } - -int manager_send_changed(Manager *manager, const char *property, ...) { - char **l; - - l = strv_from_stdarg_alloca(property); - - return manager_send_changed_strv(manager, l); -} diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 9685da07e3..e0ec45aa2f 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -86,7 +86,6 @@ int manager_rtnl_process_route(sd_netlink *nl, sd_netlink_message *message, void int manager_rtnl_process_rule(sd_netlink *nl, sd_netlink_message *message, void *userdata); int manager_send_changed_strv(Manager *m, char **properties); -int manager_send_changed(Manager *m, const char *property, ...) _sentinel_; void manager_dirty(Manager *m); int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found); From ac999bf07dcc9ed628115eacfcc7d94f582b5ad7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 10 Jun 2019 04:56:03 +0900 Subject: [PATCH 8/9] sd-network: introduce functions for new link and manager states --- src/libsystemd/sd-network/sd-network.c | 28 ++++++++++++++++++++++---- src/network/networkd-link.c | 14 ++++++++++--- src/network/networkd-manager.c | 13 ++++++++++-- src/systemd/sd-network.h | 4 ++++ 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 2d715043e1..a3c0542d7a 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -18,13 +18,13 @@ #include "strv.h" #include "util.h" -_public_ int sd_network_get_operational_state(char **state) { +static int network_get_string(const char *field, char **ret) { _cleanup_free_ char *s = NULL; int r; - assert_return(state, -EINVAL); + assert_return(ret, -EINVAL); - r = parse_env_file(NULL, "/run/systemd/netif/state", "OPER_STATE", &s); + r = parse_env_file(NULL, "/run/systemd/netif/state", field, &s); if (r == -ENOENT) return -ENODATA; if (r < 0) @@ -32,11 +32,23 @@ _public_ int sd_network_get_operational_state(char **state) { if (isempty(s)) return -ENODATA; - *state = TAKE_PTR(s); + *ret = TAKE_PTR(s); return 0; } +_public_ int sd_network_get_operational_state(char **state) { + return network_get_string("OPER_STATE", state); +} + +_public_ int sd_network_get_carrier_state(char **state) { + return network_get_string("CARRIER_STATE", state); +} + +_public_ int sd_network_get_address_state(char **state) { + return network_get_string("ADDRESS_STATE", state); +} + static int network_get_strv(const char *key, char ***ret) { _cleanup_strv_free_ char **a = NULL; _cleanup_free_ char *s = NULL; @@ -149,6 +161,14 @@ _public_ int sd_network_link_get_operational_state(int ifindex, char **state) { return network_link_get_string(ifindex, "OPER_STATE", state); } +_public_ int sd_network_link_get_carrier_state(int ifindex, char **state) { + return network_link_get_string(ifindex, "CARRIER_STATE", state); +} + +_public_ int sd_network_link_get_address_state(int ifindex, char **state) { + return network_link_get_string(ifindex, "ADDRESS_STATE", state); +} + _public_ int sd_network_link_get_required_for_online(int ifindex) { _cleanup_free_ char *s = NULL; int r; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 6cf88f071e..8859d5dda2 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3607,7 +3607,7 @@ static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) { int link_save(Link *link) { _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; - const char *admin_state, *oper_state; + const char *admin_state, *oper_state, *carrier_state, *address_state; Address *a; Route *route; Iterator i; @@ -3631,6 +3631,12 @@ int link_save(Link *link) { oper_state = link_operstate_to_string(link->operstate); assert(oper_state); + carrier_state = link_carrier_state_to_string(link->carrier_state); + assert(carrier_state); + + address_state = link_address_state_to_string(link->address_state); + assert(address_state); + r = fopen_temporary(link->state_file, &f, &temp_path); if (r < 0) goto fail; @@ -3640,8 +3646,10 @@ int link_save(Link *link) { fprintf(f, "# This is private data. Do not parse.\n" "ADMIN_STATE=%s\n" - "OPER_STATE=%s\n", - admin_state, oper_state); + "OPER_STATE=%s\n" + "CARRIER_STATE=%s\n" + "ADDRESS_STATE=%s\n", + admin_state, oper_state, carrier_state, address_state); if (link->network) { char **dhcp6_domains = NULL, **dhcp_domains = NULL; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 39a6b17c10..a239d876cc 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1083,7 +1083,7 @@ static int manager_save(Manager *m) { LinkOperationalState operstate = LINK_OPERSTATE_OFF; LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; LinkAddressState address_state = LINK_ADDRESS_STATE_OFF; - const char *operstate_str; + const char *operstate_str, *carrier_state_str, *address_state_str; int r; assert(m); @@ -1196,6 +1196,12 @@ static int manager_save(Manager *m) { operstate_str = link_operstate_to_string(operstate); assert(operstate_str); + carrier_state_str = link_carrier_state_to_string(carrier_state); + assert(carrier_state_str); + + address_state_str = link_address_state_to_string(address_state); + assert(address_state_str); + r = fopen_temporary(m->state_file, &f, &temp_path); if (r < 0) return r; @@ -1204,7 +1210,10 @@ static int manager_save(Manager *m) { fprintf(f, "# This is private data. Do not parse.\n" - "OPER_STATE=%s\n", operstate_str); + "OPER_STATE=%s\n" + "CARRIER_STATE=%s\n" + "ADDRESS_STATE=%s\n", + operstate_str, carrier_state_str, address_state_str); ordered_set_print(f, "DNS=", dns); ordered_set_print(f, "NTP=", ntp); diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index 166c30185a..478e170588 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -49,6 +49,8 @@ _SD_BEGIN_DECLARATIONS; * -ENODATA: networkd is not aware of any links */ int sd_network_get_operational_state(char **state); +int sd_network_get_carrier_state(char **state); +int sd_network_get_address_state(char **state); /* Get DNS entries for all links. These are string representations of * IP addresses */ @@ -90,6 +92,8 @@ int sd_network_link_get_setup_state(int ifindex, char **state); */ int sd_network_link_get_operational_state(int ifindex, char **state); int sd_network_link_get_required_operstate_for_online(int ifindex, char **state); +int sd_network_link_get_carrier_state(int ifindex, char **state); +int sd_network_link_get_address_state(int ifindex, char **state); /* Indicates whether the network is relevant to being online. * Possible return codes: From 1a65093774862728d1eed1411d692101581c0db8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 10 Jun 2019 05:36:32 +0900 Subject: [PATCH 9/9] timesync: judging if network is online by networkd's address state Closes #12752. --- src/libsystemd/sd-network/network-util.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c index 8daa15fdcb..08ed942638 100644 --- a/src/libsystemd/sd-network/network-util.c +++ b/src/libsystemd/sd-network/network-util.c @@ -7,14 +7,19 @@ #include "strv.h" bool network_is_online(void) { - _cleanup_free_ char *state = NULL; + _cleanup_free_ char *carrier_state = NULL, *addr_state = NULL; int r; - r = sd_network_get_operational_state(&state); + r = sd_network_get_carrier_state(&carrier_state); if (r < 0) /* if we don't know anything, we consider the system online */ return true; - if (STR_IN_SET(state, "routable", "degraded")) + r = sd_network_get_address_state(&addr_state); + if (r < 0) /* if we don't know anything, we consider the system online */ + return true; + + if (STR_IN_SET(carrier_state, "degraded-carrier", "carrier") && + STR_IN_SET(addr_state, "routable", "degraded")) return true; return false;