Index: sys/dev/mlx5/mlx5_en/en.h =================================================================== --- sys/dev/mlx5/mlx5_en/en.h +++ sys/dev/mlx5/mlx5_en/en.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "opt_rss.h" @@ -660,6 +661,7 @@ struct mlx5e_flow_table ft; struct mlx5e_eth_addr_db eth_addr; struct mlx5e_vlan_db vlan; + struct vlans_table *vlans; struct mlx5e_params params; struct mlx5e_params_ethtool params_ethtool; Index: sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c =================================================================== --- sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c +++ sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c @@ -558,6 +558,7 @@ return; PRIV_LOCK(priv); + yndx_vlan_set(priv->vlans, vid, yndx_vlan_devat(ifp, vid)); set_bit(vid, priv->vlan.active_vlans); if (test_bit(MLX5E_STATE_OPENED, &priv->state)) mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid); @@ -573,6 +574,7 @@ return; PRIV_LOCK(priv); + yndx_vlan_set(priv->vlans, vid, NULL); clear_bit(vid, priv->vlan.active_vlans); if (test_bit(MLX5E_STATE_OPENED, &priv->state)) mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid); Index: sys/dev/mlx5/mlx5_en/mlx5_en_main.c =================================================================== --- sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -3153,6 +3153,8 @@ ether_ifattach(ifp, dev_addr); /* Register for VLAN events */ + priv->vlans = malloc(sizeof(*priv->vlans), M_MLX5EN, + M_WAITOK | M_ZERO); priv->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, mlx5e_vlan_rx_add_vid, priv, EVENTHANDLER_PRI_FIRST); priv->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, @@ -3252,6 +3254,7 @@ mlx5e_disable_async_events(priv); flush_scheduled_work(); mlx5e_priv_mtx_destroy(priv); + free(priv->vlans, M_MLX5EN); free(priv, M_MLX5EN); } Index: sys/dev/mlx5/mlx5_en/mlx5_en_rx.c =================================================================== --- sys/dev/mlx5/mlx5_en/mlx5_en_rx.c +++ sys/dev/mlx5/mlx5_en/mlx5_en_rx.c @@ -184,7 +184,7 @@ struct mlx5e_rq *rq, struct mbuf *mb, u32 cqe_bcnt) { - struct ifnet *ifp = rq->ifp; + struct ifnet *ifp = rq->ifp, *rcvif; struct mlx5e_priv *priv = ifp->if_softc; int lro_num_seg; /* HW LRO session aggregated packets counter */ @@ -238,8 +238,6 @@ priv->mdev->priv.qtof_add; M_HASHTYPE_SET(mb, M_HASHTYPE_OPAQUE); } - mb->m_pkthdr.rcvif = ifp; - if (likely(ifp->if_capenable & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) && ((cqe->hds_ip_ext & (CQE_L2_OK | CQE_L3_OK | CQE_L4_OK)) == (CQE_L2_OK | CQE_L3_OK | CQE_L4_OK))) { @@ -253,8 +251,19 @@ if (cqe_has_vlan(cqe)) { mb->m_pkthdr.ether_vtag = be16_to_cpu(cqe->vlan_info); - mb->m_flags |= M_VLANTAG; + if (ifp->if_capenable & IFCAP_VLAN_HWFILTER) { + rcvif = yndx_vlan_get(priv->vlans, + EVL_VLANOFTAG(mb->m_pkthdr.ether_vtag)); + } else + rcvif = NULL; + if (rcvif == NULL) + mb->m_flags |= M_VLANTAG; + else { + ifp = rcvif; + if_inc_counter(rcvif, IFCOUNTER_IPACKETS, 1); + } } + mb->m_pkthdr.rcvif = ifp; } static inline void @@ -385,7 +394,7 @@ (rq->ifp->if_capenable & IFCAP_LRO) == 0 || rq->lro.lro_cnt == 0 || tcp_lro_rx(&rq->lro, mb, 0) != 0) { - rq->ifp->if_input(rq->ifp, mb); + rq->ifp->if_input(mb->m_pkthdr.rcvif, mb); } #endif wq_ll_pop: @@ -415,7 +424,7 @@ memset(mb->m_data, 255, 14); mb->m_data[14] = rq->ix; mb->m_pkthdr.rcvif = rq->ifp; - rq->ifp->if_input(rq->ifp, mb); + rq->ifp->if_input(mb->m_pkthdr.rcvif, mb); } #endif