Browse Source

qcacld-3.0: Validate peer before sending to serialization queue

Consider a below case
1. SAP received south bound disconnect command
2. At same time, SAP CSA to DFS channel happened
   and thus peers are deleted
3. Later same peer got re-added and south bound
   disconnect command becomes active for same peer

When SAP receives south bound disconnect req, then driver will
post WLAN_SER_CMD_WM_STATUS_CHANGE(eWNI_SME_DEAUTH_IND/
eWNI_SME_DISASSOC_IND) command to schedular thread. After posting
to schedular thread, the command will wait in SME message queue.
During this time, SAP CSA to DFS channel happened. Driver will
post CSA to schedular thread and it will wait in PE message
queue.
Since PE message queue has higher priority than SME message queue
CSA will process first. As part of CSA, driver will delete all
peer including sta hash entry.
After CSA, south bound disconnect command got queue to
serialization and same peer got re-added again.
When south bound disconnect command becomes active, the states
will not be proper (as for old peer, disassocTrigger will be
eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and for new
peer disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH)
and thus response to CSR(old peer: eWNI_SME_DISCONNECT_DONE_IND,
new peer: eWNI_SME_DISASSOC_RSP) will not be proper.
Due to this south bound disconnect command will not remove from
active queue which leads to active command timeout.

As part of fix, validate peer before sending to serialization
to avoid queueing the cmd if peer is already deleted.

Change-Id: I099b4b8e85ea8cfd24bcaec0add3c6f1fcaf8b11
CRs-Fixed: 3210877
Jyoti Kumari 2 years ago
parent
commit
f3c859ae04
1 changed files with 62 additions and 0 deletions
  1. 62 0
      core/sme/src/csr/csr_api_roam.c

+ 62 - 0
core/sme/src/csr/csr_api_roam.c

@@ -4003,6 +4003,60 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 	qdf_mem_free(roam_info);
 }
 
+/* csr_if_peer_present() - Check whether peer is present or not
+ * @mac_ctx: Pointer to mac context
+ * @bssid: Pointer to bssid address
+ * @peer_macaddr: Pointer to peer mac address
+ *
+ * Consider a case
+ * 1. SAP received south bound disconnect command
+ * 2. At same time, SAP CSA to DFS channel happened and thus peers are deleted.
+ * 3. Later same peer got re-added and south bound disconnect command becomes
+ *    active for same peer.
+ *
+ * When SAP receives south bound disconnect command req, driver will post to
+ * schedular thread and it will wait in SME message queue. When SAP CSA to DFS
+ * channel happens, driver will post to schedular thread and it will wait in PE
+ * message queue. Since PE has higher priority than SME message queue, so it
+ * will process first. As part of CSA, it will delete all peer including sta
+ * hash entry.
+ * After CSA, south bound disconnect command got queue to serialization and
+ * same peer got re-added again. When south bound disconnect command becomes
+ * active, the states will not be proper because for old peer, disassocTrigger
+ * is eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and when new peer gets
+ * re-added, disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH and
+ * thus response to CSR will not be proper. Due to this south bound disconnect
+ * command will not remove from active queue which leads to active command
+ * timeout.
+ * Validate the peer before sending to serialization to avoid queuing command
+ * if peer is already deleted.
+ *
+ * Return: True if peer is present otherwise return false
+ */
+static bool csr_if_peer_present(struct mac_context *mac_ctx,
+				uint8_t *bssid,
+				uint8_t *peer_macaddr)
+{
+	struct wlan_objmgr_peer *peer;
+	uint8_t pdev_id;
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
+
+	peer = wlan_objmgr_get_peer_by_mac_n_vdev(mac_ctx->psoc, pdev_id,
+						  bssid, peer_macaddr,
+						  WLAN_LEGACY_SME_ID);
+
+	if (!peer) {
+		sme_info("peer not found for mac: " QDF_MAC_ADDR_FMT "and bssid: "
+			  QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr),
+			  QDF_MAC_ADDR_REF(bssid));
+		return false;
+	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
+	return true;
+}
+
 static void
 csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {
@@ -4028,6 +4082,10 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 		return;
 	}
 
+	if (!csr_if_peer_present(mac_ctx, &pDisassocInd->bssid.bytes[0],
+				 &pDisassocInd->peer_macaddr.bytes[0]))
+		return;
+
 	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
 	    pDisassocInd->peer_macaddr))
 		return;
@@ -4070,6 +4128,10 @@ csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 		return;
 	}
 
+	if (!csr_if_peer_present(mac_ctx, &pDeauthInd->bssid.bytes[0],
+				 &pDeauthInd->peer_macaddr.bytes[0]))
+		return;
+
 	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
 	    pDeauthInd->peer_macaddr))
 		return;