mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 08:26:52 +03:00
sd-network: expose both admin and operational state directly
Also add a call to check if a link is loopback, as this should commonly be ignored.
This commit is contained in:
parent
089377209f
commit
deb2e5230b
@ -326,17 +326,3 @@ int net_parse_inaddr(const char *address, unsigned char *family, void *dst) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool link_has_carrier(unsigned flags, uint8_t operstate) {
|
||||
/* see Documentation/networking/operstates.txt in the kernel sources */
|
||||
|
||||
if (operstate == IF_OPER_UP)
|
||||
return true;
|
||||
|
||||
if (operstate == IF_OPER_UNKNOWN)
|
||||
/* operstate may not be implemented, so fall back to flags */
|
||||
if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -65,5 +65,3 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
|
||||
int net_parse_inaddr(const char *address, unsigned char *family, void *dst);
|
||||
|
||||
int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
|
||||
|
||||
bool link_has_carrier(unsigned flags, uint8_t operstate);
|
||||
|
@ -1117,6 +1117,20 @@ static int link_acquire_conf(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_has_carrier(unsigned flags, uint8_t operstate) {
|
||||
/* see Documentation/networking/operstates.txt in the kernel sources */
|
||||
|
||||
if (operstate == IF_OPER_UP)
|
||||
return true;
|
||||
|
||||
if (operstate == IF_OPER_UNKNOWN)
|
||||
/* operstate may not be implemented, so fall back to flags */
|
||||
if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int link_update_flags(Link *link, sd_rtnl_message *m) {
|
||||
unsigned flags, flags_added, flags_removed, generic_flags;
|
||||
uint8_t operstate;
|
||||
@ -1216,6 +1230,8 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
|
||||
link->flags = flags;
|
||||
link->operstate = operstate;
|
||||
|
||||
link_save(link);
|
||||
|
||||
if (carrier_gained) {
|
||||
log_info_link(link, "gained carrier");
|
||||
|
||||
@ -1514,8 +1530,7 @@ static int link_configure(Link *link) {
|
||||
}
|
||||
}
|
||||
|
||||
if (link_has_carrier(link->flags, link->operstate))
|
||||
{
|
||||
if (link_has_carrier(link->flags, link->operstate)) {
|
||||
r = link_acquire_conf(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1669,16 +1684,26 @@ int link_update(Link *link, sd_rtnl_message *m) {
|
||||
}
|
||||
|
||||
int link_save(Link *link) {
|
||||
_cleanup_free_ char *temp_path = NULL;
|
||||
_cleanup_free_ char *temp_path = NULL, *lease_file = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *state;
|
||||
const char *admin_state, *oper_state = "unknown";
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->state_file);
|
||||
|
||||
state = link_state_to_string(link->state);
|
||||
assert(state);
|
||||
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";
|
||||
|
||||
r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
|
||||
link->ifindex);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = fopen_temporary(link->state_file, &f, &temp_path);
|
||||
if (r < 0)
|
||||
@ -1688,22 +1713,19 @@ int link_save(Link *link) {
|
||||
|
||||
fprintf(f,
|
||||
"# This is private data. Do not parse.\n"
|
||||
"STATE=%s\n", state);
|
||||
"ADMIN_STATE=%s\n"
|
||||
"OPER_STATE=%s\n"
|
||||
"FLAGS=%u\n",
|
||||
admin_state, oper_state, link->flags);
|
||||
|
||||
if (link->dhcp_lease) {
|
||||
_cleanup_free_ char *lease_file = NULL;
|
||||
|
||||
r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
|
||||
link->ifindex);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = dhcp_lease_save(link->dhcp_lease, lease_file);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
fprintf(f, "DHCP_LEASE=%s\n", lease_file);
|
||||
}
|
||||
} else
|
||||
unlink(lease_file);
|
||||
|
||||
fflush(f);
|
||||
|
||||
@ -1721,7 +1743,7 @@ finish:
|
||||
}
|
||||
|
||||
static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||
[LINK_STATE_INITIALIZING] = "configuring",
|
||||
[LINK_STATE_INITIALIZING] = "initializing",
|
||||
[LINK_STATE_ENSLAVING] = "configuring",
|
||||
[LINK_STATE_SETTING_ADDRESSES] = "configuring",
|
||||
[LINK_STATE_SETTING_ROUTES] = "configuring",
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/poll.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "macro.h"
|
||||
@ -33,6 +34,38 @@
|
||||
#include "sd-network.h"
|
||||
#include "dhcp-lease-internal.h"
|
||||
|
||||
static int link_get_flags(unsigned index, unsigned *flags) {
|
||||
_cleanup_free_ char *s = NULL, *p = NULL;
|
||||
int r;
|
||||
|
||||
assert(index);
|
||||
assert(flags);
|
||||
|
||||
if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = parse_env_file(p, NEWLINE, "FLAGS", &s, NULL);
|
||||
if (r == -ENOENT)
|
||||
return -ENODATA;
|
||||
else if (r < 0)
|
||||
return r;
|
||||
else if (!s)
|
||||
return -EIO;
|
||||
|
||||
return safe_atou(s, flags);
|
||||
}
|
||||
|
||||
_public_ int sd_network_link_is_loopback(unsigned index) {
|
||||
unsigned flags;
|
||||
int r;
|
||||
|
||||
r = link_get_flags(index, &flags);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
return flags & IFF_LOOPBACK;
|
||||
}
|
||||
|
||||
_public_ int sd_network_get_link_state(unsigned index, char **state) {
|
||||
_cleanup_free_ char *s = NULL, *p = NULL;
|
||||
int r;
|
||||
@ -43,8 +76,7 @@ _public_ int sd_network_get_link_state(unsigned index, char **state) {
|
||||
if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
|
||||
|
||||
r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
|
||||
if (r == -ENOENT)
|
||||
return -ENODATA;
|
||||
else if (r < 0)
|
||||
@ -54,6 +86,32 @@ _public_ int sd_network_get_link_state(unsigned index, char **state) {
|
||||
|
||||
if (streq(s, "unmanaged"))
|
||||
return -EUNATCH;
|
||||
else if (streq(s, "initializing"))
|
||||
return -EBUSY;
|
||||
|
||||
*state = s;
|
||||
s = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_network_get_link_operational_state(unsigned index, char **state) {
|
||||
_cleanup_free_ char *s = NULL, *p = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(index, -EINVAL);
|
||||
assert_return(state, -EINVAL);
|
||||
|
||||
if (asprintf(&p, "/run/systemd/network/links/%u", index) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
|
||||
if (r == -ENOENT)
|
||||
return -ENODATA;
|
||||
else if (r < 0)
|
||||
return r;
|
||||
else if (!s)
|
||||
return -EIO;
|
||||
|
||||
*state = s;
|
||||
s = NULL;
|
||||
|
@ -51,8 +51,24 @@
|
||||
|
||||
_SD_BEGIN_DECLARATIONS;
|
||||
|
||||
/* Get state from ifindex. Possible states: unknown, unmanaged, failed, configuring, configured */
|
||||
int sd_network_get_link_state(unsigned index, char**state);
|
||||
/* Get state from ifindex.
|
||||
* Possible states: failed, configuring, configured
|
||||
* Possible return codes:
|
||||
* -ENODATA: networkd is not aware of the link
|
||||
* -EUNATCH: networkd is not managing this link
|
||||
* -EBUSY: udev is still processing the link, networkd does not yet know if it will manage it
|
||||
*/
|
||||
int sd_network_get_link_state(unsigned index, char **state);
|
||||
|
||||
/* Get operatinal state from ifindex.
|
||||
* Possible states: unknown, dormant, carrier
|
||||
* Possible return codes:
|
||||
* -ENODATA: networkd is not aware of the link
|
||||
*/
|
||||
int sd_network_get_link_operational_state(unsigned index, char **state);
|
||||
|
||||
/* Returns true if link exists and is loopback, and false otherwise */
|
||||
int sd_network_link_is_loopback(unsigned index);
|
||||
|
||||
/* Get DHCPv4 lease from ifindex. */
|
||||
int sd_network_get_dhcp_lease(unsigned index, sd_dhcp_lease **ret);
|
||||
@ -65,7 +81,7 @@ int sd_network_get_ifindices(unsigned **indices);
|
||||
typedef struct sd_network_monitor sd_network_monitor;
|
||||
|
||||
/* Create a new monitor. Category must be NULL, "links" or "leases". */
|
||||
int sd_network_monitor_new(const char *category, sd_network_monitor** ret);
|
||||
int sd_network_monitor_new(const char *category, sd_network_monitor **ret);
|
||||
|
||||
/* Destroys the passed monitor. Returns NULL. */
|
||||
sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m);
|
||||
|
Loading…
Reference in New Issue
Block a user