iwd: Be extra careful not to interrupt assumed activation
The IWD backend would originally use .Disconnect() on IWD dbus "Station" objects to make sure IWD is out of autoconnect or that it isn't connecting to a network that NM didn't command. Later the default became to let IWD run autoconnect so now most of the time the backend just mirrors IWD's state to NMDevice's state. Now sometimes when NMDevice still seems to have an active connection but IWD has gone through one or more state changes (which we may see after a delay due to D-Bus) and is now connected to or connecting to a different network, NMDevice would first have to go through .deactivate to mirror the fact the original connection is no longer active, and it'd use .Disconnect() which could break the new connection, so check for this situation.
This commit is contained in:

committed by
Thomas Haller

parent
cbc2354854
commit
e384ab74c2
@@ -70,6 +70,7 @@ typedef struct {
|
||||
bool secrets_failed : 1;
|
||||
bool networks_requested : 1;
|
||||
bool networks_changed : 1;
|
||||
bool assuming : 1;
|
||||
gint64 last_scan;
|
||||
uint32_t ap_id;
|
||||
guint32 rate;
|
||||
@@ -581,6 +582,10 @@ deactivate(NMDevice *device)
|
||||
if (!priv->dbus_obj)
|
||||
return;
|
||||
|
||||
/* Don't cause IWD to break the connection being assumed */
|
||||
if (priv->assuming)
|
||||
return;
|
||||
|
||||
if (priv->dbus_station_proxy) {
|
||||
gs_unref_variant GVariant *value =
|
||||
g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State");
|
||||
@@ -2719,11 +2724,19 @@ state_changed(NMDeviceIwd *self, const char *new_state)
|
||||
"IWD is connecting to the wrong AP, %s activation",
|
||||
switch_ap ? "replacing" : "aborting");
|
||||
cleanup_association_attempt(self, !switch_ap);
|
||||
|
||||
if (!switch_ap) {
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (switch_ap)
|
||||
priv->assuming = TRUE; /* Don't send Station.Disconnect() */
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
priv->assuming = FALSE;
|
||||
assume_connection(self, ap);
|
||||
return;
|
||||
}
|
||||
|
Reference in New Issue
Block a user