From 8bceafa7771800c8bdfc1b74ef39824103f5c129 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 11 Dec 2020 12:15:45 +0900 Subject: [PATCH 1/2] 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. --- src/network/networkd-link-bus.c | 11 ++++++----- src/network/networkd-link.c | 30 ++++++++++++++++-------------- 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; From f8dd40779a9aa83dc489863415739dfaedd1b004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 11 Dec 2020 11:39:16 +0100 Subject: [PATCH 2/2] network: adjust comments Co-authored-by: Carlo Teubner <435950+c4rlo@users.noreply.github.com> --- src/network/networkd-link.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index cb2fac0278..b7047c06d1 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2223,10 +2223,10 @@ int link_reconfigure(Link *link, bool force) { int r; /* 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. */ + * the function from being called multiple times simultaneously, refuse to reconfigure the + * interface in these cases. */ if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED, LINK_STATE_LINGER)) - return 0; /* o means no-op. */ + return 0; /* 0 means no-op. */ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);