[v4,1/2] rte_flow: add eCPRI key fields to flow API
diff mbox series

Message ID 1594136219-133336-2-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/iol-mellanox-Performance success Performance Testing PASS
ci/iol-testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/checkpatch warning coding style issues

Commit Message

Bing Zhao July 7, 2020, 3:36 p.m. UTC
Add a new item "rte_flow_item_ecpri" in order to match eCRPI header.

eCPRI is a packet based protocol used in the fronthaul interface of
5G networks. Header format definition could be found in the
specification via the link below:
https://www.gigalight.com/downloads/standards/ecpri-specification.pdf

eCPRI message can be over Ethernet layer (.1Q supported also) or over
UDP layer. Message header formats are the same in these two variants.

Signed-off-by: Bing Zhao <bingz@mellanox.com>
Acked-by: Ori Kam <orika@mellanox.com>
---
 doc/guides/prog_guide/rte_flow.rst     |   8 ++
 doc/guides/rel_notes/release_20_08.rst |   5 +
 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             | 163 +++++++++++++++++++++++++++++++++
 lib/librte_net/rte_ether.h             |   1 +
 8 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_net/rte_ecpri.h

Comments

Akhil Goyal July 8, 2020, 6:49 p.m. UTC | #1
> +#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

Should we have a comment for reserved and vendor specific message types as well?

> +
> +/**
> + * eCPRI Common Header
> + */
> +RTE_STD_C11
> +struct rte_ecpri_common_hdr {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +	uint32_t size:16;		/**< Payload Size */
> +	uint32_t type:8;		/**< Message Type */
> +	uint32_t c:1;			/**< Concatenation Indicator */
> +	uint32_t res:3;			/**< Reserved */
> +	uint32_t revision:4;		/**< Protocol Revision */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +	uint32_t revision:4;		/**< Protocol Revision */
> +	uint32_t res:3;			/**< Reserved */
> +	uint32_t c:1;			/**< Concatenation Indicator */
> +	uint32_t type:8;		/**< Message Type */
> +	uint32_t size:16;		/**< Payload Size */
> +#endif
> +} __rte_packed;
> +
> +/**
> + * eCPRI Message Header of Type #0: IQ Data
> + */
> +struct rte_ecpri_msg_iq_data {
> +	rte_be16_t pc_id;		/**< Physical channel ID */
> +	rte_be16_t seq_id;		/**< Sequence ID */
> +};
> +
> +/**
> + * eCPRI Message Header of Type #1: Bit Sequence
> + */
> +struct rte_ecpri_msg_bit_seq {
> +	rte_be16_t pc_id;		/**< Physical channel ID */
> +	rte_be16_t seq_id;		/**< Sequence ID */
> +};
> +
> +/**
> + * eCPRI Message Header of Type #2: Real-Time Control Data
> + */
> +struct rte_ecpri_msg_rtc_ctrl {
> +	rte_be16_t rtc_id;		/**< Real-Time Control Data ID */
> +	rte_be16_t seq_id;		/**< Sequence ID */
> +};
> +
> +/**
> + * eCPRI Message Header of Type #3: Generic Data Transfer
> + */
> +struct rte_ecpri_msg_gen_data {
> +	rte_be32_t pc_id;		/**< Physical channel ID */
> +	rte_be32_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
> +	uint32_t ele_id:16;		/**< Element ID */
> +	uint32_t rr:4;			/**< Req/Resp */
> +	uint32_t rw:4;			/**< Read/Write */
> +	uint32_t rma_id:8;		/**< Remote Memory Access ID */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +	uint32_t rma_id:8;		/**< Remote Memory Access ID */
> +	uint32_t rw:4;			/**< Read/Write */
> +	uint32_t rr:4;			/**< Req/Resp */
> +	uint32_t ele_id:16;		/**< Element ID */
> +#endif
> +	rte_be16_t addr_m;		/**< 48-bits address (16 MSB) */
> +	rte_be32_t addr_l;		/**< 48-bits address (32 LSB) */
> +	rte_be16_t length;		/**< number of bytes */
> +} __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 */

Should we also add timestamp and compensation fields as well here?

> +};
> +
> +/**
> + * 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 */
> +};

I think it is a copy paste error.
It should have uint16_t reset_id and uint8_t reset_code_op

> +
> +/**
> + * 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 */
> +};
Should we also define enums for evt_type and other fields in this file.

> +
> +/**
> + * eCPRI Message Header Format: Common Header + Message Types
> + */
> +RTE_STD_C11
> +struct rte_ecpri_msg_hdr {
> +	union {
> +		struct rte_ecpri_common_hdr common;
> +		uint32_t dw0;
> +	};
> +	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];

Why 3 dummy? IWF messages are 4.

> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_ECPRI_H_ */
> diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> index 0ae4e75..184a3f9 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
> --
> 1.8.3.1
Bing Zhao July 9, 2020, 3:58 a.m. UTC | #2
> -----Original Message-----
> From: Akhil Goyal <akhil.goyal@nxp.com>
> Sent: Thursday, July 9, 2020 2:50 AM
> To: Bing Zhao <bingz@mellanox.com>; Ori Kam
> <orika@mellanox.com>; john.mcnamara@intel.com;
> marko.kovacevic@intel.com; Thomas Monjalon
> <thomas@monjalon.net>; ferruh.yigit@intel.com;
> arybchenko@solarflare.com; olivier.matz@6wind.com
> Cc: dev@dpdk.org; wenzhuo.lu@intel.com; beilei.xing@intel.com;
> bernard.iremonger@intel.com
> Subject: RE: [dpdk-dev] [PATCH v4 1/2] rte_flow: add eCPRI key fields
> to flow API
> 
> 
> > +#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
> 
> Should we have a comment for reserved and vendor specific message
> types as well?

Yes, thanks. We can have one line or two lines of comments to describe here.

> 
> > +
> > +/**
> > + * eCPRI Common Header
> > + */
> > +RTE_STD_C11
> > +struct rte_ecpri_common_hdr {
> > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > +	uint32_t size:16;		/**< Payload Size */
> > +	uint32_t type:8;		/**< Message Type */
> > +	uint32_t c:1;			/**< Concatenation Indicator
> */
> > +	uint32_t res:3;			/**< Reserved */
> > +	uint32_t revision:4;		/**< Protocol Revision */
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +	uint32_t revision:4;		/**< Protocol Revision */
> > +	uint32_t res:3;			/**< Reserved */
> > +	uint32_t c:1;			/**< Concatenation Indicator
> */
> > +	uint32_t type:8;		/**< Message Type */
> > +	uint32_t size:16;		/**< Payload Size */
> > +#endif
> > +} __rte_packed;
> > +
> > +/**
> > + * eCPRI Message Header of Type #0: IQ Data  */ struct
> > +rte_ecpri_msg_iq_data {
> > +	rte_be16_t pc_id;		/**< Physical channel ID */
> > +	rte_be16_t seq_id;		/**< Sequence ID */
> > +};
> > +
> > +/**
> > + * eCPRI Message Header of Type #1: Bit Sequence  */ struct
> > +rte_ecpri_msg_bit_seq {
> > +	rte_be16_t pc_id;		/**< Physical channel ID */
> > +	rte_be16_t seq_id;		/**< Sequence ID */
> > +};
> > +
> > +/**
> > + * eCPRI Message Header of Type #2: Real-Time Control Data  */
> struct
> > +rte_ecpri_msg_rtc_ctrl {
> > +	rte_be16_t rtc_id;		/**< Real-Time Control Data ID
> */
> > +	rte_be16_t seq_id;		/**< Sequence ID */
> > +};
> > +
> > +/**
> > + * eCPRI Message Header of Type #3: Generic Data Transfer  */
> struct
> > +rte_ecpri_msg_gen_data {
> > +	rte_be32_t pc_id;		/**< Physical channel ID */
> > +	rte_be32_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
> > +	uint32_t ele_id:16;		/**< Element ID */
> > +	uint32_t rr:4;			/**< Req/Resp */
> > +	uint32_t rw:4;			/**< Read/Write */
> > +	uint32_t rma_id:8;		/**< Remote Memory Access
> ID */
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +	uint32_t rma_id:8;		/**< Remote Memory Access
> ID */
> > +	uint32_t rw:4;			/**< Read/Write */
> > +	uint32_t rr:4;			/**< Req/Resp */
> > +	uint32_t ele_id:16;		/**< Element ID */
> > +#endif
> > +	rte_be16_t addr_m;		/**< 48-bits address (16 MSB)
> */
> > +	rte_be32_t addr_l;		/**< 48-bits address (32 LSB)
> */
> > +	rte_be16_t length;		/**< number of bytes */
> > +} __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 */
> 
> Should we also add timestamp and compensation fields as well here?

OK, we can add it. I am not sure if there is a strong requirement for these fields.
This file is planned to define the headers of an eCPRI message. From the specification,
only the common header is named with "header". And the first bytes in the message
body will be recognized with different formats based on the type, as we know.
Regarding some message types, the first several bytes could be considered as the
"sub header" of the message, then followed by user data bytes. The length of the user
specific data is variable as well as the content.
In this case, we can that the timestamp and compensation are the user specific
data, and in each packet, it will have a different value.

> 
> > +};
> > +
> > +/**
> > + * 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 */
> > +};
> 
> I think it is a copy paste error.
> It should have uint16_t reset_id and uint8_t reset_code_op

Nice catch, thanks a lot.

> 
> > +
> > +/**
> > + * 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 */
> > +};
> Should we also define enums for evt_type and other fields in this file.

For event indication type, we could. We can use #define instead of enum since this
should be fixed value and there is no change in the next releases of the spec.
Also, other fields are not exposed in the "header" now, so to my understanding, no
need to cover them at this stage.

> 
> > +
> > +/**
> > + * eCPRI Message Header Format: Common Header + Message
> Types  */
> > +RTE_STD_C11
> > +struct rte_ecpri_msg_hdr {
> > +	union {
> > +		struct rte_ecpri_common_hdr common;
> > +		uint32_t dw0;
> > +	};
> > +	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];
> 
> Why 3 dummy? IWF messages are 4.

This is a union of the message payload body but not the "place holders" for
IWF messages. IWF messages headers are a little bit complex and not defined
in revision 1.x IIRC. This filed as well as the "dw0" is only SW level concept to
simplify the work in the driver and make compiler happy without any cost.
Some critical flags of a compiler may complain when forcing casting the structure
starts from a bit-field to a u32. And when the DW 4 bytes needs to be dumped or
checked, and when doing endianness swap, this would be easier. Maybe this field
should have a better name 😊
3 DWs for the payload sub header part is enough now. If we add the timestamp and
comp part, then we should enlarge this.

> 
> > +	};
> > +};
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_ECPRI_H_ */
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index 0ae4e75..184a3f9 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
> > --
> > 1.8.3.1

Patch
diff mbox series

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index d5dd18c..669d519 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/doc/guides/rel_notes/release_20_08.rst b/doc/guides/rel_notes/release_20_08.rst
index 5cbc4ce..2140891 100644
--- a/doc/guides/rel_notes/release_20_08.rst
+++ b/doc/guides/rel_notes/release_20_08.rst
@@ -98,6 +98,11 @@  New Features
   which are used to access packet data in a safe manner. Currently JIT support
   for these instructions is implemented for x86 only.
 
+* **Added eCPRI protocol support in rte_flow.**
+
+  The ``ECPRI`` item have been added to support eCPRI packet offloading for
+  5G network.
+
 * **Added flow performance test application.**
 
   Added new application to test ``rte_flow`` performance, including:
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 1685be5..f8fdd68 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -95,6 +95,7 @@  struct rte_flow_desc_data {
 	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 b0e4199..8a90226 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,15 @@  enum rte_flow_item_type {
 	 */
 	RTE_FLOW_ITEM_TYPE_PFCP,
 
+	/**
+	 * Matches eCPRI Header.
+	 *
+	 * Configure flow for eCPRI over ETH or UDP packets.
+	 *
+	 * See struct rte_flow_item_ecpri.
+	 */
+	RTE_FLOW_ITEM_TYPE_ECPRI,
+
 };
 
 /**
@@ -1547,6 +1557,27 @@  struct rte_flow_item_pfcp {
 #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 = {
+		.dw0 = 0x0,
+	},
+};
+#endif
+
+/**
  * Matching pattern item definition.
  *
  * A pattern is formed by stacking items starting from the lowest protocol
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index aa1d6fe..9830e77 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 f799349..24ed825 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 0000000..31974b2
--- /dev/null
+++ b/lib/librte_net/rte_ecpri.h
@@ -0,0 +1,163 @@ 
+/* 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
+	uint32_t size:16;		/**< Payload Size */
+	uint32_t type:8;		/**< Message Type */
+	uint32_t c:1;			/**< Concatenation Indicator */
+	uint32_t res:3;			/**< Reserved */
+	uint32_t revision:4;		/**< Protocol Revision */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	uint32_t revision:4;		/**< Protocol Revision */
+	uint32_t res:3;			/**< Reserved */
+	uint32_t c:1;			/**< Concatenation Indicator */
+	uint32_t type:8;		/**< Message Type */
+	uint32_t size:16;		/**< Payload Size */
+#endif
+} __rte_packed;
+
+/**
+ * eCPRI Message Header of Type #0: IQ Data
+ */
+struct rte_ecpri_msg_iq_data {
+	rte_be16_t pc_id;		/**< Physical channel ID */
+	rte_be16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #1: Bit Sequence
+ */
+struct rte_ecpri_msg_bit_seq {
+	rte_be16_t pc_id;		/**< Physical channel ID */
+	rte_be16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #2: Real-Time Control Data
+ */
+struct rte_ecpri_msg_rtc_ctrl {
+	rte_be16_t rtc_id;		/**< Real-Time Control Data ID */
+	rte_be16_t seq_id;		/**< Sequence ID */
+};
+
+/**
+ * eCPRI Message Header of Type #3: Generic Data Transfer
+ */
+struct rte_ecpri_msg_gen_data {
+	rte_be32_t pc_id;		/**< Physical channel ID */
+	rte_be32_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
+	uint32_t ele_id:16;		/**< Element ID */
+	uint32_t rr:4;			/**< Req/Resp */
+	uint32_t rw:4;			/**< Read/Write */
+	uint32_t rma_id:8;		/**< Remote Memory Access ID */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	uint32_t rma_id:8;		/**< Remote Memory Access ID */
+	uint32_t rw:4;			/**< Read/Write */
+	uint32_t rr:4;			/**< Req/Resp */
+	uint32_t ele_id:16;		/**< Element ID */
+#endif
+	rte_be16_t addr_m;		/**< 48-bits address (16 MSB) */
+	rte_be32_t addr_l;		/**< 48-bits address (32 LSB) */
+	rte_be16_t length;		/**< number of bytes */
+} __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 {
+	union {
+		struct rte_ecpri_common_hdr common;
+		uint32_t dw0;
+	};
+	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 0ae4e75..184a3f9 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