From patchwork Fri Jan 31 17:39:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65440 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 05D0DA0524; Fri, 31 Jan 2020 18:39:59 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CE7971C123; Fri, 31 Jan 2020 18:39:53 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 90B211C10F for ; Fri, 31 Jan 2020 18:39:50 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:50 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202779" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:49 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:38 +0000 Message-Id: <1580492385-120134-2-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 1/8] 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 Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- 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 Fri Jan 31 17:39:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65441 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 B1F1AA0524; Fri, 31 Jan 2020 18:40:09 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7DF691C12A; Fri, 31 Jan 2020 18:40:00 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id E740A1C10F for ; Fri, 31 Jan 2020 18:39:51 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202784" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:50 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:39 +0000 Message-Id: <1580492385-120134-3-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 2/8] 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 Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- examples/ipsec-secgw/ipsec.h | 7 +++ examples/ipsec-secgw/sad.c | 109 +++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 75 +++++++++++++++++++++++++++++ 3 files changed, 191 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..9ddb5d9 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -53,6 +53,13 @@ struct ipsec_xform; struct rte_mbuf; struct ipsec_sa; +/* + * Keeps number of configured SA's for each address family: + */ +struct ipsec_sa_cnt { + uint32_t nb_v4; + uint32_t nb_v6; +}; 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..fd31101 --- /dev/null +++ b/examples/ipsec-secgw/sad.c @@ -0,0 +1,109 @@ +/* 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; + void *tmp = NULL; + union rte_ipsec_sad_key key = { {0} }; + const union rte_ipsec_sad_key *lookup_key[1]; + + /* spi field is common for ipv4 and ipv6 key types */ + key.v4.spi = rte_cpu_to_be_32(sa->spi); + lookup_key[0] = &key; + switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) { + case IP4_TUNNEL: + rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1); + if (tmp != NULL) + return -EEXIST; + + ret = rte_ipsec_sad_add(sad->sad_v4, &key, + RTE_IPSEC_SAD_SPI_ONLY, sa); + if (ret != 0) + return ret; + break; + case IP6_TUNNEL: + rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1); + if (tmp != NULL) + return -EEXIST; + + ret = rte_ipsec_sad_add(sad->sad_v6, &key, + RTE_IPSEC_SAD_SPI_ONLY, sa); + if (ret != 0) + return ret; + break; + case TRANSPORT: + if (sp4_spi_present(sa->spi, 1, NULL, NULL) >= 0) { + rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1); + if (tmp != NULL) + return -EEXIST; + + 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) { + rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1); + if (tmp != NULL) + return -EEXIST; + + 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]; + + if ((name == NULL) || (sad == NULL) || (sa_cnt == NULL)) + return -EINVAL; + + 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_v4 * 5 / 4; + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0; + sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0; + + if (sa_cnt->nb_v4 != 0) { + 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_ONLY] = sa_cnt->nb_v6 * 5 / 4; + + if (sa_cnt->nb_v6 != 0) { + 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..29ed0f8 --- /dev/null +++ b/examples/ipsec-secgw/sad.h @@ -0,0 +1,75 @@ +/* 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]; + + /* split received packets by address family into two arrays */ + 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 Fri Jan 31 17:39:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65442 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 2DC2DA0524; Fri, 31 Jan 2020 18:40:18 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 324911C133; Fri, 31 Jan 2020 18:40:02 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id A7F791C11C for ; Fri, 31 Jan 2020 18:39:53 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202796" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:51 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:40 +0000 Message-Id: <1580492385-120134-4-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 3/8] 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 Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 182 +++++++++++++++++++++---------------- examples/ipsec-secgw/sp4.c | 24 +++-- examples/ipsec-secgw/sp6.c | 24 +++-- 7 files changed, 139 insertions(+), 101 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 9ddb5d9..5988d59 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -38,7 +38,6 @@ #define DEFAULT_MAX_CATEGORIES 1 #define IPSEC_SA_MAX_ENTRIES (128) /* must be power of 2, max 2 power 30 */ -#define SPI2IDX(spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1)) #define INVALID_SPI (0) #define DISCARD INVALID_SPI @@ -359,7 +358,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..d10a6ec 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,17 @@ 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++; rule->flags = IP4_TUNNEL; - else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) + } else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) { + sa_cnt->nb_v6++; rule->flags = IP6_TUNNEL; - else if (strcmp(tokens[ti], "transport") == 0) + } else if (strcmp(tokens[ti], "transport") == 0) { + sa_cnt->nb_v4++; + sa_cnt->nb_v6++; rule->flags = TRANSPORT; - else { + } else { APP_CHECK(0, status, "unrecognized " "input \"%s\"", tokens[ti]); return; @@ -772,19 +782,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 +805,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 +972,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 +980,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 +1267,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 +1277,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 +1300,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 +1315,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 +1353,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 +1378,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 +1387,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 +1413,18 @@ 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_arr[], uint16_t nb_pkts) { - struct rte_esp_hdr *esp; + uint32_t i; struct ip *ip; uint32_t *src4_addr; uint8_t *src6_addr; - struct ipsec_sa *sa; void *result_sa; + struct ipsec_sa *sa; - *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_arr, nb_pkts); /* * Mark need for inline offload fallback on the LSB of SA pointer. @@ -1413,43 +1435,47 @@ 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 (sa_arr[i] == NULL) + continue; - 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) && + result_sa = sa = sa_arr[i]; + if (MBUF_NO_SEC_OFFLOAD(pkts[i]) && + sa->fallback_sessions > 0) { + uintptr_t intsa = (uintptr_t)sa; + intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG; + result_sa = (void *)intsa; + } + + ip = rte_pktmbuf_mtod(pkts[i], struct ip *); + 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_arr[i] = result_sa; + else + sa_arr[i] = NULL; + 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; + sa_arr[i] = result_sa; + else + sa_arr[i] = NULL; + break; + case TRANSPORT: + sa_arr[i] = 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 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[], void *sa[], uint16_t nb_pkts) { 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 Fri Jan 31 17:39:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65443 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 B88EBA0524; Fri, 31 Jan 2020 18:40:29 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7BB2E1C138; Fri, 31 Jan 2020 18:40:03 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 1E7CD1C127 for ; Fri, 31 Jan 2020 18:39:54 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202804" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:53 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:41 +0000 Message-Id: <1580492385-120134-5-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 4/8] 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" Get rid of maximum SA limitation. Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI. Signed-off-by: Vladimir Medvedkin Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- examples/ipsec-secgw/ipsec.h | 1 - examples/ipsec-secgw/parser.c | 2 ++ examples/ipsec-secgw/parser.h | 3 ++ examples/ipsec-secgw/sa.c | 74 +++++++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 5988d59..3c77232 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -37,7 +37,6 @@ #define DEFAULT_MAX_CATEGORIES 1 -#define IPSEC_SA_MAX_ENTRIES (128) /* must be power of 2, max 2 power 30 */ #define INVALID_SPI (0) #define DISCARD INVALID_SPI diff --git a/examples/ipsec-secgw/parser.c b/examples/ipsec-secgw/parser.c index fc8c238..67df170 100644 --- a/examples/ipsec-secgw/parser.c +++ b/examples/ipsec-secgw/parser.c @@ -642,6 +642,8 @@ parse_cfg_file(const char *cfg_filename) cmdline_stdin_exit(cl); fclose(f); + sa_sort_arr(); + return 0; error_exit: diff --git a/examples/ipsec-secgw/parser.h b/examples/ipsec-secgw/parser.h index 6b8a100..1f8bd3e 100644 --- a/examples/ipsec-secgw/parser.h +++ b/examples/ipsec-secgw/parser.h @@ -75,6 +75,9 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status); void +sa_sort_arr(void); + +void parse_sa_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status); diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index d10a6ec..b3b83e3 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -133,11 +133,15 @@ const struct supported_aead_algo aead_algos[] = { } }; -static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES]; +#define SA_INIT_NB 128 + +static struct ipsec_sa *sa_out; +static uint32_t sa_out_sz; 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 ipsec_sa *sa_in; +static uint32_t sa_in_sz; static uint32_t nb_sa_in; static struct ipsec_sa_cnt sa_in_cnt; @@ -224,6 +228,31 @@ parse_key_string(const char *key_str, uint8_t *key) return nb_bytes; } +static int +extend_sa_arr(struct ipsec_sa **sa_tbl, uint32_t cur_cnt, uint32_t *cur_sz) +{ + if (*sa_tbl == NULL) { + *sa_tbl = calloc(SA_INIT_NB, sizeof(struct ipsec_sa)); + if (*sa_tbl == NULL) + return -1; + *cur_sz = SA_INIT_NB; + return 0; + } + + if (cur_cnt >= *cur_sz) { + *sa_tbl = realloc(*sa_tbl, + *cur_sz * sizeof(struct ipsec_sa) * 2); + if (*sa_tbl == NULL) + return -1; + /* clean reallocated extra space */ + memset(&(*sa_tbl)[*cur_sz], 0, + *cur_sz * sizeof(struct ipsec_sa)); + *cur_sz *= 2; + } + + return 0; +} + void parse_sa_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status) @@ -246,23 +275,15 @@ 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"); - if (status->status < 0) + if (extend_sa_arr(&sa_in, nb_sa_in, &sa_in_sz) < 0) return; - rule = &sa_in[*ri]; 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) + if (extend_sa_arr(&sa_out, nb_sa_out, &sa_out_sz) < 0) return; - rule = &sa_out[*ri]; rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; } @@ -1311,13 +1332,24 @@ ipsec_satbl_init(struct sa_ctx *ctx, uint32_t nb_ent, int32_t socket) return rc; } +static int +sa_cmp(const void *p, const void *q) +{ + uint32_t spi1 = ((const struct ipsec_sa *)p)->spi; + uint32_t spi2 = ((const struct ipsec_sa *)q)->spi; + + return (int)(spi1 - spi2); +} + /* * Walk through all SA rules to find an SA with given SPI */ int sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound) { - uint32_t i, num; + uint32_t num; + struct ipsec_sa *sa; + struct ipsec_sa tmpl; const struct ipsec_sa *sar; sar = sa_ctx->sa; @@ -1326,10 +1358,11 @@ sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound) else num = nb_sa_out; - for (i = 0; i != num; i++) { - if (sar[i].spi == spi) - return i; - } + tmpl.spi = spi; + + sa = bsearch(&tmpl, sar, num, sizeof(struct ipsec_sa), sa_cmp); + if (sa != NULL) + return RTE_PTR_DIFF(sa, sar) / sizeof(struct ipsec_sa); return -ENOENT; } @@ -1522,3 +1555,10 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, } return 0; } + +void +sa_sort_arr(void) +{ + qsort(sa_in, nb_sa_in, sizeof(struct ipsec_sa), sa_cmp); + qsort(sa_out, nb_sa_out, sizeof(struct ipsec_sa), sa_cmp); +} From patchwork Fri Jan 31 17:39:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65444 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 89405A0524; Fri, 31 Jan 2020 18:40:40 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4AD001C194; Fri, 31 Jan 2020 18:40:05 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 96DC51C127 for ; Fri, 31 Jan 2020 18:39:56 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202816" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:55 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:42 +0000 Message-Id: <1580492385-120134-6-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 5/8] examples/ipsec-secgw: get rid of maximum sp 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" Get rid of maximum SP limitation. Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI. Signed-off-by: Vladimir Medvedkin Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- examples/ipsec-secgw/parser.c | 2 + examples/ipsec-secgw/parser.h | 6 +++ examples/ipsec-secgw/sp4.c | 90 +++++++++++++++++++++++++++++++++---------- examples/ipsec-secgw/sp6.c | 88 ++++++++++++++++++++++++++++++++---------- 4 files changed, 144 insertions(+), 42 deletions(-) diff --git a/examples/ipsec-secgw/parser.c b/examples/ipsec-secgw/parser.c index 67df170..65eb7e9 100644 --- a/examples/ipsec-secgw/parser.c +++ b/examples/ipsec-secgw/parser.c @@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename) fclose(f); sa_sort_arr(); + sp4_sort_arr(); + sp6_sort_arr(); return 0; diff --git a/examples/ipsec-secgw/parser.h b/examples/ipsec-secgw/parser.h index 1f8bd3e..6e764fe 100644 --- a/examples/ipsec-secgw/parser.h +++ b/examples/ipsec-secgw/parser.h @@ -67,10 +67,16 @@ int parse_range(const char *token, uint16_t *low, uint16_t *high); void +sp4_sort_arr(void); + +void parse_sp4_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status); void +sp6_sort_arr(void); + +void parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status); diff --git a/examples/ipsec-secgw/sp4.c b/examples/ipsec-secgw/sp4.c index 1dcec52..beddd7b 100644 --- a/examples/ipsec-secgw/sp4.c +++ b/examples/ipsec-secgw/sp4.c @@ -15,7 +15,7 @@ #include "ipsec.h" #include "parser.h" -#define MAX_ACL_RULE_NUM 1024 +#define INIT_ACL_RULE_NUM 128 #define IPV4_DST_FROM_SP(acr) \ (rte_cpu_to_be_32((acr).field[DST_FIELD_IPV4].value.u32)) @@ -97,11 +97,39 @@ static struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = { RTE_ACL_RULE_DEF(acl4_rules, RTE_DIM(ip4_defs)); -static struct acl4_rules acl4_rules_out[MAX_ACL_RULE_NUM]; +static struct acl4_rules *acl4_rules_out; static uint32_t nb_acl4_rules_out; +static uint32_t sp_out_sz; -static struct acl4_rules acl4_rules_in[MAX_ACL_RULE_NUM]; +static struct acl4_rules *acl4_rules_in; static uint32_t nb_acl4_rules_in; +static uint32_t sp_in_sz; + +static int +extend_sp_arr(struct acl4_rules **sp_tbl, uint32_t cur_cnt, uint32_t *cur_sz) +{ + if (*sp_tbl == NULL) { + *sp_tbl = calloc(INIT_ACL_RULE_NUM, sizeof(struct acl4_rules)); + if (*sp_tbl == NULL) + return -1; + *cur_sz = INIT_ACL_RULE_NUM; + return 0; + } + + if (cur_cnt >= *cur_sz) { + *sp_tbl = realloc(*sp_tbl, + *cur_sz * sizeof(struct acl4_rules) * 2); + if (*sp_tbl == NULL) + return -1; + /* clean reallocated extra space */ + memset(&(*sp_tbl)[*cur_sz], 0, + *cur_sz * sizeof(struct acl4_rules)); + *cur_sz *= 2; + } + + return 0; +} + void parse_sp4_tokens(char **tokens, uint32_t n_tokens, @@ -127,9 +155,8 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens, if (strcmp(tokens[1], "in") == 0) { ri = &nb_acl4_rules_in; - APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, - "too many sp rules, abort insertion\n"); - if (status->status < 0) + if (extend_sp_arr(&acl4_rules_in, nb_acl4_rules_in, + &sp_in_sz) < 0) return; rule_ipv4 = &acl4_rules_in[*ri]; @@ -137,9 +164,8 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens, } else if (strcmp(tokens[1], "out") == 0) { ri = &nb_acl4_rules_out; - APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, - "too many sp rules, abort insertion\n"); - if (status->status < 0) + if (extend_sp_arr(&acl4_rules_out, nb_acl4_rules_out, + &sp_out_sz) < 0) return; rule_ipv4 = &acl4_rules_out[*ri]; @@ -451,7 +477,7 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, struct rte_acl_config acl_build_param; struct rte_acl_ctx *ctx; - printf("Creating SP context with %u max rules\n", MAX_ACL_RULE_NUM); + printf("Creating SP context with %u rules\n", rules_nb); memset(&acl_param, 0, sizeof(acl_param)); @@ -464,7 +490,7 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, acl_param.name = s; acl_param.socket_id = socketid; acl_param.rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ip4_defs)); - acl_param.max_rule_num = MAX_ACL_RULE_NUM; + acl_param.max_rule_num = rules_nb; ctx = rte_acl_create(&acl_param); if (ctx == NULL) @@ -566,6 +592,16 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id) "specified\n"); } +static int +sp_cmp(const void *p, const void *q) +{ + uint32_t spi1 = ((const struct acl4_rules *)p)->data.userdata; + uint32_t spi2 = ((const struct acl4_rules *)q)->data.userdata; + + return (int)(spi1 - spi2); +} + + /* * Search though SP rules for given SPI. */ @@ -573,8 +609,10 @@ int sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], uint32_t mask[2]) { - uint32_t i, num; + uint32_t num; + struct acl4_rules *rule; const struct acl4_rules *acr; + struct acl4_rules tmpl; if (inbound != 0) { acr = acl4_rules_in; @@ -584,17 +622,27 @@ sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], num = nb_acl4_rules_out; } - for (i = 0; i != num; i++) { - if (acr[i].data.userdata == spi) { - if (NULL != ip_addr && NULL != mask) { - ip_addr[0].ip.ip4 = IPV4_SRC_FROM_SP(acr[i]); - ip_addr[1].ip.ip4 = IPV4_DST_FROM_SP(acr[i]); - mask[0] = IPV4_SRC_MASK_FROM_SP(acr[i]); - mask[1] = IPV4_DST_MASK_FROM_SP(acr[i]); - } - return i; + tmpl.data.userdata = spi; + + rule = bsearch(&tmpl, acr, num, sizeof(struct acl4_rules), sp_cmp); + if (rule != NULL) { + if (NULL != ip_addr && NULL != mask) { + ip_addr[0].ip.ip4 = IPV4_SRC_FROM_SP(*rule); + ip_addr[1].ip.ip4 = IPV4_DST_FROM_SP(*rule); + mask[0] = IPV4_SRC_MASK_FROM_SP(*rule); + mask[1] = IPV4_DST_MASK_FROM_SP(*rule); } + return RTE_PTR_DIFF(rule, acr) / sizeof(struct acl4_rules); } return -ENOENT; } + +void +sp4_sort_arr(void) +{ + qsort(acl4_rules_in, nb_acl4_rules_in, sizeof(struct acl4_rules), + sp_cmp); + qsort(acl4_rules_out, nb_acl4_rules_out, sizeof(struct acl4_rules), + sp_cmp); +} diff --git a/examples/ipsec-secgw/sp6.c b/examples/ipsec-secgw/sp6.c index b489e15..328e085 100644 --- a/examples/ipsec-secgw/sp6.c +++ b/examples/ipsec-secgw/sp6.c @@ -15,7 +15,7 @@ #include "ipsec.h" #include "parser.h" -#define MAX_ACL_RULE_NUM 1024 +#define INIT_ACL_RULE_NUM 128 #define IPV6_FROM_SP(acr, fidx_low, fidx_high) \ (((uint64_t)(acr).field[(fidx_high)].value.u32 << 32) | \ @@ -146,11 +146,38 @@ static struct rte_acl_field_def ip6_defs[IP6_NUM] = { RTE_ACL_RULE_DEF(acl6_rules, RTE_DIM(ip6_defs)); -static struct acl6_rules acl6_rules_out[MAX_ACL_RULE_NUM]; +static struct acl6_rules *acl6_rules_out; static uint32_t nb_acl6_rules_out; +static uint32_t sp_out_sz; -static struct acl6_rules acl6_rules_in[MAX_ACL_RULE_NUM]; +static struct acl6_rules *acl6_rules_in; static uint32_t nb_acl6_rules_in; +static uint32_t sp_in_sz; + +static int +extend_sp_arr(struct acl6_rules **sp_tbl, uint32_t cur_cnt, uint32_t *cur_sz) +{ + if (*sp_tbl == NULL) { + *sp_tbl = calloc(INIT_ACL_RULE_NUM, sizeof(struct acl6_rules)); + if (*sp_tbl == NULL) + return -1; + *cur_sz = INIT_ACL_RULE_NUM; + return 0; + } + + if (cur_cnt >= *cur_sz) { + *sp_tbl = realloc(*sp_tbl, + *cur_sz * sizeof(struct acl6_rules) * 2); + if (*sp_tbl == NULL) + return -1; + /* clean reallocated extra space */ + memset(&(*sp_tbl)[*cur_sz], 0, + *cur_sz * sizeof(struct acl6_rules)); + *cur_sz *= 2; + } + + return 0; +} void parse_sp6_tokens(char **tokens, uint32_t n_tokens, @@ -176,9 +203,8 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, if (strcmp(tokens[1], "in") == 0) { ri = &nb_acl6_rules_in; - APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too " - "many sp rules, abort insertion\n"); - if (status->status < 0) + if (extend_sp_arr(&acl6_rules_in, nb_acl6_rules_in, + &sp_in_sz) < 0) return; rule_ipv6 = &acl6_rules_in[*ri]; @@ -186,9 +212,8 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, } else if (strcmp(tokens[1], "out") == 0) { ri = &nb_acl6_rules_out; - APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too " - "many sp rules, abort insertion\n"); - if (status->status < 0) + if (extend_sp_arr(&acl6_rules_out, nb_acl6_rules_out, + &sp_out_sz) < 0) return; rule_ipv6 = &acl6_rules_out[*ri]; @@ -583,7 +608,7 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules, struct rte_acl_config acl_build_param; struct rte_acl_ctx *ctx; - printf("Creating SP context with %u max rules\n", MAX_ACL_RULE_NUM); + printf("Creating SP context with %u rules\n", rules_nb); memset(&acl_param, 0, sizeof(acl_param)); @@ -596,7 +621,7 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules, acl_param.name = s; acl_param.socket_id = socketid; acl_param.rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ip6_defs)); - acl_param.max_rule_num = MAX_ACL_RULE_NUM; + acl_param.max_rule_num = rules_nb; ctx = rte_acl_create(&acl_param); if (ctx == NULL) @@ -698,6 +723,15 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id) "specified\n"); } +static int +sp_cmp(const void *p, const void *q) +{ + uint32_t spi1 = ((const struct acl6_rules *)p)->data.userdata; + uint32_t spi2 = ((const struct acl6_rules *)q)->data.userdata; + + return (int)(spi1 - spi2); +} + /* * Search though SP rules for given SPI. */ @@ -705,8 +739,10 @@ int sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], uint32_t mask[2]) { - uint32_t i, num; + uint32_t num; + struct acl6_rules *rule; const struct acl6_rules *acr; + struct acl6_rules tmpl; if (inbound != 0) { acr = acl6_rules_in; @@ -716,17 +752,27 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], num = nb_acl6_rules_out; } - for (i = 0; i != num; i++) { - if (acr[i].data.userdata == spi) { - if (NULL != ip_addr && NULL != mask) { - IPV6_SRC_FROM_SP(ip_addr[0], acr[i]); - IPV6_DST_FROM_SP(ip_addr[1], acr[i]); - IPV6_SRC_MASK_FROM_SP(mask[0], acr[i]); - IPV6_DST_MASK_FROM_SP(mask[1], acr[i]); - } - return i; + tmpl.data.userdata = spi; + + rule = bsearch(&tmpl, acr, num, sizeof(struct acl6_rules), sp_cmp); + if (rule != NULL) { + if (NULL != ip_addr && NULL != mask) { + IPV6_SRC_FROM_SP(ip_addr[0], *rule); + IPV6_DST_FROM_SP(ip_addr[1], *rule); + IPV6_SRC_MASK_FROM_SP(mask[0], *rule); + IPV6_DST_MASK_FROM_SP(mask[1], *rule); } + return RTE_PTR_DIFF(rule, acr) / sizeof(struct acl6_rules); } return -ENOENT; } + +void +sp6_sort_arr(void) +{ + qsort(acl6_rules_in, nb_acl6_rules_in, sizeof(struct acl6_rules), + sp_cmp); + qsort(acl6_rules_out, nb_acl6_rules_out, sizeof(struct acl6_rules), + sp_cmp); +} From patchwork Fri Jan 31 17:39:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65445 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 61FC8A0524; Fri, 31 Jan 2020 18:40:51 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 56C891C199; Fri, 31 Jan 2020 18:40:07 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 2B7341C127 for ; Fri, 31 Jan 2020 18:39:58 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202821" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:56 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:43 +0000 Message-Id: <1580492385-120134-7-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 6/8] examples/ipsec-secgw: add SAD cache 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" Introduce SAD cache. Stores the most recent SA in a per lcore cache. Cache represents flat array containing SA's indexed by SPI. Signed-off-by: Vladimir Medvedkin Acked-by: Konstantin Ananyev Acked-by: Akhil Goyal --- examples/ipsec-secgw/ipsec-secgw.c | 30 +++++++++- examples/ipsec-secgw/ipsec.h | 1 + examples/ipsec-secgw/sa.c | 32 +---------- examples/ipsec-secgw/sad.c | 40 +++++++++++++ examples/ipsec-secgw/sad.h | 111 ++++++++++++++++++++++++++++++++++--- 5 files changed, 173 insertions(+), 41 deletions(-) diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 3e5f82e..32ecd26 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -46,6 +46,7 @@ #include "ipsec.h" #include "parser.h" +#include "sad.h" #define RTE_LOGTYPE_IPSEC RTE_LOGTYPE_USER1 @@ -192,7 +193,10 @@ static uint32_t mtu_size = RTE_ETHER_MTU; static uint64_t frag_ttl_ns = MAX_FRAG_TTL_NS; /* application wide librte_ipsec/SA parameters */ -struct app_sa_prm app_sa_prm = {.enable = 0}; +struct app_sa_prm app_sa_prm = { + .enable = 0, + .cache_sz = SA_CACHE_SZ + }; static const char *cfgfile; struct lcore_rx_queue { @@ -1102,7 +1106,7 @@ main_loop(__attribute__((unused)) void *dummy) uint16_t portid; uint8_t queueid; struct lcore_conf *qconf; - int32_t socket_id; + int32_t rc, socket_id; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; struct lcore_rx_queue *rxql; @@ -1132,6 +1136,14 @@ main_loop(__attribute__((unused)) void *dummy) qconf->frag.pool_dir = socket_ctx[socket_id].mbuf_pool; qconf->frag.pool_indir = socket_ctx[socket_id].mbuf_pool_indir; + rc = ipsec_sad_lcore_cache_init(app_sa_prm.cache_sz); + if (rc != 0) { + RTE_LOG(ERR, IPSEC, + "SAD cache init on lcore %u, failed with code: %d\n", + lcore_id, rc); + return rc; + } + if (qconf->nb_rx_queue == 0) { RTE_LOG(DEBUG, IPSEC, "lcore %u has nothing to do\n", lcore_id); @@ -1271,6 +1283,7 @@ print_usage(const char *prgname) " [-w REPLAY_WINDOW_SIZE]" " [-e]" " [-a]" + " [-c]" " -f CONFIG_FILE" " --config (port,queue,lcore)[,(port,queue,lcore)]" " [--single-sa SAIDX]" @@ -1290,6 +1303,8 @@ print_usage(const char *prgname) " size for each SA\n" " -e enables ESN\n" " -a enables SA SQN atomic behaviour\n" + " -c specifies inbound SAD cache size,\n" + " zero value disables the cache (default value: 128)\n" " -f CONFIG_FILE: Configuration file\n" " --config (port,queue,lcore): Rx queue configuration\n" " --single-sa SAIDX: Use single SA index for outbound traffic,\n" @@ -1442,7 +1457,7 @@ parse_args(int32_t argc, char **argv) argvopt = argv; - while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:", + while ((opt = getopt_long(argc, argvopt, "aelp:Pu:f:j:w:c:", lgopts, &option_index)) != EOF) { switch (opt) { @@ -1501,6 +1516,15 @@ parse_args(int32_t argc, char **argv) app_sa_prm.enable = 1; app_sa_prm.flags |= RTE_IPSEC_SAFLAG_SQN_ATOM; break; + case 'c': + ret = parse_decimal(optarg); + if (ret < 0) { + printf("Invalid SA cache size: %s\n", optarg); + print_usage(prgname); + return -1; + } + app_sa_prm.cache_sz = ret; + break; case CMD_LINE_OPT_CONFIG_NUM: ret = parse_config(optarg); if (ret) { diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h index 3c77232..4f2fd61 100644 --- a/examples/ipsec-secgw/ipsec.h +++ b/examples/ipsec-secgw/ipsec.h @@ -81,6 +81,7 @@ struct app_sa_prm { uint32_t enable; /* use librte_ipsec API for ipsec pkt processing */ uint32_t window_size; /* replay window size */ uint32_t enable_esn; /* enable/disable ESN support */ + uint32_t cache_sz; /* per lcore SA cache size */ uint64_t flags; /* rte_ipsec_sa_prm.flags */ }; diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index b3b83e3..099a11b 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -839,7 +839,7 @@ sa_create(const char *name, int32_t socket_id, uint32_t nb_sa) return NULL; } - sa_ctx = rte_malloc(NULL, sizeof(struct sa_ctx) + + sa_ctx = rte_zmalloc(NULL, sizeof(struct sa_ctx) + sizeof(struct ipsec_sa) * nb_sa, RTE_CACHE_LINE_SIZE); if (sa_ctx == NULL) { @@ -1451,9 +1451,6 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], void *sa_arr[], uint16_t nb_pkts) { uint32_t i; - struct ip *ip; - uint32_t *src4_addr; - uint8_t *src6_addr; void *result_sa; struct ipsec_sa *sa; @@ -1479,32 +1476,7 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG; result_sa = (void *)intsa; } - - ip = rte_pktmbuf_mtod(pkts[i], struct ip *); - 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_arr[i] = result_sa; - else - sa_arr[i] = NULL; - 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_arr[i] = result_sa; - else - sa_arr[i] = NULL; - break; - case TRANSPORT: - sa_arr[i] = result_sa; - } + sa_arr[i] = result_sa; } } diff --git a/examples/ipsec-secgw/sad.c b/examples/ipsec-secgw/sad.c index fd31101..5b2c0e6 100644 --- a/examples/ipsec-secgw/sad.c +++ b/examples/ipsec-secgw/sad.c @@ -3,10 +3,17 @@ */ #include +#include #include "ipsec.h" #include "sad.h" +RTE_DEFINE_PER_LCORE(struct ipsec_sad_cache, sad_cache) = { + .v4 = NULL, + .v6 = NULL, + .mask = 0, +}; + int ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa) { @@ -65,6 +72,39 @@ ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa) return 0; } +/* + * Init per lcore SAD cache. + * Must be called by every processing lcore. + */ +int +ipsec_sad_lcore_cache_init(uint32_t nb_cache_ent) +{ + uint32_t cache_elem; + size_t cache_mem_sz; + struct ipsec_sad_cache *cache; + + cache = &RTE_PER_LCORE(sad_cache); + + cache_elem = rte_align32pow2(nb_cache_ent); + cache_mem_sz = sizeof(struct ipsec_sa *) * cache_elem; + + if (cache_mem_sz != 0) { + cache->v4 = rte_zmalloc_socket(NULL, cache_mem_sz, + RTE_CACHE_LINE_SIZE, rte_socket_id()); + if (cache->v4 == NULL) + return -rte_errno; + + cache->v6 = rte_zmalloc_socket(NULL, cache_mem_sz, + RTE_CACHE_LINE_SIZE, rte_socket_id()); + if (cache->v6 == NULL) + return -rte_errno; + + cache->mask = cache_elem - 1; + } + + return 0; +} + int ipsec_sad_create(const char *name, struct ipsec_sad *sad, int socket_id, struct ipsec_sa_cnt *sa_cnt) diff --git a/examples/ipsec-secgw/sad.h b/examples/ipsec-secgw/sad.h index 29ed0f8..3f92db2 100644 --- a/examples/ipsec-secgw/sad.h +++ b/examples/ipsec-secgw/sad.h @@ -7,6 +7,17 @@ #include +#define SA_CACHE_SZ 128 +#define SPI2IDX(spi, mask) ((spi) & (mask)) + +struct ipsec_sad_cache { + struct ipsec_sa **v4; + struct ipsec_sa **v6; + uint32_t mask; +}; + +RTE_DECLARE_PER_LCORE(struct ipsec_sad_cache, sad_cache); + struct ipsec_sad { struct rte_ipsec_sad *sad_v4; struct rte_ipsec_sad *sad_v6; @@ -17,8 +28,42 @@ int ipsec_sad_create(const char *name, struct ipsec_sad *sad, int ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa); +int ipsec_sad_lcore_cache_init(uint32_t nb_cache_ent); + +static inline int +cmp_sa_key(struct ipsec_sa *sa, int is_v4, struct rte_ipv4_hdr *ipv4, + struct rte_ipv6_hdr *ipv6) +{ + int sa_type = WITHOUT_TRANSPORT_VERSION(sa->flags); + if ((sa_type == TRANSPORT) || + /* IPv4 check */ + (is_v4 && (sa_type == IP4_TUNNEL) && + (sa->src.ip.ip4 == ipv4->src_addr) && + (sa->dst.ip.ip4 == ipv4->dst_addr)) || + /* IPv6 check */ + (!is_v4 && (sa_type == IP6_TUNNEL) && + (!memcmp(sa->src.ip.ip6.ip6, ipv6->src_addr, 16)) && + (!memcmp(sa->dst.ip.ip6.ip6, ipv6->dst_addr, 16)))) + return 1; + + return 0; +} + static inline void -sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[], +sa_cache_update(struct ipsec_sa **sa_cache, struct ipsec_sa *sa, uint32_t mask) +{ + uint32_t cache_idx; + + /* SAD cache is disabled */ + if (mask == 0) + return; + + cache_idx = SPI2IDX(sa->spi, mask); + sa_cache[cache_idx] = sa; +} + +static inline void +sad_lookup(struct ipsec_sad *sad, struct rte_mbuf *pkts[], void *sa[], uint16_t nb_pkts) { uint32_t i; @@ -34,13 +79,39 @@ sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[], const union rte_ipsec_sad_key *keys_v6[nb_pkts]; void *v4_res[nb_pkts]; void *v6_res[nb_pkts]; + uint32_t spi, cache_idx; + struct ipsec_sad_cache *cache; + struct ipsec_sa *cached_sa; + int is_ipv4; + + cache = &RTE_PER_LCORE(sad_cache); /* split received packets by address family into two arrays */ for (i = 0; i < nb_pkts; i++) { ipv4 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv4_hdr *); + ipv6 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv6_hdr *); esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *, pkts[i]->l3_len); - if ((ipv4->version_ihl >> 4) == IPVERSION) { + + is_ipv4 = ((ipv4->version_ihl >> 4) == IPVERSION); + spi = rte_be_to_cpu_32(esp->spi); + cache_idx = SPI2IDX(spi, cache->mask); + + if (is_ipv4) { + cached_sa = (cache->mask != 0) ? + cache->v4[cache_idx] : NULL; + /* check SAD cache entry */ + if ((cached_sa != NULL) && (cached_sa->spi == spi)) { + if (cmp_sa_key(cached_sa, 1, ipv4, ipv6)) { + /* cache hit */ + sa[i] = cached_sa; + continue; + } + } + /* + * cache miss + * preparing sad key to proceed with sad lookup + */ v4[nb_v4].spi = esp->spi; v4[nb_v4].dip = ipv4->dst_addr; v4[nb_v4].sip = ipv4->src_addr; @@ -48,7 +119,14 @@ sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[], &v4[nb_v4]; v4_idxes[nb_v4++] = i; } else { - ipv6 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv6_hdr *); + cached_sa = (cache->mask != 0) ? + cache->v6[cache_idx] : NULL; + if ((cached_sa != NULL) && (cached_sa->spi == spi)) { + if (cmp_sa_key(cached_sa, 0, ipv4, ipv6)) { + sa[i] = cached_sa; + continue; + } + } v6[nb_v6].spi = esp->spi; memcpy(v6[nb_v6].dip, ipv6->dst_addr, sizeof(ipv6->dst_addr)); @@ -65,11 +143,28 @@ sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[], 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]; + for (i = 0; i < nb_v4; i++) { + ipv4 = rte_pktmbuf_mtod(pkts[v4_idxes[i]], + struct rte_ipv4_hdr *); + if ((v4_res[i] != NULL) && + (cmp_sa_key(v4_res[i], 1, ipv4, NULL))) { + sa[v4_idxes[i]] = v4_res[i]; + sa_cache_update(cache->v4, (struct ipsec_sa *)v4_res[i], + cache->mask); + } else + sa[v4_idxes[i]] = NULL; + } + for (i = 0; i < nb_v6; i++) { + ipv6 = rte_pktmbuf_mtod(pkts[v6_idxes[i]], + struct rte_ipv6_hdr *); + if ((v6_res[i] != NULL) && + (cmp_sa_key(v6_res[i], 0, NULL, ipv6))) { + sa[v6_idxes[i]] = v6_res[i]; + sa_cache_update(cache->v6, (struct ipsec_sa *)v6_res[i], + cache->mask); + } else + sa[v6_idxes[i]] = NULL; + } } #endif /* __SAD_H__ */ From patchwork Fri Jan 31 17:39:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65446 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 5BF0AA0524; Fri, 31 Jan 2020 18:41:01 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B72371C1A0; Fri, 31 Jan 2020 18:40:08 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 56DDB1C0D7 for ; Fri, 31 Jan 2020 18:39:59 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:39:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202828" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:58 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:44 +0000 Message-Id: <1580492385-120134-8-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 7/8] examples/ipsec-secgw: set/use mbuf ptype 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" Set mbuf ptype in prepare_one_packet() after parsing ether_type. Use mbuf ptype after to recognize packet's address family. Signed-off-by: Vladimir Medvedkin Acked-by: Konstantin Ananyev --- examples/ipsec-secgw/ipsec-secgw.c | 2 ++ examples/ipsec-secgw/sad.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 32ecd26..4799bc9 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -323,6 +323,7 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) } pkt->l2_len = 0; pkt->l3_len = sizeof(*iph4); + pkt->packet_type |= RTE_PTYPE_L3_IPV4; } else if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6)) { int next_proto; size_t l3len, ext_len; @@ -357,6 +358,7 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) } pkt->l2_len = 0; pkt->l3_len = l3len; + pkt->packet_type |= RTE_PTYPE_L3_IPV6; } else { /* Unknown/Unsupported type, drop the packet */ RTE_LOG(ERR, IPSEC, "Unsupported packet type 0x%x\n", diff --git a/examples/ipsec-secgw/sad.h b/examples/ipsec-secgw/sad.h index 3f92db2..55712ba 100644 --- a/examples/ipsec-secgw/sad.h +++ b/examples/ipsec-secgw/sad.h @@ -93,7 +93,7 @@ sad_lookup(struct ipsec_sad *sad, struct rte_mbuf *pkts[], esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *, pkts[i]->l3_len); - is_ipv4 = ((ipv4->version_ihl >> 4) == IPVERSION); + is_ipv4 = pkts[i]->packet_type & RTE_PTYPE_L3_IPV4; spi = rte_be_to_cpu_32(esp->spi); cache_idx = SPI2IDX(spi, cache->mask); From patchwork Fri Jan 31 17:39:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Medvedkin X-Patchwork-Id: 65447 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 9E331A0524; Fri, 31 Jan 2020 18:41:13 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E17F81C1AE; Fri, 31 Jan 2020 18:40:23 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 723841C0D7 for ; Fri, 31 Jan 2020 18:40:00 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Jan 2020 09:40:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,386,1574150400"; d="scan'208";a="223202836" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga008.jf.intel.com with ESMTP; 31 Jan 2020 09:39:59 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Fri, 31 Jan 2020 17:39:45 +0000 Message-Id: <1580492385-120134-9-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580492385-120134-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v6 8/8] doc: update ipsec-secgw guide 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 new SAD cache option in ipsec-secgw guide. Signed-off-by: Vladimir Medvedkin Acked-by: Konstantin Ananyev --- doc/guides/sample_app_ug/ipsec_secgw.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/guides/sample_app_ug/ipsec_secgw.rst b/doc/guides/sample_app_ug/ipsec_secgw.rst index d6d8d44..5ec9b1e 100644 --- a/doc/guides/sample_app_ug/ipsec_secgw.rst +++ b/doc/guides/sample_app_ug/ipsec_secgw.rst @@ -93,6 +93,7 @@ The application has a number of command line options:: ./build/ipsec-secgw [EAL options] -- -p PORTMASK -P -u PORTMASK -j FRAMESIZE -l -w REPLAY_WINOW_SIZE -e -a + -c SAD_CACHE_SIZE --config (port,queue,lcore)[,(port,queue,lcore] --single-sa SAIDX --rxoffload MASK @@ -132,6 +133,11 @@ Where: * ``-a``: enables Security Association sequence number atomic behavior (available only with librte_ipsec code path). +* ``-c``: specifies the SAD cache size. Stores the most recent SA in a per + lcore cache. Cache represents flat array containing SA's indexed by SPI. + Zero value disables cache. + Default value: 128. + * ``--config (port,queue,lcore)[,(port,queue,lcore)]``: determines which queues from which ports are mapped to which cores.