]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make Link and NetDev always have the valid poiter to Manager
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 13 Jan 2019 15:30:37 +0000 (00:30 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 15 Jan 2019 13:48:53 +0000 (14:48 +0100)
c4397d94c3d94909188d82e086ebedf5d3690569 introduces
link_detach_from_manager() and netdev_detach_from_manager(), and they
set Link::manager or NetDev::manager NULL.
But, at the time e.g. link is removed, hence link_drop() is called,
there may be still some asynchronous netlink call is waiting, and
their callbacks hit assertion.

This make {link,netdev}_detach_from_manager() just drop all references
from manager, but keep the pointer to manager.

Fixes #11411.

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

index f0e9d002468b8b7ddd858e0a839e2666b21854bb..65959f4a03f308a22699b0cb77f573db28154349 100644 (file)
@@ -148,11 +148,16 @@ static void netdev_callbacks_clear(NetDev *netdev) {
         }
 }
 
+bool netdev_is_managed(NetDev *netdev) {
+        if (!netdev || !netdev->manager || !netdev->ifname)
+                return false;
+
+        return hashmap_get(netdev->manager->netdevs, netdev->ifname) == 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) {
index bfe1094181ae9692898b9d4b37d8720c31488432..d6524da0f3ba611e11c2181d380ad6bb08f2c2be 100644 (file)
@@ -156,6 +156,7 @@ NetDev *netdev_ref(NetDev *netdev);
 DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
 
+bool netdev_is_managed(NetDev *netdev);
 int netdev_get(Manager *manager, const char *name, NetDev **ret);
 int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
 int netdev_get_mac(const char *ifname, struct ether_addr **ret);
index 167cf650468d22e04123bdd2a0cc7c4c70b2c2ce..45b7c7c3306704d0e6cae4f648ae141a26c63f2f 100644 (file)
@@ -224,8 +224,7 @@ static int on_resolve_retry(sd_event_source *s, usec_t usec, void *userdata) {
         w = WIREGUARD(netdev);
         assert(w);
 
-        if (!netdev->manager)
-                /* The netdev is detached. */
+        if (!netdev_is_managed(netdev))
                 return 0;
 
         assert(!w->unresolved_endpoints);
@@ -260,8 +259,7 @@ static int wireguard_resolve_handler(sd_resolve_query *q,
         w = WIREGUARD(netdev);
         assert(w);
 
-        if (!netdev->manager)
-                /* The netdev is detached. */
+        if (!netdev_is_managed(netdev))
                 return 0;
 
         if (ret != 0) {
index 5353b9daaf2ffc1fc8d65b20a0cf27be374e04bb..3661498f391d4c2919fa1b82a9ab8a33dd85ac12 100644 (file)
@@ -517,8 +517,6 @@ static void link_detach_from_manager(Link *link) {
         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) {