[v2] net/enic: add support for eCPRI matching

Message ID 20220126214802.1412-1-johndale@cisco.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series [v2] net/enic: add support for eCPRI matching |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-testing warning apply patch failure
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS

Commit Message

John Daley (johndale) Jan. 26, 2022, 9:48 p.m. UTC
  eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Only up though the first packet header in the PDU can be matched.
RSS on the eCPRI header fields is not supported.

Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
---
v2 - include enic.ini update

 doc/guides/nics/features/enic.ini      |  1 +
 doc/guides/rel_notes/release_22_03.rst |  1 +
 drivers/net/enic/enic_fm_flow.c        | 65 ++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)
  

Comments

Ferruh Yigit Jan. 27, 2022, 12:15 p.m. UTC | #1
On 1/26/2022 9:48 PM, John Daley wrote:
> eCPRI message can be over Ethernet layer (.1Q supported also) or over
> UDP layer. Message header formats are the same in these two variants.
> 
> Only up though the first packet header in the PDU can be matched.
> RSS on the eCPRI header fields is not supported.
> 
> Signed-off-by: John Daley <johndale@cisco.com>
> Reviewed-by: Hyong Youb Kim <hyonkim@cisco.com>
> ---
> v2 - include enic.ini update
> 
>   doc/guides/nics/features/enic.ini      |  1 +
>   doc/guides/rel_notes/release_22_03.rst |  1 +
>   drivers/net/enic/enic_fm_flow.c        | 65 ++++++++++++++++++++++++++
>   3 files changed, 67 insertions(+)
> 
> diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
> index c3bcead05e..88e4ef8c64 100644
> --- a/doc/guides/nics/features/enic.ini
> +++ b/doc/guides/nics/features/enic.ini
> @@ -53,6 +53,7 @@ vlan                 = Y
>   vxlan                = Y
>   geneve               = Y
>   geneve_opt           = Y
> +ecpri                = Y

Can you please add in alphabetical order, as in 'doc/guides/nics/features/default.ini'?

>   
>   [rte_flow actions]
>   count                = Y
> diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
> index b38dc54e62..52d1e32cf6 100644
> --- a/doc/guides/rel_notes/release_22_03.rst
> +++ b/doc/guides/rel_notes/release_22_03.rst
> @@ -58,6 +58,7 @@ New Features
>   * **Updated Cisco enic driver.**
>   
>     * Added rte_flow support for matching GENEVE packets.
> +  * Added rte_flow support for matching eCPRI packets.
>   
>   Removed Items
>   -------------
> diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
> index 752ffeb5c5..589c9253e1 100644
> --- a/drivers/net/enic/enic_fm_flow.c
> +++ b/drivers/net/enic/enic_fm_flow.c
> @@ -237,6 +237,7 @@ static enic_copy_item_fn enic_fm_copy_item_vxlan;
>   static enic_copy_item_fn enic_fm_copy_item_gtp;
>   static enic_copy_item_fn enic_fm_copy_item_geneve;
>   static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
> +static enic_copy_item_fn enic_fm_copy_item_ecpri;
>   
>   /* Ingress actions */
>   static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
> @@ -392,6 +393,15 @@ static const struct enic_fm_items enic_fm_items[] = {
>   			       RTE_FLOW_ITEM_TYPE_END,
>   		},
>   	},
> +	[RTE_FLOW_ITEM_TYPE_ECPRI] = {
> +		.copy_item = enic_fm_copy_item_ecpri,
> +		.valid_start_item = 1,
> +		.prev_items = (const enum rte_flow_item_type[]) {
> +			       RTE_FLOW_ITEM_TYPE_ETH,
> +			       RTE_FLOW_ITEM_TYPE_UDP,
> +			       RTE_FLOW_ITEM_TYPE_END,
> +		},
> +	},
>   };
>   
>   static int
> @@ -877,6 +887,61 @@ enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
>   	return 0;
>   }
>   
> +/* Match eCPRI combined message header */
> +static int
> +enic_fm_copy_item_ecpri(struct copy_item_args *arg)
> +{
> +	const struct rte_flow_item *item = arg->item;
> +	const struct rte_flow_item_ecpri *spec = item->spec;
> +	const struct rte_flow_item_ecpri *mask = item->mask;
> +	struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
> +	struct fm_header_set *fm_data, *fm_mask;
> +	uint8_t *fm_data_to, *fm_mask_to;
> +
> +	ENICPMD_FUNC_TRACE();
> +
> +	/* Tunneling not supported- only matching on inner eCPRI fields. */
> +	if (arg->header_level > 0)
> +		return -EINVAL;
> +
> +	/* Need both spec and mask */
> +	if (!spec || !mask)
> +		return -EINVAL;
> +
> +	fm_data = &entry->ftm_data.fk_hdrset[0];
> +	fm_mask = &entry->ftm_mask.fk_hdrset[0];
> +
> +	/* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
> +	if (!(fm_data->fk_metadata & FKM_UDP) &&
> +	    (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
> +	    rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
> +	    RTE_ETHER_TYPE_ECPRI))
> +		return -EINVAL;
> +
> +	if (fm_data->fk_metadata & FKM_UDP) {
> +		/* eCPRI on UDP */
> +		fm_data->fk_header_select |= FKH_L4RAW;
> +		fm_mask->fk_header_select |= FKH_L4RAW;
> +		fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
> +		fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
> +	} else {
> +		/* eCPRI directly after Etherent header */
> +		fm_data->fk_header_select |= FKH_L3RAW;
> +		fm_mask->fk_header_select |= FKH_L3RAW;
> +		fm_data_to = &fm_data->l3.rawdata[0];
> +		fm_mask_to = &fm_mask->l3.rawdata[0];
> +	}
> +
> +	/*
> +	 * Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
> +	 * not have eCPRI header. Only 1st message header of PDU can be matched.
> +	 * "C" * bit ignored.
> +	 */
> +	memcpy(fm_data_to, spec, sizeof(*spec));
> +	memcpy(fm_mask_to, mask, sizeof(*mask));
> +	return 0;
> +}
> +
>   /*
>    * Currently, raw pattern match is very limited. It is intended for matching
>    * UDP tunnel header (e.g. vxlan or geneve).
  

Patch

diff --git a/doc/guides/nics/features/enic.ini b/doc/guides/nics/features/enic.ini
index c3bcead05e..88e4ef8c64 100644
--- a/doc/guides/nics/features/enic.ini
+++ b/doc/guides/nics/features/enic.ini
@@ -53,6 +53,7 @@  vlan                 = Y
 vxlan                = Y
 geneve               = Y
 geneve_opt           = Y
+ecpri                = Y
 
 [rte_flow actions]
 count                = Y
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index b38dc54e62..52d1e32cf6 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -58,6 +58,7 @@  New Features
 * **Updated Cisco enic driver.**
 
   * Added rte_flow support for matching GENEVE packets.
+  * Added rte_flow support for matching eCPRI packets.
 
 Removed Items
 -------------
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 752ffeb5c5..589c9253e1 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -237,6 +237,7 @@  static enic_copy_item_fn enic_fm_copy_item_vxlan;
 static enic_copy_item_fn enic_fm_copy_item_gtp;
 static enic_copy_item_fn enic_fm_copy_item_geneve;
 static enic_copy_item_fn enic_fm_copy_item_geneve_opt;
+static enic_copy_item_fn enic_fm_copy_item_ecpri;
 
 /* Ingress actions */
 static const enum rte_flow_action_type enic_fm_supported_ig_actions[] = {
@@ -392,6 +393,15 @@  static const struct enic_fm_items enic_fm_items[] = {
 			       RTE_FLOW_ITEM_TYPE_END,
 		},
 	},
+	[RTE_FLOW_ITEM_TYPE_ECPRI] = {
+		.copy_item = enic_fm_copy_item_ecpri,
+		.valid_start_item = 1,
+		.prev_items = (const enum rte_flow_item_type[]) {
+			       RTE_FLOW_ITEM_TYPE_ETH,
+			       RTE_FLOW_ITEM_TYPE_UDP,
+			       RTE_FLOW_ITEM_TYPE_END,
+		},
+	},
 };
 
 static int
@@ -877,6 +887,61 @@  enic_fm_copy_item_geneve_opt(struct copy_item_args *arg)
 	return 0;
 }
 
+/* Match eCPRI combined message header */
+static int
+enic_fm_copy_item_ecpri(struct copy_item_args *arg)
+{
+	const struct rte_flow_item *item = arg->item;
+	const struct rte_flow_item_ecpri *spec = item->spec;
+	const struct rte_flow_item_ecpri *mask = item->mask;
+	struct fm_tcam_match_entry *entry = arg->fm_tcam_entry;
+	struct fm_header_set *fm_data, *fm_mask;
+	uint8_t *fm_data_to, *fm_mask_to;
+
+	ENICPMD_FUNC_TRACE();
+
+	/* Tunneling not supported- only matching on inner eCPRI fields. */
+	if (arg->header_level > 0)
+		return -EINVAL;
+
+	/* Need both spec and mask */
+	if (!spec || !mask)
+		return -EINVAL;
+
+	fm_data = &entry->ftm_data.fk_hdrset[0];
+	fm_mask = &entry->ftm_mask.fk_hdrset[0];
+
+	/* eCPRI can only follow L2/VLAN layer if ethernet type is 0xAEFE. */
+	if (!(fm_data->fk_metadata & FKM_UDP) &&
+	    (fm_mask->l2.eth.fk_ethtype != UINT16_MAX ||
+	    rte_cpu_to_be_16(fm_data->l2.eth.fk_ethtype) !=
+	    RTE_ETHER_TYPE_ECPRI))
+		return -EINVAL;
+
+	if (fm_data->fk_metadata & FKM_UDP) {
+		/* eCPRI on UDP */
+		fm_data->fk_header_select |= FKH_L4RAW;
+		fm_mask->fk_header_select |= FKH_L4RAW;
+		fm_data_to = &fm_data->l4.rawdata[sizeof(fm_data->l4.udp)];
+		fm_mask_to = &fm_mask->l4.rawdata[sizeof(fm_data->l4.udp)];
+	} else {
+		/* eCPRI directly after Etherent header */
+		fm_data->fk_header_select |= FKH_L3RAW;
+		fm_mask->fk_header_select |= FKH_L3RAW;
+		fm_data_to = &fm_data->l3.rawdata[0];
+		fm_mask_to = &fm_mask->l3.rawdata[0];
+	}
+
+	/*
+	 * Use the raw L3 or L4 buffer to match eCPRI since fm_header_set does
+	 * not have eCPRI header. Only 1st message header of PDU can be matched.
+	 * "C" * bit ignored.
+	 */
+	memcpy(fm_data_to, spec, sizeof(*spec));
+	memcpy(fm_mask_to, mask, sizeof(*mask));
+	return 0;
+}
+
 /*
  * Currently, raw pattern match is very limited. It is intended for matching
  * UDP tunnel header (e.g. vxlan or geneve).