From c42d8036c9500a0cff0141fb88765855f3ef5973 Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Thu, 8 Aug 2019 18:44:17 -0700 Subject: [PATCH] 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 --- dp/inc/cdp_txrx_mob_def.h | 1 + dp/inc/cdp_txrx_stats_struct.h | 2 ++ dp/wifi3.0/dp_rx.c | 25 ++++++++++++++++++++++++- dp/wifi3.0/dp_stats.c | 3 +++ qdf/inc/qdf_nbuf.h | 16 ++++++++++++++++ qdf/linux/src/i_qdf_nbuf.h | 1 + qdf/linux/src/qdf_nbuf.c | 29 +++++++++++++++++++++++++++++ 7 files changed, 76 insertions(+), 1 deletion(-) diff --git a/dp/inc/cdp_txrx_mob_def.h b/dp/inc/cdp_txrx_mob_def.h index 2fd17685c4..4bf55fbd6b 100644 --- a/dp/inc/cdp_txrx_mob_def.h +++ b/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) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 78640e195a..76f2c5aa3c 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/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 { diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index fbc9087467..9f5f4988e9 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/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 */ diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index f78ac508e6..40bf8075d8 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/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); diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index cc8bf1d353..6318b85477 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/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 diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 7cb73d2d09..0ea6f2d181 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/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); diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index c6f88c54cd..e7691b8642 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/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