[21/25] net/nfp: add the offload support of IPv4 NVGRE item

Message ID 1666063359-34283-22-git-send-email-chaoyong.he@corigine.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series add the extend rte_flow offload support of nfp PMD |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Chaoyong He Oct. 18, 2022, 3:22 a.m. UTC
  Add the corresponding logics to support the offload of
IPv4 NVGRE item.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 doc/guides/nics/features/nfp.ini |  2 +
 drivers/net/nfp/nfp_flow.c       | 99 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 99 insertions(+), 2 deletions(-)
  

Patch

diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini
index 5a3d0a8..4c6d2d5 100644
--- a/doc/guides/nics/features/nfp.ini
+++ b/doc/guides/nics/features/nfp.ini
@@ -29,6 +29,8 @@  Usage doc            = Y
 [rte_flow items]
 eth                  = Y
 geneve               = Y
+gre                  = Y
+gre_key              = Y
 ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 3f06657..94d7a27 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -832,6 +832,26 @@  struct nfp_pre_tun_entry {
 				return -EINVAL;
 			}
 			break;
+		case RTE_FLOW_ITEM_TYPE_GRE:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_GRE detected");
+			/* Clear IPv4 bits */
+			key_ls->key_layer &= ~NFP_FLOWER_LAYER_IPV4;
+			key_ls->tun_type = NFP_FL_TUN_GRE;
+			key_ls->key_layer |= NFP_FLOWER_LAYER_EXT_META;
+			key_ls->key_layer_two |= NFP_FLOWER_LAYER2_GRE;
+			key_ls->key_size += sizeof(struct nfp_flower_ext_meta);
+			if (outer_ip4_flag) {
+				key_ls->key_size += sizeof(struct nfp_flower_ipv4_gre_tun);
+				/*
+				 * The outer l3 layer information is
+				 * in `struct nfp_flower_ipv4_gre_tun`
+				 */
+				key_ls->key_size -= sizeof(struct nfp_flower_ipv4);
+			}
+			break;
+		case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+			PMD_DRV_LOG(DEBUG, "RTE_FLOW_ITEM_TYPE_GRE_KEY detected");
+			break;
 		default:
 			PMD_DRV_LOG(ERR, "Item type %d not supported.", item->type);
 			return -ENOTSUP;
@@ -1558,6 +1578,62 @@  struct nfp_pre_tun_entry {
 	return ret;
 }
 
+static int
+nfp_flow_merge_gre(__rte_unused struct nfp_app_fw_flower *app_fw_flower,
+		__rte_unused struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		__rte_unused const struct rte_flow_item *item,
+		__rte_unused const struct nfp_flow_item_proc *proc,
+		bool is_mask,
+		__rte_unused bool is_outer_layer)
+{
+	struct nfp_flower_ipv4_gre_tun *tun4;
+
+	/* NVGRE is the only supported GRE tunnel type */
+	tun4 = (struct nfp_flower_ipv4_gre_tun *)*mbuf_off;
+	if (is_mask)
+		tun4->ethertype = rte_cpu_to_be_16(~0);
+	else
+		tun4->ethertype = rte_cpu_to_be_16(0x6558);
+
+	return 0;
+}
+
+static int
+nfp_flow_merge_gre_key(__rte_unused struct nfp_app_fw_flower *app_fw_flower,
+		__rte_unused struct rte_flow *nfp_flow,
+		char **mbuf_off,
+		const struct rte_flow_item *item,
+		__rte_unused const struct nfp_flow_item_proc *proc,
+		bool is_mask,
+		__rte_unused bool is_outer_layer)
+{
+	rte_be32_t tun_key;
+	const rte_be32_t *spec;
+	const rte_be32_t *mask;
+	struct nfp_flower_ipv4_gre_tun *tun4;
+
+	spec = item->spec;
+	if (spec == NULL) {
+		PMD_DRV_LOG(DEBUG, "nfp flow merge gre key: no item->spec!");
+		goto gre_key_end;
+	}
+
+	mask = item->mask ? item->mask : proc->mask_default;
+	tun_key = is_mask ? *mask : *spec;
+
+	tun4 = (struct nfp_flower_ipv4_gre_tun *)*mbuf_off;
+	tun4->tun_key = tun_key;
+	tun4->tun_flags = rte_cpu_to_be_16(NFP_FL_GRE_FLAG_KEY);
+
+gre_key_end:
+	*mbuf_off += sizeof(struct nfp_flower_ipv4_gre_tun);
+
+	return 0;
+}
+
+const rte_be32_t nfp_flow_item_gre_key = 0xffffffff;
+
 /* Graph of supported items and associated process function */
 static const struct nfp_flow_item_proc nfp_flow_item_proc_list[] = {
 	[RTE_FLOW_ITEM_TYPE_END] = {
@@ -1598,7 +1674,8 @@  struct nfp_pre_tun_entry {
 	[RTE_FLOW_ITEM_TYPE_IPV4] = {
 		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_TCP,
 			RTE_FLOW_ITEM_TYPE_UDP,
-			RTE_FLOW_ITEM_TYPE_SCTP),
+			RTE_FLOW_ITEM_TYPE_SCTP,
+			RTE_FLOW_ITEM_TYPE_GRE),
 		.mask_support = &(const struct rte_flow_item_ipv4){
 			.hdr = {
 				.type_of_service = 0xff,
@@ -1689,6 +1766,23 @@  struct nfp_pre_tun_entry {
 		.mask_sz = sizeof(struct rte_flow_item_geneve),
 		.merge = nfp_flow_merge_geneve,
 	},
+	[RTE_FLOW_ITEM_TYPE_GRE] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_GRE_KEY),
+		.mask_support = &(const struct rte_flow_item_gre){
+			.c_rsvd0_ver = RTE_BE16(0xa000),
+			.protocol = RTE_BE16(0xffff),
+		},
+		.mask_default = &rte_flow_item_gre_mask,
+		.mask_sz = sizeof(struct rte_flow_item_gre),
+		.merge = nfp_flow_merge_gre,
+	},
+	[RTE_FLOW_ITEM_TYPE_GRE_KEY] = {
+		.next_item = NEXT_ITEM(RTE_FLOW_ITEM_TYPE_ETH),
+		.mask_support = &nfp_flow_item_gre_key,
+		.mask_default = &nfp_flow_item_gre_key,
+		.mask_sz = sizeof(rte_be32_t),
+		.merge = nfp_flow_merge_gre_key,
+	},
 };
 
 static int
@@ -1746,7 +1840,8 @@  struct nfp_pre_tun_entry {
 nfp_flow_is_tun_item(const struct rte_flow_item *item)
 {
 	if (item->type == RTE_FLOW_ITEM_TYPE_VXLAN ||
-			item->type == RTE_FLOW_ITEM_TYPE_GENEVE)
+			item->type == RTE_FLOW_ITEM_TYPE_GENEVE ||
+			item->type == RTE_FLOW_ITEM_TYPE_GRE_KEY)
 		return true;
 
 	return false;