chiark / gitweb /
networkd: netdev - take ref when creating netdevs
[elogind.git] / src / network / networkd-netdev.c
index 13338aec512fcd173acfd913cde7c388e4d2f7f1..20917e334b3092513048b79eed30d7af58fa0549 100644 (file)
@@ -222,8 +222,9 @@ static int netdev_enter_ready(NetDev *netdev) {
         return 0;
 }
 
+/* callback for netdev's created without a backing Link */
 static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        NetDev *netdev = userdata;
+        _cleanup_netdev_unref_ NetDev *netdev = userdata;
         int r;
 
         assert(netdev->state != _NETDEV_STATE_INVALID);
@@ -387,9 +388,11 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
 
         if (link)
                 r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
-        else
+        else {
                 r = sd_rtnl_call_async(netdev->manager->rtnl, req, &netdev_create_handler, netdev, 0, NULL);
-        if (r < 0) {
+
+                netdev_ref(netdev);
+        } if (r < 0) {
                 log_error_netdev(netdev,
                                  "Could not send rtnetlink message: %s", strerror(-r));
                 return r;
@@ -402,6 +405,7 @@ static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
         return 0;
 }
 
+/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
 int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
         int r;
 
@@ -415,7 +419,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac
         case NETDEV_KIND_GRE:
         case NETDEV_KIND_SIT:
         case NETDEV_KIND_VTI:
-                return netdev_create_tunnel(link, netdev_create_handler);
+                return netdev_create_tunnel(netdev, link, callback);
         default:
                 break;
         }