diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 3d8b01da4621..3d1fdebf92fe 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -2141,6 +2141,43 @@ send_ind_to_sme: return true; } +/** + * lim_peer_present_on_any_sta() - Check if Same MAC is connected with STA, i.e. + * duplicate mac detection. + * @mac_ctx: Pointer to Global MAC structure + * @peer_addr: peer address to check + * + * This function will return true if a peer STA and AP are using same mac + * address. + * + * @Return: bool + */ +static bool +lim_peer_present_on_any_sta(struct mac_context *mac_ctx, uint8_t *peer_addr) +{ + struct wlan_objmgr_peer *peer; + bool sta_peer_present = false; + enum QDF_OPMODE mode; + uint8_t peer_vdev_id; + + peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc, peer_addr, + WLAN_LEGACY_MAC_ID); + if (!peer) + return sta_peer_present; + + peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); + mode = wlan_vdev_mlme_get_opmode(wlan_peer_get_vdev(peer)); + if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) { + pe_debug("duplicate mac detected!!! Peer " QDF_MAC_ADDR_STR " present on STA vdev %d", + QDF_MAC_ADDR_ARRAY(peer_addr), peer_vdev_id); + sta_peer_present = true; + } + + wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID); + + return sta_peer_present; +} + /** * lim_process_assoc_req_frame() - Process RE/ASSOC Request frame. * @mac_ctx: Pointer to Global MAC structure @@ -2218,6 +2255,14 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in return; } + if (lim_peer_present_on_any_sta(mac_ctx, hdr->sa)) + /* + * This mean a AP and STA have same mac address and device STA + * is already connected to the AP, and STA is now trying to + * connect to device SAP. So ignore association. + */ + return; + /* * If a STA is already present in DPH and it is initiating a Assoc * re-transmit, do not process it. This can happen when first Assoc Req diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 1b6c2d1a7c87..d75c224ec9da 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1562,6 +1562,7 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; uint32_t bitmap = 1 << CDP_PEER_DELETE_NO_SPECIAL; bool peer_unmap_conf_support_enabled; + uint8_t peer_vdev_id; if (!wma->interfaces[vdev_id].peer_count) { WMA_LOGE("%s: Can't remove peer with peer_addr %pM vdevid %d peer_count %d", @@ -1577,12 +1578,19 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr, return QDF_STATUS_E_INVAL; } - if (!wma_objmgr_peer_exist(wma, peer_addr, NULL)) { + if (!wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) { wma_err("peer doesn't exist peer_addr %pM vdevid %d peer_count %d", peer_addr, vdev_id, wma->interfaces[vdev_id].peer_count); return QDF_STATUS_E_INVAL; } + + if (peer_vdev_id != vdev_id) { + wma_err("peer %pM is on vdev id %d but delete req on vdevid %d peer_count %d", + peer_addr, peer_vdev_id, vdev_id, + wma->interfaces[vdev_id].peer_count); + return QDF_STATUS_E_INVAL; + } peer_unmap_conf_support_enabled = cdp_cfg_get_peer_unmap_conf_support(soc);