mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-18 08:30:41 +02:00
core: cleanup handling of AP in nm-device-wifi and fix crash
rh #1025371 reports a crash in handle_ip_config_timeout() because nm_device_wifi_get_activation_ap() did not return any access point (line nm-device-wifi.c:3105). In order to fix this, the whole handling of get_activation_ap vs. current_ap was reworked and cleaned up. This also fixes a memory leak in line nm-device-wifi.c:2111. Also rename the functions get_active_ap (to find_active_ap) and set_active_ap (to set_current_ap), because these two functions were not getter/setter for an 'active_ap' property (as would be expected from the previous name). Also ensure, that a fake AP is never in the list of valid APs without also being the current_ap. Whenever we reset a fake current_ap, the AP gets removed. https://bugzilla.redhat.com/show_bug.cgi?id=1025371 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
f6c0dd2bac
commit
1283816b41
2 changed files with 123 additions and 178 deletions
|
|
@ -196,6 +196,8 @@ static void schedule_scanlist_cull (NMDeviceWifi *self);
|
|||
|
||||
static gboolean request_wireless_scan (gpointer user_data);
|
||||
|
||||
static void remove_access_point (NMDeviceWifi *device, NMAccessPoint *ap);
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
#define NM_WIFI_ERROR (nm_wifi_error_quark ())
|
||||
|
|
@ -443,6 +445,9 @@ get_ap_by_path (NMDeviceWifi *self, const char *path)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
|
||||
if (g_strcmp0 (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0)
|
||||
return NM_AP (iter->data);
|
||||
|
|
@ -456,7 +461,10 @@ get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
for (iter = priv->ap_list; iter && path; iter = g_slist_next (iter)) {
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
|
||||
if (g_strcmp0 (path, nm_ap_get_supplicant_path (NM_AP (iter->data))) == 0)
|
||||
return NM_AP (iter->data);
|
||||
}
|
||||
|
|
@ -464,9 +472,9 @@ get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path)
|
|||
}
|
||||
|
||||
static NMAccessPoint *
|
||||
get_active_ap (NMDeviceWifi *self,
|
||||
NMAccessPoint *ignore_ap,
|
||||
gboolean match_hidden)
|
||||
find_active_ap (NMDeviceWifi *self,
|
||||
NMAccessPoint *ignore_ap,
|
||||
gboolean match_hidden)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
const char *iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
|
|
@ -523,7 +531,7 @@ get_active_ap (NMDeviceWifi *self,
|
|||
ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3],
|
||||
ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]);
|
||||
|
||||
if (ignore_ap && (ap == ignore_ap)) {
|
||||
if (ap == ignore_ap) {
|
||||
nm_log_dbg (LOGD_WIFI, " ignored");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -628,10 +636,9 @@ update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap)
|
|||
}
|
||||
|
||||
static void
|
||||
set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap)
|
||||
set_current_ap (NMDeviceWifi *self, NMAccessPoint *new_ap, gboolean recheck_available_connections, gboolean force_remove_old_ap)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv;
|
||||
char *old_path = NULL;
|
||||
NMAccessPoint *old_ap;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE_WIFI (self));
|
||||
|
|
@ -639,10 +646,8 @@ set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap)
|
|||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
old_ap = priv->current_ap;
|
||||
|
||||
if (old_ap) {
|
||||
old_path = g_strdup (nm_ap_get_dbus_path (old_ap));
|
||||
priv->current_ap = NULL;
|
||||
}
|
||||
if (old_ap == new_ap)
|
||||
return;
|
||||
|
||||
if (new_ap) {
|
||||
priv->current_ap = g_object_ref (new_ap);
|
||||
|
|
@ -656,26 +661,26 @@ set_active_ap (NMDeviceWifi *self, NMAccessPoint *new_ap)
|
|||
|
||||
/* Update seen BSSIDs cache */
|
||||
update_seen_bssids_cache (self, priv->current_ap);
|
||||
} else
|
||||
priv->current_ap = NULL;
|
||||
|
||||
if (old_ap) {
|
||||
NM80211Mode mode = nm_ap_get_mode (old_ap);
|
||||
|
||||
if (force_remove_old_ap || mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_ap_get_fake (old_ap)) {
|
||||
remove_access_point (self, old_ap);
|
||||
if (recheck_available_connections)
|
||||
nm_device_recheck_available_connections (NM_DEVICE (self));
|
||||
}
|
||||
g_object_unref (old_ap);
|
||||
}
|
||||
|
||||
/* Unref old AP here to ensure object lives if new_ap == old_ap */
|
||||
if (old_ap)
|
||||
g_object_unref (old_ap);
|
||||
|
||||
/* Only notify if it's really changed */
|
||||
if ( (!old_path && new_ap)
|
||||
|| (old_path && !new_ap)
|
||||
|| (old_path && new_ap && strcmp (old_path, nm_ap_get_dbus_path (new_ap))))
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
||||
|
||||
g_free (old_path);
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
|
||||
}
|
||||
|
||||
/* Called both as a GSourceFunc and standalone */
|
||||
static gboolean
|
||||
periodic_update (gpointer user_data)
|
||||
static void
|
||||
periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *new_ap;
|
||||
guint32 new_rate;
|
||||
|
|
@ -688,7 +693,7 @@ periodic_update (gpointer user_data)
|
|||
*/
|
||||
state = nm_device_get_state (NM_DEVICE (self));
|
||||
if (state != NM_DEVICE_STATE_ACTIVATED)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* Only update current AP if we're actually talking to something, otherwise
|
||||
* assume the old one (if any) is still valid until we're told otherwise or
|
||||
|
|
@ -698,11 +703,11 @@ periodic_update (gpointer user_data)
|
|||
if ( supplicant_state < NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING
|
||||
|| supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
|
||||
|| nm_supplicant_interface_get_scanning (priv->supplicant.iface))
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* In AP mode we currently have nothing to do. */
|
||||
if (priv->mode == NM_802_11_MODE_AP)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* In IBSS mode, most newer firmware/drivers do "BSS coalescing" where
|
||||
* multiple IBSS stations using the same SSID will eventually switch to
|
||||
|
|
@ -724,7 +729,7 @@ periodic_update (gpointer user_data)
|
|||
nm_ap_set_address (priv->current_ap, &bssid);
|
||||
}
|
||||
|
||||
new_ap = get_active_ap (self, NULL, FALSE);
|
||||
new_ap = find_active_ap (self, ignore_ap, FALSE);
|
||||
if (new_ap) {
|
||||
/* Try to smooth out the strength. Atmel cards, for example, will give no strength
|
||||
* one second and normal strength the next.
|
||||
|
|
@ -736,7 +741,7 @@ periodic_update (gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
if ((new_ap || priv->current_ap) && (new_ap != priv->current_ap)) {
|
||||
if (new_ap != priv->current_ap) {
|
||||
const struct ether_addr *new_bssid = NULL;
|
||||
const GByteArray *new_ssid = NULL;
|
||||
const struct ether_addr *old_bssid = NULL;
|
||||
|
|
@ -764,7 +769,7 @@ periodic_update (gpointer user_data)
|
|||
g_free (old_addr);
|
||||
g_free (new_addr);
|
||||
|
||||
set_active_ap (self, new_ap);
|
||||
set_current_ap (self, new_ap, TRUE, FALSE);
|
||||
}
|
||||
|
||||
new_rate = wifi_utils_get_rate (priv->wifi_data);
|
||||
|
|
@ -772,7 +777,12 @@ periodic_update (gpointer user_data)
|
|||
priv->rate = new_rate;
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
periodic_update_cb (gpointer user_data)
|
||||
{
|
||||
periodic_update (NM_DEVICE_WIFI (user_data), NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -787,17 +797,17 @@ bring_up (NMDevice *device, gboolean *no_firmware)
|
|||
|
||||
static void
|
||||
remove_access_point (NMDeviceWifi *device,
|
||||
NMAccessPoint *ap,
|
||||
gboolean recheck_available_connections)
|
||||
NMAccessPoint *ap)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
||||
|
||||
g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap);
|
||||
priv->ap_list = g_slist_remove (priv->ap_list, ap);
|
||||
g_object_unref (ap);
|
||||
g_return_if_fail (ap);
|
||||
g_return_if_fail (ap != priv->current_ap);
|
||||
g_return_if_fail (g_slist_find (priv->ap_list, ap));
|
||||
|
||||
if (recheck_available_connections)
|
||||
nm_device_recheck_available_connections (NM_DEVICE (device));
|
||||
priv->ap_list = g_slist_remove (priv->ap_list, ap);
|
||||
g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap);
|
||||
g_object_unref (ap);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -805,15 +815,14 @@ remove_all_aps (NMDeviceWifi *self)
|
|||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
/* Remove outdated APs */
|
||||
while (g_slist_length (priv->ap_list)) {
|
||||
NMAccessPoint *ap = NM_AP (priv->ap_list->data);
|
||||
remove_access_point (self, ap, FALSE);
|
||||
}
|
||||
g_slist_free (priv->ap_list);
|
||||
priv->ap_list = NULL;
|
||||
if (priv->ap_list) {
|
||||
set_current_ap (self, NULL, FALSE, FALSE);
|
||||
|
||||
nm_device_recheck_available_connections (NM_DEVICE (self));
|
||||
while (priv->ap_list)
|
||||
remove_access_point (self, NM_AP (priv->ap_list->data));
|
||||
|
||||
nm_device_recheck_available_connections (NM_DEVICE (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -821,7 +830,6 @@ deactivate (NMDevice *dev)
|
|||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *orig_ap = nm_device_wifi_get_activation_ap (self);
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NM80211Mode old_mode = priv->mode;
|
||||
|
|
@ -840,19 +848,14 @@ deactivate (NMDevice *dev)
|
|||
|
||||
cleanup_association_attempt (self, TRUE);
|
||||
|
||||
set_active_ap (self, NULL);
|
||||
priv->rate = 0;
|
||||
|
||||
/* If the AP is 'fake', i.e. it wasn't actually found from
|
||||
* a scan but the user tried to connect to it manually (maybe it
|
||||
* was non-broadcasting or something) get rid of it, because 'fake'
|
||||
* APs should only live for as long as we're connected to them. Fixes
|
||||
* a bug where user-created Ad-Hoc APs are never removed from the scan
|
||||
* list, because scanning is disabled while in Ad-Hoc mode (for stability),
|
||||
* and thus the AP culling never happens. (bgo #569241)
|
||||
*/
|
||||
if (orig_ap && nm_ap_get_fake (orig_ap))
|
||||
remove_access_point (self, orig_ap, TRUE);
|
||||
* APs should only live for as long as we're connected to them.
|
||||
**/
|
||||
set_current_ap (self, NULL, TRUE, FALSE);
|
||||
|
||||
/* Reset MAC address back to initial address */
|
||||
nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI);
|
||||
|
|
@ -1786,7 +1789,6 @@ merge_scanned_ap (NMDeviceWifi *self,
|
|||
const GByteArray *ssid;
|
||||
const struct ether_addr *bssid;
|
||||
gboolean strict_match = TRUE;
|
||||
NMAccessPoint *current_ap = NULL;
|
||||
|
||||
/* Let the manager try to fill in the SSID from seen-bssids lists */
|
||||
bssid = nm_ap_get_address (merge_ap);
|
||||
|
|
@ -1817,8 +1819,7 @@ merge_scanned_ap (NMDeviceWifi *self,
|
|||
* constructed from the NMConnection of the activation request, they won't
|
||||
* always be the same as the capabilities of the real AP from the scan.
|
||||
*/
|
||||
current_ap = nm_device_wifi_get_activation_ap (self);
|
||||
if (current_ap && nm_ap_get_fake (current_ap))
|
||||
if (priv->current_ap && nm_ap_get_fake (priv->current_ap))
|
||||
strict_match = FALSE;
|
||||
|
||||
found_ap = get_ap_by_supplicant_path (self, nm_ap_get_supplicant_path (merge_ap));
|
||||
|
|
@ -1886,8 +1887,9 @@ cull_scan_list (NMDeviceWifi *self)
|
|||
const guint prune_interval_s = SCAN_INTERVAL_MAX * 3;
|
||||
|
||||
/* Don't cull the associated AP or manually created APs */
|
||||
if (ap == priv->current_ap || nm_ap_get_fake (ap))
|
||||
if (ap == priv->current_ap)
|
||||
continue;
|
||||
g_assert (!nm_ap_get_fake (ap)); /* only the current_ap can be fake */
|
||||
|
||||
/* Don't cull APs still known to the supplicant. Since the supplicant
|
||||
* doesn't yet emit property updates for "last seen" we have to rely
|
||||
|
|
@ -1901,7 +1903,7 @@ cull_scan_list (NMDeviceWifi *self)
|
|||
continue;
|
||||
|
||||
if (nm_ap_get_last_seen (ap) + prune_interval_s < now)
|
||||
outdated_list = g_slist_append (outdated_list, ap);
|
||||
outdated_list = g_slist_prepend (outdated_list, ap);
|
||||
}
|
||||
|
||||
/* Remove outdated APs */
|
||||
|
|
@ -1921,7 +1923,7 @@ cull_scan_list (NMDeviceWifi *self)
|
|||
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)",
|
||||
ssid ? "'" : "");
|
||||
|
||||
remove_access_point (self, outdated_ap, TRUE);
|
||||
remove_access_point (self, outdated_ap);
|
||||
removed++;
|
||||
}
|
||||
g_slist_free (outdated_list);
|
||||
|
|
@ -2088,7 +2090,6 @@ link_timeout_cb (gpointer user_data)
|
|||
NMDevice *dev = NM_DEVICE (user_data);
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *ap;
|
||||
|
||||
nm_log_warn (LOGD_WIFI, "(%s): link timed out.", nm_device_get_iface (dev));
|
||||
|
||||
|
|
@ -2106,16 +2107,8 @@ link_timeout_cb (gpointer user_data)
|
|||
* Remove it from the list and if it's actually still present, it'll be
|
||||
* found in the next scan.
|
||||
*/
|
||||
if (priv->ssid_found == FALSE) {
|
||||
if (priv->current_ap) {
|
||||
ap = priv->current_ap;
|
||||
priv->current_ap = NULL;
|
||||
} else
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
|
||||
if (ap)
|
||||
remove_access_point (self, ap, TRUE);
|
||||
}
|
||||
if (priv->ssid_found == FALSE && priv->current_ap)
|
||||
set_current_ap (self, NULL, TRUE, TRUE);
|
||||
|
||||
nm_device_state_changed (dev,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
|
|
@ -2313,8 +2306,18 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
* schedule the next activation stage.
|
||||
*/
|
||||
if (devstate == NM_DEVICE_STATE_CONFIG) {
|
||||
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self);
|
||||
const GByteArray *ssid = nm_ap_get_ssid (ap);
|
||||
NMConnection *connection;
|
||||
NMSettingWireless *s_wifi;
|
||||
const GByteArray *ssid;
|
||||
|
||||
connection = nm_device_get_connection (NM_DEVICE (self));
|
||||
g_return_if_fail (connection);
|
||||
|
||||
s_wifi = nm_connection_get_setting_wireless (connection);
|
||||
g_return_if_fail (s_wifi);
|
||||
|
||||
ssid = nm_setting_wireless_get_ssid (s_wifi);
|
||||
g_return_if_fail (ssid);
|
||||
|
||||
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless) Stage 2 of 5 (Device Configure) "
|
||||
|
|
@ -2325,7 +2328,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
} else if (devstate == NM_DEVICE_STATE_ACTIVATED)
|
||||
periodic_update (self);
|
||||
periodic_update (self, NULL);
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
|
|
@ -2459,7 +2462,7 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface,
|
|||
/* Run a quick update of current AP when coming out of a scan */
|
||||
state = nm_device_get_state (NM_DEVICE (self));
|
||||
if (!scanning && state == NM_DEVICE_STATE_ACTIVATED)
|
||||
periodic_update (self);
|
||||
periodic_update (self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2520,29 +2523,6 @@ handle_auth_or_fail (NMDeviceWifi *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_encrypted (NMAccessPoint *ap, NMConnection *connection)
|
||||
{
|
||||
NM80211ApFlags flags;
|
||||
NM80211ApSecurityFlags wpa_flags, rsn_flags;
|
||||
|
||||
g_return_val_if_fail (ap != NULL, FALSE);
|
||||
g_return_val_if_fail (connection != NULL, FALSE);
|
||||
|
||||
flags = nm_ap_get_flags (ap);
|
||||
wpa_flags = nm_ap_get_wpa_flags (ap);
|
||||
rsn_flags = nm_ap_get_rsn_flags (ap);
|
||||
|
||||
if (flags & NM_802_11_AP_FLAGS_PRIVACY)
|
||||
return TRUE;
|
||||
if (wpa_flags & (NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X))
|
||||
return TRUE;
|
||||
if (rsn_flags & (NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* supplicant_connection_timeout_cb
|
||||
*
|
||||
|
|
@ -2555,7 +2535,6 @@ supplicant_connection_timeout_cb (gpointer user_data)
|
|||
NMDevice *dev = NM_DEVICE (user_data);
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *ap;
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
|
||||
|
|
@ -2593,10 +2572,8 @@ supplicant_connection_timeout_cb (gpointer user_data)
|
|||
}
|
||||
|
||||
g_assert (priv->mode == NM_802_11_MODE_INFRA);
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
g_assert (ap);
|
||||
|
||||
if (priv->ssid_found && is_encrypted (ap, connection)) {
|
||||
if (priv->ssid_found && nm_connection_get_setting_wireless_security (connection)) {
|
||||
guint64 timestamp = 0;
|
||||
gboolean new_secrets = TRUE;
|
||||
|
||||
|
|
@ -2808,6 +2785,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
const GByteArray *cloned_mac;
|
||||
GSList *iter;
|
||||
const char *mode;
|
||||
const char *ap_path;
|
||||
|
||||
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (dev, reason);
|
||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||
|
|
@ -2852,7 +2830,9 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
|
||||
/* AP mode never uses a specific object or existing scanned AP */
|
||||
if (priv->mode != NM_802_11_MODE_AP) {
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
|
||||
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
|
||||
ap = ap_path ? get_ap_by_path (self, ap_path) : NULL;
|
||||
if (ap)
|
||||
goto done;
|
||||
|
||||
|
|
@ -2891,7 +2871,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (ap));
|
||||
|
||||
done:
|
||||
set_active_ap (self, ap);
|
||||
set_current_ap (self, ap, TRUE, FALSE);
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -2944,8 +2924,11 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
g_assert (ap);
|
||||
ap = priv->current_ap;
|
||||
if (!ap) {
|
||||
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
|
@ -3020,7 +3003,7 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
}
|
||||
|
||||
if (!priv->periodic_source_id)
|
||||
priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update, self);
|
||||
priv->periodic_source_id = g_timeout_add_seconds (6, periodic_update_cb, self);
|
||||
|
||||
/* We'll get stage3 started when the supplicant connects */
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
|
|
@ -3057,32 +3040,26 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
is_static_wep (NMAccessPoint *ap, NMConnection *connection)
|
||||
is_static_wep (NMConnection *connection)
|
||||
{
|
||||
NM80211ApFlags flags;
|
||||
NM80211ApSecurityFlags wpa_flags, rsn_flags;
|
||||
NMSettingWirelessSecurity *s_wsec;
|
||||
const char *key_mgmt;
|
||||
const char *str;
|
||||
|
||||
g_return_val_if_fail (ap != NULL, FALSE);
|
||||
g_return_val_if_fail (connection != NULL, FALSE);
|
||||
|
||||
flags = nm_ap_get_flags (ap);
|
||||
wpa_flags = nm_ap_get_wpa_flags (ap);
|
||||
rsn_flags = nm_ap_get_rsn_flags (ap);
|
||||
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
||||
if (!s_wsec)
|
||||
return FALSE;
|
||||
|
||||
if ( (flags & NM_802_11_AP_FLAGS_PRIVACY)
|
||||
&& (wpa_flags == NM_802_11_AP_SEC_NONE)
|
||||
&& (rsn_flags == NM_802_11_AP_SEC_NONE)) {
|
||||
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
||||
if (s_wsec) {
|
||||
key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
|
||||
if (g_strcmp0 (key_mgmt, "none") == 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
str = nm_setting_wireless_security_get_key_mgmt (s_wsec);
|
||||
if (g_strcmp0 (str, "none") != 0)
|
||||
return FALSE;
|
||||
|
||||
return FALSE;
|
||||
str = nm_setting_wireless_security_get_auth_alg (s_wsec);
|
||||
if (g_strcmp0 (str, "leap") == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
|
|
@ -3092,7 +3069,6 @@ handle_ip_config_timeout (NMDeviceWifi *self,
|
|||
gboolean *chain_up,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMAccessPoint *ap;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
|
@ -3102,9 +3078,6 @@ handle_ip_config_timeout (NMDeviceWifi *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
g_assert (ap);
|
||||
|
||||
/* If IP configuration times out and it's a static WEP connection, that
|
||||
* usually means the WEP key is wrong. WEP's Open System auth mode has
|
||||
* no provision for figuring out if the WEP key is wrong, so you just have
|
||||
|
|
@ -3112,7 +3085,7 @@ handle_ip_config_timeout (NMDeviceWifi *self,
|
|||
* types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the
|
||||
* connection would have failed before IP configuration.
|
||||
*/
|
||||
if (is_static_wep (ap, connection) && (may_fail == FALSE)) {
|
||||
if (!may_fail && is_static_wep (connection)) {
|
||||
/* Activation failed, we must have bad encryption key */
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless): could not get IP configuration for "
|
||||
|
|
@ -3186,7 +3159,7 @@ activation_success_handler (NMDevice *dev)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMAccessPoint *ap;
|
||||
struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} };
|
||||
NMAccessPoint *tmp_ap;
|
||||
NMAccessPoint *tmp_ap = NULL;
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
|
||||
|
|
@ -3199,13 +3172,15 @@ activation_success_handler (NMDevice *dev)
|
|||
/* Clear wireless secrets tries on success */
|
||||
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL);
|
||||
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
ap = priv->current_ap;
|
||||
|
||||
/* If the AP isn't fake, it was found in the scan list and all its
|
||||
* details are known.
|
||||
*/
|
||||
if (!nm_ap_get_fake (ap))
|
||||
if (!ap || !nm_ap_get_fake (ap)){
|
||||
ap = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the activate AP was fake, it probably won't have a BSSID at all.
|
||||
* But if activation was successful, the card will know the BSSID. Grab
|
||||
|
|
@ -3219,7 +3194,7 @@ activation_success_handler (NMDevice *dev)
|
|||
if (!nm_ap_get_max_bitrate (ap))
|
||||
nm_ap_set_max_bitrate (ap, wifi_utils_get_rate (priv->wifi_data));
|
||||
|
||||
tmp_ap = get_active_ap (self, ap, TRUE);
|
||||
tmp_ap = find_active_ap (self, ap, TRUE);
|
||||
if (tmp_ap) {
|
||||
const GByteArray *ssid = nm_ap_get_ssid (tmp_ap);
|
||||
|
||||
|
|
@ -3233,16 +3208,21 @@ activation_success_handler (NMDevice *dev)
|
|||
|
||||
nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req),
|
||||
nm_ap_get_dbus_path (tmp_ap));
|
||||
|
||||
priv->ap_list = g_slist_remove (priv->ap_list, ap);
|
||||
g_object_unref (ap);
|
||||
}
|
||||
|
||||
done:
|
||||
periodic_update (self);
|
||||
periodic_update (self, ap);
|
||||
|
||||
/* Update seen BSSIDs cache with the connected AP */
|
||||
update_seen_bssids_cache (self, priv->current_ap);
|
||||
/* ap might be already unrefed, because it was a fake_ap. But we don't touch it... */
|
||||
if (tmp_ap && ap == priv->current_ap) {
|
||||
/* Strange, we would expect periodic_update() to find a better AP
|
||||
* then the fake one and reset it. Reset the fake current_ap to NULL
|
||||
* now, which will remove the fake ap.
|
||||
**/
|
||||
set_current_ap (self, NULL, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/* No need to update seen BSSIDs cache, that is done by set_current_ap() already */
|
||||
|
||||
/* Reset scan interval to something reasonable */
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN + (SCAN_INTERVAL_STEP * 2);
|
||||
|
|
@ -3251,8 +3231,6 @@ done:
|
|||
static void
|
||||
activation_failure_handler (NMDevice *dev)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMAccessPoint *ap;
|
||||
NMConnection *connection;
|
||||
|
||||
connection = nm_device_get_connection (dev);
|
||||
|
|
@ -3260,18 +3238,6 @@ activation_failure_handler (NMDevice *dev)
|
|||
|
||||
/* Clear wireless secrets tries on failure */
|
||||
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL);
|
||||
|
||||
if ((ap = nm_device_wifi_get_activation_ap (self))) {
|
||||
if (nm_ap_get_fake (ap)) {
|
||||
/* Fake APs are ones that don't show up in scans,
|
||||
* but which the user explicitly attempted to connect to.
|
||||
* However, if we fail on one of these, remove it from the
|
||||
* list because we don't have any scan or capability info
|
||||
* for it, and they are pretty much useless.
|
||||
*/
|
||||
remove_access_point (self, ap, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -3306,7 +3272,6 @@ device_state_changed (NMDevice *device,
|
|||
}
|
||||
|
||||
cleanup_association_attempt (self, TRUE);
|
||||
set_active_ap (self, NULL);
|
||||
remove_all_aps (self);
|
||||
}
|
||||
|
||||
|
|
@ -3362,23 +3327,6 @@ device_state_changed (NMDevice *device,
|
|||
remove_all_aps (self);
|
||||
}
|
||||
|
||||
NMAccessPoint *
|
||||
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
|
||||
{
|
||||
NMActRequest *req;
|
||||
const char *ap_path;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NULL);
|
||||
|
||||
req = nm_device_get_act_request (NM_DEVICE (self));
|
||||
if (!req)
|
||||
return NULL;
|
||||
|
||||
ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
|
||||
|
||||
return ap_path ? get_ap_by_path (self, ap_path) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
set_enabled (NMDevice *device, gboolean enabled)
|
||||
{
|
||||
|
|
@ -3484,7 +3432,6 @@ dispose (GObject *object)
|
|||
priv->supplicant.mgr = NULL;
|
||||
}
|
||||
|
||||
set_active_ap (self, NULL);
|
||||
remove_all_aps (self);
|
||||
|
||||
if (priv->wifi_data)
|
||||
|
|
|
|||
|
|
@ -91,8 +91,6 @@ GType nm_device_wifi_get_type (void);
|
|||
|
||||
NMDevice *nm_device_wifi_new (NMPlatformLink *platform_device);
|
||||
|
||||
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
|
||||
|
||||
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue