]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not reconfigure interface when the link gains carrier but udev not initia...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Dec 2020 03:15:45 +0000 (12:15 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Dec 2020 03:27:27 +0000 (12:27 +0900)
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
src/network/networkd-link.c

index 9f4c719e31d384d93ab20e4716018907eefd7d83..4df31df4a20c22e9333fc6ba24c41f52c52aa347 100644 (file)
@@ -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);
 }
index 547f3bbc0127282b7e80576e71fa311397705faf..cb2fac0278e7c3e04de5d5037df2a23f4a81d340 100644 (file)
@@ -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;