+#include "base/ice_switch.h"
+#include "ice_logs.h"
+#include "ice_ethdev.h"
+#include "ice_generic_flow.h"
+
+
+#define MAX_QGRP_NUM_TYPE 7
+
+#define ICE_SW_INSET_ETHER ( \
+ ICE_INSET_DMAC | ICE_INSET_SMAC | ICE_INSET_ETHERTYPE)
+#define ICE_SW_INSET_MAC_VLAN ( \
+ ICE_INSET_DMAC | ICE_INSET_SMAC | ICE_INSET_ETHERTYPE | \
+ ICE_INSET_VLAN_OUTER)
+#define ICE_SW_INSET_MAC_IPV4 ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV4_DST | ICE_INSET_IPV4_SRC | \
+ ICE_INSET_IPV4_PROTO | ICE_INSET_IPV4_TTL | ICE_INSET_IPV4_TOS)
+#define ICE_SW_INSET_MAC_IPV4_TCP ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV4_DST | ICE_INSET_IPV4_SRC | \
+ ICE_INSET_IPV4_TTL | ICE_INSET_IPV4_TOS | \
+ ICE_INSET_TCP_DST_PORT | ICE_INSET_TCP_SRC_PORT)
+#define ICE_SW_INSET_MAC_IPV4_UDP ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV4_DST | ICE_INSET_IPV4_SRC | \
+ ICE_INSET_IPV4_TTL | ICE_INSET_IPV4_TOS | \
+ ICE_INSET_UDP_DST_PORT | ICE_INSET_UDP_SRC_PORT)
+#define ICE_SW_INSET_MAC_IPV6 ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV6_DST | ICE_INSET_IPV6_SRC | \
+ ICE_INSET_IPV6_TC | ICE_INSET_IPV6_HOP_LIMIT | \
+ ICE_INSET_IPV6_NEXT_HDR)
+#define ICE_SW_INSET_MAC_IPV6_TCP ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV6_DST | ICE_INSET_IPV6_SRC | \
+ ICE_INSET_IPV6_HOP_LIMIT | ICE_INSET_IPV6_TC | \
+ ICE_INSET_TCP_DST_PORT | ICE_INSET_TCP_SRC_PORT)
+#define ICE_SW_INSET_MAC_IPV6_UDP ( \
+ ICE_INSET_DMAC | ICE_INSET_IPV6_DST | ICE_INSET_IPV6_SRC | \
+ ICE_INSET_IPV6_HOP_LIMIT | ICE_INSET_IPV6_TC | \
+ ICE_INSET_UDP_DST_PORT | ICE_INSET_UDP_SRC_PORT)
+#define ICE_SW_INSET_DIST_NVGRE_IPV4 ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_NVGRE_TNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_DIST_VXLAN_IPV4 ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_VXLAN_VNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_DIST_NVGRE_IPV4_TCP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_TCP_SRC_PORT | ICE_INSET_TUN_TCP_DST_PORT | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_NVGRE_TNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_DIST_NVGRE_IPV4_UDP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_UDP_SRC_PORT | ICE_INSET_TUN_UDP_DST_PORT | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_NVGRE_TNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_DIST_VXLAN_IPV4_TCP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_TCP_SRC_PORT | ICE_INSET_TUN_TCP_DST_PORT | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_VXLAN_VNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_DIST_VXLAN_IPV4_UDP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_UDP_SRC_PORT | ICE_INSET_TUN_UDP_DST_PORT | \
+ ICE_INSET_TUN_DMAC | ICE_INSET_TUN_VXLAN_VNI | ICE_INSET_IPV4_DST)
+#define ICE_SW_INSET_PERM_TUNNEL_IPV4 ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_IPV4_PROTO | ICE_INSET_TUN_IPV4_TOS)
+#define ICE_SW_INSET_PERM_TUNNEL_IPV4_TCP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_TCP_SRC_PORT | ICE_INSET_TUN_TCP_DST_PORT | \
+ ICE_INSET_TUN_IPV4_TOS)
+#define ICE_SW_INSET_PERM_TUNNEL_IPV4_UDP ( \
+ ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \
+ ICE_INSET_TUN_UDP_SRC_PORT | ICE_INSET_TUN_UDP_DST_PORT | \
+ ICE_INSET_TUN_IPV4_TOS)
+#define ICE_SW_INSET_MAC_PPPOE ( \
+ ICE_INSET_VLAN_OUTER | ICE_INSET_VLAN_INNER | \
+ ICE_INSET_DMAC | ICE_INSET_ETHERTYPE | ICE_INSET_PPPOE_SESSION)
+#define ICE_SW_INSET_MAC_PPPOE_PROTO ( \
+ ICE_INSET_VLAN_OUTER | ICE_INSET_VLAN_INNER | \
+ ICE_INSET_DMAC | ICE_INSET_ETHERTYPE | ICE_INSET_PPPOE_SESSION | \
+ ICE_INSET_PPPOE_PROTO)
+#define ICE_SW_INSET_MAC_IPV4_ESP ( \
+ ICE_SW_INSET_MAC_IPV4 | ICE_INSET_ESP_SPI)
+#define ICE_SW_INSET_MAC_IPV6_ESP ( \
+ ICE_SW_INSET_MAC_IPV6 | ICE_INSET_ESP_SPI)
+#define ICE_SW_INSET_MAC_IPV4_AH ( \
+ ICE_SW_INSET_MAC_IPV4 | ICE_INSET_AH_SPI)
+#define ICE_SW_INSET_MAC_IPV6_AH ( \
+ ICE_SW_INSET_MAC_IPV6 | ICE_INSET_AH_SPI)
+#define ICE_SW_INSET_MAC_IPV4_L2TP ( \
+ ICE_SW_INSET_MAC_IPV4 | ICE_INSET_L2TPV3OIP_SESSION_ID)
+#define ICE_SW_INSET_MAC_IPV6_L2TP ( \
+ ICE_SW_INSET_MAC_IPV6 | ICE_INSET_L2TPV3OIP_SESSION_ID)
+#define ICE_SW_INSET_MAC_IPV4_PFCP ( \
+ ICE_SW_INSET_MAC_IPV4 | \
+ ICE_INSET_PFCP_S_FIELD | ICE_INSET_PFCP_SEID)
+#define ICE_SW_INSET_MAC_IPV6_PFCP ( \
+ ICE_SW_INSET_MAC_IPV6 | \
+ ICE_INSET_PFCP_S_FIELD | ICE_INSET_PFCP_SEID)
+
+struct sw_meta {
+ struct ice_adv_lkup_elem *list;
+ uint16_t lkups_num;
+ struct ice_adv_rule_info rule_info;
+};
+
+static struct ice_flow_parser ice_switch_dist_parser_os;
+static struct ice_flow_parser ice_switch_dist_parser_comms;
+static struct ice_flow_parser ice_switch_perm_parser;
+
+static struct
+ice_pattern_match_item ice_switch_pattern_dist_comms[] = {
+ {pattern_ethertype,
+ ICE_SW_INSET_ETHER, ICE_INSET_NONE},
+ {pattern_ethertype_vlan,
+ ICE_SW_INSET_MAC_VLAN, ICE_INSET_NONE},
+ {pattern_eth_ipv4,
+ ICE_SW_INSET_MAC_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp,
+ ICE_SW_INSET_MAC_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_tcp,
+ ICE_SW_INSET_MAC_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv6,
+ ICE_SW_INSET_MAC_IPV6, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp,
+ ICE_SW_INSET_MAC_IPV6_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_tcp,
+ ICE_SW_INSET_MAC_IPV6_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4,
+ ICE_SW_INSET_DIST_VXLAN_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_udp,
+ ICE_SW_INSET_DIST_VXLAN_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_tcp,
+ ICE_SW_INSET_DIST_VXLAN_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4,
+ ICE_SW_INSET_DIST_NVGRE_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_udp,
+ ICE_SW_INSET_DIST_NVGRE_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_tcp,
+ ICE_SW_INSET_DIST_NVGRE_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_pppoed,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoed,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_pppoes,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoes,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_pppoes_proto,
+ ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoes_proto,
+ ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
+ {pattern_eth_ipv4_esp,
+ ICE_SW_INSET_MAC_IPV4_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_esp,
+ ICE_SW_INSET_MAC_IPV4_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_esp,
+ ICE_SW_INSET_MAC_IPV6_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp_esp,
+ ICE_SW_INSET_MAC_IPV6_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_ah,
+ ICE_SW_INSET_MAC_IPV4_AH, ICE_INSET_NONE},
+ {pattern_eth_ipv6_ah,
+ ICE_SW_INSET_MAC_IPV6_AH, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp_ah,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+ {pattern_eth_ipv4_l2tp,
+ ICE_SW_INSET_MAC_IPV4_L2TP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_l2tp,
+ ICE_SW_INSET_MAC_IPV6_L2TP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_pfcp,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+ {pattern_eth_ipv6_pfcp,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+};
+
+static struct
+ice_pattern_match_item ice_switch_pattern_dist_os[] = {
+ {pattern_ethertype,
+ ICE_SW_INSET_ETHER, ICE_INSET_NONE},
+ {pattern_ethertype_vlan,
+ ICE_SW_INSET_MAC_VLAN, ICE_INSET_NONE},
+ {pattern_eth_arp,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+ {pattern_eth_ipv4,
+ ICE_SW_INSET_MAC_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp,
+ ICE_SW_INSET_MAC_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_tcp,
+ ICE_SW_INSET_MAC_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv6,
+ ICE_SW_INSET_MAC_IPV6, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp,
+ ICE_SW_INSET_MAC_IPV6_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_tcp,
+ ICE_SW_INSET_MAC_IPV6_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4,
+ ICE_SW_INSET_DIST_VXLAN_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_udp,
+ ICE_SW_INSET_DIST_VXLAN_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_tcp,
+ ICE_SW_INSET_DIST_VXLAN_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4,
+ ICE_SW_INSET_DIST_NVGRE_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_udp,
+ ICE_SW_INSET_DIST_NVGRE_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_tcp,
+ ICE_SW_INSET_DIST_NVGRE_IPV4_TCP, ICE_INSET_NONE},
+};
+
+static struct
+ice_pattern_match_item ice_switch_pattern_perm[] = {
+ {pattern_ethertype,
+ ICE_SW_INSET_ETHER, ICE_INSET_NONE},
+ {pattern_ethertype_vlan,
+ ICE_SW_INSET_MAC_VLAN, ICE_INSET_NONE},
+ {pattern_eth_ipv4,
+ ICE_SW_INSET_MAC_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp,
+ ICE_SW_INSET_MAC_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_tcp,
+ ICE_SW_INSET_MAC_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv6,
+ ICE_SW_INSET_MAC_IPV6, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp,
+ ICE_SW_INSET_MAC_IPV6_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_tcp,
+ ICE_SW_INSET_MAC_IPV6_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_udp,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_vxlan_eth_ipv4_tcp,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_udp,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4_UDP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_nvgre_eth_ipv4_tcp,
+ ICE_SW_INSET_PERM_TUNNEL_IPV4_TCP, ICE_INSET_NONE},
+ {pattern_eth_pppoed,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoed,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_pppoes,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoes,
+ ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+ {pattern_eth_pppoes_proto,
+ ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
+ {pattern_eth_vlan_pppoes_proto,
+ ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
+ {pattern_eth_ipv4_esp,
+ ICE_SW_INSET_MAC_IPV4_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_udp_esp,
+ ICE_SW_INSET_MAC_IPV4_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_esp,
+ ICE_SW_INSET_MAC_IPV6_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp_esp,
+ ICE_SW_INSET_MAC_IPV6_ESP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_ah,
+ ICE_SW_INSET_MAC_IPV4_AH, ICE_INSET_NONE},
+ {pattern_eth_ipv6_ah,
+ ICE_SW_INSET_MAC_IPV6_AH, ICE_INSET_NONE},
+ {pattern_eth_ipv6_udp_ah,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+ {pattern_eth_ipv4_l2tp,
+ ICE_SW_INSET_MAC_IPV4_L2TP, ICE_INSET_NONE},
+ {pattern_eth_ipv6_l2tp,
+ ICE_SW_INSET_MAC_IPV6_L2TP, ICE_INSET_NONE},
+ {pattern_eth_ipv4_pfcp,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+ {pattern_eth_ipv6_pfcp,
+ ICE_INSET_NONE, ICE_INSET_NONE},
+};
+
+static int
+ice_switch_create(struct ice_adapter *ad,
+ struct rte_flow *flow,
+ void *meta,
+ struct rte_flow_error *error)
+{
+ int ret = 0;
+ struct ice_pf *pf = &ad->pf;
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ struct ice_rule_query_data rule_added = {0};
+ struct ice_rule_query_data *filter_ptr;
+ struct ice_adv_lkup_elem *list =
+ ((struct sw_meta *)meta)->list;
+ uint16_t lkups_cnt =
+ ((struct sw_meta *)meta)->lkups_num;
+ struct ice_adv_rule_info *rule_info =
+ &((struct sw_meta *)meta)->rule_info;
+
+ if (lkups_cnt > ICE_MAX_CHAIN_WORDS) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "item number too large for rule");
+ goto error;
+ }
+ if (!list) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "lookup list should not be NULL");
+ goto error;
+ }
+ ret = ice_add_adv_rule(hw, list, lkups_cnt, rule_info, &rule_added);
+ if (!ret) {
+ filter_ptr = rte_zmalloc("ice_switch_filter",
+ sizeof(struct ice_rule_query_data), 0);
+ if (!filter_ptr) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "No memory for ice_switch_filter");
+ goto error;
+ }
+ flow->rule = filter_ptr;
+ rte_memcpy(filter_ptr,
+ &rule_added,
+ sizeof(struct ice_rule_query_data));
+ } else {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "switch filter create flow fail");
+ goto error;
+ }
+
+ rte_free(list);
+ rte_free(meta);
+ return 0;
+
+error:
+ rte_free(list);
+ rte_free(meta);
+
+ return -rte_errno;
+}