]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: check the received interface name is actually new
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 12 Jul 2021 12:23:41 +0000 (21:23 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 13 Jul 2021 10:20:31 +0000 (19:20 +0900)
For some reasons I do not know, on interface renaming, kernel once send
netlink message with old interface name, and then send with new name.
If eth0 is renamed, and then new interface appears as eth0, then the
message with the old name 'eth0' makes the interface enters failed
state.

To ignore such invalid(?) rename event messages, let's confirm the
received interface name.

Fixes #20203.

src/network/networkd-link.c

index c1ab14ebec5d9d3747aa0e9b5a644b0cd76227e3..d38f5cd7cf9b854075694e15a1f5d34d4f2604fc 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <net/if.h>
 #include <netinet/in.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
@@ -20,6 +21,7 @@
 #include "ethtool-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "format-util.h"
 #include "fs-util.h"
 #include "ipvlan.h"
 #include "missing_network.h"
@@ -2160,6 +2162,7 @@ static int link_update_alternative_names(Link *link, sd_netlink_message *message
 }
 
 static int link_update_name(Link *link, sd_netlink_message *message) {
+        char ifname_from_index[IF_NAMESIZE + 1];
         const char *ifname;
         int r;
 
@@ -2176,6 +2179,16 @@ static int link_update_name(Link *link, sd_netlink_message *message) {
         if (streq(ifname, link->ifname))
                 return 0;
 
+        if (!format_ifname(link->ifindex, ifname_from_index))
+                return log_link_debug_errno(link, SYNTHETIC_ERRNO(ENXIO), "Could not get interface name for index %i.", link->ifindex);
+
+        if (!streq(ifname, ifname_from_index)) {
+                log_link_debug(link, "New interface name '%s' received from the kernel does not correspond "
+                               "with the name currently configured on the actual interface '%s'. Ignoring.",
+                               ifname, ifname_from_index);
+                return 0;
+        }
+
         log_link_info(link, "Interface name change detected, renamed to %s.", ifname);
 
         hashmap_remove(link->manager->links_by_name, link->ifname);