[RFC] rte_flow: introduce eCPRI item for rte_flow
diff mbox series

Message ID 1591717358-194133-1-git-send-email-bingz@mellanox.com
State RFC, archived
Delegated to: Ferruh Yigit
Headers show
Series
  • [RFC] rte_flow: introduce eCPRI item for rte_flow
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch warning coding style issues

Commit Message

Bing Zhao June 9, 2020, 3:42 p.m. UTC
eCPRI - enhanced CPRI - is packet based fronthaul interface developed
by CPRI (Common Public Radio Interface) forum to connect the eREC and
eRE. It supports 5G and enables increased efficiency.

More details could be found in the specification via the link below:
https://www.gigalight.com/downloads/standards/ecpri-specification.pdf

eCPRI defines a protocol layer which provides various services to the
upper layers of the protocol stack. Currently, it can be over Ethernet
or IP/UDP layer.
  1. over ETH: ethertype is 0xAEFE, 802.1Q VLAN header could also
     be supported.
  2. over UDP: no specific port in UDP header from the specification.

eCPRI message has two parts: common header and message payload. Type
field of the common header will indicate the message payload type and
its format. Detailed messages' formats could be found in the
eCPRI specification.

In order to support eCPRI in rte_flow, new definitions and structures
will be introduced.
  1. new file: rte_ecpri.h, eCPRI message headers' formats are
     defined here.
  2. new struct and enum value to define the eCPRI item in the file
     of rte_flow.h.

PMD driver should be responsible for checking the support of and
handling the match on the ecpri item (if any) when creating a flow.

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.
The 'type' field uses string type, e.g. rtc_ctrl / iq_data, and then
the next fields in the message body for each type could be different
in the CLI auto-completion.

The 3 levels matching could not be reversed. It makes no sense to
only match the 'pc_id' without matching the 'type iq_data', because
the message payload formats are different for each type. And also,
it could match the 'type rtc_ctrl' only after it is specified as an
eCPRI message item.

Signed-off-by: Bing Zhao <bingz@mellanox.com>
---
 doc/guides/prog_guide/rte_flow.rst |   8 ++
 lib/librte_ethdev/rte_flow.c       |   1 +
 lib/librte_ethdev/rte_flow.h       |  31 ++++++
 lib/librte_net/Makefile            |   1 +
 lib/librte_net/meson.build         |   3 +-
 lib/librte_net/rte_ecpri.h         | 161 +++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h         |   1 +
 7 files changed, 205 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_net/rte_ecpri.h

Patch
diff mbox series

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index d5dd18ce99..669d519233 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1362,6 +1362,14 @@  Matches a PFCP Header.
 - ``seid``: session endpoint identifier.
 - Default ``mask`` matches s_field and seid.
 
+Item: ``ECPRI``
+^^^^^^^^^^^^^
+
+Matches a eCPRI header.
+
+- ``hdr``: eCPRI header definition (``rte_ecpri.h``).
+- Default ``mask`` matches message type of common header only.
+
 Actions
 ~~~~~~~
 
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 1685be5f73..f8fdd68fe9 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -95,6 +95,7 @@  static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)),
 	MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)),
 	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
+	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index b0e4199192..2683466f7a 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -28,6 +28,7 @@ 
 #include <rte_byteorder.h>
 #include <rte_esp.h>
 #include <rte_higig.h>
+#include <rte_ecpri.h>
 #include <rte_mbuf.h>
 #include <rte_mbuf_dyn.h>
 
@@ -527,6 +528,13 @@  enum rte_flow_item_type {
 	 */
 	RTE_FLOW_ITEM_TYPE_PFCP,
 
+	/**
+	 * Matches eCPRI Header.
+	 * See struct rte_flow_item_ecpri.
+	 *
+	 */
+	RTE_FLOW_ITEM_TYPE_ECPRI,
+
 };
 
 /**
@@ -1546,6 +1554,29 @@  static const struct rte_flow_item_pfcp rte_flow_item_pfcp_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_ECPRI
+ *
+ * Match eCPRI Header
+ */
+struct rte_flow_item_ecpri {
+	struct rte_ecpri_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_ECPRI. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ecpri rte_flow_item_ecpri_mask = {
+	.hdr = {
+		.common = {
+			.type = 0xFF,
+		},
+	},
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index aa1d6fed5a..9830e771b3 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -20,5 +20,6 @@  SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_sctp.h rte_icmp.h rte_arp.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_net.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h rte_mpls.h rte_higig.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_gtp.h rte_vxlan.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ecpri.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_net/meson.build b/lib/librte_net/meson.build
index f799349b3e..24ed8253b4 100644
--- a/lib/librte_net/meson.build
+++ b/lib/librte_net/meson.build
@@ -15,7 +15,8 @@  headers = files('rte_ip.h',
 	'rte_net.h',
 	'rte_net_crc.h',
 	'rte_mpls.h',
-	'rte_higig.h')
+	'rte_higig.h',
+	'rte_ecpri.h')
 
 sources = files('rte_arp.c', 'rte_ether.c', 'rte_net.c', 'rte_net_crc.c')
 deps += ['mbuf']
diff --git a/lib/librte_net/rte_ecpri.h b/lib/librte_net/rte_ecpri.h
new file mode 100644
index 0000000000..60ba00d43f
--- /dev/null
+++ b/lib/librte_net/rte_ecpri.h
@@ -0,0 +1,161 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_ECPRI_H_
+#define _RTE_ECPRI_H_
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * eCPRI Protocol Revision 1.0, 1.1, 1.2, 2.0: 0001b
+ * Other values are reserved for future
+ */
+#define RTE_ECPRI_REV_UPTO_20		1
+
+/**
+ * eCPRI message types in specifications
+ * IWF* types will only be supported from rev.2
+ */
+#define RTE_ECPRI_MSG_TYPE_IQ_DATA	0
+#define RTE_ECPRI_MSG_TYPE_BIT_SEQ	1
+#define RTE_ECPRI_MSG_TYPE_RTC_CTRL	2
+#define RTE_ECPRI_MSG_TYPE_GEN_DATA	3
+#define RTE_ECPRI_MSG_TYPE_RM_ACC	4
+#define RTE_ECPRI_MSG_TYPE_DLY_MSR	5
+#define RTE_ECPRI_MSG_TYPE_RMT_RST	6
+#define RTE_ECPRI_MSG_TYPE_EVT_IND	7
+#define RTE_ECPRI_MSG_TYPE_IWF_UP	8
+#define RTE_ECPRI_MSG_TYPE_IWF_OPT	9
+#define RTE_ECPRI_MSG_TYPE_IWF_MAP	10
+#define RTE_ECPRI_MSG_TYPE_IWF_DCTRL	11
+
+/**
+ * eCPRI Common Header
+ */
+RTE_STD_C11
+struct rte_ecpri_common_hdr {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+	uint8_t c:1;			/**< Concatenation Indicator */
+	uint8_t res:3;			/**< Reserved */
+	uint8_t revision:4;		/**< Protocol Revision */
+	uint8_t type;			/**< Message Type */
+	uint16_t size;			/**< Payload Size */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	uint8_t revision:4;		/**< Protocol Revision */
+	uint8_t res:3;			/**< Reserved */
+	uint8_t c:1;			/**< Concatenation Indicator */
+	uint8_t type;			/**< Message Type */
+	uint16_t size;			/**< Payload Size */
+#endif
+} __rte_packed;
+
+/**
+ * eCPRI Message Header of Type #0: IQ Data
+ */
+struct rte_ecpri_msg_iq_data {
+	uint16_t pc_id;			/**< Physical channel ID */
+	uint16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #1: Bit Sequence
+ */
+struct rte_ecpri_msg_bit_seq {
+	uint16_t pc_id;			/**< Physical channel ID */
+	uint16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #2: Real-Time Control Data
+ */
+struct rte_ecpri_msg_rtc_ctrl {
+	uint16_t rtc_id;		/**< Real-Time Control Data ID */
+	uint16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #3: Generic Data Transfer
+ */
+struct rte_ecpri_msg_gen_data {
+	uint32_t pc_id;			/**< Physical channel ID */
+	uint32_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #4: Remote Memory Access
+ */
+RTE_STD_C11
+struct rte_ecpri_msg_rm_access {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+	uint8_t rma_id;			/**< Remote Memory Access ID */
+	uint8_t rr:4;			/**< Req/Resp */
+	uint8_t rw:4;			/**< Read/Write */
+	uint16_t ele_id;		/**< Element ID */
+	uint64_t length:16;		/**< number of bytes */
+	uint64_t addr: 48;		/**< 48-bits address */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	uint8_t rma_id;			/**< Remote Memory Access ID */
+	uint8_t rw:4;			/**< Read/Write */
+	uint8_t rr:4;			/**< Req/Resp */
+	uint16_t ele_id;		/**< Element ID */
+	uint64_t addr: 48;		/**< 48-bits address */
+	uint64_t length:16;		/**< number of bytes */
+#endif
+} __rte_packed;
+
+/**
+ * eCPRI Message Header of Type #5: One-Way Delay Measurement
+ */
+struct rte_ecpri_msg_delay_measure {
+	uint8_t msr_id;			/**< Measurement ID */
+	uint8_t act_type;		/**< Action Type */
+};
+
+/**
+ * eCPRI Message Header of Type #6: Remote Reset
+ */
+struct rte_ecpri_msg_remote_reset {
+	uint8_t msr_id;			/**< Measurement ID */
+	uint8_t act_type;		/**< Action Type */
+};
+
+/**
+ * eCPRI Message Header of Type #7: Event Indication
+ */
+struct rte_ecpri_msg_event_ind {
+	uint8_t evt_id;			/**< Event ID */
+	uint8_t evt_type;		/**< Event Type */
+	uint8_t seq;			/**< Sequence Number */
+	uint8_t number;			/**< Number of Faults/Notif */
+};
+
+/**
+ * eCPRI Message Header Format: Common Header + Message Types
+ */
+RTE_STD_C11
+struct rte_ecpri_msg_hdr {
+	struct rte_ecpri_common_hdr common;
+	union {
+		struct rte_ecpri_msg_iq_data type0;
+		struct rte_ecpri_msg_bit_seq type1;
+		struct rte_ecpri_msg_rtc_ctrl type2;
+		struct rte_ecpri_msg_bit_seq type3;
+		struct rte_ecpri_msg_rm_access type4;
+		struct rte_ecpri_msg_delay_measure type5;
+		struct rte_ecpri_msg_remote_reset type6;
+		struct rte_ecpri_msg_event_ind type7;
+		uint32_t dummy[3];
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_ECPRI_H_ */
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index 0ae4e75b6c..184a3f9b43 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -304,6 +304,7 @@  struct rte_vlan_hdr {
 #define RTE_ETHER_TYPE_LLDP 0x88CC /**< LLDP Protocol. */
 #define RTE_ETHER_TYPE_MPLS 0x8847 /**< MPLS ethertype. */
 #define RTE_ETHER_TYPE_MPLSM 0x8848 /**< MPLS multicast ethertype. */
+#define RTE_ETHER_TYPE_ECPRI 0xAEFE /**< eCPRI ethertype (.1Q supported). */
 
 /**
  * Extract VLAN tag information into mbuf