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 D8C85A052F; Wed, 29 Jan 2020 15:06:32 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8036B1BFFD; Wed, 29 Jan 2020 15:06:19 +0100 (CET) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id DA2A41BFF5 for ; Wed, 29 Jan 2020 15:06:14 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Jan 2020 06:06:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,378,1574150400"; d="scan'208";a="217955191" Received: from silpixa00400072.ir.intel.com ([10.237.222.213]) by orsmga007.jf.intel.com with ESMTP; 29 Jan 2020 06:06:12 -0800 From: Vladimir Medvedkin To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, akhil.goyal@nxp.com Date: Wed, 29 Jan 2020 14:06:04 +0000 Message-Id: <1580306768-110555-3-git-send-email-vladimir.medvedkin@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> References: <1580306768-110555-1-git-send-email-vladimir.medvedkin@intel.com> In-Reply-To: <1579012036-326214-1-git-send-email-vladimir.medvedkin@intel.com> References: <1579012036-326214-1-git-send-email-vladimir.medvedkin@intel.com> Subject: [dpdk-dev] [PATCH v5 2/6] 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 --- 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__ */ -- 2.7.4