From c1a3890410f043fe09af8b139eb6bfe2832089be Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Thu, 30 Nov 2017 12:03:50 -0500 Subject: [PATCH] Add a "RequiredForOnline=" Link attribute for .network files (#7347) RequiredForOnline= denotes a link/network that does/does not require being up for systemd-networkd-wait-online to consider the system online; this makes it possible to ignore devices without modifying parameters to wait-online. --- man/systemd.network.xml | 15 +++++++++++++++ src/libsystemd/sd-network/sd-network.c | 15 +++++++++++++++ src/network/networkd-link.c | 3 +++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 2 ++ src/network/wait-online/link.c | 2 ++ src/network/wait-online/link.h | 2 +- src/network/wait-online/manager.c | 3 +++ src/systemd/sd-network.h | 8 ++++++++ 10 files changed, 51 insertions(+), 1 deletion(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 57f27e6..5a5ecb0 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -252,6 +252,21 @@ controlled by other applications. + + RequiredForOnline= + + A boolean. When yes, the network is deemed + required when determining whether the system is online when running + systemd-networkd-wait-online. + When no, the network is ignored when checking for + online state. Defaults to yes. + The network will be brought up normally in all cases, but in + the event that there is no address being assigned by DHCP or the + cable is not plugged in, the link will simply remain offline and be + skipped automatically by systemd-networkd-wait-online + if RequiredForOnline=true. + + diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index e0f38b6..f6460b9 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -172,6 +172,21 @@ _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_required_for_online(int ifindex) { + _cleanup_free_ char *s = NULL; + int r; + + r = network_link_get_string(ifindex, "REQUIRED_FOR_ONLINE", &s); + if (r < 0) { + /* Handle -ENODATA as RequiredForOnline=yes, for compatibility */ + if (r == -ENODATA) + return true; + return r; + } + + return parse_boolean(s); +} + _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) { return network_link_get_string(ifindex, "LLMNR", llmnr); } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 473bd42..67cdea0 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3411,6 +3411,9 @@ int link_save(Link *link) { char **dhcp_domains = NULL; unsigned j; + fprintf(f, "REQUIRED_FOR_ONLINE=%s\n", + yes_no(link->network->required_for_online)); + if (link->dhcp6_client) { r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease); if (r < 0 && r != -ENOMSG) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 62c47d6..46eaa81 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -33,6 +33,7 @@ Link.MACAddress, config_parse_hwaddr, Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) Link.ARP, config_parse_tristate, 0, offsetof(Network, arp) Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged) +Link.RequiredForOnline, config_parse_bool, 0, offsetof(Network, required_for_online) Network.Description, config_parse_string, 0, offsetof(Network, description) Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 679d7ed..8e37a0a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -205,6 +205,7 @@ static int network_load_one(Manager *manager, const char *filename) { *d = '\0'; + network->required_for_online = true; network->dhcp = ADDRESS_FAMILY_NO; network->dhcp_use_ntp = true; network->dhcp_use_dns = true; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 4265ba6..49c6265 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -215,6 +215,8 @@ struct Network { uint32_t iaid; DUID duid; + bool required_for_online; /* Is this network required to be considered online? */ + LLDPMode lldp_mode; /* LLDP reception */ LLDPEmit lldp_emit; /* LLDP transmission */ diff --git a/src/network/wait-online/link.c b/src/network/wait-online/link.c index dfe18bd..f0cb70a 100644 --- a/src/network/wait-online/link.c +++ b/src/network/wait-online/link.c @@ -121,6 +121,8 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) { int link_update_monitor(Link *l) { assert(l); + l->required_for_online = sd_network_link_get_required_for_online(l->ifindex) != 0; + l->operational_state = mfree(l->operational_state); sd_network_link_get_operational_state(l->ifindex, &l->operational_state); diff --git a/src/network/wait-online/link.h b/src/network/wait-online/link.h index bf8b453..ab623ff 100644 --- a/src/network/wait-online/link.h +++ b/src/network/wait-online/link.h @@ -33,6 +33,7 @@ struct Link { char *ifname; unsigned flags; + bool required_for_online; char *operational_state; char *state; }; @@ -41,6 +42,5 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname); Link *link_free(Link *l); int link_update_rtnl(Link *l, sd_netlink_message *m); int link_update_monitor(Link *l); -bool link_relevant(Link *l); DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free); diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index f7a3ec8..05f030d 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -42,6 +42,9 @@ bool manager_ignore_link(Manager *m, Link *link) { if (m->interfaces && !strv_contains(m->interfaces, link->ifname)) return true; + if (!link->required_for_online) + return true; + /* ignore interfaces we explicitly are asked to ignore */ return strv_fnmatch(m->ignore, link->ifname, 0); } diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index 7f5a6bd..2d48946 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -95,6 +95,14 @@ int sd_network_link_get_setup_state(int ifindex, char **state); */ int sd_network_link_get_operational_state(int ifindex, char **state); +/* Indicates whether the network is relevant to being online. + * Possible return codes: + * 0: the connection is not required + * 1: the connection is required to consider the system online + * <0: networkd is not aware of the link + */ +int sd_network_link_get_required_for_online(int ifindex); + /* Get path to .network file applied to link */ int sd_network_link_get_network_file(int ifindex, char **filename); -- 2.7.4