From 1788c3462853e8bb955ff656007e20f402dd9af2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 10 Sep 2024 00:12:41 +0900 Subject: [PATCH] network/netdev: also check ifindex, iftype, and kind when assigning NetDev to Link 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 | 37 +++++++++++++++++++++++++++++++++++++ src/network/netdev/netdev.h | 1 + src/network/networkd-link.c | 10 ++-------- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index cc32e6d1a6e..21b897a65f0 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -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; } diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index d6b363d4f17..3bb4acf6c23 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -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); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 1c6f20695fd..f3131a6195f 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; -- 2.47.3