diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 6eb63355a4..06709679a0 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -112,13 +112,19 @@ static void netdev_callbacks_clear(NetDev *netdev) { } } +static void netdev_detach_from_manager(NetDev *netdev) { + if (netdev->ifname && netdev->manager) + hashmap_remove(netdev->manager->netdevs, netdev->ifname); + + netdev->manager = NULL; +} + static NetDev *netdev_free(NetDev *netdev) { assert(netdev); netdev_callbacks_clear(netdev); - if (netdev->ifname && netdev->manager) - hashmap_remove(netdev->manager->netdevs, netdev->ifname); + netdev_detach_from_manager(netdev); free(netdev->filename); @@ -167,6 +173,8 @@ void netdev_drop(NetDev *netdev) { netdev_callbacks_clear(netdev); + netdev_detach_from_manager(netdev); + netdev_unref(netdev); return; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index c4923980e3..a52ddee118 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -503,6 +503,17 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { return 0; } +static void link_detach_from_manager(Link *link) { + if (!link || !link->manager) + return; + + hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); + set_remove(link->manager->links_requesting_uuid, link); + link_clean(link); + + link->manager = NULL; +} + static Link *link_free(Link *link) { Address *address; Link *carrier; @@ -552,11 +563,7 @@ static Link *link_free(Link *link) { sd_ndisc_unref(link->ndisc); sd_radv_unref(link->radv); - if (link->manager) { - hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); - set_remove(link->manager->links_requesting_uuid, link); - link_clean(link); - } + link_detach_from_manager(link); free(link->ifname); @@ -2265,6 +2272,9 @@ void link_drop(Link *link) { log_link_debug(link, "Link removed"); (void) unlink(link->state_file); + + link_detach_from_manager(link); + link_unref(link); return; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 9dcd911535..89fbb4168b 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1407,10 +1407,9 @@ int manager_new(Manager **ret) { } void manager_free(Manager *m) { - Network *network; - NetDev *netdev; - Link *link; AddressPool *pool; + Network *network; + Link *link; if (!m) return; @@ -1437,16 +1436,14 @@ void manager_free(Manager *m) { link_unref(link); } - set_free_with_destructor(m->dirty_links, link_unref); - hashmap_free(m->links); - set_free(m->links_requesting_uuid); + m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref); + m->links = hashmap_free(m->links); + m->links_requesting_uuid = set_free(m->links_requesting_uuid); set_free(m->duids_requesting_uuid); hashmap_free(m->networks_by_name); - while ((netdev = hashmap_first(m->netdevs))) - netdev_unref(netdev); - hashmap_free(m->netdevs); + m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref); while ((pool = m->address_pools)) address_pool_free(pool);