diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2021-03-31 21:32:43 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2021-04-21 14:57:07 +0200 |
commit | d19773ecd4bee36f11749085a15d70a49168c0b7 (patch) | |
tree | ee23bb2b32cd28ddf712a6680d4ca36559a9172b | |
parent | a42682d44fe2220412574fb13128814e643ed775 (diff) | |
download | NetworkManager-bg/rh1945282.tar.gz |
manager: ensure auto default connection is deleted when a veth goes awaybg/rh1945282
When the link goes away the manager keeps software devices alive as
unrealized because there is still a connection for them.
If the device is software and has a NM-generated connection, keeping
the device alive means that also the generated connection stays
alive. The result is that both stick around forever even if there is
no longer a kernel link.
Add a check to avoid this situation.
https://bugzilla.redhat.com/show_bug.cgi?id=1945282
Fixes: cd0cf9229d49 ('veth: add support to configure veth interfaces')
-rw-r--r-- | src/core/nm-manager.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 90bfad73ee..216dc8d2dd 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -3511,6 +3511,45 @@ typedef struct { } PlatformLinkCbData; static gboolean +_check_remove_dev_on_link_deleted(NMManager *self, NMDevice *device) +{ + NMManagerPrivate * priv = NM_MANAGER_GET_PRIVATE(self); + NMSettingsConnection *const *scons = NULL; + NMConnection * con; + guint i; + + nm_assert(nm_device_is_software(device)); + + /* In general, software devices stick around as unrealized + * until their connection is removed. However, we don't want + * that a NM-generated connection keeps the device alive. + * If there are no other compatible connections, the device + * should be also removed. + */ + + scons = nm_settings_get_connections(priv->settings, NULL); + + for (i = 0; scons[i]; i++) { + con = nm_settings_connection_get_connection(scons[i]); + if (!nm_connection_is_virtual(con)) + continue; + + if (NM_FLAGS_HAS(nm_settings_connection_get_flags(scons[i]), + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) + continue; + + if (!nm_device_check_connection_compatible(device, con, NULL)) + continue; + + /* Found a virtual connection compatible, the device must + * stay around unrealized. */ + return FALSE; + } + + return TRUE; +} + +static gboolean _platform_link_cb_idle(PlatformLinkCbData *data) { int ifindex = data->ifindex; @@ -3535,13 +3574,15 @@ _platform_link_cb_idle(PlatformLinkCbData *data) if (device) { if (nm_device_is_software(device)) { nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_REMOVED); - /* Our software devices stick around until their connection is removed */ if (!nm_device_unrealize(device, FALSE, &error)) { _LOG2W(LOGD_DEVICE, device, "failed to unrealize: %s", error->message); g_clear_error(&error); remove_device(self, device, FALSE); } else { - nm_device_update_from_platform_link(device, NULL); + if (_check_remove_dev_on_link_deleted(self, device)) + remove_device(self, device, FALSE); + else + nm_device_update_from_platform_link(device, NULL); } } else { /* Hardware and external devices always get removed when their kernel link is gone */ |