]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/netdev: also check ifindex, iftype, and kind when assigning NetDev to Link
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Sep 2024 15:12:41 +0000 (00:12 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 10 Sep 2024 07:38:06 +0000 (16:38 +0900)
Even when a NetDev object with the same name found, its iftype or kind
may be different. For safety, let's also check them.

src/network/netdev/netdev.c
src/network/netdev/netdev.h
src/network/networkd-link.c

index cc32e6d1a6ecfd26fe2964fc624164c5a73b5280..21b897a65f09a97b03b8c255650e4959a3696466 100644 (file)
@@ -266,6 +266,43 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) {
         return 0;
 }
 
+void link_assign_netdev(Link *link) {
+        _unused_ _cleanup_(netdev_unrefp) NetDev *old = NULL;
+        NetDev *netdev;
+
+        assert(link);
+        assert(link->manager);
+        assert(link->ifname);
+
+        old = TAKE_PTR(link->netdev);
+
+        if (netdev_get(link->manager, link->ifname, &netdev) < 0)
+                return;
+
+        if (netdev->ifindex != link->ifindex)
+                return;
+
+        if (NETDEV_VTABLE(netdev)->iftype != link->iftype)
+                return;
+
+        if (!NETDEV_VTABLE(netdev)->skip_netdev_kind_check) {
+                const char *kind;
+
+                if (netdev->kind == NETDEV_KIND_TAP)
+                        kind = "tun"; /* the kernel does not distinguish between tun and tap */
+                else
+                        kind = netdev_kind_to_string(netdev->kind);
+
+                if (!streq_ptr(kind, link->kind))
+                        return;
+        }
+
+        link->netdev = netdev_ref(netdev);
+
+        if (netdev != old)
+                log_link_debug(link, "Found matching .netdev file: %s", netdev->filename);
+}
+
 void netdev_enter_failed(NetDev *netdev) {
         netdev->state = NETDEV_STATE_FAILED;
 }
index d6b363d4f1729c785bf6453bc19cf84442e5bf09..3bb4acf6c232884552c2a4c55ffe7757600a91d6 100644 (file)
@@ -207,6 +207,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
 
 bool netdev_is_managed(NetDev *netdev);
 int netdev_get(Manager *manager, const char *name, NetDev **ret);
+void link_assign_netdev(Link *link);
 int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
 int netdev_generate_hw_addr(NetDev *netdev, Link *link, const char *name,
                             const struct hw_addr_data *hw_addr, struct hw_addr_data *ret);
index 1c6f20695fd6800c727069e388c4fe2dabf94010..f3131a6195f70176b6668779d0bc04a87828bc72 100644 (file)
@@ -1307,18 +1307,15 @@ static int link_get_network(Link *link, Network **ret) {
 
 int link_reconfigure_impl(Link *link, bool force) {
         Network *network = NULL;
-        NetDev *netdev = NULL;
         int r;
 
         assert(link);
 
+        link_assign_netdev(link);
+
         if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
                 return 0;
 
-        r = netdev_get(link->manager, link->ifname, &netdev);
-        if (r < 0 && r != -ENOENT)
-                return r;
-
         r = link_get_network(link, &network);
         if (r < 0 && r != -ENOENT)
                 return r;
@@ -1383,9 +1380,6 @@ int link_reconfigure_impl(Link *link, bool force) {
         link_free_engines(link);
         link->network = network_unref(link->network);
 
-        netdev_unref(link->netdev);
-        link->netdev = netdev_ref(netdev);
-
         if (!network) {
                 link_set_state(link, LINK_STATE_UNMANAGED);
                 return 0;