소스 검색

qcacmn: Do not intrabss forward EAPOL frames

Do not forward EAPOL frames that have DA different
from the SAP vdev mac addr.

Change-Id: I23959e38b5cbd845d369bebd6913150eca4551bf
CRs-Fixed: 2860248
Yeshwanth Sriram Guntuka 4 년 전
부모
커밋
8c4c0044cb
3개의 변경된 파일45개의 추가작업 그리고 5개의 파일을 삭제
  1. 41 5
      dp/wifi3.0/dp_rx.c
  2. 2 0
      dp/wifi3.0/dp_stats.c
  3. 2 0
      dp/wifi3.0/dp_types.h

+ 41 - 5
dp/wifi3.0/dp_rx.c

@@ -2352,6 +2352,45 @@ static inline bool dp_rx_mec_check_wrapper(struct dp_soc *soc,
 }
 #endif
 
+#ifdef DISABLE_EAPOL_INTRABSS_FWD
+/*
+ * dp_rx_intrabss_fwd_wrapper() - Wrapper API for intrabss fwd. For EAPOL
+ *  pkt with DA not equal to vdev mac addr, fwd is not allowed.
+ * @soc: core txrx main context
+ * @ta_peer: source peer entry
+ * @rx_tlv_hdr: start address of rx tlvs
+ * @nbuf: nbuf that has to be intrabss forwarded
+ * @msdu_metadata: msdu metadata
+ *
+ * Return: true if it is forwarded else false
+ */
+static inline
+bool dp_rx_intrabss_fwd_wrapper(struct dp_soc *soc, struct dp_peer *ta_peer,
+				uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
+				struct hal_rx_msdu_metadata msdu_metadata)
+{
+	if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(nbuf) &&
+			 qdf_mem_cmp(qdf_nbuf_data(nbuf) +
+				     QDF_NBUF_DEST_MAC_OFFSET,
+				     ta_peer->vdev->mac_addr.raw,
+				     QDF_MAC_ADDR_SIZE))) {
+		qdf_nbuf_free(nbuf);
+		DP_STATS_INC(soc, rx.err.intrabss_eapol_drop, 1);
+		return true;
+	}
+
+	return dp_rx_intrabss_fwd(soc, ta_peer, rx_tlv_hdr, nbuf,
+				  msdu_metadata);
+}
+
+#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \
+		dp_rx_intrabss_fwd_wrapper(soc, peer, rx_tlv_hdr, nbuf, \
+					   msdu_metadata)
+#else
+#define DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata) \
+		dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf, msdu_metadata)
+#endif
+
 /**
  * dp_rx_process() - Brain of the Rx processing functionality
  *		     Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
@@ -3007,11 +3046,8 @@ done:
 
 			/* Intrabss-fwd */
 			if (dp_rx_check_ap_bridge(vdev))
-				if (dp_rx_intrabss_fwd(soc,
-							peer,
-							rx_tlv_hdr,
-							nbuf,
-							msdu_metadata)) {
+				if (DP_RX_INTRABSS_FWD(soc, peer, rx_tlv_hdr,
+						       nbuf, msdu_metadata)) {
 					nbuf = next;
 					tid_stats->intrabss_cnt++;
 					continue; /* Get next desc */

+ 2 - 0
dp/wifi3.0/dp_stats.c

@@ -5990,6 +5990,8 @@ void dp_txrx_path_stats(struct dp_soc *soc)
 			       pdev->stats.rx.intra_bss.fail.bytes);
 		DP_PRINT_STATS("intra-bss no mdns fwds %u msdus",
 			       pdev->stats.rx.intra_bss.mdns_no_fwd);
+		DP_PRINT_STATS("intra-bss EAPOL drops: %u",
+			       soc->stats.rx.err.intrabss_eapol_drop);
 
 		DP_PRINT_STATS("raw packets %u msdus ( %llu bytes),",
 			       pdev->stats.rx.raw.num,

+ 2 - 0
dp/wifi3.0/dp_types.h

@@ -1023,6 +1023,8 @@ struct dp_soc_stats {
 			uint32_t ssn_update_count;
 			/* count of bar handling fail */
 			uint32_t bar_handle_fail_count;
+			/* EAPOL drop count in intrabss scenario */
+			uint32_t intrabss_eapol_drop;
 		} err;
 
 		/* packet count per core - per ring */