wlan: Fix ULA Logic to remove EAPOL 4/4 race-condition.
Call ULA done callback from TL when it receives
EAPOL 4/4 packet. ULA done callback unblocks
set key to go through. Remove ULA logic from
SAP mode as it doesn't have race-condition.
Change-Id: Id5e08378019bb31f1829b257d32855a051ac4dcf
CRs-Fixed: 784553
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index a94dacf..acad7ab 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -49,6 +49,14 @@
#define HDD_ETHERTYPE_802_1_X ( 0x888E )
#define HDD_ETHERTYPE_802_1_X_FRAME_OFFSET ( 12 )
#define HDD_ETHERTYPE_802_1_X_SIZE ( 2 )
+
+#define HDD_ETHERTYPE_802_1_X_FRAME_SUB_TYPE_OFFSET ( 19 )
+#define HDD_ETHERTYPE_802_1_X_SUB_TYPE_MASK ( 0x8003 )
+#define HDD_ETHERTYPE_802_1_X_M1_VALUE ( 0x8000 )
+#define HDD_ETHERTYPE_802_1_X_M2_VALUE ( 0x0001 )
+#define HDD_ETHERTYPE_802_1_X_M3_VALUE ( 0x8003 )
+#define HDD_ETHERTYPE_802_1_X_M4_VALUE ( 0x0003 )
+
#ifdef FEATURE_WLAN_WAPI
#define HDD_ETHERTYPE_WAI ( 0x88b4 )
#endif
@@ -266,6 +274,14 @@
extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket );
/**============================================================================
+ @brief hdd_FindEapolSubType() - Find EAPOL SubType.
+
+ @param pVosPacket : [in] pointer to vos packet
+ @return : EAPOL_SubType value
+ ===========================================================================*/
+extern EAPOL_SubType hdd_FindEapolSubType( vos_pkt_t *pVosPacket );
+
+/**============================================================================
@brief hdd_mon_tx_mgmt_pkt() - Transmit MGMT packet received on monitor
interface.
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b022c69..ac4083d 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -8356,21 +8356,6 @@
pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
if( pHostapdState->bssState == BSS_START )
{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- vos_status = wlan_hdd_check_ula_done(pAdapter);
-
- if ( vos_status != VOS_STATUS_SUCCESS )
- {
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
- __LINE__, vos_status );
-
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
-
- status = -EINVAL;
- goto end;
- }
-
status = WLANSAP_SetKeySta( pVosContext, &setKey);
if ( status != eHAL_STATUS_SUCCESS )
@@ -8438,19 +8423,36 @@
setKey.peerMac[4], setKey.peerMac[5],
setKey.keyDirection);
- vos_status = wlan_hdd_check_ula_done(pAdapter);
-
- if ( vos_status != VOS_STATUS_SUCCESS )
+ /* Wait for EAPOL M4 before setting key.
+ * No need to consider Dynamic WEP as we will receive M8.
+ */
+ if ( (setKey.encType == eCSR_ENCRYPT_TYPE_AES ||
+ setKey.encType == eCSR_ENCRYPT_TYPE_TKIP) &&
+ ( 1
+#if defined WLAN_FEATURE_VOWIFI_11R
+ && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN
+ && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_FT_RSN_PSK
+#endif
+#ifdef FEATURE_WLAN_ESE
+ && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_WPA
+ && pHddStaCtx->conn_info.authType != eCSR_AUTH_TYPE_CCKM_RSN
+#endif
+ ))
{
- VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ vos_status = wlan_hdd_check_ula_done(pAdapter);
+
+ if ( vos_status != VOS_STATUS_SUCCESS )
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
__LINE__, vos_status );
- pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
+ pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
- status = -EINVAL;
- goto end;
+ status = -EINVAL;
+ goto end;
+ }
}
#ifdef WLAN_FEATURE_VOWIFI_11R
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index 692e256..2db04f4 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -1360,6 +1360,7 @@
VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH,
"%s: VOS packet is EAPOL packet", __func__);
pPktMetaInfo->ucIsEapol = 1;
+ pPktMetaInfo->ucEapolSubType = hdd_FindEapolSubType(pVosPacket);
}
}
@@ -1371,7 +1372,7 @@
if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "SAP TX EAPOL");
+ "SAP TX EAPOL SubType %d",pPktMetaInfo->ucEapolSubType);
}
else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
{
@@ -1526,6 +1527,7 @@
vos_pkt_t* pNextVosPacket;
hdd_context_t *pHddCtx = NULL;
v_U8_t proto_type;
+ EAPOL_SubType eapolSubType;
//Sanity check on inputs
if ( ( NULL == vosContext ) ||
@@ -1593,6 +1595,12 @@
return VOS_STATUS_E_FAILURE;
}
+ if (pHddCtx->cfg_ini->gEnableDebugLog)
+ {
+ if(hdd_IsEAPOLPacket(pVosPacket))
+ eapolSubType = hdd_FindEapolSubType(pVosPacket);
+ }
+
// Extract the OS packet (skb).
// Tell VOS to detach the OS packet from the VOS packet
status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
@@ -1625,7 +1633,7 @@
if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "SAP RX EAPOL");
+ "SAP RX EAPOL SubType %d",eapolSubType);
}
else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
{
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 370fd71..eab8bf8 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -967,7 +967,9 @@
status = hdd_wmm_acquire_access( pAdapter, ac, &granted );
pAdapter->psbChanged |= (1 << ac);
}
- if ( granted && ( pktListSize == 1 ))
+
+ if ( (granted && ( pktListSize == 1 )) ||
+ (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE))
{
//Let TL know we have a packet to send for this AC
//VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
@@ -1316,6 +1318,50 @@
}
/**============================================================================
+ @brief hdd_FindEapolSubType() - Find EAPOL SubType.
+
+ @param pVosPacket : [in] pointer to vos packet
+ @return : EAPOL_SubType value
+ ===========================================================================*/
+EAPOL_SubType hdd_FindEapolSubType( vos_pkt_t *pVosPacket )
+{
+ VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
+ void *pBuffer = NULL;
+ EAPOL_SubType subType = EAPOL_UNKNOWN;
+ v_U16_t keyInfo;
+ vosStatus = vos_pkt_peek_data( pVosPacket,
+ (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_SUB_TYPE_OFFSET,
+ &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
+ if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
+ {
+ if ( pBuffer )
+ {
+ keyInfo = (*(unsigned short*)pBuffer &
+ HDD_ETHERTYPE_802_1_X_SUB_TYPE_MASK);
+
+ switch (keyInfo) {
+ case HDD_ETHERTYPE_802_1_X_M1_VALUE:
+ subType = EAPOL_M1;
+ break;
+ case HDD_ETHERTYPE_802_1_X_M2_VALUE:
+ subType = EAPOL_M2;
+ break;
+ case HDD_ETHERTYPE_802_1_X_M3_VALUE:
+ subType = EAPOL_M3;
+ break;
+ case HDD_ETHERTYPE_802_1_X_M4_VALUE:
+ subType = EAPOL_M4;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return subType;
+}
+
+/**============================================================================
@brief hdd_IsARP() - Checks the packet is ARP or not.
@param pVosPacket : [in] pointer to vos packet
@@ -1671,8 +1717,12 @@
if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
pPktMetaInfo->ucIsEapol = 0;
- else
+ else
+ {
pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;
+ if(pPktMetaInfo->ucIsEapol)
+ pPktMetaInfo->ucEapolSubType = hdd_FindEapolSubType( pVosPacket );
+ }
if ((NULL != pHddCtx) &&
(pHddCtx->cfg_ini->gEnableDebugLog))
@@ -1682,7 +1732,7 @@
if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "STA TX EAPOL");
+ "STA TX EAPOL SubType %d",pPktMetaInfo->ucEapolSubType);
}
else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
{
@@ -1933,6 +1983,7 @@
vos_pkt_t* pVosPacket;
vos_pkt_t* pNextVosPacket;
v_U8_t proto_type;
+ EAPOL_SubType eapolSubType;
//Sanity check on inputs
if ( ( NULL == vosContext ) ||
@@ -1980,6 +2031,12 @@
return VOS_STATUS_E_FAILURE;
}
+ if (pHddCtx->cfg_ini->gEnableDebugLog)
+ {
+ if (hdd_IsEAPOLPacket(pVosPacket))
+ eapolSubType = hdd_FindEapolSubType(pVosPacket);
+ }
+
// Extract the OS packet (skb).
// Tell VOS to detach the OS packet from the VOS packet
status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
@@ -2038,7 +2095,7 @@
if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
- "STA RX EAPOL");
+ "STA RX EAPOL SubType %d",eapolSubType);
}
else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
{
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index e751579..9e208d1 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -1279,9 +1279,15 @@
/*To avoid race condition between the set key and the last EAPOL
packet, notify TL to finish upper layer authentication incase if the
last EAPOL packet pending in the TL queue.*/
- vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter);
+ vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter,
+ (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+ pHddStaCtx->conn_info.staId[0]);
- if ( vos_status != VOS_STATUS_SUCCESS )
+ if ( vos_status == VOS_STATUS_E_ALREADY )
+ {
+ return VOS_STATUS_SUCCESS;
+ }
+ else if ( vos_status != VOS_STATUS_SUCCESS )
{
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"[%4d] WLANTL_Finish_ULA returned ERROR status= %d",