+ case RTE_FLOW_ITEM_TYPE_ESP:
+ esp_spec = item->spec;
+ esp_mask = item->mask;
+ if ((esp_spec && !esp_mask) ||
+ (!esp_spec && esp_mask)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid esp item");
+ return 0;
+ }
+ /* Check esp mask and update input set */
+ if (esp_mask && esp_mask->hdr.seq) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid esp mask");
+ return 0;
+ }
+
+ if (!esp_spec && !esp_mask && !input_set) {
+ profile_rule = 1;
+ if (ipv6_valiad && udp_valiad)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV6_NAT_T;
+ else if (ipv6_valiad)
+ *tun_type = ICE_SW_TUN_PROFID_IPV6_ESP;
+ else if (ipv4_valiad)
+ return 0;
+ } else if (esp_spec && esp_mask &&
+ esp_mask->hdr.spi){
+ if (udp_valiad)
+ list[t].type = ICE_NAT_T;
+ else
+ list[t].type = ICE_ESP;
+ list[t].h_u.esp_hdr.spi =
+ esp_spec->hdr.spi;
+ list[t].m_u.esp_hdr.spi =
+ esp_mask->hdr.spi;
+ input_set |= ICE_INSET_ESP_SPI;
+ t++;
+ }
+
+ if (!profile_rule) {
+ if (ipv6_valiad && udp_valiad)
+ *tun_type = ICE_SW_TUN_IPV6_NAT_T;
+ else if (ipv4_valiad && udp_valiad)
+ *tun_type = ICE_SW_TUN_IPV4_NAT_T;
+ else if (ipv6_valiad)
+ *tun_type = ICE_SW_TUN_IPV6_ESP;
+ else if (ipv4_valiad)
+ *tun_type = ICE_SW_TUN_IPV4_ESP;
+ }
+ break;
+
+ case RTE_FLOW_ITEM_TYPE_AH:
+ ah_spec = item->spec;
+ ah_mask = item->mask;
+ if ((ah_spec && !ah_mask) ||
+ (!ah_spec && ah_mask)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid ah item");
+ return 0;
+ }
+ /* Check ah mask and update input set */
+ if (ah_mask &&
+ (ah_mask->next_hdr ||
+ ah_mask->payload_len ||
+ ah_mask->seq_num ||
+ ah_mask->reserved)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid ah mask");
+ return 0;
+ }
+
+ if (!ah_spec && !ah_mask && !input_set) {
+ profile_rule = 1;
+ if (ipv6_valiad && udp_valiad)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV6_NAT_T;
+ else if (ipv6_valiad)
+ *tun_type = ICE_SW_TUN_PROFID_IPV6_AH;
+ else if (ipv4_valiad)
+ return 0;
+ } else if (ah_spec && ah_mask &&
+ ah_mask->spi){
+ list[t].type = ICE_AH;
+ list[t].h_u.ah_hdr.spi =
+ ah_spec->spi;
+ list[t].m_u.ah_hdr.spi =
+ ah_mask->spi;
+ input_set |= ICE_INSET_AH_SPI;
+ t++;
+ }
+
+ if (!profile_rule) {
+ if (udp_valiad)
+ return 0;
+ else if (ipv6_valiad)
+ *tun_type = ICE_SW_TUN_IPV6_AH;
+ else if (ipv4_valiad)
+ *tun_type = ICE_SW_TUN_IPV4_AH;
+ }
+ break;
+
+ case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
+ l2tp_spec = item->spec;
+ l2tp_mask = item->mask;
+ if ((l2tp_spec && !l2tp_mask) ||
+ (!l2tp_spec && l2tp_mask)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid l2tp item");
+ return 0;
+ }
+
+ if (!l2tp_spec && !l2tp_mask && !input_set) {
+ if (ipv6_valiad)
+ *tun_type =
+ ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3;
+ else if (ipv4_valiad)
+ return 0;
+ } else if (l2tp_spec && l2tp_mask &&
+ l2tp_mask->session_id){
+ list[t].type = ICE_L2TPV3;
+ list[t].h_u.l2tpv3_sess_hdr.session_id =
+ l2tp_spec->session_id;
+ list[t].m_u.l2tpv3_sess_hdr.session_id =
+ l2tp_mask->session_id;
+ input_set |= ICE_INSET_L2TPV3OIP_SESSION_ID;
+ t++;
+ }
+
+ if (!profile_rule) {
+ if (ipv6_valiad)
+ *tun_type =
+ ICE_SW_TUN_IPV6_L2TPV3;
+ else if (ipv4_valiad)
+ *tun_type =
+ ICE_SW_TUN_IPV4_L2TPV3;
+ }
+ break;
+
+ case RTE_FLOW_ITEM_TYPE_PFCP:
+ pfcp_spec = item->spec;
+ pfcp_mask = item->mask;
+ /* Check if PFCP item is used to describe protocol.
+ * If yes, both spec and mask should be NULL.
+ * If no, both spec and mask shouldn't be NULL.
+ */
+ if ((!pfcp_spec && pfcp_mask) ||
+ (pfcp_spec && !pfcp_mask)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid PFCP item");
+ return -ENOTSUP;
+ }
+ if (pfcp_spec && pfcp_mask) {
+ /* Check pfcp mask and update input set */
+ if (pfcp_mask->msg_type ||
+ pfcp_mask->msg_len ||
+ pfcp_mask->seid) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid pfcp mask");
+ return -ENOTSUP;
+ }
+ if (pfcp_mask->s_field &&
+ pfcp_spec->s_field == 0x01 &&
+ ipv6_valiad)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION;
+ else if (pfcp_mask->s_field &&
+ pfcp_spec->s_field == 0x01)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION;
+ else if (pfcp_mask->s_field &&
+ !pfcp_spec->s_field &&
+ ipv6_valiad)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV6_PFCP_NODE;
+ else if (pfcp_mask->s_field &&
+ !pfcp_spec->s_field)
+ *tun_type =
+ ICE_SW_TUN_PROFID_IPV4_PFCP_NODE;
+ else
+ return -ENOTSUP;
+ }
+ break;
+