X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fice_fdir_filter.c;h=7954c6d8eaada2a013f695081d13839c887e9d69;hb=01b8739f476dbccc18d66f60bff3df91804ef634;hp=4e99df12729250f13d1b8e6941cae843b113120a;hpb=2b6d6d71a0992220043b2f5c3b885c486e7921b7;p=dpdk.git diff --git a/drivers/net/ice/ice_fdir_filter.c b/drivers/net/ice/ice_fdir_filter.c index 4e99df1272..7954c6d8ea 100644 --- a/drivers/net/ice/ice_fdir_filter.c +++ b/drivers/net/ice/ice_fdir_filter.c @@ -24,7 +24,7 @@ #define ICE_FDIR_INSET_ETH_IPV4 (\ ICE_FDIR_INSET_ETH | \ ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | ICE_INSET_IPV4_TOS | \ - ICE_INSET_IPV4_TTL | ICE_INSET_IPV4_PROTO) + ICE_INSET_IPV4_TTL | ICE_INSET_IPV4_PROTO | ICE_INSET_IPV4_PKID) #define ICE_FDIR_INSET_ETH_IPV4_UDP (\ ICE_FDIR_INSET_ETH_IPV4 | \ @@ -41,7 +41,8 @@ #define ICE_FDIR_INSET_ETH_IPV6 (\ ICE_INSET_DMAC | \ ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | ICE_INSET_IPV6_TC | \ - ICE_INSET_IPV6_HOP_LIMIT | ICE_INSET_IPV6_NEXT_HDR) + ICE_INSET_IPV6_HOP_LIMIT | ICE_INSET_IPV6_NEXT_HDR | \ + ICE_INSET_IPV6_PKID) #define ICE_FDIR_INSET_ETH_IPV6_UDP (\ ICE_FDIR_INSET_ETH_IPV6 | \ @@ -55,21 +56,26 @@ ICE_FDIR_INSET_ETH_IPV6 | \ ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT) -#define ICE_FDIR_INSET_VXLAN_IPV4 (\ - ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST) +#define ICE_FDIR_INSET_IPV4 (\ + ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \ + ICE_INSET_IPV4_PKID) -#define ICE_FDIR_INSET_VXLAN_IPV4_TCP (\ - ICE_FDIR_INSET_VXLAN_IPV4 | \ +#define ICE_FDIR_INSET_IPV4_TCP (\ + ICE_FDIR_INSET_IPV4 | \ ICE_INSET_TCP_SRC_PORT | ICE_INSET_TCP_DST_PORT) -#define ICE_FDIR_INSET_VXLAN_IPV4_UDP (\ - ICE_FDIR_INSET_VXLAN_IPV4 | \ +#define ICE_FDIR_INSET_IPV4_UDP (\ + ICE_FDIR_INSET_IPV4 | \ ICE_INSET_UDP_SRC_PORT | ICE_INSET_UDP_DST_PORT) -#define ICE_FDIR_INSET_VXLAN_IPV4_SCTP (\ - ICE_FDIR_INSET_VXLAN_IPV4 | \ +#define ICE_FDIR_INSET_IPV4_SCTP (\ + ICE_FDIR_INSET_IPV4 | \ ICE_INSET_SCTP_SRC_PORT | ICE_INSET_SCTP_DST_PORT) +#define ICE_FDIR_INSET_ETH_IPV4_VXLAN (\ + ICE_FDIR_INSET_ETH | ICE_FDIR_INSET_ETH_IPV4 | \ + ICE_INSET_VXLAN_VNI) + #define ICE_FDIR_INSET_IPV4_GTPU (\ ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | ICE_INSET_GTPU_TEID) @@ -84,36 +90,51 @@ ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \ ICE_INSET_GTPU_TEID | ICE_INSET_GTPU_QFI) +#define ICE_FDIR_INSET_IPV4_ESP (\ + ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \ + ICE_INSET_ESP_SPI) + +#define ICE_FDIR_INSET_IPV6_ESP (\ + ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \ + ICE_INSET_ESP_SPI) + +#define ICE_FDIR_INSET_IPV4_NATT_ESP (\ + ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \ + ICE_INSET_NAT_T_ESP_SPI) + +#define ICE_FDIR_INSET_IPV6_NATT_ESP (\ + ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \ + ICE_INSET_NAT_T_ESP_SPI) + static struct ice_pattern_match_item ice_fdir_pattern_list[] = { - {pattern_ethertype, ICE_FDIR_INSET_ETH, ICE_INSET_NONE}, - {pattern_eth_ipv4, ICE_FDIR_INSET_ETH_IPV4, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp, ICE_FDIR_INSET_ETH_IPV4_UDP, ICE_INSET_NONE}, - {pattern_eth_ipv4_tcp, ICE_FDIR_INSET_ETH_IPV4_TCP, ICE_INSET_NONE}, - {pattern_eth_ipv4_sctp, ICE_FDIR_INSET_ETH_IPV4_SCTP, ICE_INSET_NONE}, - {pattern_eth_ipv6, ICE_FDIR_INSET_ETH_IPV6, ICE_INSET_NONE}, - {pattern_eth_ipv6_udp, ICE_FDIR_INSET_ETH_IPV6_UDP, ICE_INSET_NONE}, - {pattern_eth_ipv6_tcp, ICE_FDIR_INSET_ETH_IPV6_TCP, ICE_INSET_NONE}, - {pattern_eth_ipv6_sctp, ICE_FDIR_INSET_ETH_IPV6_SCTP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_ipv4, - ICE_FDIR_INSET_VXLAN_IPV4, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_ipv4_udp, - ICE_FDIR_INSET_VXLAN_IPV4_UDP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_ipv4_tcp, - ICE_FDIR_INSET_VXLAN_IPV4_TCP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_ipv4_sctp, - ICE_FDIR_INSET_VXLAN_IPV4_SCTP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_eth_ipv4, - ICE_FDIR_INSET_VXLAN_IPV4, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_eth_ipv4_udp, - ICE_FDIR_INSET_VXLAN_IPV4_UDP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_eth_ipv4_tcp, - ICE_FDIR_INSET_VXLAN_IPV4_TCP, ICE_INSET_NONE}, - {pattern_eth_ipv4_udp_vxlan_eth_ipv4_sctp, - ICE_FDIR_INSET_VXLAN_IPV4_SCTP, ICE_INSET_NONE}, - {pattern_eth_ipv4_gtpu, ICE_FDIR_INSET_IPV4_GTPU, ICE_INSET_NONE}, - {pattern_eth_ipv4_gtpu_eh, ICE_FDIR_INSET_IPV4_GTPU_EH, ICE_INSET_NONE}, - {pattern_eth_ipv6_gtpu, ICE_FDIR_INSET_IPV6_GTPU, ICE_INSET_NONE}, - {pattern_eth_ipv6_gtpu_eh, ICE_FDIR_INSET_IPV6_GTPU_EH, ICE_INSET_NONE}, + {pattern_raw, ICE_INSET_NONE, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_ethertype, ICE_FDIR_INSET_ETH, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4, ICE_FDIR_INSET_ETH_IPV4, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp, ICE_FDIR_INSET_ETH_IPV4_UDP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_tcp, ICE_FDIR_INSET_ETH_IPV4_TCP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_sctp, ICE_FDIR_INSET_ETH_IPV4_SCTP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6, ICE_FDIR_INSET_ETH_IPV6, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_frag_ext, ICE_FDIR_INSET_ETH_IPV6, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp, ICE_FDIR_INSET_ETH_IPV6_UDP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_tcp, ICE_FDIR_INSET_ETH_IPV6_TCP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_sctp, ICE_FDIR_INSET_ETH_IPV6_SCTP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_esp, ICE_FDIR_INSET_IPV4_ESP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_esp, ICE_FDIR_INSET_IPV4_NATT_ESP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_esp, ICE_FDIR_INSET_IPV6_ESP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_esp, ICE_FDIR_INSET_IPV6_NATT_ESP, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_ipv4, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_IPV4, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_ipv4_udp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_IPV4_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_ipv4_tcp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_ipv4_sctp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_IPV4_SCTP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_eth_ipv4, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_ETH_IPV4, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_eth_ipv4_udp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_ETH_IPV4_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_eth_ipv4_tcp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_ETH_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_vxlan_eth_ipv4_sctp, ICE_FDIR_INSET_ETH_IPV4_VXLAN, ICE_FDIR_INSET_ETH_IPV4_SCTP, ICE_INSET_NONE}, + /* duplicated GTPU input set in 3rd column to align with shared code behavior. Ideally, only put GTPU field in 2nd column. */ + {pattern_eth_ipv4_gtpu, ICE_FDIR_INSET_IPV4_GTPU, ICE_FDIR_INSET_IPV4_GTPU, ICE_INSET_NONE}, + {pattern_eth_ipv4_gtpu_eh, ICE_FDIR_INSET_IPV4_GTPU_EH, ICE_FDIR_INSET_IPV4_GTPU_EH, ICE_INSET_NONE}, + {pattern_eth_ipv6_gtpu, ICE_FDIR_INSET_IPV6_GTPU, ICE_FDIR_INSET_IPV6_GTPU, ICE_INSET_NONE}, + {pattern_eth_ipv6_gtpu_eh, ICE_FDIR_INSET_IPV6_GTPU_EH, ICE_FDIR_INSET_IPV6_GTPU_EH, ICE_INSET_NONE}, }; static struct ice_flow_parser ice_fdir_parser; @@ -354,7 +375,7 @@ ice_fdir_counter_free(__rte_unused struct ice_pf *pf, static int ice_fdir_init_filter_list(struct ice_pf *pf) { - struct rte_eth_dev *dev = pf->adapter->eth_dev; + struct rte_eth_dev *dev = &rte_eth_devices[pf->dev_data->port_id]; struct ice_fdir_info *fdir_info = &pf->fdir; char fdir_hash_name[RTE_HASH_NAMESIZE]; int ret; @@ -400,10 +421,8 @@ ice_fdir_release_filter_list(struct ice_pf *pf) { struct ice_fdir_info *fdir_info = &pf->fdir; - if (fdir_info->hash_map) - rte_free(fdir_info->hash_map); - if (fdir_info->hash_table) - rte_hash_free(fdir_info->hash_table); + rte_free(fdir_info->hash_map); + rte_hash_free(fdir_info->hash_table); fdir_info->hash_map = NULL; fdir_info->hash_table = NULL; @@ -416,7 +435,7 @@ ice_fdir_release_filter_list(struct ice_pf *pf) static int ice_fdir_setup(struct ice_pf *pf) { - struct rte_eth_dev *eth_dev = pf->adapter->eth_dev; + struct rte_eth_dev *eth_dev = &rte_eth_devices[pf->dev_data->port_id]; struct ice_hw *hw = ICE_PF_TO_HW(pf); const struct rte_memzone *mz = NULL; char z_name[RTE_MEMZONE_NAMESIZE]; @@ -604,7 +623,7 @@ ice_fdir_prof_rm_all(struct ice_pf *pf) static void ice_fdir_teardown(struct ice_pf *pf) { - struct rte_eth_dev *eth_dev = pf->adapter->eth_dev; + struct rte_eth_dev *eth_dev = &rte_eth_devices[pf->dev_data->port_id]; struct ice_hw *hw = ICE_PF_TO_HW(pf); struct ice_vsi *vsi; int err; @@ -786,6 +805,28 @@ ice_fdir_cross_prof_conflict(struct ice_pf *pf, (pf, cflct_ptype, is_tunnel)) goto err; break; + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_UDP: + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_TCP: + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_SCTP: + cflct_ptype = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_OTHER; + if (!ice_fdir_prof_resolve_conflict + (pf, cflct_ptype, is_tunnel)) + goto err; + break; + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_OTHER: + cflct_ptype = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_UDP; + if (!ice_fdir_prof_resolve_conflict + (pf, cflct_ptype, is_tunnel)) + goto err; + cflct_ptype = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_TCP; + if (!ice_fdir_prof_resolve_conflict + (pf, cflct_ptype, is_tunnel)) + goto err; + cflct_ptype = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_SCTP; + if (!ice_fdir_prof_resolve_conflict + (pf, cflct_ptype, is_tunnel)) + goto err; + break; default: break; } @@ -885,27 +926,32 @@ ice_fdir_input_set_parse(uint64_t inset, enum ice_flow_field *field) {ICE_INSET_IPV4_TOS, ICE_FLOW_FIELD_IDX_IPV4_DSCP}, {ICE_INSET_IPV4_TTL, ICE_FLOW_FIELD_IDX_IPV4_TTL}, {ICE_INSET_IPV4_PROTO, ICE_FLOW_FIELD_IDX_IPV4_PROT}, + {ICE_INSET_IPV4_PKID, ICE_FLOW_FIELD_IDX_IPV4_ID}, {ICE_INSET_IPV6_SRC, ICE_FLOW_FIELD_IDX_IPV6_SA}, {ICE_INSET_IPV6_DST, ICE_FLOW_FIELD_IDX_IPV6_DA}, {ICE_INSET_IPV6_TC, ICE_FLOW_FIELD_IDX_IPV6_DSCP}, {ICE_INSET_IPV6_NEXT_HDR, ICE_FLOW_FIELD_IDX_IPV6_PROT}, {ICE_INSET_IPV6_HOP_LIMIT, ICE_FLOW_FIELD_IDX_IPV6_TTL}, + {ICE_INSET_IPV6_PKID, ICE_FLOW_FIELD_IDX_IPV6_ID}, + {ICE_INSET_TCP_SRC_PORT, ICE_FLOW_FIELD_IDX_TCP_SRC_PORT}, + {ICE_INSET_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT}, + {ICE_INSET_UDP_SRC_PORT, ICE_FLOW_FIELD_IDX_UDP_SRC_PORT}, + {ICE_INSET_UDP_DST_PORT, ICE_FLOW_FIELD_IDX_UDP_DST_PORT}, + {ICE_INSET_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT}, + {ICE_INSET_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT}, + {ICE_INSET_IPV4_SRC, ICE_FLOW_FIELD_IDX_IPV4_SA}, + {ICE_INSET_IPV4_DST, ICE_FLOW_FIELD_IDX_IPV4_DA}, {ICE_INSET_TCP_SRC_PORT, ICE_FLOW_FIELD_IDX_TCP_SRC_PORT}, {ICE_INSET_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT}, {ICE_INSET_UDP_SRC_PORT, ICE_FLOW_FIELD_IDX_UDP_SRC_PORT}, {ICE_INSET_UDP_DST_PORT, ICE_FLOW_FIELD_IDX_UDP_DST_PORT}, {ICE_INSET_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT}, {ICE_INSET_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT}, - {ICE_INSET_TUN_IPV4_SRC, ICE_FLOW_FIELD_IDX_IPV4_SA}, - {ICE_INSET_TUN_IPV4_DST, ICE_FLOW_FIELD_IDX_IPV4_DA}, - {ICE_INSET_TUN_TCP_SRC_PORT, ICE_FLOW_FIELD_IDX_TCP_SRC_PORT}, - {ICE_INSET_TUN_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT}, - {ICE_INSET_TUN_UDP_SRC_PORT, ICE_FLOW_FIELD_IDX_UDP_SRC_PORT}, - {ICE_INSET_TUN_UDP_DST_PORT, ICE_FLOW_FIELD_IDX_UDP_DST_PORT}, - {ICE_INSET_TUN_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT}, - {ICE_INSET_TUN_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT}, {ICE_INSET_GTPU_TEID, ICE_FLOW_FIELD_IDX_GTPU_IP_TEID}, {ICE_INSET_GTPU_QFI, ICE_FLOW_FIELD_IDX_GTPU_EH_QFI}, + {ICE_INSET_VXLAN_VNI, ICE_FLOW_FIELD_IDX_VXLAN_VNI}, + {ICE_INSET_ESP_SPI, ICE_FLOW_FIELD_IDX_ESP_SPI}, + {ICE_INSET_NAT_T_ESP_SPI, ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI}, }; for (i = 0, j = 0; i < RTE_DIM(ice_inset_map); i++) { @@ -938,6 +984,10 @@ ice_fdir_input_set_hdrs(enum ice_fltr_ptype flow, struct ice_flow_seg_info *seg) ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; + case ICE_FLTR_PTYPE_FRAG_IPV4: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV4 | + ICE_FLOW_SEG_HDR_IPV_FRAG); + break; case ICE_FLTR_PTYPE_NONF_IPV6_UDP: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6 | @@ -957,26 +1007,34 @@ ice_fdir_input_set_hdrs(enum ice_fltr_ptype flow, struct ice_flow_seg_info *seg) ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; - case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP: - case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP: - case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP: - case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER: + case ICE_FLTR_PTYPE_FRAG_IPV6: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV6 | + ICE_FLOW_SEG_HDR_IPV_FRAG); + break; + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_UDP: + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_TCP: + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_SCTP: + break; + case ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_OTHER: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV4_GTPU: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; - case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_EH_IPV4_OTHER: + case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_EH: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; - case ICE_FLTR_PTYPE_NONF_IPV6_GTPU_IPV6_OTHER: + case ICE_FLTR_PTYPE_NONF_IPV6_GTPU: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; - case ICE_FLTR_PTYPE_NONF_IPV6_GTPU_EH_IPV6_OTHER: + case ICE_FLTR_PTYPE_NONF_IPV6_GTPU_EH: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_EH | ICE_FLOW_SEG_HDR_GTPU_IP | ICE_FLOW_SEG_HDR_IPV6 | @@ -985,6 +1043,26 @@ ice_fdir_input_set_hdrs(enum ice_fltr_ptype flow, struct ice_flow_seg_info *seg) case ICE_FLTR_PTYPE_NON_IP_L2: ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ETH_NON_IP); break; + case ICE_FLTR_PTYPE_NONF_IPV4_ESP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP | + ICE_FLOW_SEG_HDR_IPV4 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV6_ESP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_ESP | + ICE_FLOW_SEG_HDR_IPV6 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP | + ICE_FLOW_SEG_HDR_IPV4 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_NAT_T_ESP | + ICE_FLOW_SEG_HDR_IPV6 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; default: PMD_DRV_LOG(ERR, "not supported filter type."); break; @@ -1013,7 +1091,7 @@ ice_fdir_input_set_conf(struct ice_pf *pf, enum ice_fltr_ptype flow, return -ENOMEM; } - /* use seg_tun[1] to record tunnel inner part or non-tunnel */ + /* use seg_tun[1] to record tunnel inner part */ for (k = 0; k <= ICE_FD_HW_SEG_TUN; k++) { seg = &seg_tun[k]; input_set = (k == ICE_FD_HW_SEG_TUN) ? inner_input_set : outer_input_set; @@ -1036,13 +1114,9 @@ ice_fdir_input_set_conf(struct ice_pf *pf, enum ice_fltr_ptype flow, } is_tunnel = ice_fdir_is_tunnel_profile(ttype); - if (!is_tunnel) { - ret = ice_fdir_hw_tbl_conf(pf, pf->main_vsi, pf->fdir.fdir_vsi, - seg_tun + 1, flow, false); - } else { - ret = ice_fdir_hw_tbl_conf(pf, pf->main_vsi, pf->fdir.fdir_vsi, - seg_tun, flow, true); - } + + ret = ice_fdir_hw_tbl_conf(pf, pf->main_vsi, pf->fdir.fdir_vsi, + seg_tun, flow, is_tunnel); if (!ret) { return ret; @@ -1113,6 +1187,24 @@ ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type) return 0; } +static int +ice_fdir_add_del_raw(struct ice_pf *pf, + struct ice_fdir_filter_conf *filter, + bool add) +{ + struct ice_hw *hw = ICE_PF_TO_HW(pf); + + unsigned char *pkt = (unsigned char *)pf->fdir.prg_pkt; + rte_memcpy(pkt, filter->pkt_buf, filter->pkt_len); + + struct ice_fltr_desc desc; + memset(&desc, 0, sizeof(desc)); + filter->input.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW; + ice_fdir_get_prgm_desc(hw, &filter->input, &desc, add); + + return ice_fdir_programming(pf, &desc); +} + static int ice_fdir_add_del_filter(struct ice_pf *pf, struct ice_fdir_filter_conf *filter, @@ -1228,6 +1320,68 @@ ice_fdir_create_filter(struct ice_adapter *ad, struct ice_fdir_fltr_pattern key; bool is_tun; int ret; + int i; + + if (filter->parser_ena) { + struct ice_hw *hw = ICE_PF_TO_HW(pf); + + int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX); + int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id]; + u16 ctrl_vsi = pf->fdir.fdir_vsi->idx; + u16 main_vsi = pf->main_vsi->idx; + bool fv_found = false; + + struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg]; + if (pi->fdir_actived_cnt != 0) { + for (i = 0; i < ICE_MAX_FV_WORDS; i++) + if (pi->prof.fv[i].proto_id != + filter->prof->fv[i].proto_id || + pi->prof.fv[i].offset != + filter->prof->fv[i].offset || + pi->prof.fv[i].msk != + filter->prof->fv[i].msk) + break; + if (i == ICE_MAX_FV_WORDS) { + fv_found = true; + pi->fdir_actived_cnt++; + } + } + + if (!fv_found) { + ret = ice_flow_set_hw_prof(hw, main_vsi, ctrl_vsi, + filter->prof, ICE_BLK_FD); + if (ret) + goto error; + } + + ret = ice_fdir_add_del_raw(pf, filter, true); + if (ret) + goto error; + + if (!fv_found) { + for (i = 0; i < filter->prof->fv_num; i++) { + pi->prof.fv[i].proto_id = + filter->prof->fv[i].proto_id; + pi->prof.fv[i].offset = + filter->prof->fv[i].offset; + pi->prof.fv[i].msk = filter->prof->fv[i].msk; + } + pi->fdir_actived_cnt = 1; + } + + if (filter->mark_flag == 1) + ice_fdir_rx_parsing_enable(ad, 1); + + entry = rte_zmalloc("fdir_entry", sizeof(*entry), 0); + if (!entry) + goto error; + + rte_memcpy(entry, filter, sizeof(*filter)); + + flow->rule = entry; + + return 0; + } ice_fdir_extract_fltr_key(&key, filter); node = ice_fdir_entry_lookup(fdir_info, &key); @@ -1249,7 +1403,7 @@ ice_fdir_create_filter(struct ice_adapter *ad, is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type); ret = ice_fdir_input_set_conf(pf, filter->input.flow_type, - filter->input_set, filter->outer_input_set, + filter->input_set_i, filter->input_set_o, filter->tunnel_type); if (ret) { rte_flow_error_set(error, -ret, @@ -1262,9 +1416,7 @@ ice_fdir_create_filter(struct ice_adapter *ad, if (filter->input.cnt_ena) { struct rte_flow_action_count *act_count = &filter->act_count; - filter->counter = ice_fdir_counter_alloc(pf, - act_count->shared, - act_count->id); + filter->counter = ice_fdir_counter_alloc(pf, 0, act_count->id); if (!filter->counter) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, NULL, @@ -1308,6 +1460,11 @@ free_counter: free_entry: rte_free(entry); return -rte_errno; + +error: + rte_free(filter->prof); + rte_free(filter->pkt_buf); + return -rte_errno; } static int @@ -1324,6 +1481,44 @@ ice_fdir_destroy_filter(struct ice_adapter *ad, filter = (struct ice_fdir_filter_conf *)flow->rule; + if (filter->parser_ena) { + struct ice_hw *hw = ICE_PF_TO_HW(pf); + + int id = ice_find_first_bit(filter->prof->ptypes, UINT16_MAX); + int ptg = hw->blk[ICE_BLK_FD].xlt1.t[id]; + u16 ctrl_vsi = pf->fdir.fdir_vsi->idx; + u16 main_vsi = pf->main_vsi->idx; + enum ice_block blk = ICE_BLK_FD; + u16 vsi_num; + + ret = ice_fdir_add_del_raw(pf, filter, false); + if (ret) + return -rte_errno; + + struct ice_fdir_prof_info *pi = &ad->fdir_prof_info[ptg]; + if (pi->fdir_actived_cnt != 0) { + pi->fdir_actived_cnt--; + if (!pi->fdir_actived_cnt) { + vsi_num = ice_get_hw_vsi_num(hw, ctrl_vsi); + ice_rem_prof_id_flow(hw, blk, vsi_num, id); + + vsi_num = ice_get_hw_vsi_num(hw, main_vsi); + ice_rem_prof_id_flow(hw, blk, vsi_num, id); + } + } + + if (filter->mark_flag == 1) + ice_fdir_rx_parsing_enable(ad, 0); + + flow->rule = NULL; + + rte_free(filter->prof); + rte_free(filter->pkt_buf); + rte_free(filter); + + return 0; + } + is_tun = ice_fdir_is_tunnel_profile(filter->tunnel_type); if (filter->counter) { @@ -1600,17 +1795,24 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, const struct rte_flow_item *item = pattern; enum rte_flow_item_type item_type; enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END; + enum rte_flow_item_type l4 = RTE_FLOW_ITEM_TYPE_END; enum ice_fdir_tunnel_type tunnel_type = ICE_FDIR_TUNNEL_TYPE_NONE; + const struct rte_flow_item_raw *raw_spec, *raw_mask; const struct rte_flow_item_eth *eth_spec, *eth_mask; - const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask; + const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask; const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; + const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_spec, + *ipv6_frag_mask; const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; const struct rte_flow_item_udp *udp_spec, *udp_mask; const struct rte_flow_item_sctp *sctp_spec, *sctp_mask; const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask; const struct rte_flow_item_gtp *gtp_spec, *gtp_mask; const struct rte_flow_item_gtp_psc *gtp_psc_spec, *gtp_psc_mask; - uint64_t input_set = ICE_INSET_NONE; + const struct rte_flow_item_esp *esp_spec, *esp_mask; + uint64_t input_set_i = ICE_INSET_NONE; /* only for tunnel inner */ + uint64_t input_set_o = ICE_INSET_NONE; /* non-tunnel and tunnel outer */ + uint64_t *input_set; uint8_t flow_type = ICE_FLTR_PTYPE_NONF_NONE; uint8_t ipv6_addr_mask[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -1619,289 +1821,483 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, uint32_t vtc_flow_cpu; uint16_t ether_type; enum rte_flow_item_type next_type; + bool is_outer = true; + struct ice_fdir_extra *p_ext_data; + struct ice_fdir_v4 *p_v4 = NULL; + struct ice_fdir_v6 *p_v6 = NULL; + struct ice_parser_result rslt; + struct ice_parser *psr; + uint8_t item_num = 0; for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { - if (item->last) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Not support range"); - return -rte_errno; + if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN) + tunnel_type = ICE_FDIR_TUNNEL_TYPE_VXLAN; + /* To align with shared code behavior, save gtpu outer + * fields in inner struct. + */ + if (item->type == RTE_FLOW_ITEM_TYPE_GTPU || + item->type == RTE_FLOW_ITEM_TYPE_GTP_PSC) { + is_outer = false; } + item_num++; + } + + /* This loop parse flow pattern and distinguish Non-tunnel and tunnel + * flow. input_set_i is used for inner part. + */ + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { item_type = item->type; + if (item->last && !(item_type == RTE_FLOW_ITEM_TYPE_IPV4 || + item_type == + RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT)) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Not support range"); + } + + input_set = (tunnel_type && !is_outer) ? + &input_set_i : &input_set_o; + switch (item_type) { + case RTE_FLOW_ITEM_TYPE_RAW: { + raw_spec = item->spec; + raw_mask = item->mask; + + if (item_num != 1) + break; + + /* convert raw spec & mask from byte string to int */ + unsigned char *tmp_spec = + (uint8_t *)(uintptr_t)raw_spec->pattern; + unsigned char *tmp_mask = + (uint8_t *)(uintptr_t)raw_mask->pattern; + uint16_t udp_port = 0; + uint16_t tmp_val = 0; + uint8_t pkt_len = 0; + uint8_t tmp = 0; + int i, j; + + pkt_len = strlen((char *)(uintptr_t)raw_spec->pattern); + if (strlen((char *)(uintptr_t)raw_mask->pattern) != + pkt_len) + return -rte_errno; + + for (i = 0, j = 0; i < pkt_len; i += 2, j++) { + tmp = tmp_spec[i]; + if (tmp >= 'a' && tmp <= 'f') + tmp_val = tmp - 'a' + 10; + if (tmp >= 'A' && tmp <= 'F') + tmp_val = tmp - 'A' + 10; + if (tmp >= '0' && tmp <= '9') + tmp_val = tmp - '0'; + + tmp_val *= 16; + tmp = tmp_spec[i + 1]; + if (tmp >= 'a' && tmp <= 'f') + tmp_spec[j] = tmp_val + tmp - 'a' + 10; + if (tmp >= 'A' && tmp <= 'F') + tmp_spec[j] = tmp_val + tmp - 'A' + 10; + if (tmp >= '0' && tmp <= '9') + tmp_spec[j] = tmp_val + tmp - '0'; + + tmp = tmp_mask[i]; + if (tmp >= 'a' && tmp <= 'f') + tmp_val = tmp - 'a' + 10; + if (tmp >= 'A' && tmp <= 'F') + tmp_val = tmp - 'A' + 10; + if (tmp >= '0' && tmp <= '9') + tmp_val = tmp - '0'; + + tmp_val *= 16; + tmp = tmp_mask[i + 1]; + if (tmp >= 'a' && tmp <= 'f') + tmp_mask[j] = tmp_val + tmp - 'a' + 10; + if (tmp >= 'A' && tmp <= 'F') + tmp_mask[j] = tmp_val + tmp - 'A' + 10; + if (tmp >= '0' && tmp <= '9') + tmp_mask[j] = tmp_val + tmp - '0'; + } + + pkt_len /= 2; + + if (ice_parser_create(&ad->hw, &psr)) + return -rte_errno; + if (ice_get_open_tunnel_port(&ad->hw, TNL_VXLAN, + &udp_port)) + ice_parser_vxlan_tunnel_set(psr, udp_port, + true); + if (ice_parser_run(psr, tmp_spec, pkt_len, &rslt)) + return -rte_errno; + ice_parser_destroy(psr); + + if (!tmp_mask) + return -rte_errno; + + filter->prof = (struct ice_parser_profile *) + ice_malloc(&ad->hw, sizeof(*filter->prof)); + if (!filter->prof) + return -ENOMEM; + + if (ice_parser_profile_init(&rslt, tmp_spec, tmp_mask, + pkt_len, ICE_BLK_FD, true, filter->prof)) + return -rte_errno; + + u8 *pkt_buf = (u8 *)ice_malloc(&ad->hw, pkt_len + 1); + if (!pkt_buf) + return -ENOMEM; + rte_memcpy(pkt_buf, tmp_spec, pkt_len); + filter->pkt_buf = pkt_buf; + + filter->pkt_len = pkt_len; + + filter->parser_ena = true; + + break; + } + case RTE_FLOW_ITEM_TYPE_ETH: + flow_type = ICE_FLTR_PTYPE_NON_IP_L2; eth_spec = item->spec; eth_mask = item->mask; - next_type = (item + 1)->type; - if (eth_spec && eth_mask) { - if (!rte_is_zero_ether_addr(ð_mask->dst)) { - input_set |= ICE_INSET_DMAC; - rte_memcpy(&filter->input.ext_data.dst_mac, - ð_spec->dst, - RTE_ETHER_ADDR_LEN); - } + if (!(eth_spec && eth_mask)) + break; - if (!rte_is_zero_ether_addr(ð_mask->src)) { - input_set |= ICE_INSET_SMAC; - rte_memcpy(&filter->input.ext_data.src_mac, - ð_spec->src, - RTE_ETHER_ADDR_LEN); - } + if (!rte_is_zero_ether_addr(ð_mask->dst)) + *input_set |= ICE_INSET_DMAC; + if (!rte_is_zero_ether_addr(ð_mask->src)) + *input_set |= ICE_INSET_SMAC; - /* Ignore this field except for ICE_FLTR_PTYPE_NON_IP_L2 */ - if (eth_mask->type == RTE_BE16(0xffff) && - next_type == RTE_FLOW_ITEM_TYPE_END) { - input_set |= ICE_INSET_ETHERTYPE; - ether_type = rte_be_to_cpu_16(eth_spec->type); - - if (ether_type == RTE_ETHER_TYPE_IPV4 || - ether_type == RTE_ETHER_TYPE_IPV6) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Unsupported ether_type."); - return -rte_errno; - } - - rte_memcpy(&filter->input.ext_data.ether_type, - ð_spec->type, - sizeof(eth_spec->type)); - flow_type = ICE_FLTR_PTYPE_NON_IP_L2; + next_type = (item + 1)->type; + /* Ignore this field except for ICE_FLTR_PTYPE_NON_IP_L2 */ + if (eth_mask->type == RTE_BE16(0xffff) && + next_type == RTE_FLOW_ITEM_TYPE_END) { + *input_set |= ICE_INSET_ETHERTYPE; + ether_type = rte_be_to_cpu_16(eth_spec->type); + + if (ether_type == RTE_ETHER_TYPE_IPV4 || + ether_type == RTE_ETHER_TYPE_IPV6) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Unsupported ether_type."); + return -rte_errno; } } + + p_ext_data = (tunnel_type && is_outer) ? + &filter->input.ext_data_outer : + &filter->input.ext_data; + rte_memcpy(&p_ext_data->src_mac, + ð_spec->src, RTE_ETHER_ADDR_LEN); + rte_memcpy(&p_ext_data->dst_mac, + ð_spec->dst, RTE_ETHER_ADDR_LEN); + rte_memcpy(&p_ext_data->ether_type, + ð_spec->type, sizeof(eth_spec->type)); break; case RTE_FLOW_ITEM_TYPE_IPV4: + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; l3 = RTE_FLOW_ITEM_TYPE_IPV4; ipv4_spec = item->spec; + ipv4_last = item->last; ipv4_mask = item->mask; + p_v4 = (tunnel_type && is_outer) ? + &filter->input.ip_outer.v4 : + &filter->input.ip.v4; - if (ipv4_spec && ipv4_mask) { - /* Check IPv4 mask and update input set */ - if (ipv4_mask->hdr.version_ihl || - ipv4_mask->hdr.total_length || - ipv4_mask->hdr.packet_id || - ipv4_mask->hdr.fragment_offset || - ipv4_mask->hdr.hdr_checksum) { - rte_flow_error_set(error, EINVAL, + if (!(ipv4_spec && ipv4_mask)) + break; + + /* Check IPv4 mask and update input set */ + if (ipv4_mask->hdr.version_ihl || + ipv4_mask->hdr.total_length || + ipv4_mask->hdr.hdr_checksum) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid IPv4 mask."); - return -rte_errno; - } - if (ipv4_mask->hdr.src_addr == UINT32_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_IPV4_SRC : - ICE_INSET_IPV4_SRC; - if (ipv4_mask->hdr.dst_addr == UINT32_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_IPV4_DST : - ICE_INSET_IPV4_DST; - if (ipv4_mask->hdr.type_of_service == UINT8_MAX) - input_set |= ICE_INSET_IPV4_TOS; - if (ipv4_mask->hdr.time_to_live == UINT8_MAX) - input_set |= ICE_INSET_IPV4_TTL; - if (ipv4_mask->hdr.next_proto_id == UINT8_MAX) - input_set |= ICE_INSET_IPV4_PROTO; - - filter->input.ip.v4.dst_ip = - ipv4_spec->hdr.dst_addr; - filter->input.ip.v4.src_ip = - ipv4_spec->hdr.src_addr; - filter->input.ip.v4.tos = - ipv4_spec->hdr.type_of_service; - filter->input.ip.v4.ttl = - ipv4_spec->hdr.time_to_live; - filter->input.ip.v4.proto = - ipv4_spec->hdr.next_proto_id; + return -rte_errno; + } + + if (ipv4_last && + (ipv4_last->hdr.version_ihl || + ipv4_last->hdr.type_of_service || + ipv4_last->hdr.time_to_live || + ipv4_last->hdr.total_length | + ipv4_last->hdr.next_proto_id || + ipv4_last->hdr.hdr_checksum || + ipv4_last->hdr.src_addr || + ipv4_last->hdr.dst_addr)) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, "Invalid IPv4 last."); + return -rte_errno; + } + + /* Mask for IPv4 src/dst addrs not supported */ + if (ipv4_mask->hdr.src_addr && + ipv4_mask->hdr.src_addr != UINT32_MAX) + return -rte_errno; + if (ipv4_mask->hdr.dst_addr && + ipv4_mask->hdr.dst_addr != UINT32_MAX) + return -rte_errno; + + if (ipv4_mask->hdr.dst_addr == UINT32_MAX) + *input_set |= ICE_INSET_IPV4_DST; + if (ipv4_mask->hdr.src_addr == UINT32_MAX) + *input_set |= ICE_INSET_IPV4_SRC; + if (ipv4_mask->hdr.time_to_live == UINT8_MAX) + *input_set |= ICE_INSET_IPV4_TTL; + if (ipv4_mask->hdr.next_proto_id == UINT8_MAX) + *input_set |= ICE_INSET_IPV4_PROTO; + if (ipv4_mask->hdr.type_of_service == UINT8_MAX) + *input_set |= ICE_INSET_IPV4_TOS; + + p_v4->dst_ip = ipv4_spec->hdr.dst_addr; + p_v4->src_ip = ipv4_spec->hdr.src_addr; + p_v4->ttl = ipv4_spec->hdr.time_to_live; + p_v4->proto = ipv4_spec->hdr.next_proto_id; + p_v4->tos = ipv4_spec->hdr.type_of_service; + + /* fragment Ipv4: + * spec is 0x2000, mask is 0x2000 + */ + if (ipv4_spec->hdr.fragment_offset == + rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG) && + ipv4_mask->hdr.fragment_offset == + rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG)) { + /* all IPv4 fragment packet has the same + * ethertype, if the spec and mask is valid, + * set ethertype into input set. + */ + flow_type = ICE_FLTR_PTYPE_FRAG_IPV4; + *input_set |= ICE_INSET_ETHERTYPE; + input_set_o |= ICE_INSET_ETHERTYPE; + } else if (ipv4_mask->hdr.packet_id == UINT16_MAX) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, "Invalid IPv4 mask."); + return -rte_errno; } - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; break; case RTE_FLOW_ITEM_TYPE_IPV6: + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; l3 = RTE_FLOW_ITEM_TYPE_IPV6; ipv6_spec = item->spec; ipv6_mask = item->mask; + p_v6 = (tunnel_type && is_outer) ? + &filter->input.ip_outer.v6 : + &filter->input.ip.v6; - if (ipv6_spec && ipv6_mask) { - /* Check IPv6 mask and update input set */ - if (ipv6_mask->hdr.payload_len) { - rte_flow_error_set(error, EINVAL, + if (!(ipv6_spec && ipv6_mask)) + break; + + /* Check IPv6 mask and update input set */ + if (ipv6_mask->hdr.payload_len) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid IPv6 mask"); - return -rte_errno; - } + return -rte_errno; + } - if (!memcmp(ipv6_mask->hdr.src_addr, - ipv6_addr_mask, - RTE_DIM(ipv6_mask->hdr.src_addr))) - input_set |= ICE_INSET_IPV6_SRC; - if (!memcmp(ipv6_mask->hdr.dst_addr, - ipv6_addr_mask, - RTE_DIM(ipv6_mask->hdr.dst_addr))) - input_set |= ICE_INSET_IPV6_DST; - - if ((ipv6_mask->hdr.vtc_flow & - rte_cpu_to_be_32(ICE_IPV6_TC_MASK)) - == rte_cpu_to_be_32(ICE_IPV6_TC_MASK)) - input_set |= ICE_INSET_IPV6_TC; - if (ipv6_mask->hdr.proto == UINT8_MAX) - input_set |= ICE_INSET_IPV6_NEXT_HDR; - if (ipv6_mask->hdr.hop_limits == UINT8_MAX) - input_set |= ICE_INSET_IPV6_HOP_LIMIT; - - rte_memcpy(filter->input.ip.v6.dst_ip, - ipv6_spec->hdr.dst_addr, 16); - rte_memcpy(filter->input.ip.v6.src_ip, - ipv6_spec->hdr.src_addr, 16); - - vtc_flow_cpu = - rte_be_to_cpu_32(ipv6_spec->hdr.vtc_flow); - filter->input.ip.v6.tc = - (uint8_t)(vtc_flow_cpu >> - ICE_FDIR_IPV6_TC_OFFSET); - filter->input.ip.v6.proto = - ipv6_spec->hdr.proto; - filter->input.ip.v6.hlim = - ipv6_spec->hdr.hop_limits; + if (!memcmp(ipv6_mask->hdr.src_addr, ipv6_addr_mask, + RTE_DIM(ipv6_mask->hdr.src_addr))) + *input_set |= ICE_INSET_IPV6_SRC; + if (!memcmp(ipv6_mask->hdr.dst_addr, ipv6_addr_mask, + RTE_DIM(ipv6_mask->hdr.dst_addr))) + *input_set |= ICE_INSET_IPV6_DST; + + if ((ipv6_mask->hdr.vtc_flow & + rte_cpu_to_be_32(ICE_IPV6_TC_MASK)) + == rte_cpu_to_be_32(ICE_IPV6_TC_MASK)) + *input_set |= ICE_INSET_IPV6_TC; + if (ipv6_mask->hdr.proto == UINT8_MAX) + *input_set |= ICE_INSET_IPV6_NEXT_HDR; + if (ipv6_mask->hdr.hop_limits == UINT8_MAX) + *input_set |= ICE_INSET_IPV6_HOP_LIMIT; + + rte_memcpy(&p_v6->dst_ip, ipv6_spec->hdr.dst_addr, 16); + rte_memcpy(&p_v6->src_ip, ipv6_spec->hdr.src_addr, 16); + vtc_flow_cpu = rte_be_to_cpu_32(ipv6_spec->hdr.vtc_flow); + p_v6->tc = (uint8_t)(vtc_flow_cpu >> ICE_FDIR_IPV6_TC_OFFSET); + p_v6->proto = ipv6_spec->hdr.proto; + p_v6->hlim = ipv6_spec->hdr.hop_limits; + break; + case RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT: + l3 = RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT; + flow_type = ICE_FLTR_PTYPE_FRAG_IPV6; + ipv6_frag_spec = item->spec; + ipv6_frag_mask = item->mask; + + if (!(ipv6_frag_spec && ipv6_frag_mask)) + break; + + /* fragment Ipv6: + * spec is 0x1, mask is 0x1 + */ + if (ipv6_frag_spec->hdr.frag_data == + rte_cpu_to_be_16(1) && + ipv6_frag_mask->hdr.frag_data == + rte_cpu_to_be_16(1)) { + /* all IPv6 fragment packet has the same + * ethertype, if the spec and mask is valid, + * set ethertype into input set. + */ + *input_set |= ICE_INSET_ETHERTYPE; + input_set_o |= ICE_INSET_ETHERTYPE; + } else if (ipv6_frag_mask->hdr.id == UINT32_MAX) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, "Invalid IPv6 mask."); + return -rte_errno; } - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; break; - case RTE_FLOW_ITEM_TYPE_TCP: - tcp_spec = item->spec; - tcp_mask = item->mask; + case RTE_FLOW_ITEM_TYPE_TCP: if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP; - else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) flow_type = ICE_FLTR_PTYPE_NONF_IPV6_TCP; - if (tcp_spec && tcp_mask) { - /* Check TCP mask and update input set */ - if (tcp_mask->hdr.sent_seq || - tcp_mask->hdr.recv_ack || - tcp_mask->hdr.data_off || - tcp_mask->hdr.tcp_flags || - tcp_mask->hdr.rx_win || - tcp_mask->hdr.cksum || - tcp_mask->hdr.tcp_urp) { - rte_flow_error_set(error, EINVAL, + tcp_spec = item->spec; + tcp_mask = item->mask; + + if (!(tcp_spec && tcp_mask)) + break; + + /* Check TCP mask and update input set */ + if (tcp_mask->hdr.sent_seq || + tcp_mask->hdr.recv_ack || + tcp_mask->hdr.data_off || + tcp_mask->hdr.tcp_flags || + tcp_mask->hdr.rx_win || + tcp_mask->hdr.cksum || + tcp_mask->hdr.tcp_urp) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid TCP mask"); - return -rte_errno; - } + return -rte_errno; + } - if (tcp_mask->hdr.src_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_TCP_SRC_PORT : - ICE_INSET_TCP_SRC_PORT; - if (tcp_mask->hdr.dst_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_TCP_DST_PORT : - ICE_INSET_TCP_DST_PORT; - - /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { - filter->input.ip.v4.dst_port = - tcp_spec->hdr.dst_port; - filter->input.ip.v4.src_port = - tcp_spec->hdr.src_port; - } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { - filter->input.ip.v6.dst_port = - tcp_spec->hdr.dst_port; - filter->input.ip.v6.src_port = - tcp_spec->hdr.src_port; - } + /* Mask for TCP src/dst ports not supported */ + if (tcp_mask->hdr.src_port && + tcp_mask->hdr.src_port != UINT16_MAX) + return -rte_errno; + if (tcp_mask->hdr.dst_port && + tcp_mask->hdr.dst_port != UINT16_MAX) + return -rte_errno; + + if (tcp_mask->hdr.src_port == UINT16_MAX) + *input_set |= ICE_INSET_TCP_SRC_PORT; + if (tcp_mask->hdr.dst_port == UINT16_MAX) + *input_set |= ICE_INSET_TCP_DST_PORT; + + /* Get filter info */ + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + assert(p_v4); + p_v4->dst_port = tcp_spec->hdr.dst_port; + p_v4->src_port = tcp_spec->hdr.src_port; + } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + assert(p_v6); + p_v6->dst_port = tcp_spec->hdr.dst_port; + p_v6->src_port = tcp_spec->hdr.src_port; } break; case RTE_FLOW_ITEM_TYPE_UDP: - udp_spec = item->spec; - udp_mask = item->mask; - + l4 = RTE_FLOW_ITEM_TYPE_UDP; if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP; - else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) flow_type = ICE_FLTR_PTYPE_NONF_IPV6_UDP; - if (udp_spec && udp_mask) { - /* Check UDP mask and update input set*/ - if (udp_mask->hdr.dgram_len || - udp_mask->hdr.dgram_cksum) { - rte_flow_error_set(error, EINVAL, + udp_spec = item->spec; + udp_mask = item->mask; + + if (!(udp_spec && udp_mask)) + break; + + /* Check UDP mask and update input set*/ + if (udp_mask->hdr.dgram_len || + udp_mask->hdr.dgram_cksum) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid UDP mask"); - return -rte_errno; - } + return -rte_errno; + } - if (udp_mask->hdr.src_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_UDP_SRC_PORT : - ICE_INSET_UDP_SRC_PORT; - if (udp_mask->hdr.dst_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_UDP_DST_PORT : - ICE_INSET_UDP_DST_PORT; - - /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { - filter->input.ip.v4.dst_port = - udp_spec->hdr.dst_port; - filter->input.ip.v4.src_port = - udp_spec->hdr.src_port; - } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { - filter->input.ip.v6.src_port = - udp_spec->hdr.src_port; - filter->input.ip.v6.dst_port = - udp_spec->hdr.dst_port; - } + /* Mask for UDP src/dst ports not supported */ + if (udp_mask->hdr.src_port && + udp_mask->hdr.src_port != UINT16_MAX) + return -rte_errno; + if (udp_mask->hdr.dst_port && + udp_mask->hdr.dst_port != UINT16_MAX) + return -rte_errno; + + if (udp_mask->hdr.src_port == UINT16_MAX) + *input_set |= ICE_INSET_UDP_SRC_PORT; + if (udp_mask->hdr.dst_port == UINT16_MAX) + *input_set |= ICE_INSET_UDP_DST_PORT; + + /* Get filter info */ + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + assert(p_v4); + p_v4->dst_port = udp_spec->hdr.dst_port; + p_v4->src_port = udp_spec->hdr.src_port; + } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + assert(p_v6); + p_v6->src_port = udp_spec->hdr.src_port; + p_v6->dst_port = udp_spec->hdr.dst_port; } break; case RTE_FLOW_ITEM_TYPE_SCTP: - sctp_spec = item->spec; - sctp_mask = item->mask; - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) flow_type = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; - else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) flow_type = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; - if (sctp_spec && sctp_mask) { - /* Check SCTP mask and update input set */ - if (sctp_mask->hdr.cksum) { - rte_flow_error_set(error, EINVAL, + sctp_spec = item->spec; + sctp_mask = item->mask; + + if (!(sctp_spec && sctp_mask)) + break; + + /* Check SCTP mask and update input set */ + if (sctp_mask->hdr.cksum) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid UDP mask"); - return -rte_errno; - } + return -rte_errno; + } - if (sctp_mask->hdr.src_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_SCTP_SRC_PORT : - ICE_INSET_SCTP_SRC_PORT; - if (sctp_mask->hdr.dst_port == UINT16_MAX) - input_set |= tunnel_type ? - ICE_INSET_TUN_SCTP_DST_PORT : - ICE_INSET_SCTP_DST_PORT; - - /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { - filter->input.ip.v4.dst_port = - sctp_spec->hdr.dst_port; - filter->input.ip.v4.src_port = - sctp_spec->hdr.src_port; - } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { - filter->input.ip.v6.dst_port = - sctp_spec->hdr.dst_port; - filter->input.ip.v6.src_port = - sctp_spec->hdr.src_port; - } + /* Mask for SCTP src/dst ports not supported */ + if (sctp_mask->hdr.src_port && + sctp_mask->hdr.src_port != UINT16_MAX) + return -rte_errno; + if (sctp_mask->hdr.dst_port && + sctp_mask->hdr.dst_port != UINT16_MAX) + return -rte_errno; + + if (sctp_mask->hdr.src_port == UINT16_MAX) + *input_set |= ICE_INSET_SCTP_SRC_PORT; + if (sctp_mask->hdr.dst_port == UINT16_MAX) + *input_set |= ICE_INSET_SCTP_DST_PORT; + + /* Get filter info */ + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + assert(p_v4); + p_v4->dst_port = sctp_spec->hdr.dst_port; + p_v4->src_port = sctp_spec->hdr.src_port; + } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + assert(p_v6); + p_v6->dst_port = sctp_spec->hdr.dst_port; + p_v6->src_port = sctp_spec->hdr.src_port; } break; case RTE_FLOW_ITEM_TYPE_VOID: @@ -1910,8 +2306,12 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, l3 = RTE_FLOW_ITEM_TYPE_END; vxlan_spec = item->spec; vxlan_mask = item->mask; + is_outer = false; - if (vxlan_spec || vxlan_mask) { + if (!(vxlan_spec && vxlan_mask)) + break; + + if (vxlan_mask->hdr.vx_flags) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, @@ -1919,70 +2319,122 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, return -rte_errno; } - tunnel_type = ICE_FDIR_TUNNEL_TYPE_VXLAN; + if (vxlan_mask->hdr.vx_vni) + *input_set |= ICE_INSET_VXLAN_VNI; + + filter->input.vxlan_data.vni = vxlan_spec->hdr.vx_vni; + break; case RTE_FLOW_ITEM_TYPE_GTPU: l3 = RTE_FLOW_ITEM_TYPE_END; + tunnel_type = ICE_FDIR_TUNNEL_TYPE_GTPU; gtp_spec = item->spec; gtp_mask = item->mask; - if (gtp_spec && gtp_mask) { - if (gtp_mask->v_pt_rsv_flags || - gtp_mask->msg_type || - gtp_mask->msg_len) { - rte_flow_error_set(error, EINVAL, + if (!(gtp_spec && gtp_mask)) + break; + + if (gtp_mask->v_pt_rsv_flags || + gtp_mask->msg_type || + gtp_mask->msg_len) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid GTP mask"); - return -rte_errno; - } - - if (gtp_mask->teid == UINT32_MAX) - input_set |= ICE_INSET_GTPU_TEID; - - filter->input.gtpu_data.teid = gtp_spec->teid; + return -rte_errno; } - tunnel_type = ICE_FDIR_TUNNEL_TYPE_GTPU; + if (gtp_mask->teid == UINT32_MAX) + input_set_o |= ICE_INSET_GTPU_TEID; + + filter->input.gtpu_data.teid = gtp_spec->teid; break; case RTE_FLOW_ITEM_TYPE_GTP_PSC: + tunnel_type = ICE_FDIR_TUNNEL_TYPE_GTPU_EH; gtp_psc_spec = item->spec; gtp_psc_mask = item->mask; - if (gtp_psc_spec && gtp_psc_mask) { - if (gtp_psc_mask->qfi == UINT8_MAX) - input_set |= ICE_INSET_GTPU_QFI; + if (!(gtp_psc_spec && gtp_psc_mask)) + break; - filter->input.gtpu_data.qfi = - gtp_psc_spec->qfi; + if (gtp_psc_mask->hdr.qfi == 0x3F) + input_set_o |= ICE_INSET_GTPU_QFI; + + filter->input.gtpu_data.qfi = + gtp_psc_spec->hdr.qfi; + break; + case RTE_FLOW_ITEM_TYPE_ESP: + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 && + l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP; + else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6 && + l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP; + else if (l3 == RTE_FLOW_ITEM_TYPE_IPV4 && + l4 == RTE_FLOW_ITEM_TYPE_END) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_ESP; + else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6 && + l4 == RTE_FLOW_ITEM_TYPE_END) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_ESP; + + esp_spec = item->spec; + esp_mask = item->mask; + + if (!(esp_spec && esp_mask)) + break; + + if (esp_mask->hdr.spi == UINT32_MAX) { + if (l4 == RTE_FLOW_ITEM_TYPE_UDP) + *input_set |= ICE_INSET_NAT_T_ESP_SPI; + else + *input_set |= ICE_INSET_ESP_SPI; } - tunnel_type = ICE_FDIR_TUNNEL_TYPE_GTPU_EH; + + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) + filter->input.ip.v4.sec_parm_idx = + esp_spec->hdr.spi; + else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + filter->input.ip.v6.sec_parm_idx = + esp_spec->hdr.spi; break; default: rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Invalid pattern item."); + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid pattern item."); return -rte_errno; } } if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU && flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP) - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER; + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU; else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU_EH && flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP) - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_EH_IPV4_OTHER; + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_EH; else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU && flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP) - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_GTPU_IPV6_OTHER; + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_GTPU; else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU_EH && flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP) - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_GTPU_EH_IPV6_OTHER; + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_GTPU_EH; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_UDP; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_TCP; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_SCTP; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP_VXLAN_IPV4_OTHER; filter->tunnel_type = tunnel_type; filter->input.flow_type = flow_type; - filter->input_set = input_set; + filter->input_set_o = input_set_o; + filter->input_set_i = input_set_i; return 0; } @@ -1993,6 +2445,7 @@ ice_fdir_parse(struct ice_adapter *ad, uint32_t array_len, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], + uint32_t priority, void **meta, struct rte_flow_error *error) { @@ -2000,19 +2453,32 @@ ice_fdir_parse(struct ice_adapter *ad, struct ice_fdir_filter_conf *filter = &pf->fdir.conf; struct ice_pattern_match_item *item = NULL; uint64_t input_set; + bool raw = false; int ret; memset(filter, 0, sizeof(*filter)); item = ice_search_pattern_match_item(ad, pattern, array, array_len, error); + + if (!ad->devargs.pipe_mode_support && priority >= 1) + return -rte_errno; + if (!item) return -rte_errno; ret = ice_fdir_parse_pattern(ad, pattern, error, filter); if (ret) goto error; - input_set = filter->input_set | filter->outer_input_set; - if (!input_set || input_set & ~item->input_set_mask) { + + if (item->pattern_list[0] == RTE_FLOW_ITEM_TYPE_RAW) + raw = true; + + input_set = filter->input_set_o | filter->input_set_i; + input_set = raw ? ~input_set : input_set; + + if (!input_set || filter->input_set_o & + ~(item->input_set_mask_o | ICE_INSET_ETHERTYPE) || + filter->input_set_i & ~item->input_set_mask_i) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC, pattern, @@ -2027,7 +2493,12 @@ ice_fdir_parse(struct ice_adapter *ad, if (meta) *meta = filter; + + rte_free(item); + return ret; error: + rte_free(filter->prof); + rte_free(filter->pkt_buf); rte_free(item); return ret; }