From patchwork Wed Oct 27 11:45:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103038 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 446C7A0547; Wed, 27 Oct 2021 13:59:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5C42D41120; Wed, 27 Oct 2021 13:59:29 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 5D7764003F for ; Wed, 27 Oct 2021 13:59:27 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090306" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090306" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185809" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:24 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com, Hemant Agrawal , Anoob Joseph Date: Wed, 27 Oct 2021 12:45:24 +0100 Message-Id: <20211027114530.2244661-2-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 1/7] examples/ipsec-secgw: add stats interval argument X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add -t for stats screen update interval, disabled by default. Signed-off-by: Radu Nicolau Acked-by: Hemant Agrawal Acked-by: Anoob Joseph --- doc/guides/sample_app_ug/ipsec_secgw.rst | 5 ++++ examples/ipsec-secgw/ipsec-secgw.c | 29 ++++++++++++++++-------- examples/ipsec-secgw/ipsec-secgw.h | 17 -------------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index 782574dd39..282926924f 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -127,6 +127,7 @@ The application has a number of command line options:: -p PORTMASK -P -u PORTMASK -j FRAMESIZE -l -w REPLAY_WINDOW_SIZE -e -a -c SAD_CACHE_SIZE + -t STATISTICS_INTERVAL -s NUMBER_OF_MBUFS_IN_PACKET_POOL -f CONFIG_FILE_PATH --config (port,queue,lcore)[,(port,queue,lcore)] @@ -176,6 +177,10 @@ Where: Zero value disables cache. Default value: 128. +* ``-t``: specifies the statistics screen update interval in seconds. If set + to zero or omitted statistics screen is disabled. + Default value: 0. + * ``-s``: sets number of mbufs in packet pool, if not provided number of mbufs will be calculated based on number of cores, eth ports and crypto queues. diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 4bdf99b62b..d9a6838459 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -179,6 +179,7 @@ static uint32_t frag_tbl_sz; static uint32_t frame_buf_size = RTE_MBUF_DEFAULT_BUF_SIZE; static uint32_t mtu_size = RTE_ETHER_MTU; static uint64_t frag_ttl_ns = MAX_FRAG_TTL_NS; +static uint32_t stats_interval; /* application wide librte_ipsec/SA parameters */ struct app_sa_prm app_sa_prm = { @@ -289,7 +290,6 @@ adjust_ipv6_pktlen(struct rte_mbuf *m, const struct rte_ipv6_hdr *iph, } } -#if (STATS_INTERVAL > 0) /* Print out statistics on packet distribution */ static void @@ -349,9 +349,8 @@ print_stats_cb(__rte_unused void *param) total_packets_dropped); printf("\n====================================================\n"); - rte_eal_alarm_set(STATS_INTERVAL * US_PER_S, print_stats_cb, NULL); + rte_eal_alarm_set(stats_interval * US_PER_S, print_stats_cb, NULL); } -#endif /* STATS_INTERVAL */ static inline void prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) @@ -1394,6 +1393,7 @@ print_usage(const char *prgname) " [-e]" " [-a]" " [-c]" + " [-t STATS_INTERVAL]" " [-s NUMBER_OF_MBUFS_IN_PKT_POOL]" " -f CONFIG_FILE" " --config (port,queue,lcore)[,(port,queue,lcore)]" @@ -1418,6 +1418,8 @@ print_usage(const char *prgname) " -a enables SA SQN atomic behaviour\n" " -c specifies inbound SAD cache size,\n" " zero value disables the cache (default value: 128)\n" + " -t specifies statistics screen update interval,\n" + " zero disables statistics screen (default value: 0)\n" " -s number of mbufs in packet pool, if not specified number\n" " of mbufs will be calculated based on number of cores,\n" " ports and crypto queues\n" @@ -1627,7 +1629,7 @@ parse_args(int32_t argc, char **argv, struct eh_conf *eh_conf) argvopt = argv; - while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:c:s:", + while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:c:t:s:", lgopts, &option_index)) != EOF) { switch (opt) { @@ -1708,6 +1710,15 @@ parse_args(int32_t argc, char **argv, struct eh_conf *eh_conf) } app_sa_prm.cache_sz = ret; break; + case 't': + ret = parse_decimal(optarg); + if (ret < 0) { + printf("Invalid interval value: %s\n", optarg); + print_usage(prgname); + return -1; + } + stats_interval = ret; + break; case CMD_LINE_OPT_CONFIG_NUM: ret = parse_config(optarg); if (ret) { @@ -3003,11 +3014,11 @@ main(int32_t argc, char **argv) check_all_ports_link_status(enabled_port_mask); -#if (STATS_INTERVAL > 0) - rte_eal_alarm_set(STATS_INTERVAL * US_PER_S, print_stats_cb, NULL); -#else - RTE_LOG(INFO, IPSEC, "Stats display disabled\n"); -#endif /* STATS_INTERVAL */ + if (stats_interval > 0) + rte_eal_alarm_set(stats_interval * US_PER_S, + print_stats_cb, NULL); + else + RTE_LOG(INFO, IPSEC, "Stats display disabled\n"); /* launch per-lcore init on every lcore */ rte_eal_mp_remote_launch(ipsec_launch_one_lcore, eh_conf, CALL_MAIN); diff --git a/examples/ipsec-secgw/ipsec-secgw.h b/examples/ipsec-secgw/ipsec-secgw.h index 96e22de45e..04b4644370 100644 --- a/examples/ipsec-secgw/ipsec-secgw.h +++ b/examples/ipsec-secgw/ipsec-secgw.h @@ -6,9 +6,6 @@ #include -#ifndef STATS_INTERVAL -#define STATS_INTERVAL 0 -#endif #define NB_SOCKETS 4 @@ -83,7 +80,6 @@ struct ethaddr_info { uint64_t src, dst; }; -#if (STATS_INTERVAL > 0) struct ipsec_core_statistics { uint64_t tx; uint64_t rx; @@ -94,7 +90,6 @@ struct ipsec_core_statistics { } __rte_cache_aligned; struct ipsec_core_statistics core_statistics[RTE_MAX_LCORE]; -#endif /* STATS_INTERVAL */ extern struct ethaddr_info ethaddr_tbl[RTE_MAX_ETHPORTS]; @@ -115,38 +110,26 @@ is_unprotected_port(uint16_t port_id) static inline void core_stats_update_rx(int n) { -#if (STATS_INTERVAL > 0) int lcore_id = rte_lcore_id(); core_statistics[lcore_id].rx += n; core_statistics[lcore_id].rx_call++; if (n == MAX_PKT_BURST) core_statistics[lcore_id].burst_rx += n; -#else - RTE_SET_USED(n); -#endif /* STATS_INTERVAL */ } static inline void core_stats_update_tx(int n) { -#if (STATS_INTERVAL > 0) int lcore_id = rte_lcore_id(); core_statistics[lcore_id].tx += n; core_statistics[lcore_id].tx_call++; -#else - RTE_SET_USED(n); -#endif /* STATS_INTERVAL */ } static inline void core_stats_update_drop(int n) { -#if (STATS_INTERVAL > 0) int lcore_id = rte_lcore_id(); core_statistics[lcore_id].dropped += n; -#else - RTE_SET_USED(n); -#endif /* STATS_INTERVAL */ } /* helper routine to free bulk of packets */ From patchwork Wed Oct 27 11:45:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103039 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D3E6DA0547; Wed, 27 Oct 2021 13:59:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 99B744113B; Wed, 27 Oct 2021 13:59:33 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id EBC6241109 for ; Wed, 27 Oct 2021 13:59:28 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090311" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090311" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185815" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:27 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:25 +0100 Message-Id: <20211027114530.2244661-3-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 2/7] examples/ipsec-secgw: update create inline session X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Rework create inline session function as to update the session configuration parameters before create session is called. Also updated the rss key array size to prevent buffers overflows with PMDs that copy more than 40 bytes. Signed-off-by: Radu Nicolau Acked-by: Akhil Goyal --- examples/ipsec-secgw/ipsec.c | 54 +++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c index 6817139663..b6b7bddca8 100644 --- a/examples/ipsec-secgw/ipsec.c +++ b/examples/ipsec-secgw/ipsec.c @@ -171,16 +171,56 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, .options = { 0 }, .replay_win_sz = 0, .direction = sa->direction, - .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP, - .mode = (sa->flags == IP4_TUNNEL || - sa->flags == IP6_TUNNEL) ? - RTE_SECURITY_IPSEC_SA_MODE_TUNNEL : - RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT, + .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP } }, .crypto_xform = sa->xforms, .userdata = NULL, }; + if (IS_TRANSPORT(sa->flags)) { + sess_conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT; + if (IS_IP4(sa->flags)) { + sess_conf.ipsec.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + sess_conf.ipsec.tunnel.ipv4.src_ip.s_addr = + sa->src.ip.ip4; + sess_conf.ipsec.tunnel.ipv4.dst_ip.s_addr = + sa->dst.ip.ip4; + } else if (IS_IP6(sa->flags)) { + sess_conf.ipsec.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV6; + + memcpy(sess_conf.ipsec.tunnel.ipv6.src_addr.s6_addr, + sa->src.ip.ip6.ip6_b, 16); + memcpy(sess_conf.ipsec.tunnel.ipv6.dst_addr.s6_addr, + sa->dst.ip.ip6.ip6_b, 16); + } + } else if (IS_TUNNEL(sa->flags)) { + sess_conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + + if (IS_IP4(sa->flags)) { + sess_conf.ipsec.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV4; + + sess_conf.ipsec.tunnel.ipv4.src_ip.s_addr = + sa->src.ip.ip4; + sess_conf.ipsec.tunnel.ipv4.dst_ip.s_addr = + sa->dst.ip.ip4; + } else if (IS_IP6(sa->flags)) { + sess_conf.ipsec.tunnel.type = + RTE_SECURITY_IPSEC_TUNNEL_IPV6; + + memcpy(sess_conf.ipsec.tunnel.ipv6.src_addr.s6_addr, + sa->src.ip.ip6.ip6_b, 16); + memcpy(sess_conf.ipsec.tunnel.ipv6.dst_addr.s6_addr, + sa->dst.ip.ip6.ip6_b, 16); + } else { + RTE_LOG(ERR, IPSEC, "invalid tunnel type\n"); + return -1; + } + } + RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n", sa->spi, sa->portid); @@ -266,10 +306,10 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, sa->attr.ingress = (sa->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS); if (sa->attr.ingress) { - uint8_t rss_key[40]; + uint8_t rss_key[64]; struct rte_eth_rss_conf rss_conf = { .rss_key = rss_key, - .rss_key_len = 40, + .rss_key_len = sizeof(rss_key), }; struct rte_eth_dev_info dev_info; uint16_t queue[RTE_MAX_QUEUES_PER_PORT]; From patchwork Wed Oct 27 11:45:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103040 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 27EBCA0547; Wed, 27 Oct 2021 13:59:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 779BA41140; Wed, 27 Oct 2021 13:59:34 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id BDC484113A for ; Wed, 27 Oct 2021 13:59:30 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090319" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090319" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185828" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:28 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:26 +0100 Message-Id: <20211027114530.2244661-4-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 3/7] examples/ipsec-secgw: add support for inline crypto UDP encapsulation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Enable UDP encapsulation for both transport and tunnel modes for the inline crypto offload path. Signed-off-by: Radu Nicolau Acked-by: Akhil Goyal --- doc/guides/sample_app_ug/ipsec_secgw.rst | 3 ++- examples/ipsec-secgw/ipsec.c | 33 +++++++++++++++++++++--- examples/ipsec-secgw/ipsec.h | 7 ++++- examples/ipsec-secgw/sa.c | 9 +++++++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index 282926924f..2d0f322427 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -717,7 +717,8 @@ where each options means: ```` * Option to enable IPsec UDP encapsulation for NAT Traversal. - Only *lookaside-protocol-offload* mode is supported at the moment. + Only *lookaside-protocol-offload* and *inline-protocol-offload* modes are + supported at the moment. * Optional: Yes, it is disabled by default diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c index b6b7bddca8..90d9e61e5b 100644 --- a/examples/ipsec-secgw/ipsec.c +++ b/examples/ipsec-secgw/ipsec.c @@ -221,6 +221,12 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, } } + if (sa->udp_encap) { + sess_conf.ipsec.options.udp_encap = 1; + sess_conf.ipsec.udp.sport = htons(sa->udp.sport); + sess_conf.ipsec.udp.dport = htons(sa->udp.dport); + } + RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n", sa->spi, sa->portid); @@ -289,12 +295,31 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, sa->ipv4_spec.hdr.src_addr = sa->src.ip.ip4; } - sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP; - sa->pattern[2].spec = &sa->esp_spec; - sa->pattern[2].mask = &rte_flow_item_esp_mask; sa->esp_spec.hdr.spi = rte_cpu_to_be_32(sa->spi); - sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + if (sa->udp_encap) { + + sa->udp_spec.hdr.dst_port = + rte_cpu_to_be_16(sa->udp.dport); + sa->udp_spec.hdr.src_port = + rte_cpu_to_be_16(sa->udp.sport); + + sa->pattern[2].mask = &rte_flow_item_udp_mask; + sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP; + sa->pattern[2].spec = &sa->udp_spec; + + sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_ESP; + sa->pattern[3].spec = &sa->esp_spec; + sa->pattern[3].mask = &rte_flow_item_esp_mask; + + sa->pattern[4].type = RTE_FLOW_ITEM_TYPE_END; + } else { + sa->pattern[2].type = RTE_FLOW_ITEM_TYPE_ESP; + sa->pattern[2].spec = &sa->esp_spec; + sa->pattern[2].mask = &rte_flow_item_esp_mask; + + sa->pattern[3].type = RTE_FLOW_ITEM_TYPE_END; + } sa->action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY; sa->action[0].conf = ips->security.ses; diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 8405c48171..06bb11d5d5 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -125,6 +125,10 @@ struct ipsec_sa { #define IP6_TRANSPORT (1 << 4) struct ip_addr src; struct ip_addr dst; + struct { + uint16_t sport; + uint16_t dport; + } udp; uint8_t cipher_key[MAX_KEY_SIZE]; uint16_t cipher_key_len; uint8_t auth_key[MAX_KEY_SIZE]; @@ -140,7 +144,7 @@ struct ipsec_sa { uint8_t fdir_qid; uint8_t fdir_flag; -#define MAX_RTE_FLOW_PATTERN (4) +#define MAX_RTE_FLOW_PATTERN (5) #define MAX_RTE_FLOW_ACTIONS (3) struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN]; struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS]; @@ -149,6 +153,7 @@ struct ipsec_sa { struct rte_flow_item_ipv4 ipv4_spec; struct rte_flow_item_ipv6 ipv6_spec; }; + struct rte_flow_item_udp udp_spec; struct rte_flow_item_esp esp_spec; struct rte_flow *flow; struct rte_security_session_conf sess_conf; diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 88dd30464f..daebc1f09b 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -771,6 +772,11 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, app_sa_prm.udp_encap = 1; udp_encap_p = 1; break; + case RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO: + rule->udp_encap = 1; + rule->udp.sport = 0; + rule->udp.dport = 4500; + break; default: APP_CHECK(0, status, "UDP encapsulation not supported for " @@ -858,6 +864,8 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound) } printf("mode:"); + if (sa->udp_encap) + printf("UDP encapsulated "); switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) { case IP4_TUNNEL: @@ -1311,6 +1319,7 @@ fill_ipsec_sa_prm(struct rte_ipsec_sa_prm *prm, const struct ipsec_sa *ss, prm->ipsec_xform.mode = (IS_TRANSPORT(ss->flags)) ? RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT : RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + prm->ipsec_xform.options.udp_encap = ss->udp_encap; prm->ipsec_xform.options.ecn = 1; prm->ipsec_xform.options.copy_dscp = 1; From patchwork Wed Oct 27 11:45:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103041 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3E2B3A0547; Wed, 27 Oct 2021 13:59:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7A3A64113F; Wed, 27 Oct 2021 13:59:38 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 0E8E541135 for ; Wed, 27 Oct 2021 13:59:32 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090325" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090325" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185851" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:30 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:27 +0100 Message-Id: <20211027114530.2244661-5-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 4/7] examples/ipsec-secgw: support telemetry X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add telemetry support to the IPsec GW sample app and add support for per SA telemetry when using IPsec library. Signed-off-by: Declan Doherty Signed-off-by: Radu Nicolau --- doc/guides/rel_notes/release_21_11.rst | 4 + doc/guides/sample_app_ug/ipsec_secgw.rst | 11 + examples/ipsec-secgw/ipsec-secgw.c | 357 ++++++++++++++++++++++- examples/ipsec-secgw/ipsec-secgw.h | 31 ++ examples/ipsec-secgw/ipsec.h | 2 + examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 15 +- 7 files changed, 402 insertions(+), 20 deletions(-) diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 1ccac87b73..0a0bf05568 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -305,6 +305,10 @@ New Features * Pcapng format with timestamps and meta-data. * Fixes packet capture with stripped VLAN tags. +* **IPsec Security Gateway sample application new features.** + + * Added support for telemetry + Removed Items ------------- diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index 2d0f322427..b0256da1d8 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -726,6 +726,17 @@ where each options means: * *udp-encap* +```` + + * Option to enable per SA telemetry. + Currently only supported with IPsec library path. + + * Optional: Yes, it is disabled by default + + * Syntax: + + * *telemetry* + Example SA rules: .. code-block:: console diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index d9a6838459..1ef24b7b5c 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "event_helper.h" #include "flow.h" @@ -668,7 +669,7 @@ send_single_packet(struct rte_mbuf *m, uint16_t port, uint8_t proto) static inline void inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip, - uint16_t lim) + uint16_t lim, struct ipsec_spd_stats *stats) { struct rte_mbuf *m; uint32_t i, j, res, sa_idx; @@ -685,25 +686,30 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip, res = ip->res[i]; if (res == BYPASS) { ip->pkts[j++] = m; + stats->bypass++; continue; } if (res == DISCARD) { free_pkts(&m, 1); + stats->discard++; continue; } /* Only check SPI match for processed IPSec packets */ if (i < lim && ((m->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD) == 0)) { + stats->discard++; free_pkts(&m, 1); continue; } sa_idx = res - 1; if (!inbound_sa_check(sa, m, sa_idx)) { + stats->discard++; free_pkts(&m, 1); continue; } ip->pkts[j++] = m; + stats->protect++; } ip->num = j; } @@ -747,6 +753,7 @@ static inline void process_pkts_inbound(struct ipsec_ctx *ipsec_ctx, struct ipsec_traffic *traffic) { + unsigned int lcoreid = rte_lcore_id(); uint16_t nb_pkts_in, n_ip4, n_ip6; n_ip4 = traffic->ip4.num; @@ -762,16 +769,20 @@ process_pkts_inbound(struct ipsec_ctx *ipsec_ctx, ipsec_process(ipsec_ctx, traffic); } - inbound_sp_sa(ipsec_ctx->sp4_ctx, ipsec_ctx->sa_ctx, &traffic->ip4, - n_ip4); + inbound_sp_sa(ipsec_ctx->sp4_ctx, + ipsec_ctx->sa_ctx, &traffic->ip4, n_ip4, + &core_statistics[lcoreid].inbound.spd4); - inbound_sp_sa(ipsec_ctx->sp6_ctx, ipsec_ctx->sa_ctx, &traffic->ip6, - n_ip6); + inbound_sp_sa(ipsec_ctx->sp6_ctx, + ipsec_ctx->sa_ctx, &traffic->ip6, n_ip6, + &core_statistics[lcoreid].inbound.spd6); } static inline void -outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, - struct traffic_type *ipsec) +outbound_spd_lookup(struct sp_ctx *sp, + struct traffic_type *ip, + struct traffic_type *ipsec, + struct ipsec_spd_stats *stats) { struct rte_mbuf *m; uint32_t i, j, sa_idx; @@ -782,17 +793,23 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, rte_acl_classify((struct rte_acl_ctx *)sp, ip->data, ip->res, ip->num, DEFAULT_MAX_CATEGORIES); - j = 0; - for (i = 0; i < ip->num; i++) { + for (i = 0, j = 0; i < ip->num; i++) { m = ip->pkts[i]; sa_idx = ip->res[i] - 1; - if (ip->res[i] == DISCARD) + + if (unlikely(ip->res[i] == DISCARD)) { free_pkts(&m, 1); - else if (ip->res[i] == BYPASS) + + stats->discard++; + } else if (unlikely(ip->res[i] == BYPASS)) { ip->pkts[j++] = m; - else { + + stats->bypass++; + } else { ipsec->res[ipsec->num] = sa_idx; ipsec->pkts[ipsec->num++] = m; + + stats->protect++; } } ip->num = j; @@ -804,15 +821,20 @@ process_pkts_outbound(struct ipsec_ctx *ipsec_ctx, { struct rte_mbuf *m; uint16_t idx, nb_pkts_out, i; + unsigned int lcoreid = rte_lcore_id(); /* Drop any IPsec traffic from protected ports */ free_pkts(traffic->ipsec.pkts, traffic->ipsec.num); traffic->ipsec.num = 0; - outbound_sp(ipsec_ctx->sp4_ctx, &traffic->ip4, &traffic->ipsec); + outbound_spd_lookup(ipsec_ctx->sp4_ctx, + &traffic->ip4, &traffic->ipsec, + &core_statistics[lcoreid].outbound.spd4); - outbound_sp(ipsec_ctx->sp6_ctx, &traffic->ip6, &traffic->ipsec); + outbound_spd_lookup(ipsec_ctx->sp6_ctx, + &traffic->ip6, &traffic->ipsec, + &core_statistics[lcoreid].outbound.spd6); if (app_sa_prm.enable == 0) { @@ -956,6 +978,7 @@ route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) int32_t pkt_hop = 0; uint16_t i, offset; uint16_t lpm_pkts = 0; + unsigned int lcoreid = rte_lcore_id(); if (nb_pkts == 0) return; @@ -991,6 +1014,7 @@ route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) } if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0) { + core_statistics[lcoreid].lpm4.miss++; free_pkts(&pkts[i], 1); continue; } @@ -1007,6 +1031,7 @@ route6_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) int32_t pkt_hop = 0; uint16_t i, offset; uint16_t lpm_pkts = 0; + unsigned int lcoreid = rte_lcore_id(); if (nb_pkts == 0) return; @@ -1043,6 +1068,7 @@ route6_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) } if (pkt_hop == -1) { + core_statistics[lcoreid].lpm6.miss++; free_pkts(&pkts[i], 1); continue; } @@ -1116,6 +1142,7 @@ drain_inbound_crypto_queues(const struct lcore_conf *qconf, { uint32_t n; struct ipsec_traffic trf; + unsigned int lcoreid = rte_lcore_id(); if (app_sa_prm.enable == 0) { @@ -1133,13 +1160,15 @@ drain_inbound_crypto_queues(const struct lcore_conf *qconf, /* process ipv4 packets */ if (trf.ip4.num != 0) { - inbound_sp_sa(ctx->sp4_ctx, ctx->sa_ctx, &trf.ip4, 0); + inbound_sp_sa(ctx->sp4_ctx, ctx->sa_ctx, &trf.ip4, 0, + &core_statistics[lcoreid].inbound.spd4); route4_pkts(qconf->rt4_ctx, trf.ip4.pkts, trf.ip4.num); } /* process ipv6 packets */ if (trf.ip6.num != 0) { - inbound_sp_sa(ctx->sp6_ctx, ctx->sa_ctx, &trf.ip6, 0); + inbound_sp_sa(ctx->sp6_ctx, ctx->sa_ctx, &trf.ip6, 0, + &core_statistics[lcoreid].inbound.spd6); route6_pkts(qconf->rt6_ctx, trf.ip6.pkts, trf.ip6.num); } } @@ -2829,6 +2858,300 @@ calculate_nb_mbufs(uint16_t nb_ports, uint16_t nb_crypto_qp, uint32_t nb_rxq, 8192U); } + +static int +handle_telemetry_cmd_ipsec_secgw_stats(const char *cmd __rte_unused, + const char *params, struct rte_tel_data *data) +{ + uint64_t total_pkts_dropped = 0, total_pkts_tx = 0, total_pkts_rx = 0; + unsigned int coreid; + + rte_tel_data_start_dict(data); + + if (params) { + coreid = (uint32_t)atoi(params); + if (rte_lcore_is_enabled(coreid) == 0) + return -EINVAL; + + total_pkts_dropped = core_statistics[coreid].dropped; + total_pkts_tx = core_statistics[coreid].tx; + total_pkts_rx = core_statistics[coreid].rx; + + } else { + for (coreid = 0; coreid < RTE_MAX_LCORE; coreid++) { + + /* skip disabled cores */ + if (rte_lcore_is_enabled(coreid) == 0) + continue; + + total_pkts_dropped += core_statistics[coreid].dropped; + total_pkts_tx += core_statistics[coreid].tx; + total_pkts_rx += core_statistics[coreid].rx; + } + } + + /* add telemetry key/values pairs */ + rte_tel_data_add_dict_u64(data, "packets received", + total_pkts_rx); + + rte_tel_data_add_dict_u64(data, "packets transmitted", + total_pkts_tx); + + rte_tel_data_add_dict_u64(data, "packets dopped", + total_pkts_dropped); + + + return 0; +} + +static void +update_lcore_statistics(struct ipsec_core_statistics *total, uint32_t coreid) +{ + struct ipsec_core_statistics *lcore_stats; + + /* skip disabled cores */ + if (rte_lcore_is_enabled(coreid) == 0) + return; + + lcore_stats = &core_statistics[coreid]; + + total->rx = lcore_stats->rx; + total->dropped = lcore_stats->dropped; + total->tx = lcore_stats->tx; + + /* outbound stats */ + total->outbound.spd6.protect += lcore_stats->outbound.spd6.protect; + total->outbound.spd6.bypass += lcore_stats->outbound.spd6.bypass; + total->outbound.spd6.discard += lcore_stats->outbound.spd6.discard; + + total->outbound.spd4.protect += lcore_stats->outbound.spd4.protect; + total->outbound.spd4.bypass += lcore_stats->outbound.spd4.bypass; + total->outbound.spd4.discard += lcore_stats->outbound.spd4.discard; + + total->outbound.sad.miss += lcore_stats->outbound.sad.miss; + + /* inbound stats */ + total->inbound.spd6.protect += lcore_stats->inbound.spd6.protect; + total->inbound.spd6.bypass += lcore_stats->inbound.spd6.bypass; + total->inbound.spd6.discard += lcore_stats->inbound.spd6.discard; + + total->inbound.spd4.protect += lcore_stats->inbound.spd4.protect; + total->inbound.spd4.bypass += lcore_stats->inbound.spd4.bypass; + total->inbound.spd4.discard += lcore_stats->inbound.spd4.discard; + + total->inbound.sad.miss += lcore_stats->inbound.sad.miss; + + + /* routing stats */ + total->lpm4.miss += lcore_stats->lpm4.miss; + total->lpm6.miss += lcore_stats->lpm6.miss; +} + +static void +update_statistics(struct ipsec_core_statistics *total, uint32_t coreid) +{ + memset(total, 0, sizeof(*total)); + + if (coreid != UINT32_MAX) { + update_lcore_statistics(total, coreid); + } else { + for (coreid = 0; coreid < RTE_MAX_LCORE; coreid++) + update_lcore_statistics(total, coreid); + } +} + +static int +handle_telemetry_cmd_ipsec_secgw_stats_outbound(const char *cmd __rte_unused, + const char *params, struct rte_tel_data *data) +{ + struct ipsec_core_statistics total_stats; + + struct rte_tel_data *spd4_data = rte_tel_data_alloc(); + struct rte_tel_data *spd6_data = rte_tel_data_alloc(); + struct rte_tel_data *sad_data = rte_tel_data_alloc(); + + unsigned int coreid = UINT32_MAX; + + /* verify allocated telemetry data structures */ + if (!spd4_data || !spd6_data || !sad_data) + return -ENOMEM; + + /* initialize telemetry data structs as dicts */ + rte_tel_data_start_dict(data); + + rte_tel_data_start_dict(spd4_data); + rte_tel_data_start_dict(spd6_data); + rte_tel_data_start_dict(sad_data); + + if (params) { + coreid = (uint32_t)atoi(params); + if (rte_lcore_is_enabled(coreid) == 0) + return -EINVAL; + } + + update_statistics(&total_stats, coreid); + + /* add spd 4 telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(spd4_data, "protect", + total_stats.outbound.spd4.protect); + rte_tel_data_add_dict_u64(spd4_data, "bypass", + total_stats.outbound.spd4.bypass); + rte_tel_data_add_dict_u64(spd4_data, "discard", + total_stats.outbound.spd4.discard); + + rte_tel_data_add_dict_container(data, "spd4", spd4_data, 0); + + /* add spd 6 telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(spd6_data, "protect", + total_stats.outbound.spd6.protect); + rte_tel_data_add_dict_u64(spd6_data, "bypass", + total_stats.outbound.spd6.bypass); + rte_tel_data_add_dict_u64(spd6_data, "discard", + total_stats.outbound.spd6.discard); + + rte_tel_data_add_dict_container(data, "spd6", spd6_data, 0); + + /* add sad telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(sad_data, "miss", + total_stats.outbound.sad.miss); + + rte_tel_data_add_dict_container(data, "sad", sad_data, 0); + + return 0; +} + +static int +handle_telemetry_cmd_ipsec_secgw_stats_inbound(const char *cmd __rte_unused, + const char *params, struct rte_tel_data *data) +{ + struct ipsec_core_statistics total_stats; + + struct rte_tel_data *spd4_data = rte_tel_data_alloc(); + struct rte_tel_data *spd6_data = rte_tel_data_alloc(); + struct rte_tel_data *sad_data = rte_tel_data_alloc(); + + unsigned int coreid = UINT32_MAX; + + /* verify allocated telemetry data structures */ + if (!spd4_data || !spd6_data || !sad_data) + return -ENOMEM; + + /* initialize telemetry data structs as dicts */ + rte_tel_data_start_dict(data); + rte_tel_data_start_dict(spd4_data); + rte_tel_data_start_dict(spd6_data); + rte_tel_data_start_dict(sad_data); + + /* add children dicts to parent dict */ + + if (params) { + coreid = (uint32_t)atoi(params); + if (rte_lcore_is_enabled(coreid) == 0) + return -EINVAL; + } + + update_statistics(&total_stats, coreid); + + /* add sad telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(sad_data, "miss", + total_stats.outbound.sad.miss); + + rte_tel_data_add_dict_container(data, "sad", sad_data, 0); + + /* add spd 4 telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(spd4_data, "protect", + total_stats.inbound.spd4.protect); + rte_tel_data_add_dict_u64(spd4_data, "bypass", + total_stats.inbound.spd4.bypass); + rte_tel_data_add_dict_u64(spd4_data, "discard", + total_stats.inbound.spd4.discard); + + rte_tel_data_add_dict_container(data, "spd4", spd4_data, 0); + + /* add spd 6 telemetry key/values pairs */ + + rte_tel_data_add_dict_u64(spd6_data, "protect", + total_stats.inbound.spd6.protect); + rte_tel_data_add_dict_u64(spd6_data, "bypass", + total_stats.inbound.spd6.bypass); + rte_tel_data_add_dict_u64(spd6_data, "discard", + total_stats.inbound.spd6.discard); + + rte_tel_data_add_dict_container(data, "spd6", spd6_data, 0); + + return 0; +} + +static int +handle_telemetry_cmd_ipsec_secgw_stats_routing(const char *cmd __rte_unused, + const char *params, struct rte_tel_data *data) +{ + struct ipsec_core_statistics total_stats; + + struct rte_tel_data *lpm4_data = rte_tel_data_alloc(); + struct rte_tel_data *lpm6_data = rte_tel_data_alloc(); + + unsigned int coreid = UINT32_MAX; + + /* initialize telemetry data structs as dicts */ + rte_tel_data_start_dict(data); + rte_tel_data_start_dict(lpm4_data); + rte_tel_data_start_dict(lpm6_data); + + + if (params) { + coreid = (uint32_t)atoi(params); + if (rte_lcore_is_enabled(coreid) == 0) + return -EINVAL; + } + + update_statistics(&total_stats, coreid); + + /* add lpm 4 telemetry key/values pairs */ + rte_tel_data_add_dict_u64(lpm4_data, "miss", + total_stats.outbound.spd4.protect); + + rte_tel_data_add_dict_container(data, "IPv4 LPM", lpm4_data, 0); + + /* add lpm 6 telemetry key/values pairs */ + rte_tel_data_add_dict_u64(lpm6_data, "miss", + total_stats.outbound.spd6.protect); + + rte_tel_data_add_dict_container(data, "IPv6 LPM", lpm6_data, 0); + + return 0; +} + +static void +ipsec_secgw_telemetry_init(void) +{ + rte_telemetry_register_cmd("/examples/ipsec-secgw/stats", + handle_telemetry_cmd_ipsec_secgw_stats, + "Returns outbound global stats. " + "Optional Parameters: int "); + + rte_telemetry_register_cmd("/examples/ipsec-secgw/stats/outbound", + handle_telemetry_cmd_ipsec_secgw_stats_outbound, + "Returns outbound global stats. " + "Optional Parameters: int "); + + rte_telemetry_register_cmd("/examples/ipsec-secgw/stats/inbound", + handle_telemetry_cmd_ipsec_secgw_stats_inbound, + "Returns outbound global stats. " + "Optional Parameters: int "); + + rte_telemetry_register_cmd("/examples/ipsec-secgw/stats/routing", + handle_telemetry_cmd_ipsec_secgw_stats_routing, + "Returns outbound global stats. " + "Optional Parameters: int "); +} + + int32_t main(int32_t argc, char **argv) { @@ -2866,6 +3189,8 @@ main(int32_t argc, char **argv) if (ret < 0) rte_exit(EXIT_FAILURE, "Invalid parameters\n"); + ipsec_secgw_telemetry_init(); + /* parse configuration file */ if (parse_cfg_file(cfgfile) < 0) { printf("parsing file \"%s\" failed\n", diff --git a/examples/ipsec-secgw/ipsec-secgw.h b/examples/ipsec-secgw/ipsec-secgw.h index 04b4644370..de9f382742 100644 --- a/examples/ipsec-secgw/ipsec-secgw.h +++ b/examples/ipsec-secgw/ipsec-secgw.h @@ -80,6 +80,17 @@ struct ethaddr_info { uint64_t src, dst; }; +struct ipsec_spd_stats { + uint64_t protect; + uint64_t bypass; + uint64_t discard; +}; + +struct ipsec_sa_stats { + uint64_t hit; + uint64_t miss; +}; + struct ipsec_core_statistics { uint64_t tx; uint64_t rx; @@ -87,6 +98,26 @@ struct ipsec_core_statistics { uint64_t tx_call; uint64_t dropped; uint64_t burst_rx; + + struct { + struct ipsec_spd_stats spd4; + struct ipsec_spd_stats spd6; + struct ipsec_sa_stats sad; + } outbound; + + struct { + struct ipsec_spd_stats spd4; + struct ipsec_spd_stats spd6; + struct ipsec_sa_stats sad; + } inbound; + + struct { + uint64_t miss; + } lpm4; + + struct { + uint64_t miss; + } lpm6; } __rte_cache_aligned; struct ipsec_core_statistics core_statistics[RTE_MAX_LCORE]; diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 06bb11d5d5..de4e0606e2 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -123,6 +123,8 @@ struct ipsec_sa { #define TRANSPORT (1 << 2) #define IP4_TRANSPORT (1 << 3) #define IP6_TRANSPORT (1 << 4) +#define SA_TELEMETRY_ENABLE (1 << 5) + struct ip_addr src; struct ip_addr dst; struct { diff --git a/examples/ipsec-secgw/meson.build b/examples/ipsec-secgw/meson.build index b4b483a782..ccdaef1c4d 100644 --- a/examples/ipsec-secgw/meson.build +++ b/examples/ipsec-secgw/meson.build @@ -6,7 +6,7 @@ # To build this example as a standalone application with an already-installed # DPDK instance, use 'make' -deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec', 'eventdev'] +deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec', 'eventdev', 'telemetry'] allow_experimental_apis = true sources = files( 'esp.c', diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index daebc1f09b..65c975993d 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -323,6 +323,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, return; if (atoi(tokens[1]) == INVALID_SPI) return; + rule->flags = 0; rule->spi = atoi(tokens[1]); rule->portid = UINT16_MAX; ips = ipsec_get_primary_session(rule); @@ -339,14 +340,14 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, if (strcmp(tokens[ti], "ipv4-tunnel") == 0) { sa_cnt->nb_v4++; - rule->flags = IP4_TUNNEL; + rule->flags |= IP4_TUNNEL; } else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) { sa_cnt->nb_v6++; - rule->flags = IP6_TUNNEL; + rule->flags |= IP6_TUNNEL; } else if (strcmp(tokens[ti], "transport") == 0) { sa_cnt->nb_v4++; sa_cnt->nb_v6++; - rule->flags = TRANSPORT; + rule->flags |= TRANSPORT; } else { APP_CHECK(0, status, "unrecognized " "input \"%s\"", tokens[ti]); @@ -357,6 +358,11 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, continue; } + if (strcmp(tokens[ti], "telemetry") == 0) { + rule->flags |= SA_TELEMETRY_ENABLE; + continue; + } + if (strcmp(tokens[ti], "cipher_algo") == 0) { const struct supported_cipher_algo *algo; uint32_t key_len; @@ -1395,6 +1401,9 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size) if (rc < 0) return rc; + if (lsa->flags & SA_TELEMETRY_ENABLE) + rte_ipsec_telemetry_sa_add(sa); + /* init primary processing session */ ips = ipsec_get_primary_session(lsa); rc = fill_ipsec_session(ips, sa); From patchwork Wed Oct 27 11:45:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103042 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4F08BA0547; Wed, 27 Oct 2021 13:59:59 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 849F541149; Wed, 27 Oct 2021 13:59:39 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id A098241144 for ; Wed, 27 Oct 2021 13:59:34 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090328" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090328" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185854" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:32 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:28 +0100 Message-Id: <20211027114530.2244661-6-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 5/7] examples/ipsec-secgw: define initial ESN value X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" New option added to the SA configuration arguments that allows setting an arbitrary start value for ESN. For example in the SA below ESN will be enabled and first egress IPsec packet will have the ESN value 10000: sa out 15 cipher_algo null auth_algo null mode ipv4-tunnel \ src 172.16.1.5 dst 172.16.2.5 \ esn 10000 Signed-off-by: Declan Doherty Signed-off-by: Radu Nicolau Acked-by: Akhil Goyal --- doc/guides/sample_app_ug/ipsec_secgw.rst | 10 ++++++++++ examples/ipsec-secgw/ipsec.c | 6 ++++++ examples/ipsec-secgw/ipsec.h | 1 + examples/ipsec-secgw/sa.c | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index b0256da1d8..02846ac160 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -737,6 +737,16 @@ where each options means: * *telemetry* + ```` + + * Enable ESN and set the initial ESN value. + + * Optional: Yes, ESN not enabled by default + + * Syntax: + + * *esn N* N is the initial ESN value + Example SA rules: .. code-block:: console diff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c index 90d9e61e5b..2d4a26c962 100644 --- a/examples/ipsec-secgw/ipsec.c +++ b/examples/ipsec-secgw/ipsec.c @@ -227,6 +227,12 @@ create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, sess_conf.ipsec.udp.dport = htons(sa->udp.dport); } + if (sa->esn > 0) { + sess_conf.ipsec.options.esn = 1; + sess_conf.ipsec.esn.value = sa->esn; + } + + RTE_LOG_DP(DEBUG, IPSEC, "Create session for SA spi %u on port %u\n", sa->spi, sa->portid); diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index de4e0606e2..b037d5179f 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -143,6 +143,7 @@ struct ipsec_sa { enum rte_security_ipsec_sa_direction direction; uint8_t udp_encap; uint16_t portid; + uint64_t esn; uint8_t fdir_qid; uint8_t fdir_flag; diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 65c975993d..8725001fc7 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -684,6 +684,16 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, continue; } + if (strcmp(tokens[ti], "esn") == 0) { + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + rule->esn = atoll(tokens[ti]); + if (status->status < 0) + return; + continue; + } + if (strcmp(tokens[ti], "fallback") == 0) { struct rte_ipsec_session *fb; From patchwork Wed Oct 27 11:45:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103043 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 73C66A0547; Wed, 27 Oct 2021 14:00:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 764814114F; Wed, 27 Oct 2021 13:59:40 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 439F94068C for ; Wed, 27 Oct 2021 13:59:36 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090334" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090334" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185859" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:34 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:29 +0100 Message-Id: <20211027114530.2244661-7-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 6/7] examples/ipsec-secgw: add ethdev reset callback X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Applications should not quietly ignore an ethdev reset event. Register an event handler for ethdev reset callback RTE_ETH_EVENT_INTR_RESET that prints a message and quits the application. Signed-off-by: Declan Doherty Signed-off-by: Radu Nicolau Acked-by: Akhil Goyal --- examples/ipsec-secgw/ipsec-secgw.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 1ef24b7b5c..bfa2070b8d 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -2545,6 +2545,17 @@ inline_ipsec_event_callback(uint16_t port_id, enum rte_eth_event_type type, return -1; } +static int +ethdev_reset_event_callback(uint16_t port_id, + enum rte_eth_event_type type __rte_unused, + void *param __rte_unused, void *ret_param __rte_unused) +{ + printf("Reset Event on port id %d\n", port_id); + printf("Force quit application"); + force_quit = true; + return 0; +} + static uint16_t rx_callback(__rte_unused uint16_t port, __rte_unused uint16_t queue, struct rte_mbuf *pkt[], uint16_t nb_pkts, @@ -3311,6 +3322,9 @@ main(int32_t argc, char **argv) rte_strerror(-ret), portid); } + rte_eth_dev_callback_register(portid, RTE_ETH_EVENT_INTR_RESET, + ethdev_reset_event_callback, NULL); + rte_eth_dev_callback_register(portid, RTE_ETH_EVENT_IPSEC, inline_ipsec_event_callback, NULL); } From patchwork Wed Oct 27 11:45:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Radu Nicolau X-Patchwork-Id: 103044 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7D96AA0547; Wed, 27 Oct 2021 14:00:14 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1EA0341154; Wed, 27 Oct 2021 13:59:46 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 1E1674068C for ; Wed, 27 Oct 2021 13:59:37 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10149"; a="230090337" X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="230090337" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2021 04:59:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,186,1631602800"; d="scan'208";a="447185866" Received: from silpixa00400884.ir.intel.com ([10.243.22.82]) by orsmga006.jf.intel.com with ESMTP; 27 Oct 2021 04:59:36 -0700 From: Radu Nicolau To: Radu Nicolau , Akhil Goyal Cc: dev@dpdk.org, declan.doherty@intel.com, hemant.agrawal@oss.nxp.com Date: Wed, 27 Oct 2021 12:45:30 +0100 Message-Id: <20211027114530.2244661-8-radu.nicolau@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211027114530.2244661-1-radu.nicolau@intel.com> References: <20210903112257.303961-1-radu.nicolau@intel.com> <20211027114530.2244661-1-radu.nicolau@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 7/7] examples/ipsec-secgw: add support for additional algorithms X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Add support for AES-GMAC, AES_CTR, AES_XCBC_MAC, AES_CCM, CHACHA20_POLY1305 Signed-off-by: Declan Doherty Signed-off-by: Radu Nicolau Acked-by: Akhil Goyal --- doc/guides/rel_notes/release_21_11.rst | 2 + doc/guides/sample_app_ug/ipsec_secgw.rst | 3 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/sa.c | 122 +++++++++++++++++++++-- 4 files changed, 119 insertions(+), 11 deletions(-) diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 0a0bf05568..1d656b8e2b 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -308,6 +308,8 @@ New Features * **IPsec Security Gateway sample application new features.** * Added support for telemetry + * Added support for more AEAD algorithms: AES-GMAC, AES_CTR, AES_XCBC_MAC, + AES_CCM, CHACHA20_POLY1305 Removed Items diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index 02846ac160..edd3d439f5 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -106,7 +106,8 @@ Constraints * No IPv6 options headers. * No AH mode. -* Supported algorithms: AES-CBC, AES-CTR, AES-GCM, 3DES-CBC, HMAC-SHA1 and NULL. +* Supported algorithms: AES-CBC, AES-CTR, AES-GCM, 3DES-CBC, HMAC-SHA1, + AES-GMAC, AES_CTR, AES_XCBC_MAC, AES_CCM, CHACHA20_POLY1305 and NULL. * Each SA must be handle by a unique lcore (*1 RX queue per port*). Compiling the Application diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index b037d5179f..0dfb0d6acb 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -63,8 +63,7 @@ struct ip_addr { } ip; }; -#define MAX_KEY_SIZE 36 - +#define MAX_KEY_SIZE 64 /* * application wide SA parameters */ diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 8725001fc7..44c18badbb 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -46,6 +46,7 @@ struct supported_cipher_algo { struct supported_auth_algo { const char *keyword; enum rte_crypto_auth_algorithm algo; + uint16_t iv_len; uint16_t digest_len; uint16_t key_len; uint8_t key_not_req; @@ -98,6 +99,20 @@ const struct supported_cipher_algo cipher_algos[] = { .block_size = 4, .key_len = 20 }, + { + .keyword = "aes-192-ctr", + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .iv_len = 16, + .block_size = 16, + .key_len = 28 + }, + { + .keyword = "aes-256-ctr", + .algo = RTE_CRYPTO_CIPHER_AES_CTR, + .iv_len = 16, + .block_size = 16, + .key_len = 36 + }, { .keyword = "3des-cbc", .algo = RTE_CRYPTO_CIPHER_3DES_CBC, @@ -126,6 +141,31 @@ const struct supported_auth_algo auth_algos[] = { .algo = RTE_CRYPTO_AUTH_SHA256_HMAC, .digest_len = 16, .key_len = 32 + }, + { + .keyword = "sha384-hmac", + .algo = RTE_CRYPTO_AUTH_SHA384_HMAC, + .digest_len = 24, + .key_len = 48 + }, + { + .keyword = "sha512-hmac", + .algo = RTE_CRYPTO_AUTH_SHA512_HMAC, + .digest_len = 32, + .key_len = 64 + }, + { + .keyword = "aes-gmac", + .algo = RTE_CRYPTO_AUTH_AES_GMAC, + .iv_len = 8, + .digest_len = 16, + .key_len = 20 + }, + { + .keyword = "aes-xcbc-mac-96", + .algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC, + .digest_len = 12, + .key_len = 16 } }; @@ -156,6 +196,42 @@ const struct supported_aead_algo aead_algos[] = { .key_len = 36, .digest_len = 16, .aad_len = 8, + }, + { + .keyword = "aes-128-ccm", + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .iv_len = 8, + .block_size = 4, + .key_len = 20, + .digest_len = 16, + .aad_len = 8, + }, + { + .keyword = "aes-192-ccm", + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .iv_len = 8, + .block_size = 4, + .key_len = 28, + .digest_len = 16, + .aad_len = 8, + }, + { + .keyword = "aes-256-ccm", + .algo = RTE_CRYPTO_AEAD_AES_CCM, + .iv_len = 8, + .block_size = 4, + .key_len = 36, + .digest_len = 16, + .aad_len = 8, + }, + { + .keyword = "chacha20-poly1305", + .algo = RTE_CRYPTO_AEAD_CHACHA20_POLY1305, + .iv_len = 12, + .block_size = 64, + .key_len = 36, + .digest_len = 16, + .aad_len = 8, } }; @@ -484,6 +560,14 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, if (status->status < 0) return; + if (algo->algo == RTE_CRYPTO_AUTH_AES_GMAC) { + key_len -= 4; + rule->auth_key_len = key_len; + rule->iv_len = algo->iv_len; + memcpy(&rule->salt, + &rule->auth_key[key_len], 4); + } + auth_algo_p = 1; continue; } @@ -1171,8 +1255,15 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], break; } - if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM) { - iv_length = 12; + + if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_GCM || + sa->aead_algo == RTE_CRYPTO_AEAD_AES_CCM || + sa->aead_algo == RTE_CRYPTO_AEAD_CHACHA20_POLY1305) { + + if (sa->aead_algo == RTE_CRYPTO_AEAD_AES_CCM) + iv_length = 11; + else + iv_length = 12; sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_AEAD; sa_ctx->xf[idx].a.aead.algo = sa->aead_algo; @@ -1196,10 +1287,8 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], case RTE_CRYPTO_CIPHER_NULL: case RTE_CRYPTO_CIPHER_3DES_CBC: case RTE_CRYPTO_CIPHER_AES_CBC: - iv_length = sa->iv_len; - break; case RTE_CRYPTO_CIPHER_AES_CTR: - iv_length = 16; + iv_length = sa->iv_len; break; default: RTE_LOG(ERR, IPSEC_ESP, @@ -1208,6 +1297,10 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], return -EINVAL; } + /* AES_GMAC uses salt like AEAD algorithms */ + if (sa->auth_algo == RTE_CRYPTO_AUTH_AES_GMAC) + iv_length = 12; + if (inbound) { sa_ctx->xf[idx].b.type = RTE_CRYPTO_SYM_XFORM_CIPHER; sa_ctx->xf[idx].b.cipher.algo = sa->cipher_algo; @@ -1229,6 +1322,9 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], sa->digest_len; sa_ctx->xf[idx].a.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + sa_ctx->xf[idx].a.auth.iv.offset = IV_OFFSET; + sa_ctx->xf[idx].a.auth.iv.length = iv_length; + } else { /* outbound */ sa_ctx->xf[idx].a.type = RTE_CRYPTO_SYM_XFORM_CIPHER; sa_ctx->xf[idx].a.cipher.algo = sa->cipher_algo; @@ -1250,11 +1346,21 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], sa->digest_len; sa_ctx->xf[idx].b.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + sa_ctx->xf[idx].b.auth.iv.offset = IV_OFFSET; + sa_ctx->xf[idx].b.auth.iv.length = iv_length; + } - sa_ctx->xf[idx].a.next = &sa_ctx->xf[idx].b; - sa_ctx->xf[idx].b.next = NULL; - sa->xforms = &sa_ctx->xf[idx].a; + if (sa->auth_algo == RTE_CRYPTO_AUTH_AES_GMAC) { + sa->xforms = inbound ? + &sa_ctx->xf[idx].a : &sa_ctx->xf[idx].b; + sa->xforms->next = NULL; + + } else { + sa_ctx->xf[idx].a.next = &sa_ctx->xf[idx].b; + sa_ctx->xf[idx].b.next = NULL; + sa->xforms = &sa_ctx->xf[idx].a; + } } if (ips->type ==