diff options
author | Dan Williams <dcbw@redhat.com> | 2015-04-20 10:18:32 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2015-08-07 12:40:58 -0500 |
commit | e0fc28b7f6a45b7fa6c6d2d76711deb72d9c91f0 (patch) | |
tree | 1f13bc05140311a456abcabe6e4df19268dfeab6 | |
parent | d760db18bfe6d85842c591f9da86a41f6eaaf600 (diff) | |
download | NetworkManager-dcbw/nm-0910-wifi-ap-list.tar.gz |
wifi: remove supplicant-forgotten current AP from list on disconnectdcbw/nm-0910-wifi-ap-list
NM never removes the current AP from the AP list, to prevent NM from
indicating that it's connected, but to nothing. But the supplicant
can remove that AP from its list at any time (out of range, turned off,
etc), leading to a priv->current_ap that is no longer known to the
supplicant but still exists in the NM AP list. Since the supplicant
has forgotten it, NM will never receive a removal signal for it.
To ensure that a supplicant-forgotten priv->current_ap is removed
from the NM AP list when priv->current_ap is cleared or changed, mark
any AP removed by the supplicant as 'fake'. It will then always be
removed in set_current_ap() and not linger in the AP list forever like
a zombie.
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 19 | ||||
-rw-r--r-- | src/devices/wifi/nm-wifi-ap.c | 3 |
2 files changed, 17 insertions, 5 deletions
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 90bb2578a4..3fce1a422f 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1644,11 +1644,20 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, priv = NM_DEVICE_WIFI_GET_PRIVATE (self); ap = get_ap_by_supplicant_path (self, object_path); - if (ap && ap != priv->current_ap) { - nm_ap_dump (ap, "removed ", nm_device_get_iface (NM_DEVICE (self))); - emit_ap_added_removed (self, ACCESS_POINT_REMOVED, ap, TRUE); - g_hash_table_remove (priv->aps, nm_ap_get_dbus_path (ap)); - schedule_ap_list_dump (self); + if (ap) { + if (ap == priv->current_ap) { + /* The current AP cannot be removed (to prevent NM indicating that + * it is connected, but to nothing), but it must be removed later + * when the current AP is changed or cleared. Set 'fake' to + * indicate that this AP is now unknown to the supplicant. + */ + nm_ap_set_fake (ap, TRUE); + } else { + nm_ap_dump (ap, "removed ", nm_device_get_iface (NM_DEVICE (self))); + emit_ap_added_removed (self, ACCESS_POINT_REMOVED, ap, TRUE); + g_hash_table_remove (priv->aps, nm_ap_get_dbus_path (ap)); + schedule_ap_list_dump (self); + } } } diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index e1f7bf1a66..68f0ee637f 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -387,6 +387,7 @@ nm_ap_update_from_properties (NMAccessPoint *ap, const char *supplicant_path, GVariant *properties) { + NMAccessPointPrivate *priv; const guint8 *bytes; GVariant *v; gsize len; @@ -397,6 +398,7 @@ nm_ap_update_from_properties (NMAccessPoint *ap, g_return_if_fail (ap != NULL); g_return_if_fail (properties != NULL); + priv = NM_AP_GET_PRIVATE (ap); g_object_freeze_notify (G_OBJECT (ap)); @@ -475,6 +477,7 @@ nm_ap_update_from_properties (NMAccessPoint *ap, nm_ap_set_supplicant_path (ap, supplicant_path); nm_ap_set_last_seen (ap, nm_utils_get_monotonic_timestamp_s ()); + priv->fake = FALSE; g_object_thaw_notify (G_OBJECT (ap)); } |