diff --git a/dp/wifi3.0/be/dp_be_rx.c b/dp/wifi3.0/be/dp_be_rx.c index d664e5bc85..2d4fe727c2 100644 --- a/dp/wifi3.0/be/dp_be_rx.c +++ b/dp/wifi3.0/be/dp_be_rx.c @@ -1218,6 +1218,14 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc, qdf_nbuf_is_ipv6_igmp_pkt(nbuf))) return false; + if (qdf_unlikely(vdev->multipass_en)) { + if (dp_rx_multipass_process(peer, nbuf, tid) == false) { + DP_PEER_PER_PKT_STATS_INC(peer, + rx.multipass_rx_pkt_drop, 1); + return false; + } + } + if (!peer->bss_peer) { if (dp_rx_intrabss_mcbc_fwd(soc, peer, NULL, nbuf, tid_stats)) dp_rx_err("forwarding failed"); diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 6c33f0164b..22b91ec00b 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -66,14 +66,17 @@ #define QDF_NBUF_SRC_MAC_OFFSET 6 #define QDF_NBUF_TRAC_IPV4_TOS_OFFSET 15 #define QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET 23 +#define QDF_NBUF_TRAC_VLAN_IPV4_PROTO_TYPE_OFFSET 27 #define QDF_NBUF_TRAC_IPV4_DEST_ADDR_OFFSET 30 #define QDF_NBUF_TRAC_IPV4_SRC_ADDR_OFFSET 26 #define QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET 20 +#define QDF_NBUF_TRAC_VLAN_IPV6_PROTO_TYPE_OFFSET 24 #define QDF_NBUF_TRAC_IPV4_ADDR_MCAST_MASK 0xE0000000 #define QDF_NBUF_TRAC_IPV4_ADDR_BCAST_MASK 0xF0000000 #define QDF_NBUF_TRAC_IPV6_DEST_ADDR_OFFSET 38 #define QDF_NBUF_TRAC_IPV6_DEST_ADDR 0xFF00 #define QDF_NBUF_TRAC_IPV6_OFFSET 14 +#define QDF_NBUF_TRAC_VLAN_IPV6_OFFSET 18 #define QDF_NBUF_TRAC_IPV6_HEADER_SIZE 40 #define QDF_NBUF_TRAC_ICMP_TYPE 1 #define QDF_NBUF_TRAC_IGMP_TYPE 2 diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 5dda67edb0..bd5974b7fe 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -1873,6 +1873,56 @@ bool __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff *skb) } qdf_export_symbol(__qdf_nbuf_is_ipv4_wapi_pkt); +/** + * qdf_nbuf_is_ipv6_vlan_pkt() - check wheather packet is vlan IPV6 + * @data: Pointer to network data buffer + * + * This api is for vlan header included ipv6 packet. + * + * Return: true if packet is vlan header included IPV6 + * false otherwise. + */ +static bool qdf_nbuf_is_ipv6_vlan_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); + + if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) { + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); + + if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_ETH_TYPE)) + return true; + } + return false; +} + +/** + * qdf_nbuf_is_ipv4_vlan_pkt() - check wheather packet is vlan IPV4 + * @data: Pointer to network data buffer + * + * This api is for vlan header included ipv4 packet. + * + * Return: true if packet is vlan header included IPV4 + * false otherwise. + */ +static bool qdf_nbuf_is_ipv4_vlan_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); + + if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) { + ether_type = *(uint16_t *)(data + + QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); + + if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) + return true; + } + return false; +} + /** * __qdf_nbuf_data_is_ipv4_igmp_pkt() - check if skb data is a igmp packet * @data: Pointer to network data buffer @@ -1884,15 +1934,26 @@ qdf_export_symbol(__qdf_nbuf_is_ipv4_wapi_pkt); */ bool __qdf_nbuf_data_is_ipv4_igmp_pkt(uint8_t *data) { - if (__qdf_nbuf_data_is_ipv4_pkt(data)) { - uint8_t pkt_type; + uint8_t pkt_type; + if (__qdf_nbuf_data_is_ipv4_pkt(data)) { pkt_type = (uint8_t)(*(uint8_t *)(data + QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); - - if (pkt_type == QDF_NBUF_TRAC_IGMP_TYPE) - return true; + goto is_igmp; } + + if (qdf_nbuf_is_ipv4_vlan_pkt(data)) { + pkt_type = (uint8_t)(*(uint8_t *)( + data + + QDF_NBUF_TRAC_VLAN_IPV4_PROTO_TYPE_OFFSET)); + goto is_igmp; + } + + return false; +is_igmp: + if (pkt_type == QDF_NBUF_TRAC_IGMP_TYPE) + return true; + return false; } @@ -1909,21 +1970,38 @@ qdf_export_symbol(__qdf_nbuf_data_is_ipv4_igmp_pkt); */ bool __qdf_nbuf_data_is_ipv6_igmp_pkt(uint8_t *data) { - if (__qdf_nbuf_data_is_ipv6_pkt(data)) { - uint8_t pkt_type; - uint8_t next_hdr; + uint8_t pkt_type; + uint8_t next_hdr; + if (__qdf_nbuf_data_is_ipv6_pkt(data)) { pkt_type = (uint8_t)(*(uint8_t *)(data + QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); - next_hdr = (uint8_t)(*(uint8_t *)(data + + next_hdr = (uint8_t)(*(uint8_t *)( + data + + QDF_NBUF_TRAC_IPV6_OFFSET + QDF_NBUF_TRAC_IPV6_HEADER_SIZE)); - - if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE) - return true; - if ((pkt_type == QDF_NBUF_TRAC_HOPOPTS_TYPE) && - (next_hdr == QDF_NBUF_TRAC_HOPOPTS_TYPE)) - return true; + goto is_mld; } + + if (qdf_nbuf_is_ipv6_vlan_pkt(data)) { + pkt_type = (uint8_t)(*(uint8_t *)( + data + + QDF_NBUF_TRAC_VLAN_IPV6_PROTO_TYPE_OFFSET)); + next_hdr = (uint8_t)(*(uint8_t *)( + data + + QDF_NBUF_TRAC_VLAN_IPV6_OFFSET + + QDF_NBUF_TRAC_IPV6_HEADER_SIZE)); + goto is_mld; + } + + return false; +is_mld: + if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE) + return true; + if ((pkt_type == QDF_NBUF_TRAC_HOPOPTS_TYPE) && + (next_hdr == QDF_NBUF_TRAC_ICMPV6_TYPE)) + return true; + return false; }