Blame SOURCES/1010-manager-delete-default-connection-when-veth-removed.patch

fd19ff
From a2cd778f7d54de1cf9f173fff5f09fededf5f49e Mon Sep 17 00:00:00 2001
fd19ff
From: Beniamino Galvani <bgalvani@redhat.com>
fd19ff
Date: Wed, 21 Apr 2021 13:42:45 +0200
fd19ff
Subject: [PATCH 1/2] device: take reference to device object before
fd19ff
 'delete_on_deactivate'
fd19ff
fd19ff
It's not clear why currently a weak reference is needed.
fd19ff
fd19ff
(cherry picked from commit a42682d44fe2220412574fb13128814e643ed775)
fd19ff
(cherry picked from commit 8cfbb73294e9eaa475d28a6eada2c5ab14f1d74a)
fd19ff
---
fd19ff
 src/core/devices/nm-device.c | 44 ++++++++++++------------------------
fd19ff
 1 file changed, 15 insertions(+), 29 deletions(-)
fd19ff
fd19ff
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
fd19ff
index 5eaf8c23e7..7c2a6d3250 100644
fd19ff
--- a/src/core/devices/nm-device.c
fd19ff
+++ b/src/core/devices/nm-device.c
fd19ff
@@ -125,7 +125,6 @@ typedef struct {
fd19ff
 typedef struct {
fd19ff
     NMDevice *device;
fd19ff
     guint     idle_add_id;
fd19ff
-    int       ifindex;
fd19ff
 } DeleteOnDeactivateData;
fd19ff
 
fd19ff
 typedef struct {
fd19ff
@@ -12141,28 +12140,19 @@ nm_device_is_nm_owned(NMDevice *self)
fd19ff
 static gboolean
fd19ff
 delete_on_deactivate_link_delete(gpointer user_data)
fd19ff
 {
fd19ff
-    DeleteOnDeactivateData *data = user_data;
fd19ff
-    NMDevice *              self = data->device;
fd19ff
+    DeleteOnDeactivateData *data        = user_data;
fd19ff
+    nm_auto_unref_object NMDevice *self = data->device;
fd19ff
+    NMDevicePrivate *              priv = NM_DEVICE_GET_PRIVATE(self);
fd19ff
+    gs_free_error GError *error         = NULL;
fd19ff
 
fd19ff
     _LOGD(LOGD_DEVICE,
fd19ff
-          "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
fd19ff
-          data->ifindex,
fd19ff
+          "delete_on_deactivate: cleanup and delete virtual link (id=%u)",
fd19ff
           data->idle_add_id);
fd19ff
 
fd19ff
-    if (data->device) {
fd19ff
-        NMDevicePrivate *priv       = NM_DEVICE_GET_PRIVATE(data->device);
fd19ff
-        gs_free_error GError *error = NULL;
fd19ff
+    priv->delete_on_deactivate_data = NULL;
fd19ff
 
fd19ff
-        g_object_remove_weak_pointer(G_OBJECT(data->device), (void **) &data->device);
fd19ff
-        priv->delete_on_deactivate_data = NULL;
fd19ff
-
fd19ff
-        if (!nm_device_unrealize(data->device, TRUE, &error))
fd19ff
-            _LOGD(LOGD_DEVICE,
fd19ff
-                  "delete_on_deactivate: unrealizing %d failed (%s)",
fd19ff
-                  data->ifindex,
fd19ff
-                  error->message);
fd19ff
-    } else if (data->ifindex > 0)
fd19ff
-        nm_platform_link_delete(nm_device_get_platform(self), data->ifindex);
fd19ff
+    if (!nm_device_unrealize(self, TRUE, &error))
fd19ff
+        _LOGD(LOGD_DEVICE, "delete_on_deactivate: unrealizing failed (%s)", error->message);
fd19ff
 
fd19ff
     nm_device_emit_recheck_auto_activate(self);
fd19ff
 
fd19ff
@@ -12181,17 +12171,16 @@ delete_on_deactivate_unschedule(NMDevice *self)
fd19ff
         priv->delete_on_deactivate_data = NULL;
fd19ff
 
fd19ff
         g_source_remove(data->idle_add_id);
fd19ff
-        g_object_remove_weak_pointer(G_OBJECT(self), (void **) &data->device);
fd19ff
         _LOGD(LOGD_DEVICE,
fd19ff
-              "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)",
fd19ff
-              data->ifindex,
fd19ff
+              "delete_on_deactivate: cancel cleanup and delete virtual link (id=%u)",
fd19ff
               data->idle_add_id);
fd19ff
+        g_object_unref(data->device);
fd19ff
         g_free(data);
fd19ff
     }
fd19ff
 }
fd19ff
 
fd19ff
 static void
fd19ff
-delete_on_deactivate_check_and_schedule(NMDevice *self, int ifindex)
fd19ff
+delete_on_deactivate_check_and_schedule(NMDevice *self)
fd19ff
 {
fd19ff
     NMDevicePrivate *       priv = NM_DEVICE_GET_PRIVATE(self);
fd19ff
     DeleteOnDeactivateData *data;
fd19ff
@@ -12208,16 +12197,13 @@ delete_on_deactivate_check_and_schedule(NMDevice *self, int ifindex)
fd19ff
         return;
fd19ff
     delete_on_deactivate_unschedule(self); /* always cancel and reschedule */
fd19ff
 
fd19ff
-    data = g_new(DeleteOnDeactivateData, 1);
fd19ff
-    g_object_add_weak_pointer(G_OBJECT(self), (void **) &data->device);
fd19ff
-    data->device                    = self;
fd19ff
-    data->ifindex                   = ifindex;
fd19ff
+    data                            = g_new(DeleteOnDeactivateData, 1);
fd19ff
+    data->device                    = g_object_ref(self);
fd19ff
     data->idle_add_id               = g_idle_add(delete_on_deactivate_link_delete, data);
fd19ff
     priv->delete_on_deactivate_data = data;
fd19ff
 
fd19ff
     _LOGD(LOGD_DEVICE,
fd19ff
-          "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)",
fd19ff
-          ifindex,
fd19ff
+          "delete_on_deactivate: schedule cleanup and delete virtual link (id=%u)",
fd19ff
           data->idle_add_id);
fd19ff
 }
fd19ff
 
fd19ff
@@ -15854,7 +15840,7 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type)
fd19ff
         /* Check if the device was deactivated, and if so, delete_link.
fd19ff
          * Don't call delete_link synchronously because we are currently
fd19ff
          * handling a state change -- which is not reentrant. */
fd19ff
-        delete_on_deactivate_check_and_schedule(self, nm_device_get_ip_ifindex(self));
fd19ff
+        delete_on_deactivate_check_and_schedule(self);
fd19ff
     }
fd19ff
 
fd19ff
     /* ip_iface should be cleared after flushing all routes and addresses, since
fd19ff
-- 
fd19ff
2.26.3
fd19ff
fd19ff
fd19ff
From a8eac46cc6a0579cd1b17634c50d9a54518cb53e Mon Sep 17 00:00:00 2001
fd19ff
From: Beniamino Galvani <bgalvani@redhat.com>
fd19ff
Date: Wed, 31 Mar 2021 21:32:43 +0200
fd19ff
Subject: [PATCH 2/2] manager: ensure auto default connection is deleted when a
fd19ff
 veth goes away
fd19ff
fd19ff
When the link goes away the manager keeps software devices alive as
fd19ff
unrealized because there is still a connection for them.
fd19ff
fd19ff
If the device is software and has a NM-generated connection, keeping
fd19ff
the device alive means that also the generated connection stays
fd19ff
alive. The result is that both stick around forever even if there is
fd19ff
no longer a kernel link.
fd19ff
fd19ff
Add a check to avoid this situation.
fd19ff
fd19ff
https://bugzilla.redhat.com/show_bug.cgi?id=1945282
fd19ff
fd19ff
Fixes: cd0cf9229d49 ('veth: add support to configure veth interfaces')
fd19ff
(cherry picked from commit d19773ecd4bee36f11749085a15d70a49168c0b7)
fd19ff
(cherry picked from commit 5279b85e02341d24a18fc8dd9238f9f68b733bff)
fd19ff
---
fd19ff
 src/core/nm-manager.c | 45 +++++++++++++++++++++++++++++++++++++++++--
fd19ff
 1 file changed, 43 insertions(+), 2 deletions(-)
fd19ff
fd19ff
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
fd19ff
index c751b2db50..804e8db0f0 100644
fd19ff
--- a/src/core/nm-manager.c
fd19ff
+++ b/src/core/nm-manager.c
fd19ff
@@ -3519,6 +3519,45 @@ typedef struct {
fd19ff
     guint      idle_id;
fd19ff
 } PlatformLinkCbData;
fd19ff
 
fd19ff
+static gboolean
fd19ff
+_check_remove_dev_on_link_deleted(NMManager *self, NMDevice *device)
fd19ff
+{
fd19ff
+    NMManagerPrivate *           priv  = NM_MANAGER_GET_PRIVATE(self);
fd19ff
+    NMSettingsConnection *const *scons = NULL;
fd19ff
+    NMConnection *               con;
fd19ff
+    guint                        i;
fd19ff
+
fd19ff
+    nm_assert(nm_device_is_software(device));
fd19ff
+
fd19ff
+    /* In general, software devices stick around as unrealized
fd19ff
+     * until their connection is removed. However, we don't want
fd19ff
+     * that a NM-generated connection keeps the device alive.
fd19ff
+     * If there are no other compatible connections, the device
fd19ff
+     * should be also removed.
fd19ff
+     */
fd19ff
+
fd19ff
+    scons = nm_settings_get_connections(priv->settings, NULL);
fd19ff
+
fd19ff
+    for (i = 0; scons[i]; i++) {
fd19ff
+        con = nm_settings_connection_get_connection(scons[i]);
fd19ff
+        if (!nm_connection_is_virtual(con))
fd19ff
+            continue;
fd19ff
+
fd19ff
+        if (NM_FLAGS_HAS(nm_settings_connection_get_flags(scons[i]),
fd19ff
+                         NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED))
fd19ff
+            continue;
fd19ff
+
fd19ff
+        if (!nm_device_check_connection_compatible(device, con, NULL))
fd19ff
+            continue;
fd19ff
+
fd19ff
+        /* Found a virtual connection compatible, the device must
fd19ff
+         * stay around unrealized. */
fd19ff
+        return FALSE;
fd19ff
+    }
fd19ff
+
fd19ff
+    return TRUE;
fd19ff
+}
fd19ff
+
fd19ff
 static gboolean
fd19ff
 _platform_link_cb_idle(PlatformLinkCbData *data)
fd19ff
 {
fd19ff
@@ -3544,13 +3583,15 @@ _platform_link_cb_idle(PlatformLinkCbData *data)
fd19ff
         if (device) {
fd19ff
             if (nm_device_is_software(device)) {
fd19ff
                 nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
fd19ff
-                /* Our software devices stick around until their connection is removed */
fd19ff
                 if (!nm_device_unrealize(device, FALSE, &error)) {
fd19ff
                     _LOG2W(LOGD_DEVICE, device, "failed to unrealize: %s", error->message);
fd19ff
                     g_clear_error(&error);
fd19ff
                     remove_device(self, device, FALSE);
fd19ff
                 } else {
fd19ff
-                    nm_device_update_from_platform_link(device, NULL);
fd19ff
+                    if (_check_remove_dev_on_link_deleted(self, device))
fd19ff
+                        remove_device(self, device, FALSE);
fd19ff
+                    else
fd19ff
+                        nm_device_update_from_platform_link(device, NULL);
fd19ff
                 }
fd19ff
             } else {
fd19ff
                 /* Hardware and external devices always get removed when their kernel link is gone */
fd19ff
-- 
fd19ff
2.26.3
fd19ff