summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/dp/txrx/ol_rx.c8
-rw-r--r--core/dp/txrx/ol_txrx_types.h3
-rw-r--r--core/mac/src/pe/include/lim_api.h4
-rw-r--r--core/mac/src/pe/lim/lim_api.c140
-rw-r--r--core/mac/src/pe/lim/lim_process_message_queue.c11
-rw-r--r--core/mac/src/sys/legacy/src/system/src/sys_entry_func.c44
-rw-r--r--core/wma/inc/wma_internal.h3
-rw-r--r--core/wma/src/wma_mgmt.c96
8 files changed, 135 insertions, 174 deletions
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c
index 093383b0b4ac..350d4c7a298d 100644
--- a/core/dp/txrx/ol_rx.c
+++ b/core/dp/txrx/ol_rx.c
@@ -1198,6 +1198,11 @@ void ol_rx_peer_init(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer)
peer->security[txrx_sec_ucast].sec_type =
peer->security[txrx_sec_mcast].sec_type = htt_sec_type_none;
peer->keyinstalled = 0;
+
+ peer->last_assoc_rcvd = 0;
+ peer->last_disassoc_rcvd = 0;
+ peer->last_deauth_rcvd = 0;
+
qdf_atomic_init(&peer->fw_pn_check);
}
@@ -1205,6 +1210,9 @@ void
ol_rx_peer_cleanup(struct ol_txrx_vdev_t *vdev, struct ol_txrx_peer_t *peer)
{
peer->keyinstalled = 0;
+ peer->last_assoc_rcvd = 0;
+ peer->last_disassoc_rcvd = 0;
+ peer->last_deauth_rcvd = 0;
ol_rx_reorder_peer_cleanup(vdev, peer);
}
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 43e2461a9115..a36346e63f1c 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -1000,6 +1000,9 @@ struct ol_txrx_peer_t {
uint32_t last_pkt_tsf;
uint8_t last_pkt_tid;
uint16_t last_pkt_center_freq;
+ qdf_time_t last_assoc_rcvd;
+ qdf_time_t last_disassoc_rcvd;
+ qdf_time_t last_deauth_rcvd;
};
enum ol_rx_err_type {
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
index 0622887c161b..e66de6befda7 100644
--- a/core/mac/src/pe/include/lim_api.h
+++ b/core/mac/src/pe/include/lim_api.h
@@ -160,10 +160,6 @@ void lim_send_heart_beat_timeout_ind(tpAniSirGlobal pMac, tpPESession psessionEn
tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
uint8_t *pRxPacketInfo,
uint32_t subType);
-bool lim_is_deauth_diassoc_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
-#ifdef WLAN_FEATURE_11W
-bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
-#endif
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QDF_STATUS pe_roam_synch_callback(tpAniSirGlobal mac_ctx,
struct sSirSmeRoamOffloadSynchInd *roam_sync_ind_ptr,
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index 176a318deeed..5912165c93aa 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -1131,134 +1131,6 @@ uint8_t lim_is_system_in_scan_state(tpAniSirGlobal pMac)
}
} /*** end lim_is_system_in_scan_state() ***/
-#ifdef WLAN_FEATURE_11W
-/**
- * lim_is_assoc_req_for_drop()- function to decides to drop assoc\reassoc
- * frames.
- * @mac: pointer to global mac structure
- * @rx_pkt_info: rx packet meta information
- *
- * This function is called before enqueuing the frame to PE queue to
- * drop flooded assoc/reassoc frames getting into PE Queue.
- *
- * Return: true for dropping the frame otherwise false
- */
-
-bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info)
-{
- uint8_t session_id;
- uint16_t aid;
- tpPESession session_entry;
- tpSirMacMgmtHdr mac_hdr;
- tpDphHashNode sta_ds;
-
- mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
- session_entry = pe_find_session_by_bssid(mac, mac_hdr->bssId,
- &session_id);
- if (!session_entry) {
- PELOG1(limLog(pMac, LOG1,
- FL("session does not exist for given STA [%pM]"),
- mac_hdr->sa););
- return false;
- }
-
- sta_ds = dph_lookup_hash_entry(mac, mac_hdr->sa, &aid,
- &session_entry->dph.dphHashTable);
- if (!sta_ds) {
- PELOG1(limLog(pMac, LOG1, FL("pStaDs is NULL")););
- return false;
- }
-
- if (!sta_ds->rmfEnabled)
- return false;
-
- if (sta_ds->pmfSaQueryState == DPH_SA_QUERY_IN_PROGRESS)
- return true;
-
- if (sta_ds->last_assoc_received_time &&
- ((qdf_mc_timer_get_system_ticks() -
- sta_ds->last_assoc_received_time) < 1000))
- return true;
-
- sta_ds->last_assoc_received_time = qdf_mc_timer_get_system_ticks();
- return false;
-}
-#endif
-
-/**
- * lim_is_deauth_diassoc_for_drop()- function to decides to drop deauth\diassoc
- * frames.
- * @mac: pointer to global mac structure
- * @rx_pkt_info: rx packet meta information
- *
- * This function is called before enqueuing the frame to PE queue to
- * drop flooded deauth/diassoc frames getting into PE Queue.
- *
- * Return: true for dropping the frame otherwise false
- */
-
-bool lim_is_deauth_diassoc_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info)
-{
- uint8_t session_id;
- uint16_t aid;
- tpPESession session_entry;
- tpSirMacMgmtHdr mac_hdr;
- tpDphHashNode sta_ds;
-
- mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
- session_entry = pe_find_session_by_bssid(mac, mac_hdr->bssId,
- &session_id);
- if (!session_entry) {
- PELOG1(limLog(mac, LOG1,
- FL("session does not exist for given STA [%pM]"),
- mac_hdr->sa););
- return true;
- }
-
- sta_ds = dph_lookup_hash_entry(mac, mac_hdr->sa, &aid,
- &session_entry->dph.dphHashTable);
- if (!sta_ds) {
- PELOG1(limLog(mac, LOG1, FL("pStaDs is NULL")););
- return true;
- }
-
-#ifdef WLAN_FEATURE_11W
- if (session_entry->limRmfEnabled) {
- if ((WMA_GET_RX_DPU_FEEDBACK(rx_pkt_info) &
- DPU_FEEDBACK_UNPROTECTED_ERROR)) {
- /* It may be possible that deauth/diassoc frames from a
- * spoofy AP is received. So if all further
- * deauth/diassoc frmaes are dropped, then it may
- * result in lossing deauth/diassoc frames from genuine
- * AP. So process all deauth/diassoc frames with
- * a time difference of 1 sec.
- */
- if ((qdf_mc_timer_get_system_ticks() -
- sta_ds->last_unprot_deauth_disassoc) < 1000)
- return true;
-
- sta_ds->last_unprot_deauth_disassoc =
- qdf_mc_timer_get_system_ticks();
- } else {
- /* PMF enabed, Management frames are protected */
- if (sta_ds->proct_deauh_disassoc_cnt)
- return true;
- else
- sta_ds->proct_deauh_disassoc_cnt++;
- }
- } else
-#endif
- /* PMF disabled */
- {
- if (sta_ds->is_disassoc_deauth_in_progress)
- return true;
- else
- sta_ds->is_disassoc_deauth_in_progress++;
- }
-
- return false;
-}
-
/**
*\brief lim_received_hb_handler()
*
@@ -2209,18 +2081,6 @@ tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
}
}
- if ((subType == SIR_MAC_MGMT_DEAUTH ||
- subType == SIR_MAC_MGMT_DISASSOC) &&
- lim_is_deauth_diassoc_for_drop(pMac, pRxPacketInfo))
- return eMGMT_DROP_SPURIOUS_FRAME;
-
-#ifdef WLAN_FEATURE_11W
- if ((subType == SIR_MAC_MGMT_ASSOC_REQ ||
- subType == SIR_MAC_MGMT_REASSOC_REQ) &&
- lim_is_assoc_req_for_drop(pMac, pRxPacketInfo))
- return eMGMT_DROP_SPURIOUS_FRAME;
-#endif
-
framelen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index 884b2050a8c4..27d6a4159760 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -803,6 +803,17 @@ lim_handle80211_frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, uint8_t *pDeferMsg
isFrmFt = WMA_GET_RX_FT_DONE(pRxPacketInfo);
fc = pHdr->fc;
+ if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pHdr->bssId, &sessionId);
+ if (psessionEntry &&
+ (QDF_SAP_MODE == psessionEntry->pePersona)) {
+ lim_log(pMac, LOG1,
+ FL("CAC timer running - drop the frame"));
+ goto end;
+ }
+ }
+
#ifdef WLAN_DUMP_MGMTFRAMES
lim_log(pMac, LOGE,
FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
diff --git a/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
index 057de0544b15..a337ec605c7f 100644
--- a/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
+++ b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
@@ -109,9 +109,6 @@ sys_bbt_process_message_core(tpAniSirGlobal mac_ctx, tpSirMsgQ msg,
cds_pkt_t *vos_pkt = (cds_pkt_t *) msg->bodyptr;
QDF_STATUS qdf_status =
wma_ds_peek_rx_packet_info(vos_pkt, &bd_ptr, false);
- uint8_t sessionid;
- tpPESession pe_session;
- tpSirMacMgmtHdr mac_hdr;
mac_ctx->sys.gSysBbtReceived++;
@@ -130,19 +127,7 @@ sys_bbt_process_message_core(tpAniSirGlobal mac_ctx, tpSirMsgQ msg,
framecount = mac_ctx->sys.gSysFrameCount[type][subtype];
if (type == SIR_MAC_MGMT_FRAME) {
- if (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
- mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
- pe_session = pe_find_session_by_bssid(mac_ctx,
- mac_hdr->bssId,
- &sessionid);
- if (pe_session &&
- (pe_session->pePersona == QDF_SAP_MODE)) {
- QDF_TRACE(QDF_MODULE_ID_SYS,
- QDF_TRACE_LEVEL_INFO_HIGH,
- FL("CAC timer is running, dropping the mgmt frame"));
- goto fail;
- }
- }
+ tpSirMacMgmtHdr mac_hdr;
/*
* Drop beacon frames in deferred state to avoid VOSS run out of
@@ -169,27 +154,26 @@ sys_bbt_process_message_core(tpAniSirGlobal mac_ctx, tpSirMsgQ msg,
goto fail;
}
+ mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
+ if (subtype == SIR_MAC_MGMT_ASSOC_REQ) {
+ sys_log(mac_ctx, LOG1,
+ FL("ASSOC REQ frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", Assoc Req count so far: %d\n"),
+ MAC_ADDR_ARRAY(mac_hdr->da),
+ MAC_ADDR_ARRAY(mac_hdr->sa),
+ MAC_ADDR_ARRAY(mac_hdr->bssId),
+ mac_ctx->sys.gSysFrameCount[type][subtype]);
+ }
if (subtype == SIR_MAC_MGMT_DEAUTH) {
- tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
- sys_log(mac_ctx, LOGE,
- FL("DEAUTH frame allowed: "
- "da: " MAC_ADDRESS_STR ", "
- "sa: " MAC_ADDRESS_STR ", "
- "bssid: " MAC_ADDRESS_STR ", "
- "DEAUTH count so far: %d\n"),
+ sys_log(mac_ctx, LOG1,
+ FL("DEAUTH frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", DEAUTH count so far: %d\n"),
MAC_ADDR_ARRAY(mac_hdr->da),
MAC_ADDR_ARRAY(mac_hdr->sa),
MAC_ADDR_ARRAY(mac_hdr->bssId),
mac_ctx->sys.gSysFrameCount[type][subtype]);
}
if (subtype == SIR_MAC_MGMT_DISASSOC) {
- tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
- sys_log(mac_ctx, LOGE,
- FL("DISASSOC frame allowed: "
- "da: " MAC_ADDRESS_STR ", "
- "sa: " MAC_ADDRESS_STR ", "
- "bssid: " MAC_ADDRESS_STR ", "
- "DISASSOC count so far: %d\n"),
+ sys_log(mac_ctx, LOG1,
+ FL("DISASSOC frame allowed: da: " MAC_ADDRESS_STR ", sa: " MAC_ADDRESS_STR ", bssid: " MAC_ADDRESS_STR ", DISASSOC count so far: %d\n"),
MAC_ADDR_ARRAY(mac_hdr->da),
MAC_ADDR_ARRAY(mac_hdr->sa),
MAC_ADDR_ARRAY(mac_hdr->bssId),
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 6d2dd9acb7fc..42c2c9d6fe3f 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -119,6 +119,9 @@
#define MAX_ENTRY_HOLD_REQ_QUEUE 2
#define MAX_ENTRY_VDEV_RESP_QUEUE 10
+/* Time(in ms) to detect DOS attack */
+#define WMA_MGMT_FRAME_DETECT_DOS_TIMER 1000
+
/**
* struct index_data_rate_type - non vht data rate type
* @mcs_index: mcs rate index
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 38dcfaf93b31..6a2ddde6bd8a 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -2859,6 +2859,96 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle,
#endif
/**
+ * wma_is_pkt_drop_candidate() - check if the mgmt frame should be droppped
+ * @wma_handle: wma handle
+ * @peer_addr: peer MAC address
+ * @subtype: Management frame subtype
+ *
+ * This function is used to decide if a particular management frame should be
+ * dropped to prevent DOS attack. Timestamp is used to decide the DOS attack.
+ *
+ * Return: true if the packet should be dropped and false oterwise
+ */
+static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
+ uint8_t *peer_addr, uint8_t subtype)
+{
+ struct ol_txrx_peer_t *peer;
+ struct ol_txrx_pdev_t *pdev_ctx;
+ uint8_t peer_id;
+ bool should_drop = false;
+
+ /*
+ * Currently this function handles only Disassoc,
+ * Deauth and Assoc req frames. Return false for
+ * all other frames.
+ */
+ if (subtype != IEEE80211_FC0_SUBTYPE_DISASSOC &&
+ subtype != IEEE80211_FC0_SUBTYPE_DEAUTH &&
+ subtype != IEEE80211_FC0_SUBTYPE_ASSOC_REQ) {
+ should_drop = false;
+ goto end;
+ }
+
+ pdev_ctx = cds_get_context(QDF_MODULE_ID_TXRX);
+ if (!pdev_ctx) {
+ WMA_LOGE(FL("Failed to get the context"));
+ should_drop = true;
+ goto end;
+ }
+
+ peer = ol_txrx_find_peer_by_addr(pdev_ctx, peer_addr, &peer_id);
+ if (!peer) {
+ if (SIR_MAC_MGMT_ASSOC_REQ != subtype) {
+ WMA_LOGI(
+ FL("Received mgmt frame: %0x from unknow peer: %pM"),
+ subtype, peer_addr);
+ should_drop = true;
+ }
+ goto end;
+ }
+
+ switch (subtype) {
+ case SIR_MAC_MGMT_ASSOC_REQ:
+ if (peer->last_assoc_rcvd) {
+ if (qdf_get_system_timestamp() - peer->last_assoc_rcvd <
+ WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
+ WMA_LOGI(FL("Dropping Assoc Req received"));
+ should_drop = true;
+ }
+ }
+ peer->last_assoc_rcvd = qdf_get_system_timestamp();
+ break;
+ case SIR_MAC_MGMT_DISASSOC:
+ if (peer->last_disassoc_rcvd) {
+ if (qdf_get_system_timestamp() -
+ peer->last_disassoc_rcvd <
+ WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
+ WMA_LOGI(FL("Dropping DisAssoc received"));
+ should_drop = true;
+ }
+ }
+ peer->last_disassoc_rcvd = qdf_get_system_timestamp();
+ break;
+ case SIR_MAC_MGMT_DEAUTH:
+ if (peer->last_deauth_rcvd) {
+ if (qdf_get_system_timestamp() -
+ peer->last_deauth_rcvd <
+ WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
+ WMA_LOGI(FL("Dropping Deauth received"));
+ should_drop = true;
+ }
+ }
+ peer->last_deauth_rcvd = qdf_get_system_timestamp();
+ break;
+ default:
+ break;
+ }
+
+end:
+ return should_drop;
+}
+
+/**
* wma_mgmt_rx_process() - process management rx frame.
* @handle: wma handle
* @data: rx data
@@ -3028,6 +3118,12 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
#endif /* WLAN_FEATURE_11W */
rx_pkt->pkt_meta.sessionId =
(vdev_id == WMA_INVALID_VDEV_ID ? 0 : vdev_id);
+
+ if (wma_is_pkt_drop_candidate(wma_handle, wh->i_addr2, mgt_subtype)) {
+ cds_pkt_return_packet(rx_pkt);
+ return -EINVAL;
+ }
+
wma_handle->mgmt_rx(wma_handle, rx_pkt);
return 0;
}