qcacld-3.0: Avoid session and peer with same MAC address

vdev create request with selfMAC address matching to any of the peer MAC
address cause crash in firmware, So before creating new session/peer
make sure that there is no peer/session with same MAC address.

Change-Id: I7be415365ab7112b013b478139deb451863d52d8
CRs-Fixed: 1115373
This commit is contained in:
Arif Hussain 2017-01-26 17:50:13 -08:00 • committed by snandini
commit ee6770181e
3 changed files with 79 additions and 3 deletions

View file

@ -14813,11 +14813,14 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
{
int status;
u16 channel;
const u8 *bssid = NULL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
const u8 *bssid_hint = req->bssid_hint;
#else
const u8 *bssid_hint = NULL;
#endif
hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
hdd_adapter_t *adapter;
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
hdd_context_t *pHddCtx;
@ -14858,6 +14861,28 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
if (0 != status)
return status;
if (req->bssid)
bssid = req->bssid;
else if (bssid_hint)
bssid = bssid_hint;
if (bssid) {
status = hdd_get_front_adapter(pHddCtx, &adapter_node);
while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
adapter = adapter_node->pAdapter;
if (!qdf_mem_cmp(adapter->macAddressCurrent.bytes,
bssid, QDF_MAC_ADDR_SIZE)) {
hdd_err("Vdev %d exist with same MAC address "
MAC_ADDRESS_STR, adapter->sessionId,
MAC_ADDR_ARRAY(bssid));
return -EINVAL;
}
status = hdd_get_next_adapter(pHddCtx, adapter_node,
&next_adapter);
adapter_node = next_adapter;
}
}
if (true == wlan_hdd_reassoc_bssid_hint(pAdapter, req, &status))
return status;

View file

@ -428,6 +428,37 @@ static void lim_process_auth_frame_type1(tpAniSirGlobal mac_ctx,
if (lim_is_auth_algo_supported(mac_ctx,
(tAniAuthType) rx_auth_frm_body->authAlgoNumber,
pe_session)) {
int i = 0;
tCsrRoamSession *session;
for (i = 0; i < mac_ctx->sme.max_intf_count; i++) {
if (!CSR_IS_SESSION_VALID(mac_ctx, i))
continue;
session = CSR_GET_SESSION(mac_ctx, i);
if (!session || qdf_mem_cmp(&session->selfMacAddr,
mac_hdr->sa, sizeof(tSirMacAddr))) {
continue;
}
pe_debug("vdev with id %d exist with same MAC "
MAC_ADDRESS_STR, session->sessionId,
MAC_ADDR_ARRAY(mac_hdr->sa));
auth_frame->authAlgoNumber =
rx_auth_frm_body->authAlgoNumber;
auth_frame->authTransactionSeqNumber =
rx_auth_frm_body->authTransactionSeqNumber + 1;
auth_frame->authStatusCode =
eSIR_MAC_WME_INVALID_PARAMS_STATUS;
lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
mac_hdr->sa, LIM_NO_WEP_IN_FC,
pe_session, false);
return;
}
switch (rx_auth_frm_body->authAlgoNumber) {
case eSIR_OPEN_SYSTEM:
lim_process_auth_open_system_algo(mac_ctx, mac_hdr,

View file

@ -65,6 +65,7 @@
#include "wlan_reg_services_api.h"
#include <wlan_scan_ucfg_api.h>
#include "wlan_reg_ucfg_api.h"
#include "ol_txrx.h"
static tSelfRecoveryStats g_self_recovery_stats;
@ -5668,19 +5669,38 @@ QDF_STATUS sme_open_session(tHalHandle hHal, csr_roam_completeCallback callback,
void *pContext, uint8_t *pSelfMacAddr,
uint8_t session_id, uint32_t type, uint32_t subType)
{
QDF_STATUS status;
QDF_STATUS status = QDF_STATUS_E_INVAL;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
struct cdp_pdev *pdev;
ol_txrx_peer_handle peer;
uint8_t peer_id;
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: type=%d, session_id %d subType=%d addr:%pM",
__func__, type, session_id, subType, pSelfMacAddr);
pdev = cds_get_context(QDF_MODULE_ID_TXRX);
if (NULL == pdev) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
"%s: Failed to get pdev handler", __func__);
return status;
}
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_ERROR(status))
return status;
status = csr_roam_open_session(pMac, callback, pContext, pSelfMacAddr,
session_id, type, subType);
peer = ol_txrx_find_peer_by_addr(pdev, pSelfMacAddr, &peer_id);
if (peer) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
"%s: Peer=%d exist with same MAC",
__func__, peer_id);
status = QDF_STATUS_E_INVAL;
} else {
status = csr_roam_open_session(pMac, callback, pContext,
pSelfMacAddr, session_id, type, subType);
}
sme_release_global_lock(&pMac->sme);
MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION,