From 47e7416b12c7b649f1561aafc0fdb69171df6ec8 Mon Sep 17 00:00:00 2001 From: Nandha Kishore Easwaran Date: Tue, 12 Dec 2017 11:54:01 +0530 Subject: [PATCH] qcacmn: Add check to drop mcast loopback packet Added a check in RX path to detect multicast loopback packets in qwrap mode. In qwrap mode, there are multiple station vaps and multicast loopback packet from one station vap should not come into the other station vap. Added a check for this by iterating through the vap list and checking if any of the vdev mac address matches with the source address of the packet. Also added a new vdev parameter to check if qwrap isolation mode is enabled. In qwrap isolation mode, loopback packets should not be dropped. Change-Id: I7d35bf657a87337871156e4caec9038432e23a87 CRs-fixed: 2149190 --- dp/inc/cdp_txrx_cmn_struct.h | 4 +++- dp/wifi3.0/dp_main.c | 3 +++ dp/wifi3.0/dp_rx.h | 44 ++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_rx_err.c | 10 ++++++++ dp/wifi3.0/dp_types.h | 2 ++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index d05ceb5cfa05..baf220620369 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -600,6 +600,7 @@ enum cdp_pdev_param_type { * @CDP_UPDATE_TDLS_FLAGS: tdls link flags * @CDP_ENABLE_AP_BRIDGE: set ap_bridging enable/disable * @CDP_ENABLE_CIPHER : set cipher type based on security + * @CDP_ENABLE_QWRAP_ISOLATION: qwrap isolation mode */ enum cdp_vdev_param_type { CDP_ENABLE_NAWDS, @@ -609,7 +610,8 @@ enum cdp_vdev_param_type { CDP_UPDATE_TDLS_FLAGS, CDP_CFG_WDS_AGING_TIMER, CDP_ENABLE_AP_BRIDGE, - CDP_ENABLE_CIPHER + CDP_ENABLE_CIPHER, + CDP_ENABLE_QWRAP_ISOLATION }; #define TXRX_FW_STATS_TXSTATS 1 diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 82cf7e26d065..f2c2747bfa8a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5089,6 +5089,9 @@ static void dp_set_vdev_param(struct cdp_vdev *vdev_handle, case CDP_ENABLE_CIPHER: vdev->sec_type = val; break; + case CDP_ENABLE_QWRAP_ISOLATION: + vdev->isolation_vdev = val; + break; default: break; } diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 00f6b3a3653f..0987b42b2796 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -613,6 +613,50 @@ static inline QDF_STATUS dp_rx_ast_set_active(struct dp_soc *soc, uint16_t sa_id } #endif +/* + * check_qwrap_multicast_loopback() - Check if rx packet is a loopback packet. + * In qwrap mode, packets originated from + * any vdev should not loopback and + * should be dropped. + * @vdev: vdev on which rx packet is received + * @nbuf: rx pkt + * + */ +#if ATH_SUPPORT_WRAP +static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, + qdf_nbuf_t nbuf) +{ + struct dp_vdev *psta_vdev; + struct dp_pdev *pdev = vdev->pdev; + uint8_t *data = qdf_nbuf_data(nbuf); + + if (qdf_unlikely(vdev->proxysta_vdev)) { + /* In qwrap isolation mode, allow loopback packets as all + * packets go to RootAP and Loopback on the mpsta. + */ + if (vdev->isolation_vdev) + return false; + TAILQ_FOREACH(psta_vdev, &pdev->vdev_list, vdev_list_elem) { + if (qdf_unlikely(psta_vdev->proxysta_vdev && + !qdf_mem_cmp(psta_vdev->mac_addr.raw, + &data[DP_MAC_ADDR_LEN], DP_MAC_ADDR_LEN))) { + /* Drop packet if source address is equal to + * any of the vdev addresses. + */ + return true; + } + } + } + return false; +} +#else +static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, + qdf_nbuf_t nbuf) +{ + return false; +} +#endif + /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 75bc9beda87b..dc5cfd279722 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -485,6 +485,16 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_free(nbuf); return; } + /* + * In qwrap mode if the received packet matches with any of the vdev + * mac addresses, drop it. Donot receive multicast packets originated + * from any proxysta. + */ + if (check_qwrap_multicast_loopback(vdev, nbuf)) { + qdf_nbuf_free(nbuf); + return; + } + if (qdf_unlikely((peer->nawds_enabled == true) && hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index b49ee24cb7aa..5b55699f3e49 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1227,6 +1227,8 @@ struct dp_vdev { /* Is this a proxySTA VAP */ bool proxysta_vdev; + /* Is isolation mode enabled */ + bool isolation_vdev; /* Address search flags to be configured in HAL descriptor */ uint8_t hal_desc_addr_search_flags;