From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 26AD9A046B for ; Thu, 27 Jun 2019 00:15:19 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 393581E20; Thu, 27 Jun 2019 00:15:18 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 70BFADED for ; Thu, 27 Jun 2019 00:15:16 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Jun 2019 15:15:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,421,1557212400"; d="scan'208";a="152808302" Received: from irsmsx153.ger.corp.intel.com ([163.33.192.75]) by orsmga007.jf.intel.com with ESMTP; 26 Jun 2019 15:15:14 -0700 Received: from irsmsx104.ger.corp.intel.com ([169.254.5.143]) by IRSMSX153.ger.corp.intel.com ([169.254.9.60]) with mapi id 14.03.0439.000; Wed, 26 Jun 2019 23:15:13 +0100 From: "Ananyev, Konstantin" To: "Zhang, Roy Fan" , "dev@dpdk.org" CC: "akhil.goyal@nxp.com" , "Kovacevic, Marko" Thread-Topic: [PATCH v3 1/2] lib/ipsec: add support for header construction Thread-Index: AQHVLDFkAxyLpc5Ue0Sup9JEtn6/FqauJXOA Date: Wed, 26 Jun 2019 22:15:12 +0000 Message-ID: <2601191342CEEE43887BDE71AB97725801689E583A@IRSMSX104.ger.corp.intel.com> References: <20190625134321.71595-1-roy.fan.zhang@intel.com> <20190626150509.17442-1-roy.fan.zhang@intel.com> <20190626150509.17442-2-roy.fan.zhang@intel.com> In-Reply-To: <20190626150509.17442-2-roy.fan.zhang@intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiODdkOWNjZTUtN2U4ZC00ZTFmLWE3MDktZTVmMTFhMWE1NTIxIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiYjNOZ05vbkZkelRxUUlJWmZ3YmRERUozalJ2dUIzOTdaV0FnZFN6WStybmJ5eWFCSXViMTFpNUZNYlZHNzUwbCJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [163.33.239.182] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v3 1/2] lib/ipsec: add support for header construction X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi Fan, > -----Original Message----- > From: Zhang, Roy Fan > Sent: Wednesday, June 26, 2019 4:05 PM > To: dev@dpdk.org > Cc: akhil.goyal@nxp.com; Ananyev, Konstantin ; Zhang, Roy Fan ; Kovacevic, > Marko > Subject: [PATCH v3 1/2] lib/ipsec: add support for header construction >=20 > Add support for RFC 4301(5.1.2) to update of > Type of service field and Traffic class field > bits inside ipv4/ipv6 packets for outbound cases > and inbound cases which deals with the update of > the DSCP/ENC bits inside each of the fields. >=20 This series cause all tunnel _esn_ testcases for non-AEAD algorithms (tun_aescbc_sha1_esn, tun_3descbc_sha1_esn, ...) to fail - ping can't go through. Both ipv4 and ipv6. Could you have a look? Thanks Konstantin=20 > Signed-off-by: Marko Kovacevic > Signed-off-by: Fan Zhang > --- > lib/librte_ipsec/esp_inb.c | 16 +++- > lib/librte_ipsec/esp_outb.c | 3 +- > lib/librte_ipsec/iph.h | 148 +++++++++++++++++++++++++++++++= ++++-- > lib/librte_ipsec/rte_ipsec_sa.h | 25 +++++++ > lib/librte_ipsec/sa.c | 17 +++++ > lib/librte_ipsec/sa.h | 2 + > lib/librte_net/rte_ip.h | 11 +++ > lib/librte_security/rte_security.h | 9 +++ > 8 files changed, 221 insertions(+), 10 deletions(-) >=20 > diff --git a/lib/librte_ipsec/esp_inb.c b/lib/librte_ipsec/esp_inb.c > index fb10b7085..3e1894e13 100644 > --- a/lib/librte_ipsec/esp_inb.c > +++ b/lib/librte_ipsec/esp_inb.c > @@ -464,13 +464,15 @@ tun_process(const struct rte_ipsec_sa *sa, struct r= te_mbuf *mb[], > uint32_t hl[num], to[num]; > struct esp_tail espt[num]; > struct rte_mbuf *ml[num]; > + const uint32_t cofs =3D sa->ctp.cipher.offset; > + void *inner_h; > + const void *outter_h; >=20 > /* > * remove icv, esp trailer and high-order > * 32 bits of esn from packet length > */ > const uint32_t tlen =3D sa->icv_len + sizeof(espt[0]) + sqh_len; > - const uint32_t cofs =3D sa->ctp.cipher.offset; >=20 > /* > * to minimize stalls due to load latency, > @@ -489,9 +491,17 @@ tun_process(const struct rte_ipsec_sa *sa, struct rt= e_mbuf *mb[], > if (tun_process_check(mb[i], &ml[i], &to[i], espt[i], adj, tl, > sa->proto) =3D=3D 0) { >=20 > + outter_h =3D rte_pktmbuf_mtod_offset(mb[i], uint8_t *, > + mb[i]->l2_len); > + > /* modify packet's layout */ > - tun_process_step2(mb[i], ml[i], hl[i], adj, to[i], > - tl, sqn + k); > + > + inner_h =3D tun_process_step2(mb[i], ml[i], hl[i], adj, > + to[i], tl, sqn + k); > + > + if ((sa->type & TUN_HDR_MSK) !=3D 0) > + update_inb_tun_l3_hdr(sa, inner_h, outter_h); > + > /* update mbuf's metadata */ > tun_process_step3(mb[i], sa->tx_offload.msk, > sa->tx_offload.val); > diff --git a/lib/librte_ipsec/esp_outb.c b/lib/librte_ipsec/esp_outb.c > index 8c6db3553..0c72a9d5f 100644 > --- a/lib/librte_ipsec/esp_outb.c > +++ b/lib/librte_ipsec/esp_outb.c > @@ -152,7 +152,8 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be6= 4_t sqc, > rte_memcpy(ph, sa->hdr, sa->hdr_len); >=20 > /* update original and new ip header fields */ > - update_tun_l3hdr(sa, ph + sa->hdr_l3_off, mb->pkt_len - sqh_len, > + > + update_outb_tun_l3hdr(sa, ph + sa->hdr_l3_off, ph + hlen, mb->pkt_len, > sa->hdr_l3_off, sqn_low16(sqc)); >=20 > /* update spi, seqn and iv */ > diff --git a/lib/librte_ipsec/iph.h b/lib/librte_ipsec/iph.h > index 62d78b7b1..1bde9daeb 100644 > --- a/lib/librte_ipsec/iph.h > +++ b/lib/librte_ipsec/iph.h > @@ -5,14 +5,17 @@ > #ifndef _IPH_H_ > #define _IPH_H_ >=20 > -#include > - > /** > * @file iph.h > * Contains functions/structures/macros to manipulate IPv4/IPv6 headers > * used internally by ipsec library. > */ >=20 > +#define IPV6_DSCP_MASK (RTE_IP_DSCP_MASK << RTE_IPV6_HDR_TC_SHIFT) > +#define IPV6_ECN_MASK (RTE_IP_ECN_MASK << RTE_IPV6_HDR_TC_SHIFT) > +#define IPV6_TOS_MASK (IPV6_ECN_MASK | IPV6_DSCP_MASK) > +#define IPV6_ECN_CE IPV6_ECN_MASK > + > /* > * Move preceding (L3) headers down to remove ESP header and IV. > */ > @@ -37,6 +40,26 @@ insert_esph(char *np, char *op, uint32_t hlen) > np[i] =3D op[i]; > } >=20 > +static inline uint8_t > +get_ipv6_tos(rte_be32_t vtc_flow) > +{ > + uint32_t v; > + > + v =3D rte_be_to_cpu_32(vtc_flow); > + return v >> RTE_IPV6_HDR_TC_SHIFT; > +} > + > +static inline rte_be32_t > +set_ipv6_tos(rte_be32_t vtc_flow, uint32_t tos) > +{ > + uint32_t v; > + > + v =3D rte_cpu_to_be_32(tos << RTE_IPV6_HDR_TC_SHIFT); > + vtc_flow &=3D ~rte_cpu_to_be_32(IPV6_TOS_MASK); > + > + return (v | vtc_flow); > +} > + > /* update original ip header fields for transport case */ > static inline int > update_trs_l3hdr(const struct rte_ipsec_sa *sa, void *p, uint32_t plen, > @@ -101,23 +124,136 @@ update_trs_l3hdr(const struct rte_ipsec_sa *sa, vo= id *p, uint32_t plen, > return rc; > } >=20 > +/** > + * Update type-of-service/traffic-class field of inbound/outbound tunnel > + * packet. > + * > + * @param ref_h: reference header, for outbound it is inner header, othe= rwise > + * outer header. > + * @param update_h: header to be updated tos/tc field, for outbound it i= s outer > + * header, otherwise inner header. > + * @param tos_mask: type-of-service mask stored in sa. > + * @param is_outh_ipv4: 1 if outer header is ipv4, 0 if it is ipv6. > + * @param is_inner_ipv4: 1 if inner header is ipv4, 0 if it is ipv6. > + * @param is_inbound: 1 if it is a inbound packet, 0 if it is outbound. > + */ > +static inline void > +update_tun_tos(const void *ref_h, void *update_h, uint32_t tos_mask, > + uint8_t is_outh_ipv4, uint8_t is_inh_ipv4, uint8_t is_inbound) > +{ > + uint8_t idx =3D ((is_inbound << 2) | (is_outh_ipv4 << 1) | is_inh_ipv4)= ; > + struct rte_ipv4_hdr *v4out_h; > + struct rte_ipv6_hdr *v6out_h; > + struct rte_ipv4_hdr *v4in_h; > + struct rte_ipv6_hdr *v6in_h; > + uint32_t itp, otp; > + uint8_t ecn_v4out, ecn_v4in; > + uint32_t ecn_v6out, ecn_v6in; > + > + switch (idx) { > + /* outbound */ > + case 0: /*outh ipv6, inh ipv6 */ > + v6out_h =3D update_h; > + otp =3D get_ipv6_tos(v6out_h->vtc_flow) & ~tos_mask; > + itp =3D get_ipv6_tos(((const struct rte_ipv6_hdr *)ref_h)-> > + vtc_flow) & tos_mask; > + v6out_h->vtc_flow =3D set_ipv6_tos(v6out_h->vtc_flow, otp | itp); > + break; > + case 1: /*outh ipv6, inh ipv4 */ > + v6out_h =3D update_h; > + otp =3D get_ipv6_tos(v6out_h->vtc_flow) & ~tos_mask; > + itp =3D ((const struct rte_ipv4_hdr *)ref_h)->type_of_service & > + tos_mask; > + v6out_h->vtc_flow =3D set_ipv6_tos(v6out_h->vtc_flow, otp | itp); > + break; > + case 2: /*outh ipv4, inh ipv6 */ > + v4out_h =3D update_h; > + otp =3D v4out_h->type_of_service & ~tos_mask; > + itp =3D get_ipv6_tos(((const struct rte_ipv6_hdr *)ref_h)-> > + vtc_flow) & tos_mask; > + v4out_h->type_of_service =3D (otp | itp); > + break; > + case 3: /* outh ipv4, inh ipv4 */ > + v4out_h =3D update_h; > + otp =3D v4out_h->type_of_service & ~tos_mask; > + itp =3D ((const struct rte_ipv4_hdr *)ref_h)->type_of_service & > + tos_mask; > + v4out_h->type_of_service =3D (otp | itp); > + break; > + /* inbound */ > + case 4: /* outh ipv6, inh ipv6 */ > + v6in_h =3D update_h; > + ecn_v6out =3D ((const struct rte_ipv6_hdr *)ref_h)->vtc_flow & > + rte_cpu_to_be_32(IPV6_ECN_MASK); > + ecn_v6in =3D v6in_h->vtc_flow & rte_cpu_to_be_32(IPV6_ECN_MASK); > + if ((ecn_v6out =3D=3D rte_cpu_to_be_32(IPV6_ECN_CE)) && > + (ecn_v6in !=3D 0)) > + v6in_h->vtc_flow |=3D rte_cpu_to_be_32(IPV6_ECN_CE); > + break; > + case 5: /* outh ipv6, inh ipv4 */ > + v4in_h =3D update_h; > + ecn_v6out =3D ((const struct rte_ipv6_hdr *)ref_h)->vtc_flow & > + rte_cpu_to_be_32(IPV6_ECN_MASK); > + ecn_v4in =3D v4in_h->type_of_service & RTE_IP_ECN_MASK; > + if ((ecn_v6out =3D=3D rte_cpu_to_be_32(IPV6_ECN_CE)) && > + (ecn_v4in !=3D 0)) > + v4in_h->type_of_service |=3D RTE_IP_ECN_CE; > + break; > + case 6: /* outh ipv4, inh ipv6 */ > + v6in_h =3D update_h; > + ecn_v4out =3D ((const struct rte_ipv4_hdr *)ref_h)-> > + type_of_service & RTE_IP_ECN_MASK; > + ecn_v6in =3D v6in_h->vtc_flow & rte_cpu_to_be_32(IPV6_ECN_MASK); > + if (ecn_v4out =3D=3D RTE_IP_ECN_CE && ecn_v6in !=3D 0) > + v6in_h->vtc_flow |=3D rte_cpu_to_be_32(IPV6_ECN_CE); > + break; > + case 7: /* outh ipv4, inh ipv4 */ > + v4in_h =3D update_h; > + ecn_v4out =3D ((const struct rte_ipv4_hdr *)ref_h)-> > + type_of_service & RTE_IP_ECN_MASK; > + ecn_v4in =3D v4in_h->type_of_service & RTE_IP_ECN_MASK; > + if (ecn_v4out =3D=3D RTE_IP_ECN_CE && ecn_v4in !=3D 0) > + v4in_h->type_of_service |=3D RTE_IP_ECN_CE; > + break; > + } > +} > + > + > /* update original and new ip header fields for tunnel case */ > static inline void > -update_tun_l3hdr(const struct rte_ipsec_sa *sa, void *p, uint32_t plen, > - uint32_t l2len, rte_be16_t pid) > +update_outb_tun_l3hdr(const struct rte_ipsec_sa *sa, void *outh, > + const void *inh, uint32_t plen, uint32_t l2len, rte_be16_t pid) > { > struct rte_ipv4_hdr *v4h; > struct rte_ipv6_hdr *v6h; > + uint8_t is_out_ipv4; >=20 > if (sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) { > - v4h =3D p; > + is_out_ipv4 =3D 1; > + v4h =3D outh; > v4h->packet_id =3D pid; > v4h->total_length =3D rte_cpu_to_be_16(plen - l2len); > } else { > - v6h =3D p; > + is_out_ipv4 =3D 0; > + v6h =3D outh; > v6h->payload_len =3D rte_cpu_to_be_16(plen - l2len - > sizeof(*v6h)); > } > + > + if (sa->type & TUN_HDR_MSK) > + update_tun_tos(inh, outh, sa->tos_mask, is_out_ipv4, > + ((sa->type & RTE_IPSEC_SATP_IPV_MASK) =3D=3D > + RTE_IPSEC_SATP_IPV4), 0); > +} > + > +static inline void > +update_inb_tun_l3_hdr(const struct rte_ipsec_sa *sa, void *ip_inner, > + const void *ip_outter) > +{ > + update_tun_tos(ip_outter, ip_inner, sa->tos_mask, > + ((sa->type & RTE_IPSEC_SATP_MODE_TUNLV4) !=3D 0), > + ((sa->type & RTE_IPSEC_SATP_IPV_MASK) =3D=3D RTE_IPSEC_SATP_IPV4), > + 1); > } >=20 > #endif /* _IPH_H_ */ > diff --git a/lib/librte_ipsec/rte_ipsec_sa.h b/lib/librte_ipsec/rte_ipsec= _sa.h > index fd9b3ed60..8f179ee9d 100644 > --- a/lib/librte_ipsec/rte_ipsec_sa.h > +++ b/lib/librte_ipsec/rte_ipsec_sa.h > @@ -95,6 +95,11 @@ enum { > RTE_SATP_LOG2_MODE, > RTE_SATP_LOG2_SQN =3D RTE_SATP_LOG2_MODE + 2, > RTE_SATP_LOG2_ESN, > + RTE_SATP_LOG2_ECN, > + RTE_SATP_LOG2_DSCP, > + RTE_SATP_LOG2_TTL, > + RTE_SATP_LOG2_DF, > + RTE_SATP_LOG2_FLABEL, > RTE_SATP_LOG2_NUM > }; >=20 > @@ -123,6 +128,26 @@ enum { > #define RTE_IPSEC_SATP_ESN_DISABLE (0ULL << RTE_SATP_LOG2_ESN) > #define RTE_IPSEC_SATP_ESN_ENABLE (1ULL << RTE_SATP_LOG2_ESN) >=20 > +#define RTE_IPSEC_SATP_ECN_MASK (1ULL << RTE_SATP_LOG2_ECN) > +#define RTE_IPSEC_SATP_ECN_DISABLE (0ULL << RTE_SATP_LOG2_ECN) > +#define RTE_IPSEC_SATP_ECN_ENABLE (1ULL << RTE_SATP_LOG2_ECN) > + > +#define RTE_IPSEC_SATP_DSCP_MASK (1ULL << RTE_SATP_LOG2_DSCP) > +#define RTE_IPSEC_SATP_DSCP_DISABLE (0ULL << RTE_SATP_LOG2_DSCP) > +#define RTE_IPSEC_SATP_DSCP_ENABLE (1ULL << RTE_SATP_LOG2_DSCP) > + > +#define RTE_IPSEC_SATP_TTL_MASK (1ULL << RTE_SATP_LOG2_TTL) > +#define RTE_IPSEC_SATP_TTL_DISABLE (0ULL << RTE_SATP_LOG2_TTL) > +#define RTE_IPSEC_SATP_TTL_ENABLE (1ULL << RTE_SATP_LOG2_TTL) > + > +#define RTE_IPSEC_SATP_DF_MASK (1ULL << RTE_SATP_LOG2_DF) > +#define RTE_IPSEC_SATP_DF_DISABLE (0ULL << RTE_SATP_LOG2_DF) > +#define RTE_IPSEC_SATP_DF_ENABLE (1ULL << RTE_SATP_LOG2_DF) > + > +#define RTE_IPSEC_SATP_FLABEL_MASK (1ULL << RTE_SATP_LOG2_FLABEL) > +#define RTE_IPSEC_SATP_FLABEL_DISABLE (0ULL << RTE_SATP_LOG2_FLABEL) > +#define RTE_IPSEC_SATP_FLABEL_ENABLE (1ULL << RTE_SATP_LOG2_FLABEL) > + > /** > * get type of given SA > * @return > diff --git a/lib/librte_ipsec/sa.c b/lib/librte_ipsec/sa.c > index 087de958a..61d817dfc 100644 > --- a/lib/librte_ipsec/sa.c > +++ b/lib/librte_ipsec/sa.c > @@ -220,6 +220,17 @@ fill_sa_type(const struct rte_ipsec_sa_prm *prm, uin= t64_t *type) > else > tp |=3D RTE_IPSEC_SATP_SQN_RAW; >=20 > + /* check for ECN flag */ > + if (prm->ipsec_xform.options.ecn =3D=3D 0) > + tp |=3D RTE_IPSEC_SATP_ECN_DISABLE; > + else > + tp |=3D RTE_IPSEC_SATP_ECN_ENABLE; > + /* check for DSCP flag */ > + if (prm->ipsec_xform.options.copy_dscp =3D=3D 0) > + tp |=3D RTE_IPSEC_SATP_DSCP_DISABLE; > + else > + tp |=3D RTE_IPSEC_SATP_DSCP_ENABLE; > + > *type =3D tp; > return 0; > } > @@ -310,6 +321,12 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rt= e_ipsec_sa_prm *prm, > static const uint64_t msk =3D RTE_IPSEC_SATP_DIR_MASK | > RTE_IPSEC_SATP_MODE_MASK; >=20 > + if (prm->ipsec_xform.options.ecn) > + sa->tos_mask |=3D RTE_IP_ECN_MASK; > + > + if (prm->ipsec_xform.options.copy_dscp) > + sa->tos_mask |=3D RTE_IP_DSCP_MASK; > + > if (cxf->aead !=3D NULL) { > switch (cxf->aead->algo) { > case RTE_CRYPTO_AEAD_AES_GCM: > diff --git a/lib/librte_ipsec/sa.h b/lib/librte_ipsec/sa.h > index 20c0a65c0..51e69ad05 100644 > --- a/lib/librte_ipsec/sa.h > +++ b/lib/librte_ipsec/sa.h > @@ -10,6 +10,7 @@ > #define IPSEC_MAX_HDR_SIZE 64 > #define IPSEC_MAX_IV_SIZE 16 > #define IPSEC_MAX_IV_QWORD (IPSEC_MAX_IV_SIZE / sizeof(uint64_t)) > +#define TUN_HDR_MSK (RTE_IPSEC_SATP_ECN_MASK | RTE_IPSEC_SATP_DSCP_MASK) >=20 > /* padding alignment for different algorithms */ > enum { > @@ -103,6 +104,7 @@ struct rte_ipsec_sa { > uint8_t iv_ofs; /* offset for algo-specific IV inside crypto op */ > uint8_t iv_len; > uint8_t pad_align; > + uint8_t tos_mask; >=20 > /* template for tunnel header */ > uint8_t hdr[IPSEC_MAX_HDR_SIZE]; > diff --git a/lib/librte_net/rte_ip.h b/lib/librte_net/rte_ip.h > index c2c67b85d..85c53e8d9 100644 > --- a/lib/librte_net/rte_ip.h > +++ b/lib/librte_net/rte_ip.h > @@ -46,6 +46,17 @@ struct rte_ipv4_hdr { > (((b) & 0xff) << 16) | \ > (((c) & 0xff) << 8) | \ > ((d) & 0xff)) > +/** > + * RFC 3168 Explicit Congestion Notification (ECN) > + * * ECT(1) (ECN-Capable Transport(1)) > + * * ECT(0) (ECN-Capable Transport(0)) > + * * ECT(CE)(CE (Congestion Experienced)) > + */ > +#define RTE_IP_ECN_MASK (0x03) > +#define RTE_IP_ECN_CE RTE_IP_ECN_MASK > + > +/** Packet Option Masks */ > +#define RTE_IP_DSCP_MASK (0xFC) >=20 > /** Maximal IPv4 packet length (including a header) */ > #define RTE_IPV4_MAX_PKT_LEN 65535 > diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte= _security.h > index 76f54e0e0..d0492928c 100644 > --- a/lib/librte_security/rte_security.h > +++ b/lib/librte_security/rte_security.h > @@ -163,6 +163,15 @@ struct rte_security_ipsec_sa_options { > * * 0: Inner packet is not modified. > */ > uint32_t dec_ttl : 1; > + > + /**< Explicit Congestion Notification (ECN) > + * > + * * 1: In tunnel mode, enable outer header ECN Field copied from > + * inner header in tunnel encapsulation, or inner header ECN > + * field construction in decapsulation. > + * * 0: Inner/outer header are not modified. > + */ > + uint32_t ecn : 1; > }; >=20 > /** IPSec security association direction */ > -- > 2.14.5