Эх сурвалжийг харах

qcacmn: Donot forward MDNS packets for NAN vdev

MDNS packets if forwarded for a NAN vdev can lead to potential flooding
of the air interface. Hence donot forward them.

Change-Id: Idfdedfb0b5b553745440587448230013f3b56a7d
CRs-Fixed: 2503360
Mohit Khanna 5 жил өмнө
parent
commit
c42d8036c9

+ 1 - 0
dp/inc/cdp_txrx_mob_def.h

@@ -23,6 +23,7 @@
 
 #define TX_WMM_AC_NUM	4
 #define ENABLE_DP_HIST_STATS
+#define DP_RX_DISABLE_NDI_MDNS_FORWARDING
 
 #define OL_TXQ_PAUSE_REASON_FW                (1 << 0)
 #define OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED (1 << 1)

+ 2 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -599,6 +599,7 @@ struct cdp_tx_stats {
  * @mec_drop: Total MEC packets dropped
  * @pkts: Intra BSS packets received
  * @fail: Intra BSS packets failed
+ * @mdns_no_fwd: Intra BSS MDNS packets not forwarded
  * @mic_err: Rx MIC errors CCMP
  * @decrypt_err: Rx Decryption Errors CRC
  * @fcserr: rx MIC check failed (CCMP)
@@ -653,6 +654,7 @@ struct cdp_rx_stats {
 	struct {
 		struct cdp_pkt_info pkts;
 		struct cdp_pkt_info fail;
+		uint32_t mdns_no_fwd;
 	} intra_bss;
 
 	struct {

+ 24 - 1
dp/wifi3.0/dp_rx.c

@@ -40,6 +40,24 @@
 #define DP_RX_TID_SAVE(_nbuf, _tid)
 #endif
 
+#ifdef DP_RX_DISABLE_NDI_MDNS_FORWARDING
+static inline
+bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
+{
+	if (ta_peer->vdev->opmode == wlan_op_mode_ndi &&
+	    qdf_nbuf_is_ipv6_mdns_pkt(nbuf)) {
+		DP_STATS_INC(ta_peer, rx.intra_bss.mdns_no_fwd, 1);
+		return false;
+	}
+		return true;
+}
+#else
+static inline
+bool dp_rx_check_ndi_mdns_fwding(struct dp_peer *ta_peer, qdf_nbuf_t nbuf)
+{
+	return true;
+}
+#endif
 static inline bool dp_rx_check_ap_bridge(struct dp_vdev *vdev)
 {
 	return vdev->ap_bridge_enabled;
@@ -471,9 +489,12 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
 	 */
 	else if (qdf_unlikely((qdf_nbuf_is_da_mcbc(nbuf) &&
 			       !ta_peer->bss_peer))) {
+		if (!dp_rx_check_ndi_mdns_fwding(ta_peer, nbuf))
+			goto end;
+
 		nbuf_copy = qdf_nbuf_copy(nbuf);
 		if (!nbuf_copy)
-			return false;
+			goto end;
 
 		len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
 		memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb));
@@ -487,6 +508,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
 			tid_stats->intrabss_cnt++;
 		}
 	}
+
+end:
 	/* return false as we have to still send the original pkt
 	 * up the stack
 	 */

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

@@ -5142,6 +5142,9 @@ void dp_txrx_path_stats(struct dp_soc *soc)
 		DP_PRINT_STATS("intra-bss fails %u msdus ( %llu bytes),",
 			       pdev->stats.rx.intra_bss.fail.num,
 			       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("raw packets %u msdus ( %llu bytes),",
 			       pdev->stats.rx.raw.num,
 			       pdev->stats.rx.raw.bytes);

+ 16 - 0
qdf/inc/qdf_nbuf.h

@@ -81,6 +81,8 @@
 #define QDF_NBUF_TRAC_ICMPV6_TYPE       0x3a
 #define QDF_NBUF_TRAC_DHCP6_SRV_PORT		547
 #define QDF_NBUF_TRAC_DHCP6_CLI_PORT		546
+#define QDF_NBUF_TRAC_MDNS_SRC_N_DST_PORT	5353
+
 
 /* EAPOL Related MASK */
 #define EAPOL_PACKET_TYPE_OFFSET		15
@@ -2489,6 +2491,20 @@ bool qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data)
 	return __qdf_nbuf_data_is_ipv4_dhcp_pkt(data);
 }
 
+/**
+ * qdf_nbuf_data_is_ipv6_mdsn_pkt() - check if it is MDNS packet.
+ * @data: Pointer to packet data buffer
+ *
+ * This func. checks whether it is a MDNS packet or not.
+ *
+ * Return: true if it is a MDNS packet, false if not
+ */
+static inline
+bool qdf_nbuf_is_ipv6_mdns_pkt(qdf_nbuf_t buf)
+{
+	return __qdf_nbuf_data_is_ipv6_mdns_pkt(qdf_nbuf_data(buf));
+}
+
 /**
  * qdf_nbuf_data_is_ipv6_dhcp_pkt() - check if it is DHCP packet.
  * @data: Pointer to DHCP packet data buffer

+ 1 - 0
qdf/linux/src/i_qdf_nbuf.h

@@ -777,6 +777,7 @@ bool __qdf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data);
 bool __qdf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data);
 bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data);
 bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data);
+bool __qdf_nbuf_data_is_ipv6_mdns_pkt(uint8_t *data);
 bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data);
 bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data);
 bool __qdf_nbuf_is_bcast_pkt(__qdf_nbuf_t nbuf);

+ 29 - 0
qdf/linux/src/qdf_nbuf.c

@@ -1790,6 +1790,35 @@ bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data)
 }
 qdf_export_symbol(__qdf_nbuf_data_is_ipv6_dhcp_pkt);
 
+/**
+ * __qdf_nbuf_data_is_ipv6_mdns_pkt() - check if skb data is a mdns packet
+ * @data: Pointer to network data buffer
+ *
+ * This api is for ipv6 packet.
+ *
+ * Return: true if packet is MDNS packet
+ *	   false otherwise
+ */
+bool __qdf_nbuf_data_is_ipv6_mdns_pkt(uint8_t *data)
+{
+	uint16_t sport;
+	uint16_t dport;
+
+	sport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
+				QDF_NBUF_TRAC_IPV6_HEADER_SIZE);
+	dport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET +
+					QDF_NBUF_TRAC_IPV6_HEADER_SIZE +
+					sizeof(uint16_t));
+
+	if (sport == QDF_SWAP_U16(QDF_NBUF_TRAC_MDNS_SRC_N_DST_PORT) &&
+	    dport == sport)
+		return true;
+	else
+		return false;
+}
+
+qdf_export_symbol(__qdf_nbuf_data_is_ipv6_mdns_pkt);
+
 /**
  * __qdf_nbuf_data_is_ipv4_mcast_pkt() - check if it is IPV4 multicast packet.
  * @data: Pointer to IPV4 packet data buffer