From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A6C14A2EDB for ; Wed, 2 Oct 2019 13:55:24 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 76D6F1BED8; Wed, 2 Oct 2019 13:55:24 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 91F101BED3 for ; Wed, 2 Oct 2019 13:55:22 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Oct 2019 04:55:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,574,1559545200"; d="scan'208";a="391557665" Received: from irsmsx110.ger.corp.intel.com ([163.33.3.25]) by fmsmga005.fm.intel.com with ESMTP; 02 Oct 2019 04:55:20 -0700 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.164]) by irsmsx110.ger.corp.intel.com ([169.254.15.189]) with mapi id 14.03.0439.000; Wed, 2 Oct 2019 12:55:19 +0100 From: "Ananyev, Konstantin" To: "Medvedkin, Vladimir" , "dev@dpdk.org" CC: "Iremonger, Bernard" , "akhil.goyal@nxp.com" Thread-Topic: [PATCH v2 2/5] ipsec: add SAD create/destroy implementation Thread-Index: AQHVeH1QaA1IGTpKQ0qojwiLycVF4adHOF9Q Date: Wed, 2 Oct 2019 11:55:19 +0000 Message-ID: <2601191342CEEE43887BDE71AB977258019196FD45@irsmsx105.ger.corp.intel.com> References: <86484bd6ca5228296c61716529afe80ece068bc6.1569867491.git.vladimir.medvedkin@intel.com> In-Reply-To: <86484bd6ca5228296c61716529afe80ece068bc6.1569867491.git.vladimir.medvedkin@intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiY2ZkMjU2NjQtZGI1My00ZWQ3LWE3ZmUtYTE4NWJiODkwNjIyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiNklEeW1UWmVrbkloU1VDWFg2SldKRmpnSFBxNml6RUpXa0Q1bnBnbVpzMjBaNllkVTJlS1k3Qm1OQ1prXC9ZbGIifQ== x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [163.33.239.180] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v2 2/5] ipsec: add SAD create/destroy implementation 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" >=20 > Replace rte_ipsec_sad_create(), rte_ipsec_sad_destroy() and > rte_ipsec_sad_find_existing() API stubs with actual > implementation. >=20 > Signed-off-by: Vladimir Medvedkin > --- > lib/librte_ipsec/Makefile | 2 +- > lib/librte_ipsec/ipsec_sad.c | 233 +++++++++++++++++++++++++++++++++++++= ++++-- > lib/librte_ipsec/meson.build | 2 +- > 3 files changed, 228 insertions(+), 9 deletions(-) >=20 > diff --git a/lib/librte_ipsec/Makefile b/lib/librte_ipsec/Makefile > index 5aaab72..81fb999 100644 > --- a/lib/librte_ipsec/Makefile > +++ b/lib/librte_ipsec/Makefile > @@ -10,7 +10,7 @@ CFLAGS +=3D -O3 > CFLAGS +=3D $(WERROR_FLAGS) -I$(SRCDIR) > CFLAGS +=3D -DALLOW_EXPERIMENTAL_API > LDLIBS +=3D -lrte_eal -lrte_mempool -lrte_mbuf -lrte_net > -LDLIBS +=3D -lrte_cryptodev -lrte_security > +LDLIBS +=3D -lrte_cryptodev -lrte_security -lrte_hash >=20 > EXPORT_MAP :=3D rte_ipsec_version.map >=20 > diff --git a/lib/librte_ipsec/ipsec_sad.c b/lib/librte_ipsec/ipsec_sad.c > index 703be65..5e05c6f 100644 > --- a/lib/librte_ipsec/ipsec_sad.c > +++ b/lib/librte_ipsec/ipsec_sad.c > @@ -2,10 +2,53 @@ > * Copyright(c) 2019 Intel Corporation > */ >=20 > +#include > #include > +#include > +#include > +#include > +#include > +#include > +#include >=20 > #include "rte_ipsec_sad.h" >=20 > +/* > + * Rules are stored in three hash tables depending on key_type. > + * Each rule will also be stored in SPI_ONLY table. > + * for each data entry within this table last two bits are reserved to > + * indicate presence of entries with the same SPI in DIP and DIP+SIP tab= les. > + */ > + > +#define IPSEC_SAD_NAMESIZE 64 > +#define SAD_PREFIX "SAD_" > +/* "SAD_" */ > +#define SAD_FORMAT SAD_PREFIX "%s" > + > +#define DEFAULT_HASH_FUNC rte_jhash > +#define MIN_HASH_ENTRIES 8U /* From rte_cuckoo_hash.h */ > + > +struct hash_cnt { > + uint32_t cnt_dip; > + uint32_t cnt_dip_sip; > +}; > + > +struct rte_ipsec_sad { > + char name[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 > + * as a helper struct. > + */ > + __extension__ struct hash_cnt cnt_arr[]; > +}; > + > +TAILQ_HEAD(rte_ipsec_sad_list, rte_tailq_entry); > +static struct rte_tailq_elem rte_ipsec_sad_tailq =3D { > + .name =3D "RTE_IPSEC_SAD", > +}; > +EAL_REGISTER_TAILQ(rte_ipsec_sad_tailq) > + > int > rte_ipsec_sad_add(__rte_unused struct rte_ipsec_sad *sad, > __rte_unused const union rte_ipsec_sad_key *key, > @@ -23,22 +66,198 @@ rte_ipsec_sad_del(__rte_unused struct rte_ipsec_sad = *sad, > } >=20 > struct rte_ipsec_sad * > -rte_ipsec_sad_create(__rte_unused const char *name, > - __rte_unused const struct rte_ipsec_sad_conf *conf) > +rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *= conf) > { > - return NULL; > + char hash_name[RTE_HASH_NAMESIZE]; > + struct rte_tailq_entry *te; > + struct rte_ipsec_sad_list *sad_list; > + struct rte_ipsec_sad *sad, *tmp_sad =3D NULL; > + struct rte_hash_parameters hash_params =3D {0}; > + int ret; > + uint32_t sa_sum; > + > + RTE_BUILD_BUG_ON(RTE_IPSEC_SAD_KEY_TYPE_MASK !=3D 3); > + > + if ((name =3D=3D NULL) || (conf =3D=3D NULL) || > + (conf->max_sa[RTE_IPSEC_SAD_SPI_ONLY] =3D=3D 0) || > + (conf->max_sa[RTE_IPSEC_SAD_SPI_DIP] =3D=3D 0) || > + (conf->max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] =3D=3D 0)) { Why not to allow 0 for some of the key_types, you are doing RTE_MAX() below= anyway? I.E: If (... || (conf->max_sa[RTE_IPSEC_SAD_SPI_ONLY] =3D=3D 0 && conf->max_sa[RTE_IPSEC_SAD_SPI_DIP] =3D=3D 0 && conf->max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] =3D=3D 0)) > + rte_errno =3D EINVAL; > + return NULL; > + } > + > + /** Init SAD*/ > + sa_sum =3D RTE_MAX(MIN_HASH_ENTRIES, > + conf->max_sa[RTE_IPSEC_SAD_SPI_ONLY]) + > + RTE_MAX(MIN_HASH_ENTRIES, > + conf->max_sa[RTE_IPSEC_SAD_SPI_DIP]) + > + RTE_MAX(MIN_HASH_ENTRIES, > + conf->max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP]); > + sad =3D rte_zmalloc_socket(NULL, sizeof(*sad) + > + (sizeof(struct hash_cnt) * sa_sum), > + RTE_CACHE_LINE_SIZE, conf->socket_id); > + if (sad =3D=3D NULL) { > + rte_errno =3D ENOMEM; > + return NULL; > + } > + > + ret =3D snprintf(sad->name, sizeof(sad->name), SAD_FORMAT, name); > + if (ret < 0 || ret >=3D (int)sizeof(sad->name)) { I think your forgot rte_free(sad) here. Alternative approach would be to have it in different order: char sad_name[sad->name]; ... ret =3D snprintf(sad_name, sizeof(sad_name), SAD_FORMAT, name); ... sad =3D rte_zmalloc_socket(...); memcpy(sad->name, sad_name, sizeof(sad->name)); > + rte_errno =3D ENAMETOOLONG; > + return NULL; > + } > + > + hash_params.hash_func =3D DEFAULT_HASH_FUNC; > + hash_params.hash_func_init_val =3D rte_rand(); > + hash_params.socket_id =3D conf->socket_id; > + hash_params.name =3D hash_name; > + if (conf->flags & RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY) > + hash_params.extra_flag =3D RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY; > + > + /** Init hash[RTE_IPSEC_SAD_SPI_ONLY] for SPI only */ > + ret =3D snprintf(hash_name, sizeof(hash_name), > + "sad_%p_1", sad); "sad_1_%p" to keep checkpatch happy? :) > + if (ret < 0 || ret >=3D (int)sizeof(hash_name)) { I don't think this format can cause hash_name[] overflow, so no point to check return value here. Though if you do - you need to call sad_destroy() then. But my suggestion would be just to remove that if(...) {...}.=20 > + rte_errno =3D ENAMETOOLONG; > + return NULL; > + } > + hash_params.key_len =3D sizeof(((struct rte_ipsec_sadv4_key *)0)->spi); > + hash_params.entries =3D sa_sum; > + sad->hash[RTE_IPSEC_SAD_SPI_ONLY] =3D rte_hash_create(&hash_params); > + if (sad->hash[RTE_IPSEC_SAD_SPI_ONLY] =3D=3D NULL) { > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + > + /** Init hash_2 for SPI + DIP */ > + ret =3D snprintf(hash_name, sizeof(hash_name), > + "sad_%p_2", sad); > + if (ret < 0 || ret >=3D (int)sizeof(hash_name)) { Same comments as above, can be safely removed I think. > + rte_errno =3D ENAMETOOLONG; > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + if (conf->flags & RTE_IPSEC_SAD_FLAG_IPV6) > + hash_params.key_len +=3D > + sizeof(((struct rte_ipsec_sadv6_key *)0)->dip); > + else > + hash_params.key_len +=3D > + sizeof(((struct rte_ipsec_sadv4_key *)0)->dip); > + hash_params.entries =3D RTE_MAX(MIN_HASH_ENTRIES, > + conf->max_sa[RTE_IPSEC_SAD_SPI_DIP]); > + sad->hash[RTE_IPSEC_SAD_SPI_DIP] =3D rte_hash_create(&hash_params); > + if (sad->hash[RTE_IPSEC_SAD_SPI_DIP] =3D=3D NULL) { > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + > + /** Init hash_3 for SPI + DIP + SIP */ > + ret =3D snprintf(hash_name, sizeof(hash_name), > + "sad_%p_3", name); > + if (ret < 0 || ret >=3D (int)sizeof(hash_name)) { Same comments as above, can be safely removed I think. > + rte_errno =3D ENAMETOOLONG; > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + if (conf->flags & RTE_IPSEC_SAD_FLAG_IPV6) > + hash_params.key_len +=3D > + sizeof(((struct rte_ipsec_sadv6_key *)0)->sip); > + else > + hash_params.key_len +=3D > + sizeof(((struct rte_ipsec_sadv4_key *)0)->sip); > + hash_params.entries =3D RTE_MAX(MIN_HASH_ENTRIES, > + conf->max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP]); > + sad->hash[RTE_IPSEC_SAD_SPI_DIP_SIP] =3D rte_hash_create(&hash_params); > + if (sad->hash[RTE_IPSEC_SAD_SPI_DIP_SIP] =3D=3D NULL) { > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + > + sad_list =3D RTE_TAILQ_CAST(rte_ipsec_sad_tailq.head, > + rte_ipsec_sad_list); > + rte_mcfg_tailq_write_lock(); > + /* guarantee there's no existing */ > + TAILQ_FOREACH(te, sad_list, next) { > + tmp_sad =3D (struct rte_ipsec_sad *)te->data; > + if (strncmp(name, tmp_sad->name, IPSEC_SAD_NAMESIZE) =3D=3D 0) I think it should be just: if (strcmp, sad->name, tmp_sad->name) > + break; > + } > + if (te !=3D NULL) { > + rte_mcfg_tailq_write_unlock(); > + rte_errno =3D EEXIST; > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + > + /* allocate tailq entry */ > + te =3D rte_zmalloc("IPSEC_SAD_TAILQ_ENTRY", sizeof(*te), 0); > + if (te =3D=3D NULL) { > + rte_mcfg_tailq_write_unlock(); > + rte_errno =3D ENOMEM; > + rte_ipsec_sad_destroy(sad); > + return NULL; > + } > + > + te->data =3D (void *)sad; > + TAILQ_INSERT_TAIL(sad_list, te, next); > + rte_mcfg_tailq_write_unlock(); > + return sad; > } >=20 > struct rte_ipsec_sad * > -rte_ipsec_sad_find_existing(__rte_unused const char *name) > +rte_ipsec_sad_find_existing(const char *name) > { > - return NULL; > + struct rte_ipsec_sad *sad =3D NULL; > + struct rte_tailq_entry *te; > + struct rte_ipsec_sad_list *sad_list; > + > + > + sad_list =3D RTE_TAILQ_CAST(rte_ipsec_sad_tailq.head, > + rte_ipsec_sad_list); > + > + rte_mcfg_tailq_read_lock(); > + TAILQ_FOREACH(te, sad_list, next) { > + sad =3D (struct rte_ipsec_sad *) te->data; > + if (strncmp(name, sad->name, IPSEC_SAD_NAMESIZE) =3D=3D 0) As I can see you trying to compare: "XXX" with "SAD_XXX". ? Think you need to do something like that: char tmp_name[IPSEC_SAD_NAMESIZE]; ... snprintf(tmp_name, sizeof(tmp_name), SAD_FORMAT, name);=20 ... if (strcmp(tmp_name, sad->name) =3D=3D 0) ... > + break; > + } > + rte_mcfg_tailq_read_unlock(); > + > + if (te =3D=3D NULL) { > + rte_errno =3D ENOENT; > + return NULL; > + } > + > + return sad; > } >=20 > void > -rte_ipsec_sad_destroy(__rte_unused struct rte_ipsec_sad *sad) > +rte_ipsec_sad_destroy(struct rte_ipsec_sad *sad) > { > - return; > + struct rte_tailq_entry *te; > + struct rte_ipsec_sad_list *sad_list; > + > + if (sad =3D=3D NULL) > + return; > + > + sad_list =3D RTE_TAILQ_CAST(rte_ipsec_sad_tailq.head, > + rte_ipsec_sad_list); > + rte_mcfg_tailq_write_lock(); > + TAILQ_FOREACH(te, sad_list, next) { > + if (te->data =3D=3D (void *)sad) > + break; > + } > + if (te !=3D NULL) > + TAILQ_REMOVE(sad_list, te, next); > + > + rte_mcfg_tailq_write_unlock(); > + > + rte_hash_free(sad->hash[RTE_IPSEC_SAD_SPI_ONLY]); > + rte_hash_free(sad->hash[RTE_IPSEC_SAD_SPI_DIP]); > + rte_hash_free(sad->hash[RTE_IPSEC_SAD_SPI_DIP_SIP]); > + rte_free(sad); > + if (te !=3D NULL) > + rte_free(te); > } >=20 > int > diff --git a/lib/librte_ipsec/meson.build b/lib/librte_ipsec/meson.build > index 91b9867..7035852 100644 > --- a/lib/librte_ipsec/meson.build > +++ b/lib/librte_ipsec/meson.build > @@ -7,4 +7,4 @@ sources =3D files('esp_inb.c', 'esp_outb.c', 'sa.c', 'ses= .c', 'ipsec_sad.c') >=20 > headers =3D files('rte_ipsec.h', 'rte_ipsec_group.h', 'rte_ipsec_sa.h', = 'rte_ipsec_sad.h') >=20 > -deps +=3D ['mbuf', 'net', 'cryptodev', 'security'] > +deps +=3D ['mbuf', 'net', 'cryptodev', 'security', 'hash'] > -- > 2.7.4