From patchwork Fri May 14 04:21:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Zou X-Patchwork-Id: 93261 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 46DA2A0A0E; Fri, 14 May 2021 06:18:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C2AD940042; Fri, 14 May 2021 06:18:46 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mails.dpdk.org (Postfix) with ESMTP id 498C840041 for ; Fri, 14 May 2021 06:18:44 +0200 (CEST) IronPort-SDR: YNS/piTEK87ufzEOR5N7n6PhgkxcdF9QbgQ8AKxajABMF+CykA7zo2QRkCgXD660+tc0E8r9lR YQACcM/M2tHQ== X-IronPort-AV: E=McAfee;i="6200,9189,9983"; a="179708575" X-IronPort-AV: E=Sophos;i="5.82,299,1613462400"; d="scan'208";a="179708575" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 May 2021 21:18:40 -0700 IronPort-SDR: Hqdw24uTvTEFfN37HaqUaRe6EvAAebb1k5L/12ce+3xXc3n4uaKNUM+ubvb6TI026RTki62I6u a9VMajnadNtA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,299,1613462400"; d="scan'208";a="393480047" Received: from dpdk51.sh.intel.com ([10.67.111.142]) by orsmga006.jf.intel.com with ESMTP; 13 May 2021 21:18:38 -0700 From: Steven Zou To: dev@dpdk.org Cc: qi.z.zhang@intel.com, "Zou, Steven" , Zou@dpdk.org Date: Fri, 14 May 2021 12:21:58 +0800 Message-Id: <20210514042158.74917-1-steven.zou@intel.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Subject: [dpdk-dev] [RFC] net/ice: couple of new DCF features X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: "Zou, Steven" This patchset is for couple of new feature on DCF 1, enable multiple DCF instances 2, enhanced GRE in DCF support 3, enhanced VxLAN support Signed-off-by: Zou, Steven --- app/test-pmd/cmdline.c | 13 +- drivers/common/iavf/virtchnl.h | 6 +- drivers/net/iavf/iavf_ethdev.c | 2 +- drivers/net/ice/base/ice_common.c | 25 ++ drivers/net/ice/base/ice_flex_pipe.c | 30 ++- drivers/net/ice/base/ice_flex_pipe.h | 2 +- drivers/net/ice/base/ice_flex_type.h | 1 + drivers/net/ice/base/ice_protocol_type.h | 16 ++ drivers/net/ice/base/ice_switch.c | 398 ++++++++++++++++++++++++++++++- drivers/net/ice/base/ice_type.h | 2 + drivers/net/ice/ice_acl_filter.c | 11 +- drivers/net/ice/ice_dcf.c | 23 +- drivers/net/ice/ice_dcf.h | 3 + drivers/net/ice/ice_dcf_ethdev.c | 228 +++++++++++++----- drivers/net/ice/ice_dcf_parent.c | 8 + drivers/net/ice/ice_ethdev.c | 4 + drivers/net/ice/ice_generic_flow.c | 37 +++ drivers/net/ice/ice_generic_flow.h | 9 + drivers/net/ice/ice_switch_filter.c | 134 ++++++++++- lib/librte_ethdev/rte_ethdev.h | 1 + 20 files changed, 871 insertions(+), 82 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 2d18b6c..4b52091 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -9084,7 +9084,7 @@ struct cmd_tunnel_filter_result { /* *** CONFIGURE TUNNEL UDP PORT *** */ struct cmd_tunnel_udp_config { - cmdline_fixed_string_t cmd; + cmdline_fixed_string_t rx_vxlan_port; cmdline_fixed_string_t what; uint16_t udp_port; portid_t port_id; @@ -9101,8 +9101,7 @@ struct cmd_tunnel_udp_config { tunnel_udp.udp_port = res->udp_port; - if (!strcmp(res->cmd, "rx_vxlan_port")) - tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN; + tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN; if (!strcmp(res->what, "add")) ret = rte_eth_dev_udp_tunnel_port_add(res->port_id, @@ -9115,9 +9114,9 @@ struct cmd_tunnel_udp_config { printf("udp tunneling add error: (%s)\n", strerror(-ret)); } -cmdline_parse_token_string_t cmd_tunnel_udp_config_cmd = - TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config, - cmd, "rx_vxlan_port"); +cmdline_parse_token_string_t cmd_tunnel_udp_config_rx_vxlan_port = + TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config, + rx_vxlan_port, "rx_vxlan_port"); cmdline_parse_token_string_t cmd_tunnel_udp_config_what = TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config, what, "add#rm"); @@ -9134,7 +9133,7 @@ struct cmd_tunnel_udp_config { .help_str = "rx_vxlan_port add|rm : " "Add/Remove a tunneling UDP port filter", .tokens = { - (void *)&cmd_tunnel_udp_config_cmd, + (void *)&cmd_tunnel_udp_config_rx_vxlan_port, (void *)&cmd_tunnel_udp_config_what, (void *)&cmd_tunnel_udp_config_udp_port, (void *)&cmd_tunnel_udp_config_port_id, diff --git a/drivers/common/iavf/virtchnl.h b/drivers/common/iavf/virtchnl.h index 302cc24..e7f7a02 100644 --- a/drivers/common/iavf/virtchnl.h +++ b/drivers/common/iavf/virtchnl.h @@ -128,7 +128,9 @@ enum virtchnl_ops { VIRTCHNL_OP_DISABLE_CHANNELS = 31, VIRTCHNL_OP_ADD_CLOUD_FILTER = 32, VIRTCHNL_OP_DEL_CLOUD_FILTER = 33, - /* opcodes 34, 35, 36, 37 and 38 are reserved */ + /* opcodes 34, 35, 36 and 37 are reserved */ + VIRTCHNL_OP_DCF_RULE_FLUSH = 6000, + VIRTCHNL_OP_DCF_VLAN_OFFLOAD = 38, VIRTCHNL_OP_DCF_CMD_DESC = 39, VIRTCHNL_OP_DCF_CMD_BUFF = 40, VIRTCHNL_OP_DCF_DISABLE = 41, @@ -771,6 +773,7 @@ enum virtchnl_event_codes { VIRTCHNL_EVENT_RESET_IMPENDING, VIRTCHNL_EVENT_PF_DRIVER_CLOSE, VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE, + VIRTCHNL_EVENT_DCF_VSI_INFO = 1000, }; #define PF_EVENT_SEVERITY_INFO 0 @@ -1468,6 +1471,7 @@ enum virtchnl_vector_limits { */ valid_len = msglen; break; + case VIRTCHNL_OP_DCF_RULE_FLUSH: case VIRTCHNL_OP_DCF_DISABLE: case VIRTCHNL_OP_DCF_GET_VSI_MAP: case VIRTCHNL_OP_DCF_GET_PKG_INFO: diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index 93c68e6..eca54a9 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -2115,7 +2115,7 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev) iavf_dcf_cap_check_handler(__rte_unused const char *key, const char *value, __rte_unused void *opaque) { - if (strcmp(value, "dcf")) + if (strcmp(value, "dcf") && strcmp(value, "mdcf")) return -1; return 0; diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c index 304e55e..4039e34 100644 --- a/drivers/net/ice/base/ice_common.c +++ b/drivers/net/ice/base/ice_common.c @@ -538,6 +538,28 @@ enum ice_status return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); } +static int ice_buildin_recipe_init(struct ice_hw *hw) +{ + struct ice_switch_info *sw = hw->switch_info; + struct ice_sw_recipe *recipe; + + sw->buildin_recipes = ice_malloc(hw, + sizeof(sw->buildin_recipes[0]) * ICE_MAX_NUM_RECIPES); + + if (!sw->buildin_recipes) + return ICE_ERR_NO_MEMORY; + + recipe = &sw->buildin_recipes[10]; + recipe->is_root = 1; + + recipe->lkup_exts.n_val_words = 1; + recipe->lkup_exts.field_mask[0] = 0x00ff; + recipe->lkup_exts.fv_words[0].off = 8; + recipe->lkup_exts.fv_words[0].prot_id = 32; + + return ICE_SUCCESS; +} + /** * ice_init_fltr_mgmt_struct - initializes filter management list and locks * @hw: pointer to the HW struct @@ -558,6 +580,8 @@ enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) INIT_LIST_HEAD(&sw->vsi_list_map_head); sw->prof_res_bm_init = 0; + ice_buildin_recipe_init(hw); + status = ice_init_def_sw_recp(hw, &hw->switch_info->recp_list); if (status) { ice_free(hw, hw->switch_info); @@ -628,6 +652,7 @@ enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) ice_free(hw, recps[i].root_buf); } ice_rm_sw_replay_rule_info(hw, sw); + ice_free(hw, sw->buildin_recipes); ice_free(hw, sw->recp_list); ice_free(hw, sw); } diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c index 7594df1..6906259 100644 --- a/drivers/net/ice/base/ice_flex_pipe.c +++ b/drivers/net/ice/base/ice_flex_pipe.c @@ -13,6 +13,7 @@ static const struct ice_tunnel_type_scan tnls[] = { { TNL_VXLAN, "TNL_VXLAN_PF" }, { TNL_GENEVE, "TNL_GENEVE_PF" }, + { TNL_ECPRI, "TNL_UDP_ECPRI_PF" }, { TNL_LAST, "" } }; @@ -1280,6 +1281,9 @@ static void ice_init_pkg_regs(struct ice_hw *hw) */ static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver) { + if (pkg_ver->major == 0xFF) + return ICE_SUCCESS; + if (pkg_ver->major != ICE_PKG_SUPP_VER_MAJ || pkg_ver->minor != ICE_PKG_SUPP_VER_MNR) return ICE_ERR_NOT_SUPPORTED; @@ -1664,6 +1668,7 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw) * @ids_cnt: lookup/protocol count * @bm: bitmap of field vectors to consider * @fv_list: Head of a list + * @lkup_exts: lookup elements * * Finds all the field vector entries from switch block that contain * a given protocol ID and returns a list of structures of type @@ -1674,7 +1679,8 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw) */ enum ice_status ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, - ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) + ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list, + struct ice_prot_lkup_ext *lkup_exts) { struct ice_sw_fv_list_entry *fvl; struct ice_sw_fv_list_entry *tmp; @@ -1705,6 +1711,7 @@ enum ice_status if (!ice_is_bit_set(bm, (u16)offset)) continue; +#if 0 for (i = 0; i < ids_cnt; i++) { int j; @@ -1729,6 +1736,27 @@ enum ice_status break; } } +#else + int found = 1; + for (i = 0; i < lkup_exts->n_val_words; i++) { + int j; + + for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) + if (fv->ew[j].prot_id == lkup_exts->fv_words[i].prot_id && fv->ew[j].off == lkup_exts->fv_words[i].off) + break; + if (j >= hw->blk[ICE_BLK_SW].es.fvw) + found = 0; + } + if (found) { + fvl = (struct ice_sw_fv_list_entry *) + ice_malloc(hw, sizeof(*fvl)); + if (!fvl) + goto err; + fvl->fv_ptr = fv; + fvl->profile_id = offset; + LIST_ADD(&fvl->list_entry, fv_list); + } +#endif } while (fv); if (LIST_EMPTY(fv_list)) return ICE_ERR_CFG; diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h index 214c7a2..4ea0650 100644 --- a/drivers/net/ice/base/ice_flex_pipe.h +++ b/drivers/net/ice/base/ice_flex_pipe.h @@ -37,7 +37,7 @@ enum ice_status ice_init_prof_result_bm(struct ice_hw *hw); enum ice_status ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, - ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list); + ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list, struct ice_prot_lkup_ext *lkup_exts); bool ice_get_open_tunnel_port(struct ice_hw *hw, enum ice_tunnel_type type, u16 *port); diff --git a/drivers/net/ice/base/ice_flex_type.h b/drivers/net/ice/base/ice_flex_type.h index 1dd57ba..bbe7a8a 100644 --- a/drivers/net/ice/base/ice_flex_type.h +++ b/drivers/net/ice/base/ice_flex_type.h @@ -516,6 +516,7 @@ struct ice_pkg_enum { enum ice_tunnel_type { TNL_VXLAN = 0, TNL_GENEVE, + TNL_ECPRI, TNL_LAST = 0xFF, TNL_ALL = 0xFF, }; diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h index e8caefd..f9fc208 100644 --- a/drivers/net/ice/base/ice_protocol_type.h +++ b/drivers/net/ice/base/ice_protocol_type.h @@ -44,6 +44,7 @@ enum ice_protocol_type { ICE_GENEVE, ICE_VXLAN_GPE, ICE_NVGRE, + ICE_GRE, ICE_GTP, ICE_PPPOE, ICE_PFCP, @@ -65,6 +66,7 @@ enum ice_sw_tunnel_type { ICE_SW_TUN_VXLAN, /* VXLAN matches only non-VLAN pkts */ ICE_SW_TUN_VXLAN_VLAN, /* VXLAN matches both VLAN and non-VLAN pkts */ ICE_SW_TUN_NVGRE, + ICE_SW_TUN_GRE, ICE_SW_TUN_UDP, /* This means all "UDP" tunnel types: VXLAN-GPE, VXLAN * and GENEVE */ @@ -196,6 +198,10 @@ enum ice_prot_id { #define ICE_TUN_FLAG_VLAN_MASK 0x01 #define ICE_TUN_FLAG_FV_IND 2 +#define ICE_GRE_FLAG_MDID 22 +#define ICE_GRE_FLAG_MDID_OFF (ICE_MDID_SIZE * ICE_GRE_FLAG_MDID) +#define ICE_GRE_FLAG_MASK 0x01C0 + #define ICE_PROTOCOL_MAX_ENTRIES 16 /* Mapping of software defined protocol ID to hardware defined protocol ID */ @@ -336,6 +342,15 @@ struct ice_nvgre { __be32 tni_flow; }; +struct ice_gre { + __be16 flags; + __be16 protocol; + __be16 chksum; + __be16 offset; + __be32 key; + __be32 seqnum; +}; + union ice_prot_hdr { struct ice_ether_hdr eth_hdr; struct ice_ethtype_hdr ethertype; @@ -346,6 +361,7 @@ struct ice_nvgre { struct ice_sctp_hdr sctp_hdr; struct ice_udp_tnl_hdr tnl_hdr; struct ice_nvgre nvgre_hdr; + struct ice_gre gre_hdr; struct ice_udp_gtp_hdr gtp_hdr; struct ice_pppoe_hdr pppoe_hdr; struct ice_pfcp_hdr pfcp_hdr; diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index dc55d7e..b1a6ee3 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -11,6 +11,8 @@ #define ICE_ETH_VLAN_TCI_OFFSET 14 #define ICE_MAX_VLAN_ID 0xFFF #define ICE_IPV4_NVGRE_PROTO_ID 0x002F +#define ICE_IPV4_GRE_PROTO_ID 0x002F +#define ICE_IPV6_GRE_PROTO_ID 0x002F #define ICE_PPP_IPV6_PROTO_ID 0x0057 #define ICE_IPV6_ETHER_ID 0x86DD #define ICE_TCP_PROTO_ID 0x06 @@ -126,6 +128,209 @@ struct ice_dummy_pkt_offsets { 0x00, 0x08, 0x00, 0x00, }; +static const struct ice_dummy_pkt_offsets dummy_ipv6_gre_udp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV6_OFOS, 14 }, + { ICE_GRE, 54 }, + { ICE_IPV6_IL, 58 }, + { ICE_UDP_ILOS, 98 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_ipv6_gre_udp_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x36, 0x2f, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x86, 0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x11, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0xff, 0xd8, 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c1k1_tcp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 50 }, + { ICE_TCP_IL, 70 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c1k1_tcp_packet[] = { + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x08, 0x00, /* ICE_ETYPE_OL 12 */ + + 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */ + 0x00, 0x01, 0x00, 0x00, + 0x40, 0x2f, 0x7c, 0x7e, + 0x7f, 0x00, 0x00, 0x01, + 0x7f, 0x00, 0x00, 0x01, + + 0xb0, 0x00, 0x08, 0x00, /* ICE_GRE 34 */ + 0x46, 0x1e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x45, 0x00, 0x00, 0x2a, /* ICE_IPV4_IL 50 */ + 0x00, 0x01, 0x00, 0x00, + 0x40, 0x06, 0x7c, 0xcb, + 0x7f, 0x00, 0x00, 0x01, + 0x7f, 0x00, 0x00, 0x01, + + 0x00, 0x14, 0x00, 0x50, /* ICE_TCP_IL 70 */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x50, 0x02, 0x20, 0x00, + 0x91, 0x7a, 0x00, 0x00, + + 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c1k1_udp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 50 }, + { ICE_UDP_ILOS, 70 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c1k1_udp_packet[] = { + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x08, 0x00, /* ICE_ETYPE_OL 12 */ + + 0x45, 0x00, 0x00, 0x42, /* ICE_IPV4_OFOS 14 */ + 0x00, 0x01, 0x00, 0x00, + 0x40, 0x2f, 0x7c, 0x8a, + 0x7f, 0x00, 0x00, 0x01, + 0x7f, 0x00, 0x00, 0x01, + + 0xb0, 0x00, 0x08, 0x00, /* ICE_GRE 34 */ + 0x46, 0x1d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0x45, 0x00, 0x00, 0x1e, /* ICE_IPV4_IL 50 */ + 0x00, 0x01, 0x00, 0x00, + 0x40, 0x11, 0x7c, 0xcc, + 0x7f, 0x00, 0x00, 0x01, + 0x7f, 0x00, 0x00, 0x01, + + 0x00, 0x35, 0x00, 0x35, /* ICE_UDP_ILOS 70 */ + 0x00, 0x0a, 0x01, 0x6e, + + 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c0k1_tcp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 46 }, + { ICE_TCP_IL, 66 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c0k1_tcp_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4a, 0x00, 0x01, 0x00, 0x00, 0x40, 0x2f, + 0x7c, 0x82, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, + 0x00, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, + 0x7c, 0xcb, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x00, 0x14, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, + 0x20, 0x00, 0x91, 0x7a, 0x00, 0x00, 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c0k1_udp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 46 }, + { ICE_UDP_ILOS, 66 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c0k1_udp_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x40, 0x2f, + 0x7c, 0x8e, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, + 0x00, 0x1e, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, + 0x7c, 0xcc, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x00, 0x35, 0x00, 0x35, 0x00, 0x0a, + 0x01, 0x6e, 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c0k0_tcp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 42 }, + { ICE_TCP_IL, 62 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c0k0_tcp_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x46, 0x00, 0x01, 0x00, 0x00, 0x40, 0x2f, + 0x7c, 0x86, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x45, 0x00, 0x00, 0x2a, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x06, 0x7c, 0xcb, 0x7f, 0x00, + 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x14, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0x91, 0x7a, + 0x00, 0x00, 0x00, 0x00, +}; + +static const struct ice_dummy_pkt_offsets dummy_gre_rfc1701_c0k0_udp_packet_offsets[] = { + { ICE_MAC_OFOS, 0 }, + { ICE_ETYPE_OL, 12 }, + { ICE_IPV4_OFOS, 14 }, + { ICE_GRE, 34 }, + { ICE_IPV4_IL, 42 }, + { ICE_UDP_ILOS, 62 }, + { ICE_PROTOCOL_LAST, 0 }, +}; + +static const u8 dummy_gre_rfc1701_c0k0_udp_packet[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x3a, 0x00, 0x01, 0x00, 0x00, 0x40, 0x2f, + 0x7c, 0x92, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, + 0x00, 0x01, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x45, 0x00, 0x00, 0x1e, 0x00, 0x01, + 0x00, 0x00, 0x40, 0x11, 0x7c, 0xcc, 0x7f, 0x00, + 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x35, + 0x00, 0x35, 0x00, 0x0a, 0x01, 0x6e, 0x00, 0x00, +}; + static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = { { ICE_MAC_OFOS, 0 }, { ICE_ETYPE_OL, 12 }, @@ -6043,6 +6248,7 @@ enum ice_status { ICE_GENEVE, { 8, 10, 12, 14 } }, { ICE_VXLAN_GPE, { 8, 10, 12, 14 } }, { ICE_NVGRE, { 0, 2, 4, 6 } }, + { ICE_GRE, { 0, 2, 4, 6, 8, 10, 12, 14 } }, { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20 } }, { ICE_PPPOE, { 0, 2, 4, 6 } }, { ICE_PFCP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, @@ -6077,6 +6283,7 @@ enum ice_status { ICE_GENEVE, ICE_UDP_OF_HW }, { ICE_VXLAN_GPE, ICE_UDP_OF_HW }, { ICE_NVGRE, ICE_GRE_OF_HW }, + { ICE_GRE, ICE_GRE_OF_HW }, { ICE_GTP, ICE_UDP_OF_HW }, { ICE_PPPOE, ICE_PPPOE_HW }, { ICE_PFCP, ICE_UDP_ILOS_HW }, @@ -6088,6 +6295,47 @@ enum ice_status { ICE_VLAN_EX, ICE_VLAN_OF_HW }, }; +static u16 buildin_recipe_get(struct ice_switch_info *sw, + struct ice_prot_lkup_ext *lkup_exts) +{ + int i; + + if (!sw->buildin_recipes) + return ICE_MAX_NUM_RECIPES; + + for (i = 10; i < ICE_MAX_NUM_RECIPES; i++) { + struct ice_sw_recipe *recp = &sw->buildin_recipes[i]; + struct ice_fv_word *a = lkup_exts->fv_words; + struct ice_fv_word *b = recp->lkup_exts.fv_words; + u16 *c = recp->lkup_exts.field_mask; + u16 *d = lkup_exts->field_mask; + bool found = true; + u8 p, q; + + if (!recp->is_root) + continue; + + if (recp->lkup_exts.n_val_words != lkup_exts->n_val_words) + continue; + + for (p = 0; p < lkup_exts->n_val_words; p++) { + for (q = 0; q < recp->lkup_exts.n_val_words; q++) { + if (a[p].off == b[q].off && + a[p].prot_id == b[q].prot_id && + d[p] == c[q]) + break; + } + if (q >= recp->lkup_exts.n_val_words) { + found = false; + break; + } + } + if (found) + return i; + } + return ICE_MAX_NUM_RECIPES; +} + /** * ice_find_recp - find a recipe * @hw: pointer to the hardware structure @@ -6100,8 +6348,15 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, { bool refresh_required = true; struct ice_sw_recipe *recp; + u16 buildin_rid; u8 i; + if (hw->use_buildin_recipe) { + buildin_rid = buildin_recipe_get(hw->switch_info, lkup_exts); + if (buildin_rid < ICE_MAX_NUM_RECIPES) + return buildin_rid; + } + /* Walk through existing recipes to find a match */ recp = hw->switch_info->recp_list; for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { @@ -6196,6 +6451,7 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) struct ice_prot_lkup_ext *lkup_exts) { u8 j, word, prot_id, ret_val; + u8 extra_byte = 0; if (!ice_prot_type_to_id(rule->type, &prot_id)) return 0; @@ -6208,8 +6464,16 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) /* No more space to accommodate */ if (word >= ICE_MAX_CHAIN_WORDS) return 0; + if (rule->type == ICE_GRE) { + if (ice_prot_ext[rule->type].offs[j] == 0) { + if (((u16 *)&rule->h_u)[j] == 0x20) { + extra_byte = 4; + } + continue; + } + } lkup_exts->fv_words[word].off = - ice_prot_ext[rule->type].offs[j]; + ice_prot_ext[rule->type].offs[j] - extra_byte; lkup_exts->fv_words[word].prot_id = ice_prot_id_tbl[rule->type].protocol_id; lkup_exts->field_mask[word] = @@ -6753,10 +7017,11 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) * @lkups_cnt: number of protocols * @bm: bitmap of field vectors to consider * @fv_list: pointer to a list that holds the returned field vectors + * @lkup_exts: lookup elements */ static enum ice_status ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, - ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) +ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list, struct ice_prot_lkup_ext *lkup_exts) { enum ice_status status; u8 *prot_ids; @@ -6776,7 +7041,7 @@ static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) } /* Find field vectors that include all specified protocol types */ - status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list); + status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list, lkup_exts); free_mem: ice_free(hw, prot_ids); @@ -6806,6 +7071,10 @@ static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) *mask = ICE_TUN_FLAG_MASK; return true; + case ICE_SW_TUN_GRE: + *mask = ICE_GRE_FLAG_MASK; + return true; + case ICE_SW_TUN_GENEVE_VLAN: case ICE_SW_TUN_VXLAN_VLAN: *mask = ICE_TUN_FLAG_MASK & ~ICE_TUN_FLAG_VLAN_MASK; @@ -6826,7 +7095,15 @@ static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) ice_add_special_words(struct ice_adv_rule_info *rinfo, struct ice_prot_lkup_ext *lkup_exts) { + u8 has_gre_key = 0; u16 mask; + u8 i; + + for (i = 0; i < lkup_exts->n_val_words; i++) { + if (lkup_exts->fv_words[i].prot_id == 0x40) { + has_gre_key = 1; + } + } /* If this is a tunneled packet, then add recipe index to match the * tunnel bit in the packet metadata flags. @@ -6838,6 +7115,12 @@ static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF; lkup_exts->field_mask[word] = mask; + + if (rinfo->tun_type == ICE_SW_TUN_GRE) + lkup_exts->fv_words[word].off = ICE_GRE_FLAG_MDID_OFF; + + if (!has_gre_key) + lkup_exts->field_mask[word] = 0x0140; } else { return ICE_ERR_MAX_LIMIT; } @@ -6879,6 +7162,9 @@ static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) case ICE_SW_TUN_NVGRE: prof_type = ICE_PROF_TUN_GRE; break; + case ICE_SW_TUN_GRE: + prof_type = ICE_PROF_TUN_GRE; + break; case ICE_SW_TUN_PPPOE: case ICE_SW_TUN_PPPOE_QINQ: prof_type = ICE_PROF_TUN_PPPOE; @@ -7099,7 +7385,7 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) */ ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); - status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list); + status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list, lkup_exts); if (status) goto err_unroll; @@ -7248,6 +7534,8 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) const struct ice_dummy_pkt_offsets **offsets) { bool tcp = false, udp = false, ipv6 = false, vlan = false; + bool gre_c_bit = false; + bool gre_k_bit = false; bool gre = false; u16 i; @@ -7256,10 +7544,26 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) udp = true; else if (lkups[i].type == ICE_TCP_IL) tcp = true; - else if (lkups[i].type == ICE_IPV6_OFOS) + else if (lkups[i].type == ICE_IPV6_OFOS) { ipv6 = true; + if (lkups[i].h_u.ipv6_hdr.next_hdr == ICE_IPV6_GRE_PROTO_ID && + lkups[i].m_u.ipv6_hdr.next_hdr == 0xFF) + gre = true; + } else if (lkups[i].type == ICE_VLAN_OFOS) vlan = true; + else if (lkups[i].type == ICE_GRE) { + if (lkups[i].h_u.gre_hdr.flags & 0x20) + gre_k_bit = true; + if (lkups[i].h_u.gre_hdr.flags & 0x80) + gre_c_bit = true; + } + else if (lkups[i].type == ICE_IPV4_OFOS && + lkups[i].h_u.ipv4_hdr.protocol == + ICE_IPV4_GRE_PROTO_ID && + lkups[i].m_u.ipv4_hdr.protocol == + 0xFF) + gre = true; else if (lkups[i].type == ICE_IPV4_OFOS && lkups[i].h_u.ipv4_hdr.protocol == ICE_IPV4_NVGRE_PROTO_ID && @@ -7469,6 +7773,12 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) } if (tun_type == ICE_SW_IPV4_TCP) { + if (vlan && tcp) { + *pkt = dummy_vlan_tcp_packet; + *pkt_len = sizeof(dummy_vlan_tcp_packet); + *offsets = dummy_vlan_tcp_packet_offsets; + return; + } *pkt = dummy_tcp_packet; *pkt_len = sizeof(dummy_tcp_packet); *offsets = dummy_tcp_packet_offsets; @@ -7476,6 +7786,12 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) } if (tun_type == ICE_SW_IPV4_UDP) { + if (vlan && udp) { + *pkt = dummy_vlan_udp_packet; + *pkt_len = sizeof(dummy_vlan_udp_packet); + *offsets = dummy_vlan_udp_packet_offsets; + return; + } *pkt = dummy_udp_packet; *pkt_len = sizeof(dummy_udp_packet); *offsets = dummy_udp_packet_offsets; @@ -7503,6 +7819,13 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) return; } + if (ipv6 && gre) { + *pkt = dummy_ipv6_gre_udp_packet; + *pkt_len = sizeof(dummy_ipv6_gre_udp_packet); + *offsets = dummy_ipv6_gre_udp_packet_offsets; + return; + } + if (tun_type == ICE_SW_TUN_NVGRE || gre) { if (tcp) { *pkt = dummy_gre_tcp_packet; @@ -7517,6 +7840,46 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) return; } + if (tun_type == ICE_SW_TUN_GRE || gre) { + if (tcp) { + if (gre_c_bit && gre_k_bit) { + *pkt = dummy_gre_rfc1701_c1k1_tcp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c1k1_tcp_packet); + *offsets = dummy_gre_rfc1701_c1k1_tcp_packet_offsets; + return; + } + if (!gre_c_bit && gre_k_bit) { + *pkt = dummy_gre_rfc1701_c0k1_tcp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c0k1_tcp_packet); + *offsets = dummy_gre_rfc1701_c0k1_tcp_packet_offsets; + return; + } + + *pkt = dummy_gre_rfc1701_c0k0_tcp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c0k0_tcp_packet); + *offsets = dummy_gre_rfc1701_c0k0_tcp_packet_offsets; + return; + } + + if (gre_c_bit && gre_k_bit) { + *pkt = dummy_gre_rfc1701_c1k1_udp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c1k1_udp_packet); + *offsets = dummy_gre_rfc1701_c1k1_udp_packet_offsets; + return; + } + if (!gre_c_bit && gre_k_bit) { + *pkt = dummy_gre_rfc1701_c0k1_udp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c0k1_udp_packet); + *offsets = dummy_gre_rfc1701_c0k1_udp_packet_offsets; + return; + } + + *pkt = dummy_gre_rfc1701_c0k0_udp_packet; + *pkt_len = sizeof(dummy_gre_rfc1701_c0k0_udp_packet); + *offsets = dummy_gre_rfc1701_c0k0_udp_packet_offsets; + return; + } + if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE || tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP || tun_type == ICE_SW_TUN_GENEVE_VLAN || @@ -7658,6 +8021,9 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) case ICE_NVGRE: len = sizeof(struct ice_nvgre); break; + case ICE_GRE: + len = sizeof(struct ice_gre); + break; case ICE_VXLAN: case ICE_GENEVE: case ICE_VXLAN_GPE: @@ -7691,6 +8057,20 @@ bool ice_is_prof_rule(enum ice_sw_tunnel_type type) if (len % ICE_BYTES_PER_WORD) return ICE_ERR_CFG; + if (lkups[i].type == ICE_GRE) { + if (lkups[i].h_u.gre_hdr.flags == 0x20) { + offset -= 4; + } + for (j = 1; j < len / sizeof(u16); j++) + if (((u16 *)&lkups[i].m_u)[j]) + ((u16 *)(pkt + offset))[j] = + (((u16 *)(pkt + offset))[j] & + ~((u16 *)&lkups[i].m_u)[j]) | + (((u16 *)&lkups[i].h_u)[j] & + ((u16 *)&lkups[i].m_u)[j]); + continue; + } + /* We have the offset to the header start, the length, the * caller's header values and mask. Use this information to * copy the data into the dummy packet appropriately based on @@ -8267,8 +8647,11 @@ enum ice_status return ICE_ERR_CFG; count = ice_fill_valid_words(&lkups[i], &lkup_exts); - if (!count) - return ICE_ERR_CFG; + if (!count) { + if (lkups[i].type == ICE_GRE) + continue; + return ICE_ERR_CFG; + } } /* Create any special protocol/offset pairs, such as looking at tunnel @@ -8357,6 +8740,7 @@ enum ice_status struct ice_switch_info *sw; sw = hw->switch_info; + if (!sw->buildin_recipes[remove_entry->rid].is_root) if (!sw->recp_list[remove_entry->rid].recp_created) return ICE_ERR_PARAM; list_head = &sw->recp_list[remove_entry->rid].filt_rules; diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index 6b8d44f..d364066 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -838,6 +838,7 @@ struct ice_switch_info { u16 max_used_prof_index; ice_declare_bitmap(prof_res_bm[ICE_MAX_NUM_PROFILES], ICE_MAX_FV_WORDS); + struct ice_sw_recipe *buildin_recipes; }; /* Port hardware description */ @@ -985,6 +986,7 @@ struct ice_hw { ice_declare_bitmap(fdir_perfect_fltr, ICE_FLTR_PTYPE_MAX); struct ice_lock rss_locks; /* protect RSS configuration */ struct LIST_HEAD_TYPE rss_list_head; + u8 use_buildin_recipe; }; /* Statistics collected by each port, VSI, VEB, and S-channel */ diff --git a/drivers/net/ice/ice_acl_filter.c b/drivers/net/ice/ice_acl_filter.c index f7dbe53..2658515 100644 --- a/drivers/net/ice/ice_acl_filter.c +++ b/drivers/net/ice/ice_acl_filter.c @@ -25,6 +25,7 @@ #include "ice_ethdev.h" #include "ice_generic_flow.h" #include "base/ice_flow.h" +#include "ice_dcf_ethdev.h" #define MAX_ACL_SLOTS_ID 2048 @@ -978,8 +979,11 @@ static void ice_deinit_acl(struct ice_pf *pf) struct ice_pf *pf = &ad->pf; struct ice_hw *hw = ICE_PF_TO_HW(pf); struct ice_flow_parser *parser = &ice_acl_parser; + struct rte_eth_dev *eth_dev = ad->eth_dev; + struct ice_dcf_adapter *dcf_adapter = eth_dev->data->dev_private; + struct ice_dcf_hw *dcf_hw = &dcf_adapter->real_hw; - if (!ad->hw.dcf_enabled) + if (!ad->hw.dcf_enabled || dcf_hw->multi_inst) return 0; ret = ice_acl_prof_alloc(hw); @@ -1025,8 +1029,11 @@ static void ice_deinit_acl(struct ice_pf *pf) struct ice_pf *pf = &ad->pf; struct ice_hw *hw = ICE_PF_TO_HW(pf); struct ice_flow_parser *parser = &ice_acl_parser; + struct rte_eth_dev *eth_dev = ad->eth_dev; + struct ice_dcf_adapter *dcf_adapter = eth_dev->data->dev_private; + struct ice_dcf_hw *dcf_hw = &dcf_adapter->real_hw; - if (ad->hw.dcf_enabled) { + if (ad->hw.dcf_enabled && !dcf_hw->multi_inst) { ice_unregister_parser(parser, ad); ice_deinit_acl(pf); ice_acl_prof_free(hw); diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c index 44dbd3b..d4b1bb9 100644 --- a/drivers/net/ice/ice_dcf.c +++ b/drivers/net/ice/ice_dcf.c @@ -642,7 +642,8 @@ if (ice_dcf_get_vf_vsi_map(hw) < 0) { PMD_INIT_LOG(ERR, "Failed to get VF VSI map"); - ice_dcf_mode_disable(hw); + if (!hw->multi_inst) + ice_dcf_mode_disable(hw); goto err_alloc; } @@ -700,8 +701,8 @@ rte_intr_disable(intr_handle); rte_intr_callback_unregister(intr_handle, ice_dcf_dev_interrupt_handler, hw); - - ice_dcf_mode_disable(hw); + if (!hw->multi_inst) + ice_dcf_mode_disable(hw); iavf_shutdown_adminq(&hw->avf); rte_free(hw->arq_buf); @@ -1079,3 +1080,19 @@ rte_free(list); return err; } + +int +ice_dcf_flush_rules(struct ice_dcf_hw *hw) +{ + struct dcf_virtchnl_cmd args; + int err = 0; + + memset(&args, 0, sizeof(args)); + args.v_op = VIRTCHNL_OP_DCF_RULE_FLUSH; + + err = ice_dcf_execute_virtchnl_cmd(hw, &args); + if (err) + PMD_DRV_LOG(WARNING, "fail to execute command OF_DCF_RULE_FLUSH, DCF role must be preempted."); + + return 0; +} diff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h index ff02996..bebbc88 100644 --- a/drivers/net/ice/ice_dcf.h +++ b/drivers/net/ice/ice_dcf.h @@ -51,6 +51,8 @@ struct ice_dcf_hw { uint16_t vsi_id; struct rte_eth_dev *eth_dev; + bool multi_inst; + bool dcf_replaced; uint8_t *rss_lut; uint8_t *rss_key; uint64_t supported_rxdid; @@ -77,5 +79,6 @@ int ice_dcf_send_aq_cmd(void *dcf_hw, struct ice_aq_desc *desc, int ice_dcf_query_stats(struct ice_dcf_hw *hw, struct virtchnl_eth_stats *pstats); int ice_dcf_add_del_all_mac_addr(struct ice_dcf_hw *hw, bool add); +int ice_dcf_flush_rules(struct ice_dcf_hw *hw); #endif /* _ICE_DCF_H_ */ diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c index b983d84..dd835fe 100644 --- a/drivers/net/ice/ice_dcf_ethdev.c +++ b/drivers/net/ice/ice_dcf_ethdev.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -26,6 +27,13 @@ #include "ice_dcf_ethdev.h" #include "ice_rxtx.h" +static int +ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel); +static int +ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel); + static uint16_t ice_dcf_recv_pkts(__rte_unused void *rx_queue, __rte_unused struct rte_mbuf **bufs, @@ -866,6 +874,64 @@ return 0; } +/* Add UDP tunneling port */ +static int +ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel) +{ + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_adapter *parent_adapter = &adapter->parent; + struct ice_hw *parent_hw = &parent_adapter->hw; + int ret = 0; + + if (!udp_tunnel) + return -EINVAL; + + switch (udp_tunnel->prot_type) { + case RTE_TUNNEL_TYPE_VXLAN: + ret = ice_create_tunnel(parent_hw, TNL_VXLAN, + udp_tunnel->udp_port); + break; + case RTE_TUNNEL_TYPE_ECPRI: + ret = ice_create_tunnel(parent_hw, TNL_ECPRI, + udp_tunnel->udp_port); + break; + default: + PMD_DRV_LOG(ERR, "Invalid tunnel type"); + ret = -EINVAL; + break; + } + + return ret; +} + +/* Delete UDP tunneling port */ +static int +ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel) +{ + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_adapter *parent_adapter = &adapter->parent; + struct ice_hw *parent_hw = &parent_adapter->hw; + int ret = 0; + + if (!udp_tunnel) + return -EINVAL; + + switch (udp_tunnel->prot_type) { + case RTE_TUNNEL_TYPE_VXLAN: + case RTE_TUNNEL_TYPE_ECPRI: + ret = ice_destroy_tunnel(parent_hw, udp_tunnel->udp_port, 0); + break; + default: + PMD_DRV_LOG(ERR, "Invalid tunnel type"); + ret = -EINVAL; + break; + } + + return ret; +} + static const struct eth_dev_ops ice_dcf_eth_dev_ops = { .dev_start = ice_dcf_dev_start, .dev_stop = ice_dcf_dev_stop, @@ -888,91 +954,139 @@ .allmulticast_enable = ice_dcf_dev_allmulticast_enable, .allmulticast_disable = ice_dcf_dev_allmulticast_disable, .filter_ctrl = ice_dcf_dev_filter_ctrl, + .udp_tunnel_port_add = ice_dcf_dev_udp_tunnel_port_add, + .udp_tunnel_port_del = ice_dcf_dev_udp_tunnel_port_del, }; static int -ice_dcf_dev_init(struct rte_eth_dev *eth_dev) +ice_dcf_cap_check_handler(__rte_unused const char *key, + const char *value, void *opaque) { - struct ice_dcf_adapter *adapter = eth_dev->data->dev_private; + bool *mi = opaque; + + if (!strcmp(value, "dcf")) { + *mi = 0; + return 0; + } + if (!strcmp(value, "mdcf")) { + *mi = 1; + return 0; + } + + return -1; +} - eth_dev->dev_ops = &ice_dcf_eth_dev_ops; - eth_dev->rx_pkt_burst = ice_dcf_recv_pkts; - eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts; +static int +parse_bool(const char *key, const char *value, void *args) +{ + int *i = (int *)args; + char *end; + int num; - if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return 0; + num = strtoul(value, &end, 10); - adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg; - if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) { - PMD_INIT_LOG(ERR, "Failed to init DCF hardware"); - return -1; - } + if (num != 0 && num != 1) { + PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", " + "value must be 0 or 1", + value, key); + return -1; + } - if (ice_dcf_init_parent_adapter(eth_dev) != 0) { - PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter"); - ice_dcf_uninit_hw(eth_dev, &adapter->real_hw); - return -1; - } - - return 0; + *i = num; + return 0; } static int -ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev) +ice_dcf_cap_selected(struct ice_dcf_adapter *adapter, + struct rte_devargs *devargs) { - ice_dcf_dev_close(eth_dev); + struct ice_adapter *ad = &adapter->parent; + struct rte_kvargs *kvlist; + const char *key_cap = "cap"; + const char *key_br = "br"; + int ret = 0; - return 0; -} + if (devargs == NULL) + return 0; -static int -ice_dcf_cap_check_handler(__rte_unused const char *key, - const char *value, __rte_unused void *opaque) -{ - if (strcmp(value, "dcf")) - return -1; + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (kvlist == NULL) + return 0; - return 0; + if (!rte_kvargs_count(kvlist, key_cap)) + goto exit; + + /* dcf capability selected when there's a key-value pair: cap=dcf */ + if (rte_kvargs_process(kvlist, key_cap, + ice_dcf_cap_check_handler, + &adapter->real_hw.multi_inst) < 0) + goto exit; + + /* dcf capability selected when there's a key-value pair: cap=dcf */ + if (rte_kvargs_process(kvlist, key_br, + &parse_bool, + &ad->hw.use_buildin_recipe) < 0) + goto exit; + + ret = 1; + +exit: + rte_kvargs_free(kvlist); + return ret; } +/** + * Queue xstats filled automatically by ethdev layer. + * PMDs filling the queue xstats themselves should not set this flag + */ +#define RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS 0x0040 static int -ice_dcf_cap_selected(struct rte_devargs *devargs) +ice_dcf_dev_init(struct rte_eth_dev *eth_dev) { - struct rte_kvargs *kvlist; - const char *key = "cap"; - int ret = 0; + struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device); + struct ice_dcf_adapter *adapter = eth_dev->data->dev_private; - if (devargs == NULL) - return 0; + if (!ice_dcf_cap_selected(adapter, pci_dev->device.devargs)) + return 1; - kvlist = rte_kvargs_parse(devargs->args, NULL); - if (kvlist == NULL) - return 0; + eth_dev->dev_ops = &ice_dcf_eth_dev_ops; + eth_dev->rx_pkt_burst = ice_dcf_recv_pkts; + eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts; - if (!rte_kvargs_count(kvlist, key)) - goto exit; + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; - /* dcf capability selected when there's a key-value pair: cap=dcf */ - if (rte_kvargs_process(kvlist, key, - ice_dcf_cap_check_handler, NULL) < 0) - goto exit; + eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; - ret = 1; + adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg; + if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) { + PMD_INIT_LOG(ERR, "Failed to init DCF hardware"); + return -1; + } -exit: - rte_kvargs_free(kvlist); - return ret; + if (ice_dcf_init_parent_adapter(eth_dev) != 0) { + PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter"); + ice_dcf_uninit_hw(eth_dev, &adapter->real_hw); + return -1; + } + + return 0; +} + +static int +ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev) +{ + ice_dcf_dev_close(eth_dev); + + return 0; } static int eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) { - if (!ice_dcf_cap_selected(pci_dev->device.devargs)) - return 1; - - return rte_eth_dev_pci_generic_probe(pci_dev, - sizeof(struct ice_dcf_adapter), - ice_dcf_dev_init); + return rte_eth_dev_pci_generic_probe(pci_dev, + sizeof(struct ice_dcf_adapter), + ice_dcf_dev_init); } static int eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) @@ -995,4 +1109,6 @@ static int eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) RTE_PMD_REGISTER_PCI(net_ice_dcf, rte_ice_dcf_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_ice_dcf, pci_id_ice_dcf_map); RTE_PMD_REGISTER_KMOD_DEP(net_ice_dcf, "* igb_uio | vfio-pci"); -RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf"); +RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, + "cap=dcf|mdcf " + "br=<1|0>"); diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c index 30ead4c..fdeef7d 100644 --- a/drivers/net/ice/ice_dcf_parent.c +++ b/drivers/net/ice/ice_dcf_parent.c @@ -112,6 +112,9 @@ { struct ice_dcf_hw *hw = param; + if (hw->multi_inst) + return NULL; + usleep(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL); rte_spinlock_lock(&vsi_update_lock); @@ -160,6 +163,10 @@ pthread_create(&thread, NULL, ice_dcf_vsi_update_service_handler, dcf_hw); break; + case VIRTCHNL_EVENT_DCF_VSI_INFO: + if (dcf_hw->vsi_id != pf_msg->event_data.vf_vsi_map.vsi_id) + dcf_hw->dcf_replaced = true; + break; default: PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event); break; @@ -381,6 +388,7 @@ static void ice_dcf_uninit_parent_hw(struct ice_hw *hw) parent_hw->aq_send_cmd_fn = ice_dcf_send_aq_cmd; parent_hw->aq_send_cmd_param = &adapter->real_hw; parent_hw->dcf_enabled = true; + hw->dcf_replaced = false; err = ice_dcf_init_parent_hw(parent_hw); if (err) { diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index b01f2cd..58bffe1 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -72,6 +72,7 @@ struct proto_xtr_ol_flag { #define ICE_OS_DEFAULT_PKG_NAME "ICE OS Default Package" #define ICE_COMMS_PKG_NAME "ICE COMMS Package" +#define ICE_CUSTOM_OS_PKG_NAME "Tencent ICE OS Package" #define ICE_MAX_RES_DESC_NUM 1024 static int ice_dev_configure(struct rte_eth_dev *dev); @@ -1810,6 +1811,9 @@ enum ice_pkg_type else if (!strncmp((char *)hw->active_pkg_name, ICE_COMMS_PKG_NAME, ICE_PKG_NAME_SIZE)) package_type = ICE_PKG_TYPE_COMMS; + if (!strncmp((char *)hw->active_pkg_name, ICE_CUSTOM_OS_PKG_NAME, + ICE_PKG_NAME_SIZE)) + package_type = ICE_PKG_TYPE_OS_DEFAULT; else package_type = ICE_PKG_TYPE_UNKNOWN; diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c index cead476..f42df9b 100644 --- a/drivers/net/ice/ice_generic_flow.c +++ b/drivers/net/ice/ice_generic_flow.c @@ -17,6 +17,7 @@ #include "ice_ethdev.h" #include "ice_generic_flow.h" +#include "ice_dcf.h" /** * Non-pipeline mode, fdir and switch both used as distributor, @@ -1003,6 +1004,33 @@ enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_icmp6[] = { RTE_FLOW_ITEM_TYPE_ICMP6, RTE_FLOW_ITEM_TYPE_END, }; +/* IPv4 GRE RAW IPv4 */ +enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_GRE, + RTE_FLOW_ITEM_TYPE_RAW, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_udp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_GRE, + RTE_FLOW_ITEM_TYPE_RAW, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_END, +}; +enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_tcp[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_GRE, + RTE_FLOW_ITEM_TYPE_RAW, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_END, +}; /*IPv4 GTPU (EH) */ enum rte_flow_item_type pattern_eth_ipv4_gtpu[] = { @@ -2286,10 +2314,16 @@ struct ice_pattern_match_item * struct rte_flow_error *error) { struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct ice_adapter *ad = + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct ice_dcf_hw *hw = ad->hw.aq_send_cmd_param; struct rte_flow *p_flow; void *temp; int ret = 0; + if (hw->dcf_replaced) + return ret; + TAILQ_FOREACH_SAFE(p_flow, &pf->flow_list, node, temp) { ret = ice_flow_destroy(dev, p_flow, error); if (ret) { @@ -2298,6 +2332,9 @@ struct ice_pattern_match_item * } } + if (ad->hw.dcf_enabled && hw->multi_inst) + return ice_dcf_flush_rules(ad->hw.aq_send_cmd_param); + return ret; } diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h index 434d2f4..f212736 100644 --- a/drivers/net/ice/ice_generic_flow.h +++ b/drivers/net/ice/ice_generic_flow.h @@ -35,6 +35,7 @@ #define ICE_PROT_AH (1ULL << 24) #define ICE_PROT_L2TPV3OIP (1ULL << 25) #define ICE_PROT_PFCP (1ULL << 26) +#define ICE_PROT_GRE (1ULL << 27) /* field */ @@ -61,6 +62,7 @@ #define ICE_L2TPV3OIP_SESSION_ID (1ULL << 43) #define ICE_PFCP_SEID (1ULL << 42) #define ICE_PFCP_S_FIELD (1ULL << 41) +#define ICE_RAW_PATTERN (1ULL << 40) /* input set */ @@ -189,6 +191,8 @@ (ICE_PROT_GTPU | ICE_GTPU_TEID) #define ICE_INSET_GTPU_QFI \ (ICE_PROT_GTPU | ICE_GTPU_QFI) +#define ICE_INSET_RAW \ + (ICE_PROT_GRE | ICE_RAW_PATTERN) #define ICE_INSET_PPPOE_SESSION \ (ICE_PROT_PPPOE_S | ICE_PPPOE_SESSION) #define ICE_INSET_PPPOE_PROTO \ @@ -361,6 +365,11 @@ extern enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_sctp[]; extern enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_icmp6[]; +/* IPv4 GRE RAW IPv4 */ +extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4[]; +extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_udp[]; +extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_tcp[]; + /* IPv4 GTPU (EH) */ extern enum rte_flow_item_type pattern_eth_ipv4_gtpu[]; extern enum rte_flow_item_type pattern_eth_ipv4_gtpu_eh[]; diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c index 8cba6eb..6746179 100644 --- a/drivers/net/ice/ice_switch_filter.c +++ b/drivers/net/ice/ice_switch_filter.c @@ -31,12 +31,15 @@ #define ICE_PPP_IPV4_PROTO 0x0021 #define ICE_PPP_IPV6_PROTO 0x0057 #define ICE_IPV4_PROTO_NVGRE 0x002F +#define ICE_IPV6_PROTO_NVGRE 0x002F #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_VLAN_IPV4 ( \ + ICE_SW_INSET_MAC_VLAN | ICE_SW_INSET_MAC_IPV4) #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) @@ -48,6 +51,10 @@ 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_VLAN_IPV4_TCP ( \ + ICE_SW_INSET_MAC_VLAN | ICE_SW_INSET_MAC_IPV4_TCP) +#define ICE_SW_INSET_MAC_VLAN_IPV4_UDP ( \ + ICE_SW_INSET_MAC_VLAN | ICE_SW_INSET_MAC_IPV4_UDP) #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 | \ @@ -82,6 +89,17 @@ 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_DIST_GRE_RAW_IPV4 ( \ + ICE_INSET_TUN_IPV4_SRC | ICE_INSET_TUN_IPV4_DST | \ + ICE_INSET_IPV4_DST | ICE_INSET_RAW) +#define ICE_SW_INSET_DIST_GRE_RAW_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_IPV4_DST | ICE_INSET_RAW) +#define ICE_SW_INSET_DIST_GRE_RAW_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_IPV4_DST | ICE_INSET_RAW) #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) @@ -131,6 +149,13 @@ ICE_SW_INSET_MAC_IPV6 | \ ICE_INSET_PFCP_S_FIELD | ICE_INSET_PFCP_SEID) +#define CUSTOM_GRE_KEY_OFFSET 4 +#define CUSTOM_GRE_RAW_KEY_LEN 2*CUSTOM_GRE_KEY_OFFSET + +#define GRE_CFLAG (0x80) +#define GRE_KFLAG (0x20) +#define GRE_SFLAG (0x10) + struct sw_meta { struct ice_adv_lkup_elem *list; uint16_t lkups_num; @@ -156,6 +181,12 @@ struct sw_meta { ICE_SW_INSET_MAC_IPV4_UDP, ICE_INSET_NONE}, {pattern_eth_ipv4_tcp, ICE_SW_INSET_MAC_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_vlan_ipv4, + ICE_SW_INSET_MAC_VLAN_IPV4, ICE_INSET_NONE}, + {pattern_eth_vlan_ipv4_tcp, + ICE_SW_INSET_MAC_VLAN_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_vlan_ipv4_udp, + ICE_SW_INSET_MAC_VLAN_IPV4_UDP, ICE_INSET_NONE}, {pattern_eth_ipv6, ICE_SW_INSET_MAC_IPV6, ICE_INSET_NONE}, {pattern_eth_ipv6_udp, @@ -174,6 +205,12 @@ struct sw_meta { 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_ipv4_gre_raw_ipv4, + ICE_SW_INSET_DIST_GRE_RAW_IPV4, ICE_INSET_NONE}, + {pattern_eth_ipv4_gre_raw_ipv4_tcp, + ICE_SW_INSET_DIST_GRE_RAW_IPV4_TCP, ICE_INSET_NONE}, + {pattern_eth_ipv4_gre_raw_ipv4_udp, + ICE_SW_INSET_DIST_GRE_RAW_IPV4_UDP, ICE_INSET_NONE}, }; static struct @@ -453,9 +490,10 @@ struct sw_meta { struct rte_flow *flow, struct rte_flow_error *error) { + struct ice_dcf_hw *dcf_hw = ad->hw.aq_send_cmd_param; + struct ice_rule_query_data *filter_ptr; struct ice_hw *hw = &ad->hw; int ret; - struct ice_rule_query_data *filter_ptr; filter_ptr = (struct ice_rule_query_data *) flow->rule; @@ -469,7 +507,7 @@ struct sw_meta { } ret = ice_rem_adv_rule_by_id(hw, filter_ptr); - if (ret) { + if (ret && !(hw->dcf_enabled && dcf_hw->multi_inst)) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "fail to destroy switch filter rule"); @@ -477,7 +515,7 @@ struct sw_meta { } rte_free(filter_ptr); - return ret; + return 0; } static void @@ -502,6 +540,8 @@ struct sw_meta { 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_nvgre *nvgre_spec, *nvgre_mask; + const struct rte_flow_item_gre *gre_spec, *gre_mask; + const struct rte_flow_item_raw *raw_spec, *raw_mask; const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask; const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; const struct rte_flow_item_pppoe *pppoe_spec, *pppoe_mask; @@ -519,12 +559,16 @@ struct sw_meta { bool tunnel_valid = 0; bool profile_rule = 0; bool nvgre_valid = 0; + bool gre_valid = 0; bool vxlan_valid = 0; bool ipv6_valid = 0; bool ipv4_valid = 0; bool udp_valid = 0; bool tcp_valid = 0; uint16_t j, t = 0; + int32_t off; + uint16_t len; + uint16_t c_rsvd0_ver = 0; for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { @@ -734,6 +778,10 @@ struct sw_meta { break; } } + if ((ipv6_spec->hdr.proto & + ipv6_mask->hdr.proto) == + ICE_IPV6_PROTO_NVGRE) + *tun_type = ICE_SW_TUN_AND_NON_TUN; if (ipv6_mask->hdr.proto && tunnel_valid) input_set |= @@ -1047,6 +1095,84 @@ struct sw_meta { } break; + case RTE_FLOW_ITEM_TYPE_GRE: + gre_spec = item->spec; + gre_mask = item->mask; + + gre_valid = 1; + tunnel_valid = 1; + if(gre_spec && gre_mask) { + list[t].type = ICE_GRE; + if(gre_mask->c_rsvd0_ver) { + /* GRE RFC1701 */ + list[t].h_u.gre_hdr.flags = gre_spec->c_rsvd0_ver; + list[t].m_u.gre_hdr.flags = gre_mask->c_rsvd0_ver; + c_rsvd0_ver = gre_spec->c_rsvd0_ver & gre_mask->c_rsvd0_ver; + } + } + break; + + case RTE_FLOW_ITEM_TYPE_RAW: + raw_spec = item->spec; + raw_mask = item->mask; + + if(list[t].type != ICE_GRE) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "RAW must follow GRE."); + return -rte_errno; + } + + if((c_rsvd0_ver & GRE_KFLAG) == 0) { + if(raw_spec && raw_mask) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "invalid pattern! k_bit is 0 while raw pattern exists."); + return -rte_errno; + } + break; + } + + if((!raw_spec) || (!raw_mask)) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "invalid pattern! k_bit is 1 while raw pattern doesn't exist."); + return -rte_errno; + } + + off = raw_spec->offset; + len = raw_spec->length; + + if((c_rsvd0_ver & GRE_CFLAG) == GRE_CFLAG) { + if(off != CUSTOM_GRE_KEY_OFFSET) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "invalid pattern! c_bit is 1 while offset is not 4."); + return -rte_errno; + } + } + + if(len > CUSTOM_GRE_RAW_KEY_LEN) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Only support 4 bytes matching."); + return -rte_errno; + } + + if(raw_spec && raw_mask) { + /* store pattern to header buffer */ + const uint8_t *pat_src = (const uint8_t *)raw_spec->pattern; + uint8_t *key_dst = (uint8_t *)&list[t].h_u.gre_hdr.key; + + int i = 0; + for(i=0; i < len; i++) { + int t = 0; + if(pat_src[i] >= '0' && pat_src[i] <= '9') + t = pat_src[i] - '0'; + else if(pat_src[i] >= 'a' && pat_src[i] <= 'f') + t = pat_src[i] - 'a' + 10; + else + printf("invalid pattern.\n"); + + key_dst[i/2] = (i%2) ? (key_dst[i/2]+t) : t*16; + } + list[t].m_u.gre_hdr.key = 0xffffffff; + input_set |= ICE_INSET_RAW; + input_set_byte += 2; + t++; + } + break; + case RTE_FLOW_ITEM_TYPE_VLAN: vlan_spec = item->spec; vlan_mask = item->mask; @@ -1402,6 +1528,8 @@ struct sw_meta { *tun_type = ICE_SW_TUN_VXLAN; else if (nvgre_valid) *tun_type = ICE_SW_TUN_NVGRE; + else if (gre_valid) + *tun_type = ICE_SW_TUN_GRE; else if (ipv4_valid && tcp_valid) *tun_type = ICE_SW_IPV4_TCP; else if (ipv4_valid && udp_valid) diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h index 0934e02..846fa66 100644 --- a/lib/librte_ethdev/rte_ethdev.h +++ b/lib/librte_ethdev/rte_ethdev.h @@ -1043,6 +1043,7 @@ enum rte_eth_tunnel_type { RTE_TUNNEL_TYPE_IP_IN_GRE, RTE_L2_TUNNEL_TYPE_E_TAG, RTE_TUNNEL_TYPE_VXLAN_GPE, + RTE_TUNNEL_TYPE_ECPRI, RTE_TUNNEL_TYPE_MAX, };