mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-01 00:58:00 +02:00
wifi: don't allow scan requests when associating
Shouldn't be allowing scan requests when associating or when the supplicant is otherwise busy doing something else. Older fullmac cards are much more likely to run into this problem since they usually take longer to connect; since they take so long, NM may sometimes request a scan during association or during DHCP which can cause the card to miss DHCP replies. I've never seen this happen with mac80211 drivers though.
This commit is contained in:
parent
f1444bbabe
commit
6f21e935d6
2 changed files with 38 additions and 26 deletions
|
|
@ -1624,32 +1624,41 @@ nm_device_wifi_get_bssid (NMDeviceWifi *self,
|
|||
|
||||
|
||||
static gboolean
|
||||
can_scan (NMDeviceWifi *self)
|
||||
scanning_allowed (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
guint32 sup_state;
|
||||
NMDeviceState dev_state;
|
||||
gboolean is_disconnected = FALSE;
|
||||
NMActRequest *req;
|
||||
|
||||
g_return_val_if_fail (priv->supplicant.iface != NULL, FALSE);
|
||||
|
||||
sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface);
|
||||
dev_state = nm_device_get_state (NM_DEVICE (self));
|
||||
|
||||
/* Don't scan when unknown, unmanaged, or unavailable */
|
||||
if (dev_state < NM_DEVICE_STATE_DISCONNECTED)
|
||||
switch (nm_device_get_state (NM_DEVICE (self))) {
|
||||
case NM_DEVICE_STATE_UNKNOWN:
|
||||
case NM_DEVICE_STATE_UNMANAGED:
|
||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||
case NM_DEVICE_STATE_PREPARE:
|
||||
case NM_DEVICE_STATE_CONFIG:
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
/* Don't scan when unusable or activating */
|
||||
return FALSE;
|
||||
|
||||
is_disconnected = ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING
|
||||
|| dev_state == NM_DEVICE_STATE_DISCONNECTED
|
||||
|| dev_state == NM_DEVICE_STATE_FAILED) ? TRUE : FALSE;
|
||||
|
||||
/* All wireless devices can scan when disconnected */
|
||||
if (is_disconnected)
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
case NM_DEVICE_STATE_FAILED:
|
||||
/* Can always scan when disconnected */
|
||||
return TRUE;
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
/* Need to do further checks when activated */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't scan if the supplicant is busy */
|
||||
sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface);
|
||||
if ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE
|
||||
|| nm_supplicant_interface_get_scanning (priv->supplicant.iface))
|
||||
return FALSE;
|
||||
|
||||
/* Don't scan when a shared connection is active; it makes drivers mad */
|
||||
req = nm_device_get_act_request (NM_DEVICE (self));
|
||||
|
|
@ -1671,10 +1680,10 @@ can_scan (NMDeviceWifi *self)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
scan_allowed_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
scanning_allowed_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
{
|
||||
if (!g_value_get_boolean (handler_return))
|
||||
g_value_set_boolean (return_accu, FALSE);
|
||||
|
|
@ -1682,7 +1691,7 @@ scan_allowed_accumulator (GSignalInvocationHint *ihint,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
scan_allowed (NMDeviceWifi *self)
|
||||
check_scanning_allowed (NMDeviceWifi *self)
|
||||
{
|
||||
GValue instance = { 0, };
|
||||
GValue retval = { 0, };
|
||||
|
|
@ -1707,7 +1716,7 @@ request_wireless_scan (gpointer user_data)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
gboolean backoff = FALSE;
|
||||
|
||||
if (can_scan (self) && scan_allowed (self)) {
|
||||
if (check_scanning_allowed (self)) {
|
||||
if (nm_supplicant_interface_request_scan (priv->supplicant.iface)) {
|
||||
/* success */
|
||||
backoff = TRUE;
|
||||
|
|
@ -1785,7 +1794,7 @@ supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface,
|
|||
gboolean success,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
if (can_scan (self))
|
||||
if (check_scanning_allowed (self))
|
||||
schedule_scan (self, TRUE);
|
||||
}
|
||||
|
||||
|
|
@ -3544,6 +3553,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
parent_class->can_interrupt_activation = real_can_interrupt_activation;
|
||||
parent_class->spec_match_list = spec_match_list;
|
||||
|
||||
klass->scanning_allowed = scanning_allowed;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property (object_class, PROP_HW_ADDRESS,
|
||||
g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS,
|
||||
|
|
@ -3635,8 +3646,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
g_signal_new ("scanning-allowed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
scan_allowed_accumulator, NULL,
|
||||
G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_allowed),
|
||||
scanning_allowed_accumulator, NULL,
|
||||
_nm_marshal_BOOLEAN__VOID,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ struct _NMDeviceWifiClass
|
|||
void (*access_point_removed) (NMDeviceWifi *device, NMAccessPoint *ap);
|
||||
void (*hidden_ap_found) (NMDeviceWifi *device, NMAccessPoint *ap);
|
||||
void (*properties_changed) (NMDeviceWifi *device, GHashTable *properties);
|
||||
gboolean (*scanning_allowed) (NMDeviceWifi *device);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue