mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Merge pull request #19163 from sipraga/online-if-required
network: introduce an online state that respects RequiredForOnline=
This commit is contained in:
@@ -187,14 +187,46 @@
|
||||
|
||||
<para>Produces output similar to:
|
||||
<programlisting>
|
||||
● State: routable
|
||||
Address: 10.193.76.5 on eth0
|
||||
192.168.122.1 on virbr0
|
||||
169.254.190.105 on eth0
|
||||
fe80::5054:aa:bbbb:cccc on eth0
|
||||
Gateway: 10.193.11.1 (CISCO SYSTEMS, INC.) on eth0
|
||||
DNS: 8.8.8.8
|
||||
8.8.4.4</programlisting></para>
|
||||
● State: routable
|
||||
Online state: online
|
||||
Address: 10.193.76.5 on eth0
|
||||
192.168.122.1 on virbr0
|
||||
169.254.190.105 on eth0
|
||||
fe80::5054:aa:bbbb:cccc on eth0
|
||||
Gateway: 10.193.11.1 (CISCO SYSTEMS, INC.) on eth0
|
||||
DNS: 8.8.8.8
|
||||
8.8.4.4</programlisting></para>
|
||||
|
||||
<para>In the overall network status, the online state depends on the individual online state of all
|
||||
required links. Managed links are required for online by default. In this case, the online state is
|
||||
one of the following:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>unknown</term>
|
||||
<listitem>
|
||||
<para>all links have unknown online status (i.e. there are no required links)</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>offline</term>
|
||||
<listitem>
|
||||
<para>all required links are offline</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>partial</term>
|
||||
<listitem>
|
||||
<para>some, but not all, required links are online</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>online</term>
|
||||
<listitem>
|
||||
<para>all required links are online</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
<para>Takes a boolean or a minimum operational state and an optional maximum operational state.
|
||||
Please see <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
for possible operational states. When <literal>yes</literal>, the network is deemed required when
|
||||
determining whether the system is online when running
|
||||
<command>systemd-networkd-wait-online</command>. When <literal>no</literal>, the network is ignored
|
||||
when checking for online state. When a minimum operational state and an optional maximum operational
|
||||
determining whether the system is online (including when running
|
||||
<command>systemd-networkd-wait-online</command>). When <literal>no</literal>, the network is ignored
|
||||
when determining the online state. When a minimum operational state and an optional maximum operational
|
||||
state are set, <literal>yes</literal> is implied, and this controls the minimum and maximum
|
||||
operational state required for the network interface to be considered online.
|
||||
Defaults to <literal>yes</literal>.</para>
|
||||
@@ -232,13 +232,13 @@
|
||||
<varlistentry>
|
||||
<term><varname>RequiredFamilyForOnline=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies an address family. When specified,
|
||||
<command>systemd-networkd-wait-online</command> waits for at least one routable or link-local
|
||||
IP address in the family should be configured on the link. Takes one of
|
||||
<literal>ipv4</literal>, <literal>ipv6</literal>, <literal>both</literal>, or
|
||||
<literal>any</literal>. Defaults to <literal>any</literal>. Note that this will be used only
|
||||
when <varname>RequiredForOnline=</varname> is true, or its minimum operational state is
|
||||
<literal>degraded</literal> or above. Otherwise, it will be ignored.</para>
|
||||
<para>Takes an address family. When specified, an IP address in the given family is deemed required
|
||||
when determining whether the link is online (including when running
|
||||
<command>systemd-networkd-wait-online</command>). Takes one of <literal>ipv4</literal>,
|
||||
<literal>ipv6</literal>, <literal>both</literal>, or <literal>any</literal>. Defaults to
|
||||
<literal>any</literal>. Note that this option has no effect if
|
||||
<literal>RequiredForOnline=no</literal>, or if <literal>RequiredForOnline=</literal> specifies a
|
||||
minimum operational state below <literal>degraded</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@@ -13,20 +13,34 @@
|
||||
#include "strv.h"
|
||||
|
||||
bool network_is_online(void) {
|
||||
_cleanup_free_ char *carrier_state = NULL, *addr_state = NULL;
|
||||
_cleanup_free_ char *online_state = NULL;
|
||||
LinkOnlineState state;
|
||||
int r;
|
||||
|
||||
r = sd_network_get_carrier_state(&carrier_state);
|
||||
if (r < 0) /* if we don't know anything, we consider the system online */
|
||||
return true;
|
||||
r = sd_network_get_online_state(&online_state);
|
||||
if (r < 0)
|
||||
state = _LINK_ONLINE_STATE_INVALID;
|
||||
else
|
||||
state = link_online_state_from_string(online_state);
|
||||
|
||||
r = sd_network_get_address_state(&addr_state);
|
||||
if (r < 0) /* if we don't know anything, we consider the system online */
|
||||
if (state >= LINK_ONLINE_STATE_PARTIAL)
|
||||
return true;
|
||||
else if (state < 0) {
|
||||
_cleanup_free_ char *carrier_state = NULL, *addr_state = NULL;
|
||||
|
||||
if (STR_IN_SET(carrier_state, "degraded-carrier", "carrier") &&
|
||||
STR_IN_SET(addr_state, "routable", "degraded"))
|
||||
return true;
|
||||
r = sd_network_get_carrier_state(&carrier_state);
|
||||
if (r < 0) /* if we don't know anything, we consider the system online */
|
||||
return true;
|
||||
|
||||
r = sd_network_get_address_state(&addr_state);
|
||||
if (r < 0) /* if we don't know anything, we consider the system online */
|
||||
return true;
|
||||
|
||||
/* we don't know the online state for certain, so make an educated guess */
|
||||
if (STR_IN_SET(carrier_state, "degraded-carrier", "carrier") &&
|
||||
STR_IN_SET(addr_state, "routable", "degraded"))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -73,6 +87,14 @@ static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_address_state, LinkAddressState);
|
||||
|
||||
static const char *const link_online_state_table[_LINK_ONLINE_STATE_MAX] = {
|
||||
[LINK_ONLINE_STATE_OFFLINE] = "offline",
|
||||
[LINK_ONLINE_STATE_PARTIAL] = "partial",
|
||||
[LINK_ONLINE_STATE_ONLINE] = "online",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(link_online_state, LinkOnlineState);
|
||||
|
||||
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out) {
|
||||
LinkOperationalStateRange range = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
||||
_cleanup_free_ const char *min = NULL;
|
||||
|
||||
@@ -54,6 +54,14 @@ typedef enum LinkAddressState {
|
||||
_LINK_ADDRESS_STATE_INVALID = -EINVAL,
|
||||
} LinkAddressState;
|
||||
|
||||
typedef enum LinkOnlineState {
|
||||
LINK_ONLINE_STATE_OFFLINE,
|
||||
LINK_ONLINE_STATE_PARTIAL,
|
||||
LINK_ONLINE_STATE_ONLINE,
|
||||
_LINK_ONLINE_STATE_MAX,
|
||||
_LINK_ONLINE_STATE_INVALID = -EINVAL,
|
||||
} LinkOnlineState;
|
||||
|
||||
const char* link_operstate_to_string(LinkOperationalState s) _const_;
|
||||
LinkOperationalState link_operstate_from_string(const char *s) _pure_;
|
||||
|
||||
@@ -66,6 +74,9 @@ AddressFamily link_required_address_family_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_;
|
||||
|
||||
const char* link_online_state_to_string(LinkOnlineState s) _const_;
|
||||
LinkOnlineState link_online_state_from_string(const char *s) _pure_;
|
||||
|
||||
typedef struct LinkOperationalStateRange {
|
||||
LinkOperationalState min;
|
||||
LinkOperationalState max;
|
||||
|
||||
@@ -56,6 +56,10 @@ _public_ int sd_network_get_ipv6_address_state(char **state) {
|
||||
return network_get_string("IPV6_ADDRESS_STATE", state);
|
||||
}
|
||||
|
||||
_public_ int sd_network_get_online_state(char **state) {
|
||||
return network_get_string("ONLINE_STATE", state);
|
||||
}
|
||||
|
||||
static int network_get_strv(const char *key, char ***ret) {
|
||||
_cleanup_strv_free_ char **a = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
@@ -204,6 +208,10 @@ _public_ int sd_network_link_get_ipv6_address_state(int ifindex, char **state) {
|
||||
return network_link_get_string(ifindex, "IPV6_ADDRESS_STATE", state);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_online_state(int ifindex, char **state) {
|
||||
return network_link_get_string(ifindex, "ONLINE_STATE", state);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_get_dhcp6_client_iaid_string(int ifindex, char **iaid) {
|
||||
return network_link_get_string(ifindex, "DHCP6_CLIENT_IAID", iaid);
|
||||
}
|
||||
|
||||
@@ -225,6 +225,25 @@ static void setup_state_to_color(const char *state, const char **on, const char
|
||||
}
|
||||
}
|
||||
|
||||
static void online_state_to_color(const char *state, const char **on, const char **off) {
|
||||
if (streq_ptr(state, "online")) {
|
||||
if (on)
|
||||
*on = ansi_highlight_green();
|
||||
if (off)
|
||||
*off = ansi_normal();
|
||||
} else if (streq_ptr(state, "partial")) {
|
||||
if (on)
|
||||
*on = ansi_highlight_yellow();
|
||||
if (off)
|
||||
*off = ansi_normal();
|
||||
} else {
|
||||
if (on)
|
||||
*on = "";
|
||||
if (off)
|
||||
*off = "";
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct VxLanInfo {
|
||||
uint32_t vni;
|
||||
uint32_t link;
|
||||
@@ -1514,9 +1533,9 @@ static int link_status_one(
|
||||
|
||||
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL;
|
||||
_cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL,
|
||||
*setup_state = NULL, *operational_state = NULL, *lease_file = NULL, *activation_policy = NULL;
|
||||
*setup_state = NULL, *operational_state = NULL, *online_state = NULL, *lease_file = NULL, *activation_policy = NULL;
|
||||
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL,
|
||||
*on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup;
|
||||
*on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup, *on_color_online;
|
||||
_cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
|
||||
_cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
@@ -1529,6 +1548,9 @@ static int link_status_one(
|
||||
(void) sd_network_link_get_operational_state(info->ifindex, &operational_state);
|
||||
operational_state_to_color(info->name, operational_state, &on_color_operational, &off_color_operational);
|
||||
|
||||
(void) sd_network_link_get_online_state(info->ifindex, &online_state);
|
||||
online_state_to_color(online_state, &on_color_online, NULL);
|
||||
|
||||
r = sd_network_link_get_setup_state(info->ifindex, &setup_state);
|
||||
if (r == -ENODATA) /* If there's no info available about this iface, it's unmanaged by networkd */
|
||||
setup_state = strdup("unmanaged");
|
||||
@@ -1613,6 +1635,14 @@ static int link_status_one(
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
r = table_add_many(table,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Online state:",
|
||||
TABLE_STRING, online_state ?: "unknown",
|
||||
TABLE_SET_COLOR, on_color_online);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
strv_sort(info->alternative_names);
|
||||
r = dump_list(table, "Alternative Names:", info->alternative_names);
|
||||
if (r < 0)
|
||||
@@ -2272,9 +2302,9 @@ static int link_status_one(
|
||||
}
|
||||
|
||||
static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
|
||||
_cleanup_free_ char *operational_state = NULL;
|
||||
_cleanup_free_ char *operational_state = NULL, *online_state = NULL;
|
||||
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
|
||||
const char *on_color_operational;
|
||||
const char *on_color_operational, *on_color_online;
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
TableCell *cell;
|
||||
int r;
|
||||
@@ -2284,6 +2314,9 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
|
||||
(void) sd_network_get_operational_state(&operational_state);
|
||||
operational_state_to_color(NULL, operational_state, &on_color_operational, NULL);
|
||||
|
||||
(void) sd_network_get_online_state(&online_state);
|
||||
online_state_to_color(online_state, &on_color_online, NULL);
|
||||
|
||||
table = table_new("dot", "key", "value");
|
||||
if (!table)
|
||||
return log_oom();
|
||||
@@ -2305,7 +2338,11 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
|
||||
TABLE_SET_COLOR, on_color_operational,
|
||||
TABLE_STRING, "State:",
|
||||
TABLE_STRING, strna(operational_state),
|
||||
TABLE_SET_COLOR, on_color_operational);
|
||||
TABLE_SET_COLOR, on_color_operational,
|
||||
TABLE_EMPTY,
|
||||
TABLE_STRING, "Online state:",
|
||||
TABLE_STRING, online_state ?: "unknown",
|
||||
TABLE_SET_COLOR, on_color_online);
|
||||
if (r < 0)
|
||||
return table_log_add_error(r);
|
||||
|
||||
|
||||
@@ -60,7 +60,8 @@ int link_build_json(Link *link, JsonVariant **ret) {
|
||||
JSON_BUILD_PAIR("CarrierState", JSON_BUILD_STRING(link_carrier_state_to_string(link->carrier_state))),
|
||||
JSON_BUILD_PAIR("AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->address_state))),
|
||||
JSON_BUILD_PAIR("IPv4AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv4_address_state))),
|
||||
JSON_BUILD_PAIR("IPv6AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv6_address_state)))));
|
||||
JSON_BUILD_PAIR("IPv6AddressState", JSON_BUILD_STRING(link_address_state_to_string(link->ipv6_address_state))),
|
||||
JSON_BUILD_PAIR("OnlineState", JSON_BUILD_STRING(link_online_state_to_string(link->online_state)))));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
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);
|
||||
BUS_DEFINE_PROPERTY_GET_ENUM(property_get_online_state, link_online_state, LinkOnlineState);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
|
||||
|
||||
static int property_get_bit_rates(
|
||||
@@ -716,6 +717,7 @@ const sd_bus_vtable link_vtable[] = {
|
||||
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Link, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Link, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("OnlineState", "s", property_get_online_state, offsetof(Link, online_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", "(tt)", property_get_bit_rates, 0, 0),
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ 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);
|
||||
int property_get_online_state(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
|
||||
|
||||
int bus_link_method_set_ntp_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||
|
||||
@@ -202,6 +202,7 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
||||
LinkOperationalState operstate;
|
||||
LinkCarrierState carrier_state;
|
||||
LinkAddressState ipv4_address_state, ipv6_address_state, address_state;
|
||||
LinkOnlineState online_state;
|
||||
_cleanup_strv_free_ char **p = NULL;
|
||||
uint8_t ipv4_scope = RT_SCOPE_NOWHERE, ipv6_scope = RT_SCOPE_NOWHERE;
|
||||
bool changed = false;
|
||||
@@ -277,6 +278,38 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
||||
else
|
||||
operstate = LINK_OPERSTATE_ENSLAVED;
|
||||
|
||||
/* Only determine online state for managed links with RequiredForOnline=yes */
|
||||
if (!link->network || !link->network->required_for_online)
|
||||
online_state = _LINK_ONLINE_STATE_INVALID;
|
||||
else if (operstate < link->network->required_operstate_for_online.min ||
|
||||
operstate > link->network->required_operstate_for_online.max)
|
||||
online_state = LINK_ONLINE_STATE_OFFLINE;
|
||||
else {
|
||||
AddressFamily required_family = link->network->required_family_for_online;
|
||||
bool needs_ipv4 = required_family & ADDRESS_FAMILY_IPV4;
|
||||
bool needs_ipv6 = required_family & ADDRESS_FAMILY_IPV6;
|
||||
|
||||
/* The operational state is within the range required for online.
|
||||
* If a particular address family is also required, we might revert
|
||||
* to offline in the blocks below.
|
||||
*/
|
||||
online_state = LINK_ONLINE_STATE_ONLINE;
|
||||
|
||||
if (link->network->required_operstate_for_online.min >= LINK_OPERSTATE_DEGRADED) {
|
||||
if (needs_ipv4 && ipv4_address_state < LINK_ADDRESS_STATE_DEGRADED)
|
||||
online_state = LINK_ONLINE_STATE_OFFLINE;
|
||||
if (needs_ipv6 && ipv6_address_state < LINK_ADDRESS_STATE_DEGRADED)
|
||||
online_state = LINK_ONLINE_STATE_OFFLINE;
|
||||
}
|
||||
|
||||
if (link->network->required_operstate_for_online.min >= LINK_OPERSTATE_ROUTABLE) {
|
||||
if (needs_ipv4 && ipv4_address_state < LINK_ADDRESS_STATE_ROUTABLE)
|
||||
online_state = LINK_ONLINE_STATE_OFFLINE;
|
||||
if (needs_ipv6 && ipv6_address_state < LINK_ADDRESS_STATE_ROUTABLE)
|
||||
online_state = LINK_ONLINE_STATE_OFFLINE;
|
||||
}
|
||||
}
|
||||
|
||||
if (link->carrier_state != carrier_state) {
|
||||
link->carrier_state = carrier_state;
|
||||
changed = true;
|
||||
@@ -312,6 +345,13 @@ void link_update_operstate(Link *link, bool also_update_master) {
|
||||
log_oom();
|
||||
}
|
||||
|
||||
if (link->online_state != online_state) {
|
||||
link->online_state = online_state;
|
||||
changed = true;
|
||||
if (strv_extend(&p, "OnlineState") < 0)
|
||||
log_oom();
|
||||
}
|
||||
|
||||
if (p)
|
||||
link_send_changed_strv(link, p);
|
||||
if (changed)
|
||||
@@ -2330,6 +2370,7 @@ static int link_initialized_and_synced(Link *link) {
|
||||
}
|
||||
|
||||
link->network = network_ref(network);
|
||||
link_update_operstate(link, false);
|
||||
link_dirty(link);
|
||||
}
|
||||
|
||||
@@ -2466,6 +2507,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
*link = (Link) {
|
||||
.n_ref = 1,
|
||||
.state = LINK_STATE_PENDING,
|
||||
.online_state = _LINK_ONLINE_STATE_INVALID,
|
||||
.ifindex = ifindex,
|
||||
.iftype = iftype,
|
||||
.ifname = TAKE_PTR(ifname),
|
||||
|
||||
@@ -77,6 +77,7 @@ typedef struct Link {
|
||||
LinkAddressState address_state;
|
||||
LinkAddressState ipv4_address_state;
|
||||
LinkAddressState ipv6_address_state;
|
||||
LinkOnlineState online_state;
|
||||
|
||||
unsigned address_label_messages;
|
||||
unsigned static_address_messages;
|
||||
|
||||
@@ -271,6 +271,7 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Manager, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Manager, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("OnlineState", "s", property_get_online_state, offsetof(Manager, online_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD_WITH_ARGS("ListLinks",
|
||||
SD_BUS_NO_ARGS,
|
||||
|
||||
@@ -380,6 +380,7 @@ int manager_new(Manager **ret) {
|
||||
|
||||
*m = (Manager) {
|
||||
.speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
|
||||
.online_state = _LINK_ONLINE_STATE_INVALID,
|
||||
.manage_foreign_routes = true,
|
||||
.manage_foreign_rules = true,
|
||||
.ethtool_fd = -1,
|
||||
|
||||
@@ -42,6 +42,7 @@ struct Manager {
|
||||
LinkAddressState address_state;
|
||||
LinkAddressState ipv4_address_state;
|
||||
LinkAddressState ipv6_address_state;
|
||||
LinkOnlineState online_state;
|
||||
|
||||
Hashmap *links;
|
||||
Hashmap *netdevs;
|
||||
|
||||
@@ -105,11 +105,13 @@ static int ordered_set_put_in4_addrv(
|
||||
|
||||
int manager_save(Manager *m) {
|
||||
_cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
|
||||
const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str;
|
||||
const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str, *online_state_str;
|
||||
LinkOperationalState operstate = LINK_OPERSTATE_OFF;
|
||||
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
|
||||
LinkAddressState ipv4_address_state = LINK_ADDRESS_STATE_OFF, ipv6_address_state = LINK_ADDRESS_STATE_OFF,
|
||||
address_state = LINK_ADDRESS_STATE_OFF;
|
||||
LinkOnlineState online_state;
|
||||
size_t links_offline = 0, links_online = 0;
|
||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_strv_free_ char **p = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
@@ -134,6 +136,13 @@ int manager_save(Manager *m) {
|
||||
if (!link->network)
|
||||
continue;
|
||||
|
||||
if (link->network->required_for_online) {
|
||||
if (link->online_state == LINK_ONLINE_STATE_OFFLINE)
|
||||
links_offline++;
|
||||
else if (link->online_state == LINK_ONLINE_STATE_ONLINE)
|
||||
links_online++;
|
||||
}
|
||||
|
||||
/* First add the static configured entries */
|
||||
if (link->n_dns != UINT_MAX)
|
||||
r = ordered_set_put_dns_servers(&dns, link->ifindex, link->dns, link->n_dns);
|
||||
@@ -215,6 +224,10 @@ int manager_save(Manager *m) {
|
||||
if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED)
|
||||
carrier_state = LINK_CARRIER_STATE_CARRIER;
|
||||
|
||||
online_state = links_online > 0 ?
|
||||
(links_offline > 0 ? LINK_ONLINE_STATE_PARTIAL : LINK_ONLINE_STATE_ONLINE) :
|
||||
(links_offline > 0 ? LINK_ONLINE_STATE_OFFLINE : _LINK_ONLINE_STATE_INVALID);
|
||||
|
||||
operstate_str = link_operstate_to_string(operstate);
|
||||
assert(operstate_str);
|
||||
|
||||
@@ -245,6 +258,10 @@ int manager_save(Manager *m) {
|
||||
"IPV6_ADDRESS_STATE=%s\n",
|
||||
operstate_str, carrier_state_str, address_state_str, ipv4_address_state_str, ipv6_address_state_str);
|
||||
|
||||
online_state_str = link_online_state_to_string(online_state);
|
||||
if (online_state_str)
|
||||
fprintf(f, "ONLINE_STATE=%s\n", online_state_str);
|
||||
|
||||
ordered_set_print(f, "DNS=", dns);
|
||||
ordered_set_print(f, "NTP=", ntp);
|
||||
ordered_set_print(f, "SIP=", sip);
|
||||
@@ -291,6 +308,12 @@ int manager_save(Manager *m) {
|
||||
log_oom();
|
||||
}
|
||||
|
||||
if (m->online_state != online_state) {
|
||||
m->online_state = online_state;
|
||||
if (strv_extend(&p, "OnlineState") < 0)
|
||||
log_oom();
|
||||
}
|
||||
|
||||
if (p) {
|
||||
r = manager_send_changed_strv(m, p);
|
||||
if (r < 0)
|
||||
@@ -445,9 +468,13 @@ int link_save(Link *link) {
|
||||
|
||||
if (link->network) {
|
||||
char **dhcp6_domains = NULL, **dhcp_domains = NULL;
|
||||
const char *dhcp_domainname = NULL, *p;
|
||||
const char *dhcp_domainname = NULL, *online_state, *p;
|
||||
bool space;
|
||||
|
||||
online_state = link_online_state_to_string(link->online_state);
|
||||
if (online_state)
|
||||
fprintf(f, "ONLINE_STATE=%s\n", online_state);
|
||||
|
||||
fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
|
||||
yes_no(link->network->required_for_online));
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ int sd_network_get_carrier_state(char **state);
|
||||
int sd_network_get_address_state(char **state);
|
||||
int sd_network_get_ipv4_address_state(char **state);
|
||||
int sd_network_get_ipv6_address_state(char **state);
|
||||
int sd_network_get_online_state(char **state);
|
||||
|
||||
/* Get DNS entries for all links. These are string representations of
|
||||
* IP addresses */
|
||||
@@ -99,6 +100,7 @@ int sd_network_link_get_carrier_state(int ifindex, char **state);
|
||||
int sd_network_link_get_address_state(int ifindex, char **state);
|
||||
int sd_network_link_get_ipv4_address_state(int ifindex, char **state);
|
||||
int sd_network_link_get_ipv6_address_state(int ifindex, char **state);
|
||||
int sd_network_link_get_online_state(int ifindex, char **state);
|
||||
|
||||
/* Indicates whether the network is relevant to being online.
|
||||
* Possible return codes:
|
||||
|
||||
@@ -412,6 +412,7 @@ DHCP={dhcp_mode}
|
||||
out = subprocess.check_output(['networkctl', '-n', '0', 'status', self.iface])
|
||||
self.assertRegex(out, br'Type:\s+ether')
|
||||
self.assertRegex(out, br'State:\s+routable.*configured')
|
||||
self.assertRegex(out, br'Online state:\s+online')
|
||||
self.assertRegex(out, br'Address:\s+192.168.5.\d+')
|
||||
if ipv6:
|
||||
self.assertRegex(out, br'2600::')
|
||||
|
||||
Reference in New Issue
Block a user