From 222d392527d3c74d31d08166eb1580b9c4f5204f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 11 Jun 2014 16:47:07 +0200 Subject: [PATCH 1/1] core: fix deactivation of assumed connections on device removal (bgo #729833) The following procedure leaves an NMActiveConnection around for a deactivated device, which causes errors in libnm-glib clients when they cannot create the GObject for the non-existent device of the AC. 1) allow a device which can assume connections to be activated 2) stop NM, which should leave the device's IP configuration up 3) start NM and allow it to assume the device's existing connection 4) remove the device, either by unplugging it or 'rmmod' The device is removed by nm-manager.c::remove_device(), but the device object is not moved to UNMANAGED state, leaving the NMActiveConnection completely unaware the device has gone away. The nm-manager.c::remove_device() code did not correctly handle moving a forcibly removed (eg, by unplugging or 'ip link del' or 'rmmod') device to the UNMANAGED state when the device was active with an assumed connection. To fix this, make the conditions when the device should be deactivated on removal much more explicit. A device should be deactivated on removal if: 1) it is forcibly removed, eg by the kernel network interface being removed due to 'ip link del' or hotplugging, or internally by NM due to a parent WWAN interface taking priority over a WWAN ethernet interface 2) if the device cannot assume connections, in which case NetworkManager must have activated the device and since we cannot assume the connection on restart, we should deactivate it 3) if the device is not activated, to ensure that its IPv6 parameters and other things get reset to the pre-NetworkManager values https://bugzilla.gnome.org/show_bug.cgi?id=729833 https://bugzilla.gnome.org/show_bug.cgi?id=731277 https://bugzilla.redhat.com/show_bug.cgi?id=1108167 Related: https://bugzilla.gnome.org/show_bug.cgi?id=729832 (cherry picked from commit 4b6f0d50a456a29e17785fb8b13c11ce018b31db) Signed-off-by: Thomas Haller --- src/nm-manager.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index b7e89d7..d45226b 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -746,20 +746,23 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); if (nm_device_get_managed (device)) { - /* Leave configured interfaces up when quitting so they can be - * taken over again if NM starts up, and to ensure connectivity while - * NM is gone. Assumed connections don't get taken down even if they - * haven't been fully activated. - */ - - if ( !nm_device_can_assume_connections (device) - || (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) - || !quitting) { - NMActRequest *req = nm_device_get_act_request (device); + NMActRequest *req = nm_device_get_act_request (device); + gboolean unmanage = FALSE; - if (!req || !nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (req))) - nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED); - } + /* Leave activated interfaces up when quitting so their configuration + * can be taken over when NM restarts. This ensures connectivity while + * NM is stopped. Devices which do not support connection assumption + * cannot be left up. + */ + if (!quitting) /* Forced removal; device already gone */ + unmanage = TRUE; + else if (!nm_device_can_assume_connections (device)) + unmanage = TRUE; + else if (!req) + unmanage = TRUE; + + if (unmanage) + nm_device_set_manager_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED); } g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, manager); -- 1.8.3.1