mirror of
https://github.com/systemd/systemd
synced 2024-07-09 04:26:06 +00:00
Merge pull request #12762 from yuwata/network-introduce-carrier-and-network-state-12752
network: introduce carrier and address state to fix network_is_online()
This commit is contained in:
commit
762267cdc1
|
@ -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;
|
||||
|
@ -32,3 +37,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);
|
||||
|
|
|
@ -20,5 +20,30 @@ 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_;
|
||||
|
||||
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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
#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"
|
||||
#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,13 +63,15 @@ 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", "(tt)", property_get_bit_rates, 0, 0),
|
||||
|
||||
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;
|
||||
|
@ -145,17 +150,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 +168,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);
|
||||
}
|
||||
|
|
20
src/network/networkd-link-bus.h
Normal file
20
src/network/networkd-link-bus.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* 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_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);
|
|
@ -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"
|
||||
|
@ -358,69 +360,110 @@ 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;
|
||||
_cleanup_strv_free_ char **p = NULL;
|
||||
uint8_t scope = RT_SCOPE_NOWHERE;
|
||||
bool changed = false;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -3563,7 +3606,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;
|
||||
|
@ -3587,6 +3630,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;
|
||||
|
@ -3596,8 +3645,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;
|
||||
|
|
|
@ -60,6 +60,8 @@ typedef struct Link {
|
|||
|
||||
LinkState state;
|
||||
LinkOperationalState operstate;
|
||||
LinkCarrierState carrier_state;
|
||||
LinkAddressState address_state;
|
||||
|
||||
unsigned address_messages;
|
||||
unsigned address_label_messages;
|
||||
|
@ -183,12 +185,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);
|
||||
|
|
|
@ -2,32 +2,30 @@
|
|||
|
||||
#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
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -1105,9 +1106,12 @@ 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;
|
||||
const char *operstate_str;
|
||||
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
|
||||
LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
|
||||
const char *operstate_str, *carrier_state_str, *address_state_str;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
@ -1137,6 +1141,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;
|
||||
|
||||
|
@ -1208,9 +1218,18 @@ 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);
|
||||
|
||||
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;
|
||||
|
@ -1219,7 +1238,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);
|
||||
|
@ -1241,9 +1263,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;
|
||||
|
|
|
@ -33,6 +33,8 @@ struct Manager {
|
|||
|
||||
char *state_file;
|
||||
LinkOperationalState operational_state;
|
||||
LinkCarrierState carrier_state;
|
||||
LinkAddressState address_state;
|
||||
|
||||
Hashmap *links;
|
||||
Hashmap *netdevs;
|
||||
|
@ -83,7 +85,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(Manager *m, const char *property, ...) _sentinel_;
|
||||
int manager_send_changed_strv(Manager *m, char **properties);
|
||||
void manager_dirty(Manager *m);
|
||||
|
||||
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue
Block a user