qcacld-3.0: Process external auth command and set preauth node state

Hostapd sends SAE authentication status with the NL command
NL80211_CMD_EXTERNAL_AUTH. Extract status and peer mac address
from the command data and set mlmState in preauth node accordingly.

Change-Id: If507a2f56c031ae1885a11d5f7cbe31a18aa8821
CRs-Fixed: 2396366
This commit is contained in:
Srinivas Dasari 2019-02-11 17:24:48 +05:30 • committed by nshrivas
commit e854ff0828
5 changed files with 116 additions and 41 deletions

View file

@ -20852,6 +20852,7 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
int ret;
mac_handle_t mac_handle;
struct qdf_mac_addr peer_mac_addr;
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
hdd_err("Command not allowed in FTM mode");
@ -20865,10 +20866,12 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
if (ret)
return ret;
hdd_debug("external_auth status: %d", params->status);
hdd_debug("external_auth status: %d peer mac: " QDF_MAC_ADDR_STR,
params->status, QDF_MAC_ADDR_ARRAY(params->bssid));
mac_handle = hdd_ctx->mac_handle;
sme_handle_sae_msg(mac_handle, adapter->vdev_id, params->status);
qdf_mem_copy(peer_mac_addr.bytes, params->bssid, QDF_MAC_ADDR_SIZE);
sme_handle_sae_msg(mac_handle, adapter->vdev_id, params->status,
peer_mac_addr);
return ret;
}

View file

@ -6061,12 +6061,14 @@ struct sir_sae_info {
* @length: message length
* @session_id: SME session id
* @sae_status: SAE status, 0: Success, Non-zero: Failure.
* @peer_mac_addr: peer MAC address
*/
struct sir_sae_msg {
uint16_t message_type;
uint16_t length;
uint16_t session_id;
uint8_t sae_status;
tSirMacAddr peer_mac_addr;
};
/**

View file

@ -65,6 +65,82 @@ static void lim_process_normal_hdd_msg(struct mac_context *mac_ctx,
struct scheduler_msg *msg, uint8_t rsp_reqd);
#ifdef WLAN_FEATURE_SAE
/**
* lim_process_sae_msg_sta() - Process SAE message for STA
* @mac: Global MAC pointer
* @session: Pointer to the PE session entry
* @sae_msg: SAE message buffer pointer
*
* Return: None
*/
static void lim_process_sae_msg_sta(struct mac_context *mac,
struct pe_session *session,
struct sir_sae_msg *sae_msg)
{
switch (session->limMlmState) {
case eLIM_MLM_WT_SAE_AUTH_STATE:
/* SAE authentication is completed.
* Restore from auth state
*/
if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
lim_deactivate_and_change_timer(mac,
eLIM_AUTH_SAE_TIMER);
/* success */
if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
lim_restore_from_auth_state(mac,
eSIR_SME_SUCCESS,
eSIR_MAC_SUCCESS_STATUS,
session);
else
lim_restore_from_auth_state(mac, eSIR_SME_AUTH_REFUSED,
eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
break;
default:
/* SAE msg is received in unexpected state */
pe_err("received SAE msg in state %X", session->limMlmState);
lim_print_mlm_state(mac, LOGE, session->limMlmState);
break;
}
}
/**
* lim_process_sae_msg_ap() - Process SAE message
* @mac: Global MAC pointer
* @session: Pointer to the PE session entry
* @sae_msg: SAE message buffer pointer
*
* Return: None
*/
static void lim_process_sae_msg_ap(struct mac_context *mac,
struct pe_session *session,
struct sir_sae_msg *sae_msg)
{
struct tLimPreAuthNode *sta_pre_auth_ctx;
/* Extract pre-auth context for the STA and move limMlmState
* of preauth node to eLIM_MLM_AUTHENTICATED_STATE
*/
sta_pre_auth_ctx = lim_search_pre_auth_list(mac,
sae_msg->peer_mac_addr);
if (!sta_pre_auth_ctx) {
pe_debug("No preauth node created for "
QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
return;
}
if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS) {
sta_pre_auth_ctx->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
} else {
pe_debug("SAE authentication failed for "
QDF_MAC_ADDR_STR " status: %u",
QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr),
sae_msg->sae_status);
lim_delete_pre_auth_node(mac, sae_msg->peer_mac_addr);
}
}
/**
* lim_process_sae_msg() - Process SAE message
* @mac: Global MAC pointer
@ -89,40 +165,23 @@ static void lim_process_sae_msg(struct mac_context *mac, struct sir_sae_msg *bod
return;
}
if (session->pePersona != QDF_STA_MODE) {
if (session->pePersona != QDF_STA_MODE &&
session->pePersona != QDF_SAP_MODE) {
pe_err("SAE:Not supported in this mode %d",
session->pePersona);
return;
}
pe_debug("SAE:status %d limMlmState %d pePersona %d",
sae_msg->sae_status, session->limMlmState,
session->pePersona);
switch (session->limMlmState) {
case eLIM_MLM_WT_SAE_AUTH_STATE:
/* SAE authentication is completed. Restore from auth state */
if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
lim_deactivate_and_change_timer(mac,
eLIM_AUTH_SAE_TIMER);
/* success */
if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
lim_restore_from_auth_state(mac,
eSIR_SME_SUCCESS,
eSIR_MAC_SUCCESS_STATUS,
session);
else
lim_restore_from_auth_state(mac,
eSIR_SME_AUTH_REFUSED,
eSIR_MAC_UNSPEC_FAILURE_STATUS,
session);
break;
default:
/* SAE msg is received in unexpected state */
pe_err("received SAE msg in state %X",
session->limMlmState);
lim_print_mlm_state(mac, LOGE, session->limMlmState);
break;
}
pe_debug("SAE:status %d limMlmState %d pePersona %d peer: "
QDF_MAC_ADDR_STR, sae_msg->sae_status,
session->limMlmState, session->pePersona,
QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
if (LIM_IS_STA_ROLE(session))
lim_process_sae_msg_sta(mac, session, sae_msg);
else if (LIM_IS_AP_ROLE(session))
lim_process_sae_msg_ap(mac, session, sae_msg);
else
pe_debug("Unsupported interface");
}
#else
static inline void lim_process_sae_msg(struct mac_context *mac, void *body)

View file

@ -2467,15 +2467,20 @@ QDF_STATUS sme_send_mgmt_tx(mac_handle_t mac_handle, uint8_t session_id,
* @mac_handle: The handle returned by mac_open
* @session_id: session id
* @sae_status: status of SAE authentication
* @peer_mac_addr: mac address of the peer to be authenticated
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
uint8_t sae_status);
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
uint8_t session_id,
uint8_t sae_status,
struct qdf_mac_addr peer_mac_addr);
#else
static inline
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
uint8_t sae_status)
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
uint8_t session_id,
uint8_t sae_status,
struct qdf_mac_addr peer_mac_addr)
{
return QDF_STATUS_SUCCESS;
}

View file

@ -14351,8 +14351,10 @@ int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
}
#ifdef WLAN_FEATURE_SAE
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
uint8_t sae_status)
QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
uint8_t session_id,
uint8_t sae_status,
struct qdf_mac_addr peer_mac_addr)
{
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
@ -14369,9 +14371,13 @@ QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
sae_msg->length = sizeof(*sae_msg);
sae_msg->session_id = session_id;
sae_msg->sae_status = sae_status;
sme_debug("SAE: sae_status %d session_id %d",
sae_msg->sae_status,
sae_msg->session_id);
qdf_mem_copy(sae_msg->peer_mac_addr,
peer_mac_addr.bytes,
QDF_MAC_ADDR_SIZE);
sme_debug("SAE: sae_status %d session_id %d Peer: "
MAC_ADDRESS_STR, sae_msg->sae_status,
sae_msg->session_id,
MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
sch_msg.type = eWNI_SME_SEND_SAE_MSG;
sch_msg.bodyptr = sae_msg;