summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-12-11 12:15:45 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2020-12-11 12:27:27 +0900
commit8bceafa7771800c8bdfc1b74ef39824103f5c129 (patch)
tree335b83ac77c68f3d894c40c505b8346b893a0e38
parent239952e890fd4b53859f84bbc43d910e68a8f6bc (diff)
downloadsystemd-8bceafa7771800c8bdfc1b74ef39824103f5c129.tar.gz
network: do not reconfigure interface when the link gains carrier but udev not initialized it yet
When an interface gains carrier but udev have not initialized the interface or link_initialized_handler() has not been called yet, then link_configure will be called twice. Thus LLDP client will be configured twice, and triggers assertion. Fixes #17929.
-rw-r--r--src/network/networkd-link-bus.c11
-rw-r--r--src/network/networkd-link.c30
2 files changed, 22 insertions, 19 deletions
diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
index 9f4c719e31..4df31df4a2 100644
--- a/src/network/networkd-link-bus.c
+++ b/src/network/networkd-link-bus.c
@@ -667,11 +667,12 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
r = link_reconfigure(l, true);
if (r < 0)
return r;
-
- link_set_state(l, LINK_STATE_INITIALIZED);
- r = link_save_and_clean(l);
- if (r < 0)
- return r;
+ if (r > 0) {
+ link_set_state(l, LINK_STATE_INITIALIZED);
+ r = link_save_and_clean(l);
+ if (r < 0)
+ return r;
+ }
return sd_bus_reply_method_return(message, NULL);
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 547f3bbc01..cb2fac0278 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2118,22 +2118,21 @@ static int link_configure_continue(Link *link) {
}
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
+ _cleanup_strv_free_ char **s = NULL;
Network *network;
int r;
- if (m) {
- _cleanup_strv_free_ char **s = NULL;
+ assert(m);
- r = sd_netlink_message_get_errno(m);
- if (r < 0)
- return r;
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0)
+ return r;
- r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
- if (r < 0 && r != -ENODATA)
- return r;
+ r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
+ if (r < 0 && r != -ENODATA)
+ return r;
- strv_free_and_replace(link->alternative_names, s);
- }
+ strv_free_and_replace(link->alternative_names, s);
r = network_get(link->manager, link->iftype, link->sd_device,
link->ifname, link->alternative_names, link->driver,
@@ -2223,8 +2222,11 @@ int link_reconfigure(Link *link, bool force) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
- if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
- return 0;
+ /* When link in pending or initialized state, then link_configure() will be called. To prevent
+ * the function be called multiple times simultaneously, refuse to reconfigure the interface in
+ * these case. */
+ if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED, LINK_STATE_LINGER))
+ return 0; /* o means no-op. */
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
link->ifindex);
@@ -2239,7 +2241,7 @@ int link_reconfigure(Link *link, bool force) {
link_ref(link);
- return 0;
+ return 1; /* 1 means the interface will be reconfigured. */
}
static int link_initialized_and_synced(Link *link) {
@@ -2476,7 +2478,7 @@ static int link_carrier_gained(Link *link) {
if (r < 0)
return r;
if (r > 0) {
- r = link_reconfigure_internal(link, NULL, false);
+ r = link_reconfigure(link, false);
if (r < 0) {
link_enter_failed(link);
return r;