qcacld-3.0: Fix freeing of SAP PE session lim_send_sme_disassoc_ntf

When a peer connected to a SAP session triggers disconnect,
lim_send_sme_disassoc_ntf is called with the reason
eLIM_PEER_ENTITY_DISASSOC. This leads to the PE sesssion for the SAP
being freed as part of the lim_send_disconnect_done_ind added in the
change Iec0176fecf218e07f31b258c0dc52aefb480defe.

Modify the lim_send_disconnect_done_ind API to just prepare the
disconnect done indication message and the calling function
lim_send_sme_disassoc_ntf would send the notification to SME and
free the PE session only if the current session is a STA.

Change-Id: I377f86f10becd467417d4c6409d167020e26fe87
CRs-Fixed: 2241899
This commit is contained in:
Vignesh Viswanathan 2018-05-15 20:13:35 +05:30 • committed by nshrivas
commit 5b909f56aa
3 changed files with 100 additions and 52 deletions

View file

@ -2282,6 +2282,8 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
tpDphHashNode pStaDs;
tpPESession psessionEntry;
uint8_t sessionId;
uint32_t *msg = NULL;
QDF_STATUS status;
qdf_mem_copy(&smeDisassocCnf, pMsgBuf,
sizeof(struct sSirSmeDisassocCnf));
@ -2291,16 +2293,26 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
&sessionId);
if (psessionEntry == NULL) {
pe_err("session does not exist for given bssId");
lim_send_disconnect_done_ind(pMac, NULL, CSR_SESSION_ID_INVALID,
eSIR_SME_INVALID_SESSION, NULL);
status = lim_prepare_disconnect_done_ind(pMac, &msg,
CSR_SESSION_ID_INVALID,
eSIR_SME_INVALID_SESSION,
NULL);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}
if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
pe_err("received invalid SME_DISASSOC_CNF message");
lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
eSIR_SME_INVALID_PARAMETERS,
smeDisassocCnf.bssid.bytes);
status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
eSIR_SME_INVALID_PARAMETERS,
&smeDisassocCnf.bssid.bytes[0]);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
@ -2324,11 +2336,15 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
psessionEntry->limSmeState);
lim_print_sme_state(pMac, LOGE,
psessionEntry->limSmeState);
lim_send_disconnect_done_ind(pMac, psessionEntry,
sessionId,
eSIR_SME_INVALID_STATE,
smeDisassocCnf.bssid.
bytes);
status = lim_prepare_disconnect_done_ind(pMac, &msg,
sessionId,
eSIR_SME_INVALID_STATE,
&smeDisassocCnf.bssid.
bytes[0]);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}
break;
@ -2341,9 +2357,13 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
default: /* eLIM_UNKNOWN_ROLE */
pe_err("received unexpected SME_DISASSOC_CNF role %d",
GET_LIM_SYSTEM_ROLE(psessionEntry));
lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
eSIR_SME_INVALID_STATE,
smeDisassocCnf.bssid.bytes);
status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
eSIR_SME_INVALID_STATE,
&smeDisassocCnf.bssid.bytes[0]);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}
@ -2357,10 +2377,14 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
pe_err("DISASSOC_CNF for a STA with no context, addr= "
MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes));
lim_send_disconnect_done_ind(pMac, psessionEntry,
status = lim_prepare_disconnect_done_ind(pMac, &msg,
sessionId,
eSIR_SME_INVALID_PARAMETERS,
smeDisassocCnf.bssid.bytes);
&smeDisassocCnf.bssid.bytes[0]);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}
@ -2371,9 +2395,14 @@ static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBu
pe_err("No need of cleanup for addr:" MAC_ADDRESS_STR "as MLM state is %d",
MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes),
pStaDs->mlmStaContext.mlmState);
lim_send_disconnect_done_ind(pMac, NULL,
CSR_SESSION_ID_INVALID,
eSIR_SME_SUCCESS, NULL);
status = lim_prepare_disconnect_done_ind(pMac, &msg,
CSR_SESSION_ID_INVALID,
eSIR_SME_SUCCESS,
NULL);
if (QDF_IS_STATUS_SUCCESS(status))
lim_send_sme_disassoc_deauth_ntf(pMac,
QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return;
}

View file

@ -806,6 +806,7 @@ lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
tpPESession session = NULL;
uint16_t i, assoc_id;
tpDphHashNode sta_ds = NULL;
QDF_STATUS status;
pe_debug("Disassoc Ntf with trigger : %d reasonCode: %d",
disassocTrigger, reasonCode);
@ -893,9 +894,14 @@ lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
case eLIM_PEER_ENTITY_DISASSOC:
case eLIM_LINK_MONITORING_DISASSOC:
lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
reasonCode, peerMacAddr);
return;
status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
smesessionId,
reasonCode, &peerMacAddr[0]);
if (!QDF_IS_STATUS_SUCCESS(status)) {
pe_err("Failed to prepare message");
return;
}
break;
default:
/**
@ -1162,31 +1168,30 @@ lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac,
#endif /* FEATURE_WLAN_TDLS */
void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
tpPESession session_entry, uint8_t session_id,
tSirResultCodes reason_code,
tSirMacAddr peer_mac_addr)
QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
uint32_t **msg,
uint8_t session_id,
tSirResultCodes reason_code,
uint8_t *peer_mac_addr)
{
struct sir_sme_discon_done_ind *sir_sme_dis_ind;
uint32_t *msg;
sir_sme_dis_ind =
qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
sir_sme_dis_ind = qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
if (!sir_sme_dis_ind) {
pe_err("call to AllocateMemory failed for disconnect indication");
return;
pe_err("Failed to allocate memory");
return QDF_STATUS_E_FAILURE;
}
pe_debug("send eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
pe_debug("Prepare eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
reason_code);
sir_sme_dis_ind->message_type =
eWNI_SME_DISCONNECT_DONE_IND;
sir_sme_dis_ind->length =
sizeof(*sir_sme_dis_ind);
sir_sme_dis_ind->message_type = eWNI_SME_DISCONNECT_DONE_IND;
sir_sme_dis_ind->length = sizeof(*sir_sme_dis_ind);
sir_sme_dis_ind->session_id = session_id;
qdf_mem_copy(sir_sme_dis_ind->peer_mac, peer_mac_addr,
ETH_ALEN);
if (peer_mac_addr)
qdf_mem_copy(&sir_sme_dis_ind->peer_mac,
&peer_mac_addr, ETH_ALEN);
/*
* Instead of sending deauth reason code as 505 which is
* internal value(eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE)
@ -1197,14 +1202,9 @@ void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
else
sir_sme_dis_ind->reason_code = reason_code;
msg = (uint32_t *)sir_sme_dis_ind;
*msg = (uint32_t *)sir_sme_dis_ind;
/*Delete the PE session created */
if (session_entry)
pe_delete_session(mac_ctx, session_entry);
lim_send_sme_disassoc_deauth_ntf(mac_ctx, QDF_STATUS_SUCCESS,
(uint32_t *)msg);
return QDF_STATUS_SUCCESS;
}
/**
@ -1245,7 +1245,8 @@ lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
tSirSmeDeauthInd *pSirSmeDeauthInd;
tpPESession psessionEntry;
uint8_t sessionId;
uint32_t *pMsg;
uint32_t *pMsg = NULL;
QDF_STATUS status;
psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
switch (deauthTrigger) {
@ -1281,9 +1282,14 @@ lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
case eLIM_PEER_ENTITY_DEAUTH:
case eLIM_LINK_MONITORING_DEAUTH:
lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
reasonCode, peerMacAddr);
return;
status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
smesessionId, reasonCode,
&peerMacAddr[0]);
if (!QDF_IS_STATUS_SUCCESS(status)) {
pe_err("Failed to prepare message");
return;
}
break;
default:
/**
* Deauthentication indication due to Deauthentication

View file

@ -44,10 +44,23 @@ void lim_send_sme_start_bss_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
tpPESession, uint8_t, uint16_t);
void lim_send_sme_join_reassoc_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
uint16_t, tpPESession, uint8_t, uint16_t);
void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
tpPESession session_entry, uint8_t session_id,
tSirResultCodes reason_code,
tSirMacAddr peer_mac_addr);
/*
* lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message
* @mac_ctx: Global mac_ctx
* @session_id: PE session id
* @reason_code: Disconnect indication reason code
* @peer_mac_addr: MAC address of the peer
*
* Prepares the disconnect done indication message to be sent to the upper layer
*
* Return: QDF Status
*/
QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
uint32_t **msg,
uint8_t session_id,
tSirResultCodes reason_code,
uint8_t *peer_mac_addr);
void lim_send_sme_disassoc_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes,
uint16_t, uint16_t, uint8_t, uint16_t, tpPESession);
void lim_send_sme_deauth_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, uint16_t,