summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-04-15 17:34:00 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-25 10:44:46 +0200
commitbd08ce56156751d58584a44e766ef61340cdae2d (patch)
treebff9431752249fd71641cc74b3a1cd73f7a34586
parent0beb9542e90ab1c5d1507a1046a326fbcf73861c (diff)
downloadsystemd-bd08ce56156751d58584a44e766ef61340cdae2d.tar.gz
network: prevent interfaces to be initialized multiple times
When a uevent is received during the relevant interface is in LINK_STATE_PENDING, then the interface may be initialized twice. To prevent that, this introduces LINK_STATE_INITIALIZED.
-rw-r--r--src/network/networkd-link.c15
-rw-r--r--src/network/networkd-link.h13
2 files changed, 17 insertions, 11 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 49363299e5..3bc7f69cb3 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1455,7 +1455,7 @@ static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
log_link_debug(link, "Setting MTU done.");
- if (link->state == LINK_STATE_PENDING)
+ if (link->state == LINK_STATE_INITIALIZED)
(void) link_configure_after_setting_mtu(link);
return 1;
@@ -2644,7 +2644,7 @@ static int link_enter_join_netdev(Link *link) {
assert(link);
assert(link->network);
- assert(link->state == LINK_STATE_PENDING);
+ assert(link->state == LINK_STATE_INITIALIZED);
link_set_state(link, LINK_STATE_CONFIGURING);
@@ -3057,7 +3057,7 @@ static int link_configure(Link *link) {
assert(link);
assert(link->network);
- assert(link->state == LINK_STATE_PENDING);
+ assert(link->state == LINK_STATE_INITIALIZED);
if (STRPTR_IN_SET(link->kind, "can", "vcan"))
return link_configure_can(link);
@@ -3206,7 +3206,7 @@ static int link_configure_after_setting_mtu(Link *link) {
assert(link);
assert(link->network);
- assert(link->state == LINK_STATE_PENDING);
+ assert(link->state == LINK_STATE_INITIALIZED);
if (link->setting_mtu)
return 0;
@@ -3357,10 +3357,13 @@ static int link_initialized_and_synced(Link *link) {
assert(link->ifname);
assert(link->manager);
- if (link->state != LINK_STATE_PENDING)
+ /* We may get called either from the asynchronous netlink callback,
+ * or directly for link_add() if running in a container. See link_add(). */
+ if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED))
return 1;
log_link_debug(link, "Link state is up-to-date");
+ link_set_state(link, LINK_STATE_INITIALIZED);
r = link_new_bound_by_list(link);
if (r < 0)
@@ -3436,6 +3439,7 @@ int link_initialized(Link *link, sd_device *device) {
return 0;
log_link_debug(link, "udev initialized link");
+ link_set_state(link, LINK_STATE_INITIALIZED);
link->sd_device = sd_device_ref(device);
@@ -4353,6 +4357,7 @@ void link_clean(Link *link) {
static const char* const link_state_table[_LINK_STATE_MAX] = {
[LINK_STATE_PENDING] = "pending",
+ [LINK_STATE_INITIALIZED] = "initialized",
[LINK_STATE_CONFIGURING] = "configuring",
[LINK_STATE_CONFIGURED] = "configured",
[LINK_STATE_UNMANAGED] = "unmanaged",
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index e65246c87d..e322ec2262 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -20,12 +20,13 @@
#include "set.h"
typedef enum LinkState {
- LINK_STATE_PENDING,
- LINK_STATE_CONFIGURING,
- LINK_STATE_CONFIGURED,
- LINK_STATE_UNMANAGED,
- LINK_STATE_FAILED,
- LINK_STATE_LINGER,
+ LINK_STATE_PENDING, /* udev has not initialized the link */
+ LINK_STATE_INITIALIZED, /* udev has initialized the link */
+ LINK_STATE_CONFIGURING, /* configuring addresses, routes, etc. */
+ LINK_STATE_CONFIGURED, /* everything is configured */
+ LINK_STATE_UNMANAGED, /* Unmanaged=yes is set */
+ LINK_STATE_FAILED, /* at least one configuration process failed */
+ LINK_STATE_LINGER, /* RTM_DELLINK for the link has been received */
_LINK_STATE_MAX,
_LINK_STATE_INVALID = -1
} LinkState;