[v6,2/2] app/testpmd: add eCPRI in flow creation patterns

Message ID 1594560903-313858-3-git-send-email-bingz@mellanox.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series rte_flow: introduce eCPRI item for rte_flow |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/travis-robot warning Travis build: failed
ci/Intel-compilation success Compilation OK

Commit Message

Bing Zhao July 12, 2020, 1:35 p.m. UTC
  In order to verify offloading of eCPRI protocol via flow rules, the
command line of flow creation should support the parsing of the eCPRI
pattern.

Based on the specification, one eCPRI message will have the common
header and payload. Payload format is various based on the type field
of the common header. Fixed strings will be used instead of integer
to make the CLI easy for auto-completion.

The testpmd command line examples of flow to match eCPRI item are
listed below:
  1. flow create 0 ... pattern eth / ecpri / end actions ...
    This is to match all eCPRI messages.
  2. flow create 0 ... pattern eth / ecpri common type rtc_ctrl / end actions ...
    This is to match all eCPRI messages with the type #2 - "Real-Time
    Control Data".
  3. flow create 0 ... pattern eth / ecpri common type iq_data pc_id is [U16Int] / end actions ...
    This is to match eCPRI messages with the type #0 - "IQ Data", and
    the physical channel ID 'pc_id' of the messages is a specific
    value. Since the sequence ID is changeable, there is no need to
    match that field in the flow.
Currently, only type #0, #2 and #5 will be supported.

Since eCPRI could be over Ethernet layer (or after .1Q) and UDP
layer, it is the PMD driver's responsibility to check whether eCPRI
is supported and which protocol stack is supported. Network byte
order should be used for eCPRI header, the same as other headers.

Signed-off-by: Bing Zhao <bingz@mellanox.com>
Acked-by: Ori Kam <orika@mellanox.com>
---
v3: Add commit for testpmd support.
v6: change the members definition of 'struct rte_ecpri_common_hdr'
---
 app/test-pmd/cmdline_flow.c | 144 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)
  

Patch

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4e2006c..6263d30 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -230,6 +230,15 @@  enum index {
 	ITEM_PFCP,
 	ITEM_PFCP_S_FIELD,
 	ITEM_PFCP_SEID,
+	ITEM_ECPRI,
+	ITEM_ECPRI_COMMON,
+	ITEM_ECPRI_COMMON_TYPE,
+	ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
+	ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
+	ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
+	ITEM_ECPRI_MSG_IQ_DATA_PCID,
+	ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
+	ITEM_ECPRI_MSG_DLY_MSR_MSRID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -791,6 +800,7 @@  struct parse_action_priv {
 	ITEM_ESP,
 	ITEM_AH,
 	ITEM_PFCP,
+	ITEM_ECPRI,
 	END_SET,
 	ZERO,
 };
@@ -1101,6 +1111,24 @@  struct parse_action_priv {
 	ZERO,
 };
 
+static const enum index item_ecpri[] = {
+	ITEM_ECPRI_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ecpri_common[] = {
+	ITEM_ECPRI_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_ecpri_common_type[] = {
+	ITEM_ECPRI_COMMON_TYPE_IQ_DATA,
+	ITEM_ECPRI_COMMON_TYPE_RTC_CTRL,
+	ITEM_ECPRI_COMMON_TYPE_DLY_MSR,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1409,6 +1437,9 @@  static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_item_ecpri_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_rss(struct context *, const struct token *,
 			       const char *, unsigned int, void *,
 			       unsigned int);
@@ -2802,6 +2833,66 @@  static int comp_set_raw_index(struct context *, const struct token *,
 		.next = NEXT(item_pfcp, NEXT_ENTRY(UNSIGNED), item_param),
 		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)),
 	},
+	[ITEM_ECPRI] = {
+		.name = "ecpri",
+		.help = "match eCPRI header",
+		.priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
+		.next = NEXT(item_ecpri),
+		.call = parse_vc,
+	},
+	[ITEM_ECPRI_COMMON] = {
+		.name = "common",
+		.help = "eCPRI common header",
+		.next = NEXT(item_ecpri_common),
+	},
+	[ITEM_ECPRI_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_ecpri_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)),
+	},
+	[ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = {
+		.name = "iq_data",
+		.help = "Type #0: IQ Data",
+		.next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_ecpri_type,
+	},
+	[ITEM_ECPRI_MSG_IQ_DATA_PCID] = {
+		.name = "pc_id",
+		.help = "Physical Channel ID",
+		.next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
+				hdr.type0.pc_id)),
+	},
+	[ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = {
+		.name = "rtc_ctrl",
+		.help = "Type #2: Real-Time Control Data",
+		.next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_ecpri_type,
+	},
+	[ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = {
+		.name = "rtc_id",
+		.help = "Real-Time Control Data ID",
+		.next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
+				hdr.type2.rtc_id)),
+	},
+	[ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = {
+		.name = "delay_measure",
+		.help = "Type #5: One-Way Delay Measurement",
+		.next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_ecpri_type,
+	},
+	[ITEM_ECPRI_MSG_DLY_MSR_MSRID] = {
+		.name = "msr_id",
+		.help = "Measurement ID",
+		.next = NEXT(item_ecpri, NEXT_ENTRY(UNSIGNED), item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri,
+				hdr.type5.msr_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -4124,6 +4215,59 @@  static int comp_set_raw_index(struct context *, const struct token *,
 	return len;
 }
 
+/** Parse eCPRI common header type field. */
+static int
+parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_ecpri *ecpri;
+	struct rte_flow_item_ecpri *ecpri_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_ECPRI_COMMON_TYPE_IQ_DATA:
+		msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA;
+		break;
+	case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL:
+		msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL;
+		break;
+	case ITEM_ECPRI_COMMON_TYPE_DLY_MSR:
+		msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data;
+	ecpri->hdr.common.type = msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data +
+						    (data_size * 2));
+	ecpri_mask->hdr.common.type = 0xFF;
+	if (arg->hton) {
+		ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32);
+		ecpri_mask->hdr.common.u32 =
+				rte_cpu_to_be_32(ecpri_mask->hdr.common.u32);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = ecpri;
+	item->mask = ecpri_mask;
+	return len;
+}
+
 /** Parse RSS action. */
 static int
 parse_vc_action_rss(struct context *ctx, const struct token *token,