Browse Source

qcacld-3.0: Fix logic to drop duplicate deauth/disassoc frames

In wma_is_pkt_drop_candidate the frame received time is updated
even when the frame was dropped and thus the received time of
the frame keeps on increasing. Thus the condition to check if
frame is allowed after WMA_MGMT_FRAME_DETECT_DOS_TIMER ms always
fails if driver continuously keep on getting the frames.

This can lead to dropping of valid deauth/disassoc frames in case
if RMF is enabled and some rouge peer keep on sending rogue
deauth/disassoc frames and thus even if peer send valid deauth
peer will not get disconnected.

To fix this update the rcvd time stamp only when the frame is
allowed, as this timestamp should be used to block the duplicate
frames for WMA_MGMT_FRAME_DETECT_DOS_TIMER ms.

Change-Id: I4f480e21369b585d78f240c5f4f062d010d889a8
CRs-Fixed: 2256679
Abhishek Singh 6 years ago
parent
commit
8874df976e
1 changed files with 19 additions and 28 deletions
  1. 19 28
      core/wma/src/wma_mgmt.c

+ 19 - 28
core/wma/src/wma_mgmt.c

@@ -3736,46 +3736,37 @@ static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle,
 	switch (subtype) {
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 		ptr = cdp_peer_last_assoc_received(soc, peer);
-		if (ptr == NULL) {
+		if (!ptr) {
 			WMA_LOGE(FL("cdp_peer_last_assoc_received Failed"));
 			should_drop = true;
 			goto end;
-		} else if (*ptr > 0) {
-			if ((qdf_get_system_timestamp() - *ptr) <
-				WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
-				    WMA_LOGI(FL("Dropping Assoc Req received"));
-				    should_drop = true;
-			}
+		} else if (*ptr > 0 &&
+			   qdf_system_time_before(qdf_get_system_timestamp(),
+				    *ptr + WMA_MGMT_FRAME_DETECT_DOS_TIMER)) {
+			WMA_LOGD(FL("Dropping Assoc Req as it is received after %d ms of last frame. Allow it only after %d ms"),
+				 (int)(qdf_get_system_timestamp() - *ptr),
+				  WMA_MGMT_FRAME_DETECT_DOS_TIMER);
+			should_drop = true;
+			break;
 		}
 		*ptr = qdf_get_system_timestamp();
 		break;
 	case IEEE80211_FC0_SUBTYPE_DISASSOC:
+	case IEEE80211_FC0_SUBTYPE_DEAUTH:
 		ptr = cdp_peer_last_disassoc_received(soc, peer);
-		if (ptr == NULL) {
+		if (!ptr) {
 			WMA_LOGE(FL("cdp_peer_last_disassoc_received Failed"));
 			should_drop = true;
 			goto end;
-		} else if (*ptr > 0) {
-			if ((qdf_get_system_timestamp() - *ptr) <
-				WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
-				    WMA_LOGI(FL("Dropping DisAssoc received"));
-				    should_drop = true;
-			}
-		}
-		*ptr = qdf_get_system_timestamp();
-		break;
-	case IEEE80211_FC0_SUBTYPE_DEAUTH:
-		ptr = cdp_peer_last_deauth_received(soc, peer);
-		if (ptr == NULL) {
-			WMA_LOGE(FL("cdp_peer_last_deauth_received Failed"));
+		} else if (*ptr > 0  &&
+			   qdf_system_time_before(qdf_get_system_timestamp(),
+				    *ptr + WMA_MGMT_FRAME_DETECT_DOS_TIMER)) {
+			WMA_LOGD(FL("Dropping subtype %x frame as it is received after %d ms of last frame. Allow it only after %d ms"),
+				 subtype, (int)
+				 (qdf_get_system_timestamp() - *ptr),
+				 WMA_MGMT_FRAME_DETECT_DOS_TIMER);
 			should_drop = true;
-			goto end;
-		} else if (*ptr > 0) {
-			if ((qdf_get_system_timestamp() - *ptr) <
-				WMA_MGMT_FRAME_DETECT_DOS_TIMER) {
-				    WMA_LOGI(FL("Dropping Deauth received"));
-				    should_drop = true;
-			}
+			break;
 		}
 		*ptr = qdf_get_system_timestamp();
 		break;