[v5,2/2] app/testpmd: add eCPRI in flow creation patterns
diff mbox series

Message ID 1594370723-343354-3-git-send-email-bingz@mellanox.com
State Superseded
Delegated to: Ferruh Yigit
Headers show
Series
  • rte_flow: introduce eCPRI item for rte_flow
Related show

Checks

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

Commit Message

Bing Zhao July 10, 2020, 8:45 a.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>
---
 app/test-pmd/cmdline_flow.c | 143 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)

Patch
diff mbox series

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 4e2006c..801581e 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,58 @@  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.dw0 = rte_cpu_to_be_32(ecpri->hdr.dw0);
+		ecpri_mask->hdr.dw0 = rte_cpu_to_be_32(ecpri_mask->hdr.dw0);
+	}
+	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,