From patchwork Wed Apr 13 16:09:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Liu X-Patchwork-Id: 109652 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 D80BFA0508; Wed, 13 Apr 2022 10:12:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1346C42835; Wed, 13 Apr 2022 10:11:39 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 7958042802 for ; Wed, 13 Apr 2022 10:11:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649837496; x=1681373496; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=e3DAAmQzR/BbODjS4ihK3J3G75SEspdVFZqp2V/eqf4=; b=Q38llHzxnMaW8sX9t6WtgpQxq4lp4ynrZKBLSG7+ENZpgknR/+6wNDLQ 8VMNR6PVcNPTQXzIT8pYEVEP6ftvmSiN566HrRbnxx4VsDO9cDCm+RL45 rSEvYSF5ZN8DxHelZO1vvmz1PcGg4E5+9bFYC/H4luDc1fKq3G5I7Ynq/ EVe0CPF/FkNaAnaQ33ryMpU0v8WtG+gzfmneKxKx4AFY/sjSUFSB1tGfz Rc8XiU7wHesGhbgtUgXJt2N365tteoslBxHvwKmV+x62SvP9j8fOy8LAD 9+KwH3kBukQETJJVeT3RLjcNFv/6Rrh3gWPVzH8v0Zv3ftuuTkWmfz3wr g==; X-IronPort-AV: E=McAfee;i="6400,9594,10315"; a="287630064" X-IronPort-AV: E=Sophos;i="5.90,256,1643702400"; d="scan'208";a="287630064" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2022 01:11:35 -0700 X-IronPort-AV: E=Sophos;i="5.90,256,1643702400"; d="scan'208";a="526847758" Received: from intel-cd-odc-kevin.cd.intel.com ([10.240.178.195]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2022 01:11:32 -0700 From: Kevin Liu To: dev@dpdk.org Cc: qiming.yang@intel.com, qi.z.zhang@intel.com, stevex.yang@intel.com, Alvin Zhang , Junfeng Guo , Kevin Liu Subject: [PATCH v2 20/33] net/ice/base: support IPv4 GRE tunnel Date: Wed, 13 Apr 2022 16:09:19 +0000 Message-Id: <20220413160932.2074781-21-kevinx.liu@intel.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220413160932.2074781-1-kevinx.liu@intel.com> References: <20220407105706.18889-1-kevinx.liu@intel.com> <20220413160932.2074781-1-kevinx.liu@intel.com> MIME-Version: 1.0 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 From: Alvin Zhang Add definitions, trainer packets and routine path for IPv4 GRE tunnel. Ref: https://www.ietf.org/rfc/rfc1701.html Signed-off-by: Junfeng Guo Signed-off-by: Alvin Zhang Signed-off-by: Kevin Liu --- drivers/net/ice/base/ice_flex_pipe.c | 37 ++- drivers/net/ice/base/ice_flex_pipe.h | 3 +- drivers/net/ice/base/ice_protocol_type.h | 15 ++ drivers/net/ice/base/ice_switch.c | 304 ++++++++++++++++++++++- 4 files changed, 332 insertions(+), 27 deletions(-) diff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c index f6a29f87c5..8672c41c69 100644 --- a/drivers/net/ice/base/ice_flex_pipe.c +++ b/drivers/net/ice/base/ice_flex_pipe.c @@ -1851,6 +1851,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, * @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 @@ -1861,7 +1862,8 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, */ 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; @@ -1892,29 +1894,26 @@ ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, if (!ice_is_bit_set(bm, (u16)offset)) continue; - for (i = 0; i < ids_cnt; i++) { + int found = 1; + for (i = 0; i < lkup_exts->n_val_words; i++) { int j; - /* This code assumes that if a switch field vector line - * has a matching protocol, then this line will contain - * the entries necessary to represent every field in - * that protocol header. - */ for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) - if (fv->ew[j].prot_id == prot_ids[i]) + 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) - break; - if (i + 1 == ids_cnt) { - 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); - break; - } + 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); } } while (fv); if (LIST_EMPTY(fv_list)) diff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h index 23ba45564a..a22d66f3cf 100644 --- a/drivers/net/ice/base/ice_flex_pipe.h +++ b/drivers/net/ice/base/ice_flex_pipe.h @@ -37,7 +37,8 @@ void 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); enum ice_status ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count); u16 ice_pkg_buf_get_free_space(struct ice_buf_build *bld); diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h index eec9f27823..ffd34606e0 100644 --- a/drivers/net/ice/base/ice_protocol_type.h +++ b/drivers/net/ice/base/ice_protocol_type.h @@ -67,6 +67,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 */ @@ -231,6 +232,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 */ @@ -371,6 +376,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; @@ -381,6 +395,7 @@ union ice_prot_hdr { 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 c742dba138..1b51cd4321 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -12,6 +12,7 @@ #define ICE_MAX_VLAN_ID 0xFFF #define ICE_IPV6_ETHER_ID 0x86DD #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_TCP_PROTO_ID 0x06 @@ -158,6 +159,188 @@ static const u8 dummy_ipv6_gre_udp_packet[] = { 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 }, @@ -173,7 +356,7 @@ static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = { }; static const u8 dummy_udp_tun_tcp_packet[] = { - 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -224,7 +407,7 @@ static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = { }; static const u8 dummy_udp_tun_udp_packet[] = { - 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6892,6 +7075,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { { 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, 22 } }, { ICE_PPPOE, { 0, 2, 4, 6 } }, { ICE_PFCP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, @@ -6927,6 +7111,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { { 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 }, @@ -7065,6 +7250,7 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 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; @@ -7077,8 +7263,15 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule, /* 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] = @@ -7622,10 +7815,12 @@ ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, * @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; @@ -7645,7 +7840,8 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, } /* 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); @@ -7681,6 +7877,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; @@ -7702,6 +7902,12 @@ ice_add_special_words(struct ice_adv_rule_info *rinfo, struct ice_prot_lkup_ext *lkup_exts) { u16 mask; + u8 has_gre_key = 0; + 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. @@ -7713,6 +7919,13 @@ ice_add_special_words(struct ice_adv_rule_info *rinfo, 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; } @@ -7754,6 +7967,9 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 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; @@ -8079,7 +8295,8 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, */ 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; @@ -8228,6 +8445,8 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 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, mpls = false; u16 i; @@ -8245,6 +8464,17 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, } 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_ETYPE_OL && lkups[i].h_u.ethertype.ethtype_id == CPU_TO_BE16(ICE_IPV6_ETHER_ID) && @@ -8650,6 +8880,46 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, return; } + if (tun_type == ICE_SW_TUN_GRE && 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 (tun_type == ICE_SW_TUN_GRE) { + 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_PROFID_IPV4_VXLAN || @@ -8800,6 +9070,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 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: @@ -8833,6 +9106,20 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 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 @@ -9420,8 +9707,11 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, return ICE_ERR_CFG; count = ice_fill_valid_words(&lkups[i], &lkup_exts); - if (!count) + if (!count) { + if (lkups[i].type == ICE_GRE) + continue; return ICE_ERR_CFG; + } } /* Create any special protocol/offset pairs, such as looking at tunnel