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.
This commit is contained in:
Yu Watanabe
2024-09-10 16:38:06 +09:00
parent f2129f1d8c
commit 1788c34628
3 changed files with 40 additions and 8 deletions
+37
View 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;
}
+1
View 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);
+2 -8
View 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;