[1/3] net: add MACsec header

Message ID 20220814184620.512343-2-gakhil@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series security: support MACsec |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Akhil Goyal Aug. 14, 2022, 6:46 p.m. UTC
  Added MACsec protocol header to be used for supporting
MACsec protocol offload in hardware or directly in the application.

Signed-off-by: Akhil Goyal <gakhil@marvell.com>
---
 doc/api/doxy-api-index.md |  3 ++-
 lib/net/meson.build       |  1 +
 lib/net/rte_macsec.h      | 56 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 lib/net/rte_macsec.h
  

Comments

Akhil Goyal Sept. 22, 2022, 3:29 p.m. UTC | #1
Hi Olivier,

Could you please review this patch? 
Apologies. I missed to add you earlier.

Regards,
Akhil

> Subject: [PATCH 1/3] net: add MACsec header
> 
> Added MACsec protocol header to be used for supporting
> MACsec protocol offload in hardware or directly in the application.
> 
> Signed-off-by: Akhil Goyal <gakhil@marvell.com>
> ---
>  doc/api/doxy-api-index.md |  3 ++-
>  lib/net/meson.build       |  1 +
>  lib/net/rte_macsec.h      | 56 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 59 insertions(+), 1 deletion(-)
>  create mode 100644 lib/net/rte_macsec.h
> 
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 186a258be4..99e49340d3 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -126,7 +126,8 @@ The public API headers are grouped by topics:
>    [Geneve](@ref rte_geneve.h),
>    [eCPRI](@ref rte_ecpri.h),
>    [L2TPv2](@ref rte_l2tpv2.h),
> -  [PPP](@ref rte_ppp.h)
> +  [PPP](@ref rte_ppp.h),
> +  [MACsec](@ref rte_macsec.h)
> 
>  - **QoS**:
>    [metering](@ref rte_meter.h),
> diff --git a/lib/net/meson.build b/lib/net/meson.build
> index e899846578..3e63abaca8 100644
> --- a/lib/net/meson.build
> +++ b/lib/net/meson.build
> @@ -21,6 +21,7 @@ headers = files(
>          'rte_geneve.h',
>          'rte_l2tpv2.h',
>          'rte_ppp.h',
> +        'rte_macsec.h',
>  )
> 
>  sources = files(
> diff --git a/lib/net/rte_macsec.h b/lib/net/rte_macsec.h
> new file mode 100644
> index 0000000000..f1b59253f6
> --- /dev/null
> +++ b/lib/net/rte_macsec.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2022 Marvell.
> + */
> +
> +#ifndef _RTE_MACSEC_H_
> +#define _RTE_MACSEC_H_
> +
> +/**
> + * @file
> + *
> + * MACsec-related defines
> + */
> +
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +
> +/* SecTAG length = macsec ether header without the optional SCI */
> +#define RTE_MACSEC_TAG_LEN 6
> +#define RTE_MACSEC_SCI_LEN 8
> +
> +#define RTE_MACSEC_TCI_VERSION	0x80 /**< Version mask for MACsec.
> Should be 0. */
> +#define RTE_MACSEC_TCI_ES	0x40 /**< End station - SCI is not valid */
> +#define RTE_MACSEC_TCI_SC	0x20 /**< SCI present */
> +#define RTE_MACSEC_TCI_SCB	0x10 /**< Secure channel support EPON single
> copy broadcast */
> +#define RTE_MACSEC_TCI_E	0x08 /**< User data is encrypted */
> +#define RTE_MACSEC_TCI_C	0x04 /**< User data was changed (because of
> encryption) */
> +#define RTE_MACSEC_AN_MASK	0x03 /**< Association number mask in
> tci_an */
> +#define RTE_MACSEC_NUM_AN	4    /**< 2 bits for the association
> number */
> +#define RTE_MACSEC_SALT_LEN	12   /**< Salt length for MACsec SA */
> +
> +/**
> + * MACsec Header
> + */
> +struct rte_macsec_hdr {
> +	/* SecTAG */
> +	uint8_t  tci_an;	/**< Tag control information and Association number
> of SC */
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +	uint8_t short_length : 6; /**< Short Length */
> +	uint8_t unused : 2;
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +	uint8_t unused : 2;
> +	uint8_t short_length : 6;
> +#endif
> +	rte_be32_t packet_number; /**< Packet number to support replay
> protection */
> +	uint8_t secure_channel_id[8]; /* optional */
> +} __rte_packed;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* RTE_MACSEC_H_ */
> --
> 2.25.1
  
Olivier Matz Sept. 26, 2022, 12:51 p.m. UTC | #2
Hi Akhil,

Few comments below.

On Mon, Aug 15, 2022 at 12:16:18AM +0530, Akhil Goyal wrote:
> Added MACsec protocol header to be used for supporting
> MACsec protocol offload in hardware or directly in the application.
> 
> Signed-off-by: Akhil Goyal <gakhil@marvell.com>
> ---
>  doc/api/doxy-api-index.md |  3 ++-
>  lib/net/meson.build       |  1 +
>  lib/net/rte_macsec.h      | 56 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 59 insertions(+), 1 deletion(-)
>  create mode 100644 lib/net/rte_macsec.h
> 
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 186a258be4..99e49340d3 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -126,7 +126,8 @@ The public API headers are grouped by topics:
>    [Geneve](@ref rte_geneve.h),
>    [eCPRI](@ref rte_ecpri.h),
>    [L2TPv2](@ref rte_l2tpv2.h),
> -  [PPP](@ref rte_ppp.h)
> +  [PPP](@ref rte_ppp.h),
> +  [MACsec](@ref rte_macsec.h)
>  
>  - **QoS**:
>    [metering](@ref rte_meter.h),
> diff --git a/lib/net/meson.build b/lib/net/meson.build
> index e899846578..3e63abaca8 100644
> --- a/lib/net/meson.build
> +++ b/lib/net/meson.build
> @@ -21,6 +21,7 @@ headers = files(
>          'rte_geneve.h',
>          'rte_l2tpv2.h',
>          'rte_ppp.h',
> +        'rte_macsec.h',
>  )
>  
>  sources = files(
> diff --git a/lib/net/rte_macsec.h b/lib/net/rte_macsec.h
> new file mode 100644
> index 0000000000..f1b59253f6
> --- /dev/null
> +++ b/lib/net/rte_macsec.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2022 Marvell.
> + */
> +
> +#ifndef _RTE_MACSEC_H_
> +#define _RTE_MACSEC_H_
> +
> +/**
> + * @file
> + *
> + * MACsec-related defines
> + */
> +
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +
> +/* SecTAG length = macsec ether header without the optional SCI */
> +#define RTE_MACSEC_TAG_LEN 6

Use a doxygen-like comment.

Is this define required? In my understanding, it is the same as
sizeof(struct rte_macsec_hdr).

> +#define RTE_MACSEC_SCI_LEN 8

Missing doxygen doc.

> +
> +#define RTE_MACSEC_TCI_VERSION	0x80 /**< Version mask for MACsec. Should be 0. */
> +#define RTE_MACSEC_TCI_ES	0x40 /**< End station - SCI is not valid */
> +#define RTE_MACSEC_TCI_SC	0x20 /**< SCI present */
> +#define RTE_MACSEC_TCI_SCB	0x10 /**< Secure channel support EPON single copy broadcast */

support -> supports?

> +#define RTE_MACSEC_TCI_E	0x08 /**< User data is encrypted */
> +#define RTE_MACSEC_TCI_C	0x04 /**< User data was changed (because of encryption) */


In [1], I can read the following, which is not similar:

E and C bits used to determine if packet is encrypted
• E, C = 1, 1 – Encrypted
• E, C = 0, 0 – Authenticated-Only

Is there any reference paper for macsec header?

[1] https://www.marvell.com/content/dam/marvell/en/public-collateral/automotive-solutions/marvell-macsec-security-in-ethernet-based-vehicle-white-paper.pdf


> +#define RTE_MACSEC_AN_MASK	0x03 /**< Association number mask in tci_an */

nit: all comments should end with a dot.


>
> +#define RTE_MACSEC_NUM_AN	4    /**< 2 bits for the association number */

I don't get how this defined is used. Can the comment be clarified?

> +#define RTE_MACSEC_SALT_LEN	12   /**< Salt length for MACsec SA */

Same here.

> +
> +/**
> + * MACsec Header
> + */
> +struct rte_macsec_hdr {
> +	/* SecTAG */

Is the SecTAG comment required? Or maybe it should be moved
above the struct?

> +	uint8_t  tci_an;	/**< Tag control information and Association number of SC */

nit: duplicated spaces after uint8_t

Can we use a bitfield here for tci and an, like you did for short_length?

Like this:

	uint8_t tci:6;
	uint8_t an:2;

Or:

	uint8_t tci_version:1;
	uint8_t tci_es:1;
	uint8_t tci_sc:1;
	uint8_t tci_scb:1;
	uint8_t tci_e:1;
	uint8_t tci_c:1;
	uint8_t an:2;

I think the 2nd one is easier to use.

> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +	uint8_t short_length : 6; /**< Short Length */
> +	uint8_t unused : 2;

nit: no spaces around ':'

> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +	uint8_t unused : 2;
> +	uint8_t short_length : 6;
> +#endif
> +	rte_be32_t packet_number; /**< Packet number to support replay protection */
> +	uint8_t secure_channel_id[8]; /* optional */

8 -> RTE_MACSEC_SCI_LEN ?

I think it would be more convenient to have another struct
for the secure_channel_id.

For instance, this pseudo code:

	struct struct rte_macsec_hdr *hdr = NULL;
	struct struct rte_macsec_sci_hdr *hdr_sci = NULL;

	if (seg_len(mbuf) < sizeof(*hdr))
		return -1;
	if (hdr.tci_sc) {
		if (seg_len(mbuf) < sizeof(*hdr_sci))
			return -1;
		hdr_sci = hdr;
	}

With only one struct, it is difficult to properly do the length check.


> +} __rte_packed;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* RTE_MACSEC_H_ */
> -- 
> 2.25.1
> 

Thanks,
Olivier
  
Akhil Goyal Sept. 26, 2022, 1:41 p.m. UTC | #3
Hi Olivier,

Thanks for your review. I will fix the issues in next version.

> Hi Akhil,
> 
> Few comments below.
> 
> On Mon, Aug 15, 2022 at 12:16:18AM +0530, Akhil Goyal wrote:
> > Added MACsec protocol header to be used for supporting
> > MACsec protocol offload in hardware or directly in the application.
> >
> > Signed-off-by: Akhil Goyal <gakhil@marvell.com>
> > ---
> >  doc/api/doxy-api-index.md |  3 ++-
> >  lib/net/meson.build       |  1 +
> >  lib/net/rte_macsec.h      | 56 +++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 59 insertions(+), 1 deletion(-)
> >  create mode 100644 lib/net/rte_macsec.h
> >
> > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> > index 186a258be4..99e49340d3 100644
> > --- a/doc/api/doxy-api-index.md
> > +++ b/doc/api/doxy-api-index.md
> > @@ -126,7 +126,8 @@ The public API headers are grouped by topics:
> >    [Geneve](@ref rte_geneve.h),
> >    [eCPRI](@ref rte_ecpri.h),
> >    [L2TPv2](@ref rte_l2tpv2.h),
> > -  [PPP](@ref rte_ppp.h)
> > +  [PPP](@ref rte_ppp.h),
> > +  [MACsec](@ref rte_macsec.h)
> >
> >  - **QoS**:
> >    [metering](@ref rte_meter.h),
> > diff --git a/lib/net/meson.build b/lib/net/meson.build
> > index e899846578..3e63abaca8 100644
> > --- a/lib/net/meson.build
> > +++ b/lib/net/meson.build
> > @@ -21,6 +21,7 @@ headers = files(
> >          'rte_geneve.h',
> >          'rte_l2tpv2.h',
> >          'rte_ppp.h',
> > +        'rte_macsec.h',
> >  )
> >
> >  sources = files(
> > diff --git a/lib/net/rte_macsec.h b/lib/net/rte_macsec.h
> > new file mode 100644
> > index 0000000000..f1b59253f6
> > --- /dev/null
> > +++ b/lib/net/rte_macsec.h
> > @@ -0,0 +1,56 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright(C) 2022 Marvell.
> > + */
> > +
> > +#ifndef _RTE_MACSEC_H_
> > +#define _RTE_MACSEC_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * MACsec-related defines
> > + */
> > +
> > +#include <rte_byteorder.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +
> > +/* SecTAG length = macsec ether header without the optional SCI */
> > +#define RTE_MACSEC_TAG_LEN 6
> 
> Use a doxygen-like comment.
> 
> Is this define required? In my understanding, it is the same as
> sizeof(struct rte_macsec_hdr).
> 
> > +#define RTE_MACSEC_SCI_LEN 8
> 
> Missing doxygen doc.
> 
> > +
> > +#define RTE_MACSEC_TCI_VERSION	0x80 /**< Version mask for MACsec.
> Should be 0. */
> > +#define RTE_MACSEC_TCI_ES	0x40 /**< End station - SCI is not valid
> */
> > +#define RTE_MACSEC_TCI_SC	0x20 /**< SCI present */
> > +#define RTE_MACSEC_TCI_SCB	0x10 /**< Secure channel support
> EPON single copy broadcast */
> 
> support -> supports?
> 
> > +#define RTE_MACSEC_TCI_E	0x08 /**< User data is encrypted */
> > +#define RTE_MACSEC_TCI_C	0x04 /**< User data was changed (because of
> encryption) */
> 
> 
> In [1], I can read the following, which is not similar:
> 
> E and C bits used to determine if packet is encrypted
> • E, C = 1, 1 – Encrypted
> • E, C = 0, 0 – Authenticated-Only
> 
> Is there any reference paper for macsec header?
> 
> [1] https://www.marvell.com/content/dam/marvell/en/public-
> collateral/automotive-solutions/marvell-macsec-security-in-ethernet-based-
> vehicle-white-paper.pdf
> 
> 
> > +#define RTE_MACSEC_AN_MASK	0x03 /**< Association number mask in
> tci_an */
> 
> nit: all comments should end with a dot.
> 
> 
> >
> > +#define RTE_MACSEC_NUM_AN	4    /**< 2 bits for the association
> number */
> 
> I don't get how this defined is used. Can the comment be clarified?
> 
> > +#define RTE_MACSEC_SALT_LEN	12   /**< Salt length for MACsec SA */
> 
> Same here.
> 
> > +
> > +/**
> > + * MACsec Header
> > + */
> > +struct rte_macsec_hdr {
> > +	/* SecTAG */
> 
> Is the SecTAG comment required? Or maybe it should be moved
> above the struct?
> 
> > +	uint8_t  tci_an;	/**< Tag control information and Association number
> of SC */
> 
> nit: duplicated spaces after uint8_t
> 
> Can we use a bitfield here for tci and an, like you did for short_length?
> 
> Like this:
> 
> 	uint8_t tci:6;
> 	uint8_t an:2;
> 
> Or:
> 
> 	uint8_t tci_version:1;
> 	uint8_t tci_es:1;
> 	uint8_t tci_sc:1;
> 	uint8_t tci_scb:1;
> 	uint8_t tci_e:1;
> 	uint8_t tci_c:1;
> 	uint8_t an:2;
> 
> I think the 2nd one is easier to use.
> 
> > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > +	uint8_t short_length : 6; /**< Short Length */
> > +	uint8_t unused : 2;
> 
> nit: no spaces around ':'
> 
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +	uint8_t unused : 2;
> > +	uint8_t short_length : 6;
> > +#endif
> > +	rte_be32_t packet_number; /**< Packet number to support replay
> protection */
> > +	uint8_t secure_channel_id[8]; /* optional */
> 
> 8 -> RTE_MACSEC_SCI_LEN ?
> 
> I think it would be more convenient to have another struct
> for the secure_channel_id.
> 
> For instance, this pseudo code:
> 
> 	struct struct rte_macsec_hdr *hdr = NULL;
> 	struct struct rte_macsec_sci_hdr *hdr_sci = NULL;
> 
> 	if (seg_len(mbuf) < sizeof(*hdr))
> 		return -1;
> 	if (hdr.tci_sc) {
> 		if (seg_len(mbuf) < sizeof(*hdr_sci))
> 			return -1;
> 		hdr_sci = hdr;
> 	}
> 
> With only one struct, it is difficult to properly do the length check.
> 
> 
> > +} __rte_packed;
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* RTE_MACSEC_H_ */
> > --
> > 2.25.1
> >
> 
> Thanks,
> Olivier
  
Akhil Goyal Sept. 27, 2022, 8:36 a.m. UTC | #4
Hi Olivier,

> > +#define RTE_MACSEC_TCI_E	0x08 /**< User data is encrypted */
> > +#define RTE_MACSEC_TCI_C	0x04 /**< User data was changed (because of
> encryption) */
> 
E bit means the user data is encrypted if set. Above defines are mask to each of the fields in tci_an.
I would add a comment that these are masks to each of the fields.

C bit means the user data is changed (because of encryption)

> 
> In [1], I can read the following, which is not similar:
> 
> E and C bits used to determine if packet is encrypted
> • E, C = 1, 1 – Encrypted
> • E, C = 0, 0 – Authenticated-Only
> 
> Is there any reference paper for macsec header?

The reference is IEEE802.1AE standard.
https://ieeexplore.ieee.org/document/8585421

> 
> [1] https://www.marvell.com/content/dam/marvell/en/public-
> collateral/automotive-solutions/marvell-macsec-security-in-ethernet-based-
> vehicle-white-paper.pdf
> 
> 


> >
> > +#define RTE_MACSEC_NUM_AN	4    /**< 2 bits for the association
> number */
> 
> I don't get how this defined is used. Can the comment be clarified?

In case of MACsec we can have 4 different SAs for each of the secure channel
Based on the AN field.
RTE_MACSEC_NUM_AN is basically added to make an upper limit to the array of SAs.
I will re-write the comment as
#define RTE_MACSEC_NUM_AN	4    /**< Max number of association numbers. */

Or shall I move it to rte_security?


> 
> > +#define RTE_MACSEC_SALT_LEN	12   /**< Salt length for MACsec SA */
For MACsec SA configuration, Salt is used which has a fixed size of 12 bytes.
Do you want me to move it to rte_security?

> 
> Same here.
> 
> > +
> > +/**
> > + * MACsec Header
> > + */
> > +struct rte_macsec_hdr {
> > +	/* SecTAG */
> 
> Is the SecTAG comment required? Or maybe it should be moved
> above the struct?
> 
> > +	uint8_t  tci_an;	/**< Tag control information and Association number
> of SC */
> 
> nit: duplicated spaces after uint8_t
> 
> Can we use a bitfield here for tci and an, like you did for short_length?

Would it be really necessary to split it to bitfields.
Can we not use it like vtc_flow in rte_ipv6_hdr?

> 
> Like this:
> 
> 	uint8_t tci:6;
> 	uint8_t an:2;
> 
> Or:
> 
> 	uint8_t tci_version:1;
> 	uint8_t tci_es:1;
> 	uint8_t tci_sc:1;
> 	uint8_t tci_scb:1;
> 	uint8_t tci_e:1;
> 	uint8_t tci_c:1;
> 	uint8_t an:2;
> 
> I think the 2nd one is easier to use.
> 
> > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > +	uint8_t short_length : 6; /**< Short Length */
> > +	uint8_t unused : 2;
> 
> nit: no spaces around ':'
> 
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +	uint8_t unused : 2;
> > +	uint8_t short_length : 6;
> > +#endif
> > +	rte_be32_t packet_number; /**< Packet number to support replay
> protection */
> > +	uint8_t secure_channel_id[8]; /* optional */
> 
> 8 -> RTE_MACSEC_SCI_LEN ?
> 
> I think it would be more convenient to have another struct
> for the secure_channel_id.

Ok Can we use it like this

struct rte_macsec_sci_hdr {
        uint8_t sci[RTE_MACSEC_SCI_LEN]; /**< Optional secure channel id. */
} __rte_packed;

struct rte_macsec_hdr {
        uint8_t tci_an; /**< Tag control information and Association number of SC. */
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
        uint8_t short_length:6; /**< Short Length. */
        uint8_t unused:2;
#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
        uint8_t unused:2;
        uint8_t short_length:6; /**< Short Length. */
#endif
        rte_be32_t packet_number; /**< Packet number to support replay protection. */
        union {
                uint8_t payload[0];
                struct rte_macsec_sci_hdr sci[0];
        };
} __rte_packed;
  

Patch

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 186a258be4..99e49340d3 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -126,7 +126,8 @@  The public API headers are grouped by topics:
   [Geneve](@ref rte_geneve.h),
   [eCPRI](@ref rte_ecpri.h),
   [L2TPv2](@ref rte_l2tpv2.h),
-  [PPP](@ref rte_ppp.h)
+  [PPP](@ref rte_ppp.h),
+  [MACsec](@ref rte_macsec.h)
 
 - **QoS**:
   [metering](@ref rte_meter.h),
diff --git a/lib/net/meson.build b/lib/net/meson.build
index e899846578..3e63abaca8 100644
--- a/lib/net/meson.build
+++ b/lib/net/meson.build
@@ -21,6 +21,7 @@  headers = files(
         'rte_geneve.h',
         'rte_l2tpv2.h',
         'rte_ppp.h',
+        'rte_macsec.h',
 )
 
 sources = files(
diff --git a/lib/net/rte_macsec.h b/lib/net/rte_macsec.h
new file mode 100644
index 0000000000..f1b59253f6
--- /dev/null
+++ b/lib/net/rte_macsec.h
@@ -0,0 +1,56 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2022 Marvell.
+ */
+
+#ifndef _RTE_MACSEC_H_
+#define _RTE_MACSEC_H_
+
+/**
+ * @file
+ *
+ * MACsec-related defines
+ */
+
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* SecTAG length = macsec ether header without the optional SCI */
+#define RTE_MACSEC_TAG_LEN 6
+#define RTE_MACSEC_SCI_LEN 8
+
+#define RTE_MACSEC_TCI_VERSION	0x80 /**< Version mask for MACsec. Should be 0. */
+#define RTE_MACSEC_TCI_ES	0x40 /**< End station - SCI is not valid */
+#define RTE_MACSEC_TCI_SC	0x20 /**< SCI present */
+#define RTE_MACSEC_TCI_SCB	0x10 /**< Secure channel support EPON single copy broadcast */
+#define RTE_MACSEC_TCI_E	0x08 /**< User data is encrypted */
+#define RTE_MACSEC_TCI_C	0x04 /**< User data was changed (because of encryption) */
+#define RTE_MACSEC_AN_MASK	0x03 /**< Association number mask in tci_an */
+#define RTE_MACSEC_NUM_AN	4    /**< 2 bits for the association number */
+#define RTE_MACSEC_SALT_LEN	12   /**< Salt length for MACsec SA */
+
+/**
+ * MACsec Header
+ */
+struct rte_macsec_hdr {
+	/* SecTAG */
+	uint8_t  tci_an;	/**< Tag control information and Association number of SC */
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+	uint8_t short_length : 6; /**< Short Length */
+	uint8_t unused : 2;
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+	uint8_t unused : 2;
+	uint8_t short_length : 6;
+#endif
+	rte_be32_t packet_number; /**< Packet number to support replay protection */
+	uint8_t secure_channel_id[8]; /* optional */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_MACSEC_H_ */