Implement comprehensive L2TPv2 support for Flow Director -Flow pattern definitions for different L2TPv2 packet combinations -FDIR filter parsing logic -Flow type assignment for proper packet classification
Signed-off-by: Shaiq Wani <[email protected]> Tested-by: Jiale Song <[email protected]> --- drivers/net/intel/ice/ice_fdir_filter.c | 487 +++++++++++++++++++---- drivers/net/intel/ice/ice_generic_flow.c | 177 ++++++++ 2 files changed, 587 insertions(+), 77 deletions(-) diff --git a/drivers/net/intel/ice/ice_fdir_filter.c b/drivers/net/intel/ice/ice_fdir_filter.c index 9dfe5c02cb..79c9dddae6 100644 --- a/drivers/net/intel/ice/ice_fdir_filter.c +++ b/drivers/net/intel/ice/ice_fdir_filter.c @@ -107,6 +107,31 @@ ICE_INSET_IPV6_SRC | ICE_INSET_IPV6_DST | \ ICE_INSET_NAT_T_ESP_SPI) +#define ICE_FDIR_INSET_L2TPV2 (\ + ICE_INSET_SMAC | ICE_INSET_DMAC | ICE_INSET_L2TPV2OIP_SESSION_ID) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV4 (\ + ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV4_UDP (\ + ICE_FDIR_INSET_L2TPV2_PPP_IPV4 | ICE_INSET_TUN_UDP_SRC_PORT | \ + ICE_INSET_TUN_UDP_DST_PORT) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV4_TCP (\ + ICE_FDIR_INSET_L2TPV2_PPP_IPV4 | ICE_INSET_TUN_TCP_SRC_PORT | \ + ICE_INSET_TUN_TCP_DST_PORT) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV6 (\ + ICE_INSET_TUN_IPV6_SRC | ICE_INSET_TUN_IPV6_DST) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV6_UDP (\ + ICE_FDIR_INSET_L2TPV2_PPP_IPV6 | ICE_INSET_TUN_UDP_SRC_PORT | \ + ICE_INSET_TUN_UDP_DST_PORT) + +#define ICE_FDIR_INSET_L2TPV2_PPP_IPV6_TCP (\ + ICE_FDIR_INSET_L2TPV2_PPP_IPV6 | ICE_INSET_TUN_TCP_SRC_PORT | \ + ICE_INSET_TUN_TCP_DST_PORT) + static struct ice_pattern_match_item ice_fdir_supported_pattern[] = { {pattern_raw, ICE_INSET_NONE, ICE_INSET_NONE, ICE_INSET_NONE}, {pattern_ethertype, ICE_FDIR_INSET_ETH, ICE_INSET_NONE, ICE_INSET_NONE}, @@ -132,10 +157,26 @@ static struct ice_pattern_match_item ice_fdir_supported_pattern[] = { {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}, + {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}, + {pattern_eth_ipv4_udp_l2tpv2, ICE_FDIR_INSET_L2TPV2, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp, ICE_FDIR_INSET_L2TPV2, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2, ICE_FDIR_INSET_L2TPV2, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp, ICE_FDIR_INSET_L2TPV2, ICE_INSET_NONE, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6_UDP, ICE_INSET_NONE}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, ICE_FDIR_INSET_L2TPV2, ICE_FDIR_INSET_L2TPV2_PPP_IPV6_TCP, ICE_INSET_NONE}, }; static int @@ -957,6 +998,7 @@ ice_fdir_input_set_parse(uint64_t inset, enum ice_flow_field *field) {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}, + {ICE_INSET_L2TPV2OIP_SESSION_ID, ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID}, }; for (i = 0, j = 0; i < RTE_DIM(ice_inset_map); i++) { @@ -1068,6 +1110,43 @@ ice_fdir_input_set_hdrs(enum ice_fltr_ptype flow, struct ice_flow_seg_info *seg) ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_IPV_OTHER); break; + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_CONTROL: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV2 | + ICE_FLOW_SEG_HDR_IPV6 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4_TCP: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4_UDP: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6_TCP: + case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6_UDP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV2 | + ICE_FLOW_SEG_HDR_PPP | + ICE_FLOW_SEG_HDR_IPV6 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_CONTROL: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV2 | + ICE_FLOW_SEG_HDR_IPV4 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4_TCP: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4_UDP: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6_TCP: + case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6_UDP: + ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_L2TPV2 | + ICE_FLOW_SEG_HDR_PPP | + ICE_FLOW_SEG_HDR_IPV4 | + ICE_FLOW_SEG_HDR_IPV_OTHER); + break; + default: PMD_DRV_LOG(ERR, "not supported filter type."); break; @@ -1170,7 +1249,10 @@ ice_fdir_uninit(struct ice_adapter *ad) static int ice_fdir_is_tunnel_profile(enum ice_fdir_tunnel_type tunnel_type) { - if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN) + if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_VXLAN || + tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 || + tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU || + tunnel_type == ICE_FDIR_TUNNEL_TYPE_GTPU_EH) return 1; else return 0; @@ -1239,6 +1321,9 @@ ice_fdir_extract_fltr_key(struct ice_fdir_fltr_pattern *key, rte_memcpy(&key->gtpu_data, &input->gtpu_data, sizeof(key->gtpu_data)); rte_memcpy(&key->gtpu_mask, &input->gtpu_mask, sizeof(key->gtpu_mask)); + rte_memcpy(&key->l2tpv2_data, &input->l2tpv2_data, sizeof(key->l2tpv2_data)); + rte_memcpy(&key->l2tpv2_mask, &input->l2tpv2_mask, sizeof(key->l2tpv2_mask)); + key->tunnel_type = filter->tunnel_type; } @@ -1797,16 +1882,22 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, const struct rte_flow_item_gtp *gtp_spec, *gtp_mask; const struct rte_flow_item_gtp_psc *gtp_psc_spec, *gtp_psc_mask; const struct rte_flow_item_esp *esp_spec, *esp_mask; + const struct rte_flow_item_l2tpv2 *l2tpv2_spec, *l2tpv2_mask; + const struct rte_flow_item_ppp *ppp_spec, *ppp_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; + enum rte_flow_item_type inner_l3 = RTE_FLOW_ITEM_TYPE_END; + enum rte_flow_item_type inner_l4 = RTE_FLOW_ITEM_TYPE_END; + enum rte_flow_item_type current_l3 = RTE_FLOW_ITEM_TYPE_END; + bool ppp_present = false; uint8_t ipv6_addr_mask[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; uint32_t vtc_flow_cpu; - uint16_t ether_type; + uint16_t ether_type = 0, flags_version = 0; enum rte_flow_item_type next_type; bool is_outer = true; struct ice_fdir_extra *p_ext_data; @@ -1994,22 +2085,30 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, ð_spec->hdr.ether_type, sizeof(eth_spec->hdr.ether_type)); break; case RTE_FLOW_ITEM_TYPE_IPV4: - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; - l3 = RTE_FLOW_ITEM_TYPE_IPV4; + /* Only set flow_type for outer IPv4, track inner L3 for tunnels */ + if (is_outer || !tunnel_type) { + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; + l3 = RTE_FLOW_ITEM_TYPE_IPV4; + current_l3 = RTE_FLOW_ITEM_TYPE_IPV4; + } else { + inner_l3 = RTE_FLOW_ITEM_TYPE_IPV4; + current_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; + &filter->input.ip_outer.v4 : + &filter->input.ip.v4; 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) { + ipv4_mask->hdr.total_length || + ipv4_mask->hdr.hdr_checksum) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, @@ -2041,10 +2140,18 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, 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.dst_addr == UINT32_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_IPV4_DST; + else + *input_set |= ICE_INSET_IPV4_DST; + } + if (ipv4_mask->hdr.src_addr == UINT32_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_IPV4_SRC; + else + *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) @@ -2085,48 +2192,62 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, break; case RTE_FLOW_ITEM_TYPE_IPV6: - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; - l3 = RTE_FLOW_ITEM_TYPE_IPV6; + if (is_outer || !tunnel_type) { + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; + l3 = RTE_FLOW_ITEM_TYPE_IPV6; + current_l3 = RTE_FLOW_ITEM_TYPE_IPV6; + } else { + inner_l3 = RTE_FLOW_ITEM_TYPE_IPV6; + current_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)) - break; + 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; - } + /* 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; + } - if (!memcmp(&ipv6_mask->hdr.src_addr, ipv6_addr_mask, - sizeof(ipv6_mask->hdr.src_addr))) + if (!memcmp(&ipv6_mask->hdr.src_addr, ipv6_addr_mask, + sizeof(ipv6_mask->hdr.src_addr))) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_IPV6_SRC; + else *input_set |= ICE_INSET_IPV6_SRC; - if (!memcmp(&ipv6_mask->hdr.dst_addr, ipv6_addr_mask, - sizeof(ipv6_mask->hdr.dst_addr))) + } + if (!memcmp(&ipv6_mask->hdr.dst_addr, ipv6_addr_mask, + sizeof(ipv6_mask->hdr.dst_addr))) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_IPV6_DST; + else *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; + } + 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; @@ -2160,10 +2281,16 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, break; case RTE_FLOW_ITEM_TYPE_TCP: - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP; - if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_TCP; + if (!is_outer && tunnel_type) { + /* For inner TCP in tunnels, track inner_l4 */ + inner_l4 = RTE_FLOW_ITEM_TYPE_TCP; + } else { + /* For outer TCP, update flow_type normally */ + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_TCP; + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_TCP; + } tcp_spec = item->spec; tcp_mask = item->mask; @@ -2194,28 +2321,42 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, 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; + if (tcp_mask->hdr.src_port == UINT16_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_TCP_SRC_PORT; + else + *input_set |= ICE_INSET_TCP_SRC_PORT; + } + if (tcp_mask->hdr.dst_port == UINT16_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_TCP_DST_PORT; + else + *input_set |= ICE_INSET_TCP_DST_PORT; + } /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + if (current_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) { + } else if (current_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: - l4 = RTE_FLOW_ITEM_TYPE_UDP; - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP; - if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_UDP; + if (!is_outer && tunnel_type) { + /* For inner UDP in tunnels, track inner_l4 */ + inner_l4 = RTE_FLOW_ITEM_TYPE_UDP; + } else { + /* For outer UDP, update flow_type normally */ + l4 = RTE_FLOW_ITEM_TYPE_UDP; + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_UDP; + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_UDP; + } udp_spec = item->spec; udp_mask = item->mask; @@ -2241,27 +2382,41 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, 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; + if (udp_mask->hdr.src_port == UINT16_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_UDP_SRC_PORT; + else + *input_set |= ICE_INSET_UDP_SRC_PORT; + } + if (udp_mask->hdr.dst_port == UINT16_MAX) { + if (tunnel_type && !is_outer && tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) + *input_set |= ICE_INSET_TUN_UDP_DST_PORT; + else + *input_set |= ICE_INSET_UDP_DST_PORT; + } /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + if (current_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) { + } else if (current_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: - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) - flow_type = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; - if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) - flow_type = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; + if (!is_outer && tunnel_type) { + /* For inner SCTP in tunnels, track inner_l4 */ + inner_l4 = RTE_FLOW_ITEM_TYPE_SCTP; + } else { + /* For outer SCTP, update flow_type normally */ + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; + if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; + } sctp_spec = item->spec; sctp_mask = item->mask; @@ -2292,11 +2447,11 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, *input_set |= ICE_INSET_SCTP_DST_PORT; /* Get filter info */ - if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + if (current_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) { + } else if (current_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; @@ -2399,6 +2554,114 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, filter->input.ip.v6.sec_parm_idx = esp_spec->hdr.spi; break; + case RTE_FLOW_ITEM_TYPE_L2TPV2: + + l2tpv2_spec = item->spec; + l2tpv2_mask = item->mask; + + if (l2tpv2_spec && l2tpv2_mask) { + flags_version = + rte_be_to_cpu_16(l2tpv2_spec->hdr.common.flags_version); + if ((flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL && + l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA && + l2tpv2_mask->hdr.type7.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L && + l2tpv2_mask->hdr.type6.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S && + l2tpv2_mask->hdr.type5.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_O && + l2tpv2_mask->hdr.type4.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S && + l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_O && + l2tpv2_mask->hdr.type2.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S_O && + l2tpv2_mask->hdr.type1.session_id == UINT16_MAX) || + (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S_O && + l2tpv2_mask->hdr.type0.session_id == UINT16_MAX)) { + input_set_o |= ICE_INSET_L2TPV2OIP_SESSION_ID; + } + } + + tunnel_type = ICE_FDIR_TUNNEL_TYPE_L2TPV2; + + struct ice_fdir_l2tpv2 l2tpv2_be; + memset(&l2tpv2_be, 0, sizeof(l2tpv2_be)); + + if (flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL) { + l2tpv2_be.length = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.length); + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.session_id); + l2tpv2_be.ns = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.ns); + l2tpv2_be.nr = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.nr); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA) { + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type7.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type7.session_id); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L) { + l2tpv2_be.length = rte_cpu_to_be_16(l2tpv2_spec->hdr.type6.length); + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type6.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type6.session_id); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S) { + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type5.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type5.session_id); + l2tpv2_be.ns = rte_cpu_to_be_16(l2tpv2_spec->hdr.type5.ns); + l2tpv2_be.nr = rte_cpu_to_be_16(l2tpv2_spec->hdr.type5.nr); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_O) { + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type4.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type4.session_id); + l2tpv2_be.offset_size = rte_cpu_to_be_16(l2tpv2_spec->hdr.type4.offset_size); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S) { + l2tpv2_be.length = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.length); + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.session_id); + l2tpv2_be.ns = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.ns); + l2tpv2_be.nr = rte_cpu_to_be_16(l2tpv2_spec->hdr.type3.nr); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_O) { + l2tpv2_be.length = rte_cpu_to_be_16(l2tpv2_spec->hdr.type2.length); + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type2.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type2.session_id); + l2tpv2_be.offset_size = rte_cpu_to_be_16(l2tpv2_spec->hdr.type2.offset_size); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S_O) { + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type1.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type1.session_id); + l2tpv2_be.ns = rte_cpu_to_be_16(l2tpv2_spec->hdr.type1.ns); + l2tpv2_be.nr = rte_cpu_to_be_16(l2tpv2_spec->hdr.type1.nr); + l2tpv2_be.offset_size = rte_cpu_to_be_16(l2tpv2_spec->hdr.type1.offset_size); + } else if (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S_O) { + l2tpv2_be.length = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.length); + l2tpv2_be.tunnel_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.tunnel_id); + l2tpv2_be.session_id = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.session_id); + l2tpv2_be.ns = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.ns); + l2tpv2_be.nr = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.nr); + l2tpv2_be.offset_size = rte_cpu_to_be_16(l2tpv2_spec->hdr.type0.offset_size); + } + + /* Copy converted values to filter */ + filter->input.l2tpv2_data.flags_version = rte_cpu_to_be_16(flags_version); + filter->input.l2tpv2_data.length = l2tpv2_be.length; + filter->input.l2tpv2_data.tunnel_id = l2tpv2_be.tunnel_id; + filter->input.l2tpv2_data.session_id = l2tpv2_be.session_id; + filter->input.l2tpv2_data.ns = l2tpv2_be.ns; + filter->input.l2tpv2_data.nr = l2tpv2_be.nr; + filter->input.l2tpv2_data.offset_size = l2tpv2_be.offset_size; + break; + case RTE_FLOW_ITEM_TYPE_PPP: + ppp_spec = item->spec; + ppp_mask = item->mask; + + /* PPP marks transition from outer to inner in L2TPv2 tunnels */ + if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2) { + is_outer = false; + ppp_present = true; + } + + if (ppp_spec && ppp_mask) { + filter->input.ppp_data.addr = ppp_spec->hdr.addr; + filter->input.ppp_data.ctrl = ppp_spec->hdr.ctrl; + filter->input.ppp_data.proto_id = ppp_spec->hdr.proto_id; + } + break; default: rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, @@ -2432,12 +2695,82 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad, 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; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP && + flags_version != RTE_L2TPV2_MSG_TYPE_CONTROL && + !ppp_present) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && + flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP && + flags_version != RTE_L2TPV2_MSG_TYPE_CONTROL && + !ppp_present) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && + flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP && + flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL && + !ppp_present) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_CONTROL; + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && + flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP && + flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL && + !ppp_present) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_CONTROL; + /* Handle L2TPV2 with PPP and inner protocols */ + else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && + ppp_present && + inner_l3 != RTE_FLOW_ITEM_TYPE_END) { + /* L2TPV2 with inner IPv4/IPv6 */ + if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP) { + /* Outer IPv4 + inner protocol */ + if (inner_l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + if (inner_l4 == RTE_FLOW_ITEM_TYPE_TCP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4_TCP; + else if (inner_l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4_UDP; + else + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV4; + } else if (inner_l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + if (inner_l4 == RTE_FLOW_ITEM_TYPE_TCP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6_TCP; + else if (inner_l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6_UDP; + else + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP_IPV6; + } + } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP) { + /* Outer IPv6 + inner protocol */ + if (inner_l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + if (inner_l4 == RTE_FLOW_ITEM_TYPE_TCP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4_TCP; + else if (inner_l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4_UDP; + else + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV4; + } else if (inner_l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + if (inner_l4 == RTE_FLOW_ITEM_TYPE_TCP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6_TCP; + else if (inner_l4 == RTE_FLOW_ITEM_TYPE_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6_UDP; + else + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP_IPV6; + } + } + } else if (tunnel_type == ICE_FDIR_TUNNEL_TYPE_L2TPV2 && ppp_present && + inner_l3 == RTE_FLOW_ITEM_TYPE_END) { + /* Handle L2TPV2 with PPP but no inner protocol specified */ + if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV4_L2TPV2_PPP; + else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP) + flow_type = ICE_FLTR_PTYPE_NONF_IPV6_L2TPV2_PPP; + } filter->tunnel_type = tunnel_type; filter->input.flow_type = flow_type; filter->input_set_o = input_set_o; filter->input_set_i = input_set_i; + + return 0; } @@ -2476,8 +2809,8 @@ ice_fdir_parse(struct ice_adapter *ad, 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) { + ~(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, diff --git a/drivers/net/intel/ice/ice_generic_flow.c b/drivers/net/intel/ice/ice_generic_flow.c index 4049157eab..644958cccf 100644 --- a/drivers/net/intel/ice/ice_generic_flow.c +++ b/drivers/net/intel/ice/ice_generic_flow.c @@ -1794,6 +1794,166 @@ enum rte_flow_item_type pattern_eth_ipv6_pfcp[] = { RTE_FLOW_ITEM_TYPE_PFCP, RTE_FLOW_ITEM_TYPE_END, }; +enum rte_flow_item_type pattern_eth_ipv4_l2tpv2[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_l2tpv2[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_END, +}; +/* PPPoL2TPv2oUDP */ +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_L2TPV2, + RTE_FLOW_ITEM_TYPE_PPP, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; + typedef bool (*parse_engine_t)(struct ice_adapter *ad, struct rte_flow *flow, @@ -2021,6 +2181,23 @@ static struct ice_ptype_match ice_ptype_map[] = { {pattern_eth_ipv4_udp_esp, ICE_MAC_IPV4_NAT_T_ESP}, {pattern_eth_ipv4_ah, ICE_MAC_IPV4_AH}, {pattern_eth_ipv4_l2tp, ICE_MAC_IPV4_L2TPV3}, + {pattern_eth_ipv4_udp_l2tpv2, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, ICE_MAC_IPV4_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, ICE_MAC_IPV6_L2TPV2}, + {pattern_eth_ipv4_pfcp, ICE_MAC_IPV4_PFCP_SESSION}, {pattern_eth_ipv6, ICE_PTYPE_IPV6_PAY}, {pattern_eth_ipv6_udp, ICE_PTYPE_IPV6_UDP_PAY}, -- 2.34.1

