From patchwork Wed Dec 11 16:45:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 63774 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8EB1BA04F6; Wed, 11 Dec 2019 17:45:47 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 166521BE9E; Wed, 11 Dec 2019 17:45:42 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 289BD91 for ; Wed, 11 Dec 2019 17:45:38 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Dec 2019 08:45:38 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,301,1571727600"; d="scan'208";a="238613890" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by fmsmga004.fm.intel.com with ESMTP; 11 Dec 2019 08:45:37 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Wed, 11 Dec 2019 16:45:31 +0000 Message-Id: <4697977e04cf3622d1752e171956709a3eff6e10.1576081138.git.vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h 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" Move IPSEC_SAD_NAMESIZE into public header and rename it to RTE_IPSEC_SAD_NAMESIZE Signed-off-by: Vladimir Medvedkin --- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/librte_ipsec/ipsec_sad.c b/lib/librte_ipsec/ipsec_sad.c index db2c44c..2c994ed 100644 --- a/lib/librte_ipsec/ipsec_sad.c +++ b/lib/librte_ipsec/ipsec_sad.c @@ -20,7 +20,6 @@ * indicate presence of entries with the same SPI in DIP and DIP+SIP tables. */ -#define IPSEC_SAD_NAMESIZE 64 #define SAD_PREFIX "SAD_" /* "SAD_" */ #define SAD_FORMAT SAD_PREFIX "%s" @@ -34,7 +33,7 @@ struct hash_cnt { }; struct rte_ipsec_sad { - char name[IPSEC_SAD_NAMESIZE]; + char name[RTE_IPSEC_SAD_NAMESIZE]; struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK]; /* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete @@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; - char sad_name[IPSEC_SAD_NAMESIZE]; + char sad_name[RTE_IPSEC_SAD_NAMESIZE]; struct rte_tailq_entry *te; struct rte_ipsec_sad_list *sad_list; struct rte_ipsec_sad *sad, *tmp_sad = NULL; @@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) return NULL; } - ret = snprintf(sad_name, IPSEC_SAD_NAMESIZE, SAD_FORMAT, name); - if (ret < 0 || ret >= IPSEC_SAD_NAMESIZE) { + ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, SAD_FORMAT, name); + if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE) { rte_errno = ENAMETOOLONG; return NULL; } @@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) /* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; - if (strncmp(sad_name, tmp_sad->name, IPSEC_SAD_NAMESIZE) == 0) + if (strncmp(sad_name, tmp_sad->name, + RTE_IPSEC_SAD_NAMESIZE) == 0) break; } if (te != NULL) { @@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) struct rte_ipsec_sad * rte_ipsec_sad_find_existing(const char *name) { - char sad_name[IPSEC_SAD_NAMESIZE]; + char sad_name[RTE_IPSEC_SAD_NAMESIZE]; struct rte_ipsec_sad *sad = NULL; struct rte_tailq_entry *te; struct rte_ipsec_sad_list *sad_list; int ret; - ret = snprintf(sad_name, IPSEC_SAD_NAMESIZE, SAD_FORMAT, name); - if (ret < 0 || ret >= IPSEC_SAD_NAMESIZE) { + ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, SAD_FORMAT, name); + if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE) { rte_errno = ENAMETOOLONG; return NULL; } @@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name) rte_mcfg_tailq_read_lock(); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; - if (strncmp(sad_name, sad->name, IPSEC_SAD_NAMESIZE) == 0) + if (strncmp(sad_name, sad->name, RTE_IPSEC_SAD_NAMESIZE) == 0) break; } rte_mcfg_tailq_read_unlock(); diff --git a/lib/librte_ipsec/rte_ipsec_sad.h b/lib/librte_ipsec/rte_ipsec_sad.h index 8386f73..dcc8224 100644 --- a/lib/librte_ipsec/rte_ipsec_sad.h +++ b/lib/librte_ipsec/rte_ipsec_sad.h @@ -47,6 +47,8 @@ union rte_ipsec_sad_key { struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64 /** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1 /** Flag to support reader writer concurrency */ From patchwork Wed Dec 11 16:45:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 63775 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E1A2CA04F6; Wed, 11 Dec 2019 17:45:57 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E4E731BF6D; Wed, 11 Dec 2019 17:45:43 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id E38B091 for ; Wed, 11 Dec 2019 17:45:39 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Dec 2019 08:45:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,301,1571727600"; d="scan'208";a="238613901" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by fmsmga004.fm.intel.com with ESMTP; 11 Dec 2019 08:45:38 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Wed, 11 Dec 2019 16:45:32 +0000 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD 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" Add initial support for librte_ipsec SAD library Signed-off-by: Vladimir Medvedkin --- examples/ipsec-secgw/ipsec.h | 11 ++++++ examples/ipsec-secgw/sad.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 8e07521..132286c 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -53,6 +53,17 @@ struct ipsec_xform; struct rte_mbuf; struct ipsec_sa; +/* + * Keeps number of configured SA's of each type: + * transport + * v4 tunnel + * v6 tunnel + */ +struct ipsec_sa_cnt { + uint32_t nb_trn; + uint32_t nb_v4_tun; + uint32_t nb_v6_tun; +}; typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa, struct rte_crypto_op *cop); diff --git a/examples/ipsec-secgw/sad.c b/examples/ipsec-secgw/sad.c new file mode 100644 index 0000000..bcac462 --- /dev/null +++ b/examples/ipsec-secgw/sad.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Intel Corporation + */ + +#include + +#include "ipsec.h" +#include "sad.h" + +int +ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa) +{ + int ret; + union rte_ipsec_sad_key key = { {0} }; + + /* spi field is common for ipv4 and ipv6 key types */ + key.v4.spi = rte_cpu_to_be_32(sa->spi); + switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) { + case IP4_TUNNEL: + key.v4.dip = rte_cpu_to_be_32(sa->dst.ip.ip4); + key.v4.sip = rte_cpu_to_be_32(sa->src.ip.ip4); + ret = rte_ipsec_sad_add(sad->sad_v4, &key, + RTE_IPSEC_SAD_SPI_DIP_SIP, sa); + if (ret != 0) + return ret; + break; + case IP6_TUNNEL: + memcpy(key.v6.dip, sa->dst.ip.ip6.ip6, + sizeof(key.v6.dip)); + memcpy(key.v6.sip, sa->src.ip.ip6.ip6, + sizeof(key.v6.sip)); + ret = rte_ipsec_sad_add(sad->sad_v6, &key, + RTE_IPSEC_SAD_SPI_DIP_SIP, sa); + if (ret != 0) + return ret; + break; + case TRANSPORT: + if (sp4_spi_present(sa->spi, 1, NULL, NULL) >= 0) { + ret = rte_ipsec_sad_add(sad->sad_v4, &key, + RTE_IPSEC_SAD_SPI_ONLY, sa); + if (ret != 0) + return ret; + } + + if (sp6_spi_present(sa->spi, 1, NULL, NULL) >= 0) { + ret = rte_ipsec_sad_add(sad->sad_v6, &key, + RTE_IPSEC_SAD_SPI_ONLY, sa); + if (ret != 0) + return ret; + } + } + + return 0; +} + +int +ipsec_sad_create(const char *name, struct ipsec_sad *sad, + int socket_id, struct ipsec_sa_cnt *sa_cnt) +{ + int ret; + struct rte_ipsec_sad_conf sad_conf; + char sad_name[RTE_IPSEC_SAD_NAMESIZE]; + + ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v4", name); + if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE) + return -ENAMETOOLONG; + + sad_conf.socket_id = socket_id; + sad_conf.flags = 0; + /* Make SAD have extra 25% of required number of entries */ + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_trn * 5 / 4; + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0; + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = sa_cnt->nb_v4_tun * 5 / 4; + + sad->sad_v4 = rte_ipsec_sad_create(sad_name, &sad_conf); + if (sad->sad_v4 == NULL) + return -rte_errno; + + ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v6", name); + if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE) + return -ENAMETOOLONG; + sad_conf.flags = RTE_IPSEC_SAD_FLAG_IPV6; + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = sa_cnt->nb_v6_tun * 5 / 4; + + sad->sad_v6 = rte_ipsec_sad_create(name, &sad_conf); + if (sad->sad_v6 == NULL) + return -rte_errno; + + return 0; +} diff --git a/examples/ipsec-secgw/sad.h b/examples/ipsec-secgw/sad.h new file mode 100644 index 0000000..e754d57 --- /dev/null +++ b/examples/ipsec-secgw/sad.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Intel Corporation + */ + +#ifndef __SAD_H__ +#define __SAD_H__ + +#include + +struct ipsec_sad { + struct rte_ipsec_sad *sad_v4; + struct rte_ipsec_sad *sad_v6; +}; + +int ipsec_sad_create(const char *name, struct ipsec_sad *sad, + int socket_id, struct ipsec_sa_cnt *sa_cnt); + +int ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa); + +static inline void +sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[], + void *sa[], uint16_t nb_pkts) +{ + uint32_t i; + uint32_t nb_v4 = 0, nb_v6 = 0; + struct rte_esp_hdr *esp; + struct rte_ipv4_hdr *ipv4; + struct rte_ipv6_hdr *ipv6; + struct rte_ipsec_sadv4_key v4[nb_pkts]; + struct rte_ipsec_sadv6_key v6[nb_pkts]; + int v4_idxes[nb_pkts]; + int v6_idxes[nb_pkts]; + const union rte_ipsec_sad_key *keys_v4[nb_pkts]; + const union rte_ipsec_sad_key *keys_v6[nb_pkts]; + void *v4_res[nb_pkts]; + void *v6_res[nb_pkts]; + + for (i = 0; i < nb_pkts; i++) { + ipv4 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv4_hdr *); + esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *, + pkts[i]->l3_len); + if ((ipv4->version_ihl >> 4) == IPVERSION) { + v4[nb_v4].spi = esp->spi; + v4[nb_v4].dip = ipv4->dst_addr; + v4[nb_v4].sip = ipv4->src_addr; + keys_v4[nb_v4] = (const union rte_ipsec_sad_key *) + &v4[nb_v4]; + v4_idxes[nb_v4++] = i; + } else { + ipv6 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv6_hdr *); + v6[nb_v6].spi = esp->spi; + memcpy(v6[nb_v6].dip, ipv6->dst_addr, + sizeof(ipv6->dst_addr)); + memcpy(v6[nb_v6].sip, ipv6->src_addr, + sizeof(ipv6->src_addr)); + keys_v6[nb_v6] = (const union rte_ipsec_sad_key *) + &v6[nb_v6]; + v6_idxes[nb_v6++] = i; + } + } + + if (nb_v4 != 0) + rte_ipsec_sad_lookup(sad->sad_v4, keys_v4, v4_res, nb_v4); + if (nb_v6 != 0) + rte_ipsec_sad_lookup(sad->sad_v6, keys_v6, v6_res, nb_v6); + + for (i = 0; i < nb_v4; i++) + sa[v4_idxes[i]] = v4_res[i]; + + for (i = 0; i < nb_v6; i++) + sa[v6_idxes[i]] = v6_res[i]; +} + +#endif /* __SAD_H__ */ From patchwork Wed Dec 11 16:45:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 63776 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5B210A04F6; Wed, 11 Dec 2019 17:46:07 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B83071BF73; Wed, 11 Dec 2019 17:45:45 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 4AD471BE83 for ; Wed, 11 Dec 2019 17:45:41 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Dec 2019 08:45:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,301,1571727600"; d="scan'208";a="238613913" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by fmsmga004.fm.intel.com with ESMTP; 11 Dec 2019 08:45:39 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Wed, 11 Dec 2019 16:45:33 +0000 Message-Id: <4f2553a3a2f24442574dc61b8f780c6c10cde83a.1576081138.git.vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 3/4] examples/ipsec-secgw: integrate inbound SAD 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" Integrate ipsec SAD support into secgw app: 1. Use SAD library for inbound SA lookup 2. Changes in struct sa_ctx: - sa array allocates dynamically depending on number of configured sa - All SA's are kept one by one without using SPI2IDX 3. SP's userdata now contain index of SA in sa_ctx instead of SPI 4. Get rid of SPI2IDX macro Signed-off-by: Vladimir Medvedkin --- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 2 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 160 +++++++++++++++++-------------------- examples/ipsec-secgw/sp4.c | 24 +++--- examples/ipsec-secgw/sp6.c | 24 +++--- 7 files changed, 110 insertions(+), 107 deletions(-) diff --git a/examples/ipsec-secgw/Makefile b/examples/ipsec-secgw/Makefile index 851123b..8734b15 100644 --- a/examples/ipsec-secgw/Makefile +++ b/examples/ipsec-secgw/Makefile @@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 3b5aaf6..3e5f82e 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip, continue; } - sa_idx = SPI2IDX(res); + sa_idx = res - 1; if (!inbound_sa_check(sa, m, sa_idx)) { rte_pktmbuf_free(m); continue; @@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j = 0; for (i = 0; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx = SPI2IDX(ip->res[i]); + sa_idx = ip->res[i] - 1; if (ip->res[i] == DISCARD) rte_pktmbuf_free(m); else if (ip->res[i] == BYPASS) diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 132286c..f731bf8 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -363,7 +363,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], * or -ENOENT otherwise. */ int -sa_spi_present(uint32_t spi, int inbound); +sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound); void sa_init(struct socket_ctx *ctx, int32_t socket_id); diff --git a/examples/ipsec-secgw/meson.build b/examples/ipsec-secgw/meson.build index 9ece345..6bd5b78 100644 --- a/examples/ipsec-secgw/meson.build +++ b/examples/ipsec-secgw/meson.build @@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' ) diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 7f046e3..8cc7b17 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -24,6 +24,7 @@ #include "ipsec.h" #include "esp.h" #include "parser.h" +#include "sad.h" #define IPDEFTTL 64 @@ -134,9 +135,11 @@ const struct supported_aead_algo aead_algos[] = { static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES]; static uint32_t nb_sa_out; +static struct ipsec_sa_cnt sa_out_cnt; static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES]; static uint32_t nb_sa_in; +static struct ipsec_sa_cnt sa_in_cnt; static const struct supported_cipher_algo * find_match_cipher_algo(const char *cipher_keyword) @@ -229,6 +232,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, struct rte_ipsec_session *ips; uint32_t ti; /*token index*/ uint32_t *ri /*rule index*/; + struct ipsec_sa_cnt *sa_cnt; uint32_t cipher_algo_p = 0; uint32_t auth_algo_p = 0; uint32_t aead_algo_p = 0; @@ -241,6 +245,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, if (strcmp(tokens[0], "in") == 0) { ri = &nb_sa_in; + sa_cnt = &sa_in_cnt; APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status, "too many sa rules, abort insertion\n"); @@ -251,6 +256,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; } else { ri = &nb_sa_out; + sa_cnt = &sa_out_cnt; APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status, "too many sa rules, abort insertion\n"); @@ -280,13 +286,16 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, if (status->status < 0) return; - if (strcmp(tokens[ti], "ipv4-tunnel") == 0) + if (strcmp(tokens[ti], "ipv4-tunnel") == 0) { + sa_cnt->nb_v4_tun++; rule->flags = IP4_TUNNEL; - else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) + } else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) { + sa_cnt->nb_v6_tun++; rule->flags = IP6_TUNNEL; - else if (strcmp(tokens[ti], "transport") == 0) + } else if (strcmp(tokens[ti], "transport") == 0) { + sa_cnt->nb_trn++; rule->flags = TRANSPORT; - else { + } else { APP_CHECK(0, status, "unrecognized " "input \"%s\"", tokens[ti]); return; @@ -772,19 +781,21 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound) printf("\n"); } +struct ipsec_xf { + struct rte_crypto_sym_xform a; + struct rte_crypto_sym_xform b; +}; + struct sa_ctx { void *satbl; /* pointer to array of rte_ipsec_sa objects*/ - struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES]; - union { - struct { - struct rte_crypto_sym_xform a; - struct rte_crypto_sym_xform b; - }; - } xf[IPSEC_SA_MAX_ENTRIES]; + struct ipsec_sad sad; + struct ipsec_xf *xf; + uint32_t nb_sa; + struct ipsec_sa sa[]; }; static struct sa_ctx * -sa_create(const char *name, int32_t socket_id) +sa_create(const char *name, int32_t socket_id, uint32_t nb_sa) { char s[PATH_MAX]; struct sa_ctx *sa_ctx; @@ -793,20 +804,31 @@ sa_create(const char *name, int32_t socket_id) snprintf(s, sizeof(s), "%s_%u", name, socket_id); - /* Create SA array table */ + /* Create SA context */ printf("Creating SA context with %u maximum entries on socket %d\n", - IPSEC_SA_MAX_ENTRIES, socket_id); + nb_sa, socket_id); - mz_size = sizeof(struct sa_ctx); + mz_size = sizeof(struct ipsec_xf) * nb_sa; mz = rte_memzone_reserve(s, mz_size, socket_id, RTE_MEMZONE_1GB | RTE_MEMZONE_SIZE_HINT_ONLY); if (mz == NULL) { - printf("Failed to allocate SA DB memory\n"); + printf("Failed to allocate SA XFORM memory\n"); rte_errno = ENOMEM; return NULL; } - sa_ctx = (struct sa_ctx *)mz->addr; + sa_ctx = rte_malloc(NULL, sizeof(struct sa_ctx) + + sizeof(struct ipsec_sa) * nb_sa, RTE_CACHE_LINE_SIZE); + + if (sa_ctx == NULL) { + printf("Failed to allocate SA CTX memory\n"); + rte_errno = ENOMEM; + rte_memzone_free(mz); + return NULL; + } + + sa_ctx->xf = (struct ipsec_xf *)mz->addr; + sa_ctx->nb_sa = nb_sa; return sa_ctx; } @@ -949,7 +971,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0; for (i = 0; i < nb_entries; i++) { - idx = SPI2IDX(entries[i].spi); + idx = i; sa = &sa_ctx->sa[idx]; if (sa->spi != 0) { printf("Index %u already in use by SPI %u\n", @@ -957,6 +979,13 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], return -EINVAL; } *sa = entries[i]; + + if (inbound) { + rc = ipsec_sad_add(&sa_ctx->sad, sa); + if (rc != 0) + return rc; + } + sa->seq = 0; ips = ipsec_get_primary_session(sa); @@ -1237,8 +1266,7 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size) * one per session. */ static int -ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent, - uint32_t nb_ent, int32_t socket) +ipsec_satbl_init(struct sa_ctx *ctx, uint32_t nb_ent, int32_t socket) { int32_t rc, sz; uint32_t i, idx; @@ -1248,7 +1276,7 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent, struct rte_ipsec_sa_prm prm; /* determine SA size */ - idx = SPI2IDX(ent[0].spi); + idx = 0; fill_ipsec_sa_prm(&prm, ctx->sa + idx, NULL, NULL); sz = rte_ipsec_sa_size(&prm); if (sz < 0) { @@ -1271,7 +1299,7 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent, rc = 0; for (i = 0; i != nb_ent && rc == 0; i++) { - idx = SPI2IDX(ent[i].spi); + idx = i; sa = (struct rte_ipsec_sa *)((uintptr_t)ctx->satbl + sz * i); lsa = ctx->sa + idx; @@ -1286,18 +1314,16 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent, * Walk through all SA rules to find an SA with given SPI */ int -sa_spi_present(uint32_t spi, int inbound) +sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound) { uint32_t i, num; const struct ipsec_sa *sar; - if (inbound != 0) { - sar = sa_in; + sar = sa_ctx->sa; + if (inbound != 0) num = nb_sa_in; - } else { - sar = sa_out; + else num = nb_sa_out; - } for (i = 0; i != num; i++) { if (sar[i].spi == spi) @@ -1326,16 +1352,21 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id) if (nb_sa_in > 0) { name = "sa_in"; - ctx->sa_in = sa_create(name, socket_id); + ctx->sa_in = sa_create(name, socket_id, nb_sa_in); if (ctx->sa_in == NULL) rte_exit(EXIT_FAILURE, "Error [%d] creating SA " "context %s in socket %d\n", rte_errno, name, socket_id); + rc = ipsec_sad_create(name, &ctx->sa_in->sad, socket_id, + &sa_in_cnt); + if (rc != 0) + rte_exit(EXIT_FAILURE, "failed to init SAD\n"); + sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx); if (app_sa_prm.enable != 0) { - rc = ipsec_satbl_init(ctx->sa_in, sa_in, nb_sa_in, + rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in, socket_id); if (rc != 0) rte_exit(EXIT_FAILURE, @@ -1346,7 +1377,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id) if (nb_sa_out > 0) { name = "sa_out"; - ctx->sa_out = sa_create(name, socket_id); + ctx->sa_out = sa_create(name, socket_id, nb_sa_out); if (ctx->sa_out == NULL) rte_exit(EXIT_FAILURE, "Error [%d] creating SA " "context %s in socket %d\n", rte_errno, @@ -1355,7 +1386,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id) sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx); if (app_sa_prm.enable != 0) { - rc = ipsec_satbl_init(ctx->sa_out, sa_out, nb_sa_out, + rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out, socket_id); if (rc != 0) rte_exit(EXIT_FAILURE, @@ -1381,28 +1412,13 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx) return 0; } -static inline void -single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt, - void **sa_ret) +void +inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], + void *sa[], uint16_t nb_pkts) { - struct rte_esp_hdr *esp; - struct ip *ip; - uint32_t *src4_addr; - uint8_t *src6_addr; - struct ipsec_sa *sa; - void *result_sa; + uint32_t i; - *sa_ret = NULL; - - ip = rte_pktmbuf_mtod(pkt, struct ip *); - esp = rte_pktmbuf_mtod_offset(pkt, struct rte_esp_hdr *, pkt->l3_len); - - if (esp->spi == INVALID_SPI) - return; - - result_sa = sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))]; - if (rte_be_to_cpu_32(esp->spi) != sa->spi) - return; + sad_lookup(&sa_ctx->sad, pkts, sa, nb_pkts); /* * Mark need for inline offload fallback on the LSB of SA pointer. @@ -1413,40 +1429,14 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt, * pointer to prevent from unintentional use. Use ipsec_mask_saptr * to get valid struct pointer. */ - if (MBUF_NO_SEC_OFFLOAD(pkt) && sa->fallback_sessions > 0) { - uintptr_t intsa = (uintptr_t)sa; - intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG; - result_sa = (void *)intsa; + for (i = 0; i < nb_pkts; i++) { + if (MBUF_NO_SEC_OFFLOAD(pkts[i]) && (sa[i] != NULL) && + ((struct ipsec_sa *)sa[i])->fallback_sessions > 0) { + uintptr_t intsa = (uintptr_t)sa[i]; + intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG; + sa[i] = (void *)intsa; + } } - - switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) { - case IP4_TUNNEL: - src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src)); - if ((ip->ip_v == IPVERSION) && - (sa->src.ip.ip4 == *src4_addr) && - (sa->dst.ip.ip4 == *(src4_addr + 1))) - *sa_ret = result_sa; - break; - case IP6_TUNNEL: - src6_addr = RTE_PTR_ADD(ip, offsetof(struct ip6_hdr, ip6_src)); - if ((ip->ip_v == IP6_VERSION) && - !memcmp(&sa->src.ip.ip6.ip6, src6_addr, 16) && - !memcmp(&sa->dst.ip.ip6.ip6, src6_addr + 16, 16)) - *sa_ret = result_sa; - break; - case TRANSPORT: - *sa_ret = result_sa; - } -} - -void -inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], - void *sa[], uint16_t nb_pkts) -{ - uint32_t i; - - for (i = 0; i < nb_pkts; i++) - single_inbound_lookup(sa_ctx->sa, pkts[i], &sa[i]); } void diff --git a/examples/ipsec-secgw/sp4.c b/examples/ipsec-secgw/sp4.c index 3871c6c..1dcec52 100644 --- a/examples/ipsec-secgw/sp4.c +++ b/examples/ipsec-secgw/sp4.c @@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, * check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value(int inbound) +check_spi_value(struct sa_ctx *sa_ctx, int inbound) { uint32_t i, num, spi; - const struct acl4_rules *acr; + int32_t spi_idx; + struct acl4_rules *acr; if (inbound != 0) { acr = acl4_rules_in; @@ -508,11 +509,16 @@ check_spi_value(int inbound) for (i = 0; i != num; i++) { spi = acr[i].data.userdata; - if (spi != DISCARD && spi != BYPASS && - sa_spi_present(spi, inbound) < 0) { - RTE_LOG(ERR, IPSEC, "SPI %u is not present in SAD\n", - spi); - return -ENOENT; + if (spi != DISCARD && spi != BYPASS) { + spi_idx = sa_spi_present(sa_ctx, spi, inbound); + if (spi_idx < 0) { + RTE_LOG(ERR, IPSEC, + "SPI %u is not present in SAD\n", + spi); + return -ENOENT; + } + /* Update userdata with spi index */ + acr[i].data.userdata = spi_idx + 1; } } @@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id) rte_exit(EXIT_FAILURE, "Outbound SP DB for socket %u already " "initialized\n", socket_id); - if (check_spi_value(1) < 0) + if (check_spi_value(ctx->sa_in, 1) < 0) rte_exit(EXIT_FAILURE, "Inbound IPv4 SP DB has unmatched in SAD SPIs\n"); - if (check_spi_value(0) < 0) + if (check_spi_value(ctx->sa_out, 0) < 0) rte_exit(EXIT_FAILURE, "Outbound IPv4 SP DB has unmatched in SAD SPIs\n"); diff --git a/examples/ipsec-secgw/sp6.c b/examples/ipsec-secgw/sp6.c index d8be6b1..b489e15 100644 --- a/examples/ipsec-secgw/sp6.c +++ b/examples/ipsec-secgw/sp6.c @@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules, * check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value(int inbound) +check_spi_value(struct sa_ctx *sa_ctx, int inbound) { uint32_t i, num, spi; - const struct acl6_rules *acr; + int32_t spi_idx; + struct acl6_rules *acr; if (inbound != 0) { acr = acl6_rules_in; @@ -640,11 +641,16 @@ check_spi_value(int inbound) for (i = 0; i != num; i++) { spi = acr[i].data.userdata; - if (spi != DISCARD && spi != BYPASS && - sa_spi_present(spi, inbound) < 0) { - RTE_LOG(ERR, IPSEC, "SPI %u is not present in SAD\n", - spi); - return -ENOENT; + if (spi != DISCARD && spi != BYPASS) { + spi_idx = sa_spi_present(sa_ctx, spi, inbound); + if (spi_idx < 0) { + RTE_LOG(ERR, IPSEC, + "SPI %u is not present in SAD\n", + spi); + return -ENOENT; + } + /* Update userdata with spi index */ + acr[i].data.userdata = spi_idx + 1; } } @@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id) rte_exit(EXIT_FAILURE, "Outbound IPv6 SP DB for socket %u " "already initialized\n", socket_id); - if (check_spi_value(1) < 0) + if (check_spi_value(ctx->sa_in, 1) < 0) rte_exit(EXIT_FAILURE, "Inbound IPv6 SP DB has unmatched in SAD SPIs\n"); - if (check_spi_value(0) < 0) + if (check_spi_value(ctx->sa_out, 0) < 0) rte_exit(EXIT_FAILURE, "Outbound IPv6 SP DB has unmatched in SAD SPIs\n"); From patchwork Wed Dec 11 16:45:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 63777 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 09C6CA04F6; Wed, 11 Dec 2019 17:46:21 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1D5341BF80; Wed, 11 Dec 2019 17:45:48 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 826AC1BEDE for ; Wed, 11 Dec 2019 17:45:42 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Dec 2019 08:45:41 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,301,1571727600"; d="scan'208";a="238613922" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by fmsmga004.fm.intel.com with ESMTP; 11 Dec 2019 08:45:40 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Wed, 11 Dec 2019 16:45:34 +0000 Message-Id: <4c45de61634b8b9d533f09175e70efdfc6c9b647.1576081138.git.vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation 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" Parse config file and save SA's into linked list instead of flat array with predefined size. Signed-off-by: Vladimir Medvedkin --- examples/ipsec-secgw/sa.c | 78 +++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index 8cc7b17..32919fe 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "ipsec.h" #include "esp.h" @@ -133,11 +134,17 @@ const struct supported_aead_algo aead_algos[] = { } }; -static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES]; +struct ipsec_sa_mgmt { + STAILQ_ENTRY(ipsec_sa_mgmt) next; + struct ipsec_sa sa; +}; +STAILQ_HEAD(sa_head, ipsec_sa_mgmt); + +static struct sa_head sa_out_head = STAILQ_HEAD_INITIALIZER(sa_out_head); static uint32_t nb_sa_out; static struct ipsec_sa_cnt sa_out_cnt; -static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES]; +static struct sa_head sa_in_head = STAILQ_HEAD_INITIALIZER(sa_in_head); static uint32_t nb_sa_in; static struct ipsec_sa_cnt sa_in_cnt; @@ -228,6 +235,8 @@ void parse_sa_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status) { + struct ipsec_sa_mgmt *sa_mgmt; + struct sa_head *head; struct ipsec_sa *rule = NULL; struct rte_ipsec_session *ips; uint32_t ti; /*token index*/ @@ -243,27 +252,21 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, uint32_t portid_p = 0; uint32_t fallback_p = 0; + sa_mgmt = calloc(1, sizeof(struct ipsec_sa_mgmt)); + if (sa_mgmt == NULL) + return; + + rule = &sa_mgmt->sa; + if (strcmp(tokens[0], "in") == 0) { ri = &nb_sa_in; sa_cnt = &sa_in_cnt; - - APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status, - "too many sa rules, abort insertion\n"); - if (status->status < 0) - return; - - rule = &sa_in[*ri]; + head = &sa_in_head; rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; } else { ri = &nb_sa_out; sa_cnt = &sa_out_cnt; - - APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status, - "too many sa rules, abort insertion\n"); - if (status->status < 0) - return; - - rule = &sa_out[*ri]; + head = &sa_out_head; rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; } @@ -687,6 +690,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->portid = -1; } + STAILQ_INSERT_TAIL(head, sa_mgmt, next); *ri = *ri + 1; } @@ -956,12 +960,13 @@ sa_add_address_inline_crypto(struct ipsec_sa *sa) } static int -sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], +sa_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries, uint32_t nb_entries, uint32_t inbound, struct socket_ctx *skt_ctx) { + struct ipsec_sa_mgmt *sa_mgmt; struct ipsec_sa *sa; - uint32_t i, idx; + uint32_t idx; uint16_t iv_length, aad_length; int inline_status; int32_t rc; @@ -970,15 +975,18 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], /* for ESN upper 32 bits of SQN also need to be part of AAD */ aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0; - for (i = 0; i < nb_entries; i++) { - idx = i; + sa_mgmt = STAILQ_FIRST(entries); + for (idx = 0; idx < nb_entries; idx++) { + if (sa_mgmt == NULL) + rte_exit(EXIT_FAILURE, "SA mgmt queue is broken\n"); + sa = &sa_ctx->sa[idx]; if (sa->spi != 0) { printf("Index %u already in use by SPI %u\n", idx, sa->spi); return -EINVAL; } - *sa = entries[i]; + *sa = sa_mgmt->sa; if (inbound) { rc = ipsec_sad_add(&sa_ctx->sad, sa); @@ -1114,20 +1122,29 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], print_one_sa_rule(sa, inbound); } + sa_mgmt = STAILQ_NEXT(sa_mgmt, next); } + for (sa_mgmt = STAILQ_FIRST(entries); sa_mgmt != NULL; + sa_mgmt = STAILQ_FIRST(entries)) { + STAILQ_REMOVE_HEAD(entries, next); + free(sa_mgmt); + } + + STAILQ_INIT(entries); + return 0; } static inline int -sa_out_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], +sa_out_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries, uint32_t nb_entries, struct socket_ctx *skt_ctx) { return sa_add_rules(sa_ctx, entries, nb_entries, 0, skt_ctx); } static inline int -sa_in_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], +sa_in_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries, uint32_t nb_entries, struct socket_ctx *skt_ctx) { return sa_add_rules(sa_ctx, entries, nb_entries, 1, skt_ctx); @@ -1363,7 +1380,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id) if (rc != 0) rte_exit(EXIT_FAILURE, "failed to init SAD\n"); - sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx); + sa_in_add_rules(ctx->sa_in, &sa_in_head, nb_sa_in, ctx); if (app_sa_prm.enable != 0) { rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in, @@ -1383,7 +1400,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id) "context %s in socket %d\n", rte_errno, name, socket_id); - sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx); + sa_out_add_rules(ctx->sa_out, &sa_out_head, nb_sa_out, ctx); if (app_sa_prm.enable != 0) { rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out, @@ -1451,21 +1468,22 @@ outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[], /* * Select HW offloads to be used. + * Called before sa_init, so working with mgmt queue */ int sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, uint64_t *tx_offloads) { + struct ipsec_sa_mgmt *sa_mgmt; struct ipsec_sa *rule; - uint32_t idx_sa; enum rte_security_session_action_type rule_type; *rx_offloads = 0; *tx_offloads = 0; /* Check for inbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) { - rule = &sa_in[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_in_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type == @@ -1475,8 +1493,8 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, } /* Check for outbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) { - rule = &sa_out[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_out_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type ==