[PATCH] Use correct BSSID for deauth/disconnect in mac80211 EALREADY workaround

Mykyta Iziumtsev mykyta.iziumtsev at gmail.com
Wed Sep 26 10:52:04 EDT 2012


If auth/connect request to mac80211 fails with EALREADY -
there'll be retry after forced deauth/disconnect. The problem is that
wrong BSSID is used in this deauth/disconnect request. Instead of
BSSID of currently associated AP - BSSID of new AP will be used.

For NL80211_CMD_DEAUTHENTICATE use correct cached BSSID value.

For NL80211_CMD_DISCONNECT BSSID is not needed at all,
because mac80211 uses locally saved value.

Signed-hostap: Mykyta Iziumtsev <mykyta.iziumtsev at gmail.com>
---
 src/drivers/driver_nl80211.c |   56 +++++++-----------------------------------
 1 file changed, 9 insertions(+), 47 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a5659c9..0a9f836 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4565,11 +4565,13 @@ static int wpa_driver_nl80211_authenticate(
 	enum nl80211_iftype nlmode;
 	int count = 0;
 	int is_retry;
+	u8 prev_auth_bssid[ETH_ALEN];

 	is_retry = drv->retry_auth;
 	drv->retry_auth = 0;

 	drv->associated = 0;
+	os_memcpy(prev_auth_bssid, drv->auth_bssid, ETH_ALEN);
 	os_memset(drv->auth_bssid, 0, ETH_ALEN);
 	/* FIX: IBSS mode */
 	nlmode = params->p2p ?
@@ -4648,7 +4650,7 @@ retry:
 			"nl80211: MLME command failed (auth): ret=%d (%s)",
 			ret, strerror(-ret));
 		count++;
-		if (ret == -EALREADY && count == 1 && params->bssid &&
+		if (ret == -EALREADY && count == 1 &&
 		    !params->local_state_change) {
 			/*
 			 * mac80211 does not currently accept new
@@ -4658,7 +4660,7 @@ retry:
 			wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
 				   "after forced deauthentication");
 			wpa_driver_nl80211_deauthenticate(
-				bss, params->bssid,
+				bss, prev_auth_bssid,
 				WLAN_REASON_PREV_AUTH_NOT_VALID);
 			nlmsg_free(msg);
 			goto retry;
@@ -6617,51 +6619,11 @@ nla_put_failure:
 }


-static unsigned int nl80211_get_assoc_bssid(struct
wpa_driver_nl80211_data *drv,
-					    u8 *bssid)
+static int nl80211_disconnect(struct wpa_driver_nl80211_data *drv)
 {
-	struct nl_msg *msg;
-	int ret;
-	struct nl80211_bss_info_arg arg;
-
-	os_memset(&arg, 0, sizeof(arg));
-	msg = nlmsg_alloc();
-	if (!msg)
-		goto nla_put_failure;
-
-	nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
-
-	arg.drv = drv;
-	ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
-	msg = NULL;
-	if (ret == 0) {
-		if (is_zero_ether_addr(arg.assoc_bssid))
-			return -ENOTCONN;
-		os_memcpy(bssid, arg.assoc_bssid, ETH_ALEN);
-		return 0;
-	}
-	wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
-		   "(%s)", ret, strerror(-ret));
-nla_put_failure:
-	nlmsg_free(msg);
-	return drv->assoc_freq;
-}
-
-
-static int nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
-			      const u8 *bssid)
-{
-	u8 addr[ETH_ALEN];
-
-	if (bssid == NULL) {
-		int res = nl80211_get_assoc_bssid(drv, addr);
-		if (res)
-			return res;
-		bssid = addr;
-	}
-
-	return wpa_driver_nl80211_disconnect(drv, bssid,
+	u8 zero_addr[ETH_ALEN];
+	os_memset(zero_addr, 0, ETH_ALEN);
+	return wpa_driver_nl80211_disconnect(drv, zero_addr,
 					     WLAN_REASON_PREV_AUTH_NOT_VALID);
 }

@@ -6843,7 +6805,7 @@ skip_auth_type:
 		 * disconnection.
 		 */
 		if (ret == -EALREADY)
-			nl80211_disconnect(drv, params->bssid);
+			nl80211_disconnect(drv);
 		goto nla_put_failure;
 	}
 	ret = 0;
-- 
1.7.10


More information about the HostAP mailing list