From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from dpdk.org (dpdk.org [92.243.14.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 7A363A04F0;
	Mon, 13 Jan 2020 13:55:44 +0100 (CET)
Received: from [92.243.14.124] (localhost [127.0.0.1])
	by dpdk.org (Postfix) with ESMTP id 3CA851D528;
	Mon, 13 Jan 2020 13:55:32 +0100 (CET)
Received: from mga06.intel.com (mga06.intel.com [134.134.136.31])
 by dpdk.org (Postfix) with ESMTP id 496491C20D
 for <dev@dpdk.org>; Mon, 13 Jan 2020 13:55:28 +0100 (CET)
X-Amp-Result: SKIPPED(no attachment in message)
X-Amp-File-Uploaded: False
Received: from fmsmga002.fm.intel.com ([10.253.24.26])
 by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;
 13 Jan 2020 04:55:27 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.69,429,1571727600"; d="scan'208";a="255876832"
Received: from silpixa00400072.ir.intel.com ([10.237.222.213])
 by fmsmga002.fm.intel.com with ESMTP; 13 Jan 2020 04:55:26 -0800
From: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
To: dev@dpdk.org
Cc: konstantin.ananyev@intel.com,
	akhil.goyal@nxp.com
Date: Mon, 13 Jan 2020 12:55:19 +0000
Message-Id: <1578920122-228017-3-git-send-email-vladimir.medvedkin@intel.com>
X-Mailer: git-send-email 2.7.4
In-Reply-To: <1578920122-228017-1-git-send-email-vladimir.medvedkin@intel.com>
References: <1578920122-228017-1-git-send-email-vladimir.medvedkin@intel.com>
In-Reply-To: <cover.1576684589.git.vladimir.medvedkin@intel.com>
References: <cover.1576684589.git.vladimir.medvedkin@intel.com>
Subject: [dpdk-dev] [PATCH v3 2/5] 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 <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

Add initial support for librte_ipsec SAD library

Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
 examples/ipsec-secgw/ipsec.h | 11 ++++++
 examples/ipsec-secgw/sad.c   | 94 ++++++++++++++++++++++++++++++++++++++++++++
 examples/ipsec-secgw/sad.h   | 74 ++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 examples/ipsec-secgw/sad.c
 create mode 100644 examples/ipsec-secgw/sad.h

diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 8e07521..132286c 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -53,6 +53,17 @@ struct ipsec_xform;
 struct rte_mbuf;
 
 struct ipsec_sa;
+/*
+ * Keeps number of configured SA's of each type:
+ * transport
+ * v4 tunnel
+ * v6 tunnel
+ */
+struct ipsec_sa_cnt {
+	uint32_t	nb_trn;
+	uint32_t	nb_v4_tun;
+	uint32_t	nb_v6_tun;
+};
 
 typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa,
 		struct rte_crypto_op *cop);
diff --git a/examples/ipsec-secgw/sad.c b/examples/ipsec-secgw/sad.c
new file mode 100644
index 0000000..1445c48
--- /dev/null
+++ b/examples/ipsec-secgw/sad.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <rte_errno.h>
+
+#include "ipsec.h"
+#include "sad.h"
+
+int
+ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa)
+{
+	int ret;
+	union rte_ipsec_sad_key key = { {0} };
+
+	/* spi field is common for ipv4 and ipv6 key types */
+	key.v4.spi = rte_cpu_to_be_32(sa->spi);
+	switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
+	case IP4_TUNNEL:
+		key.v4.dip = rte_cpu_to_be_32(sa->dst.ip.ip4);
+		key.v4.sip = rte_cpu_to_be_32(sa->src.ip.ip4);
+		ret = rte_ipsec_sad_add(sad->sad_v4, &key,
+				RTE_IPSEC_SAD_SPI_DIP_SIP, sa);
+		if (ret != 0)
+			return ret;
+		break;
+	case IP6_TUNNEL:
+		memcpy(key.v6.dip, sa->dst.ip.ip6.ip6,
+				sizeof(key.v6.dip));
+		memcpy(key.v6.sip, sa->src.ip.ip6.ip6,
+				sizeof(key.v6.sip));
+		ret = rte_ipsec_sad_add(sad->sad_v6, &key,
+				RTE_IPSEC_SAD_SPI_DIP_SIP, sa);
+		if (ret != 0)
+			return ret;
+		break;
+	case TRANSPORT:
+		if (sp4_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
+			ret = rte_ipsec_sad_add(sad->sad_v4, &key,
+				RTE_IPSEC_SAD_SPI_ONLY, sa);
+			if (ret != 0)
+				return ret;
+		}
+
+		if (sp6_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
+			ret = rte_ipsec_sad_add(sad->sad_v6, &key,
+				RTE_IPSEC_SAD_SPI_ONLY, sa);
+			if (ret != 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int
+ipsec_sad_create(const char *name, struct ipsec_sad *sad,
+	int socket_id, struct ipsec_sa_cnt *sa_cnt)
+{
+	int ret;
+	struct rte_ipsec_sad_conf sad_conf;
+	char sad_name[RTE_IPSEC_SAD_NAMESIZE];
+
+	ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v4", name);
+	if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
+		return -ENAMETOOLONG;
+
+	sad_conf.socket_id = socket_id;
+	sad_conf.flags = 0;
+	/* Make SAD have extra 25% of required number of entries */
+	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_trn * 5 / 4;
+	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0;
+	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = sa_cnt->nb_v4_tun * 5 / 4;
+
+	if ((sa_cnt->nb_trn != 0) || (sa_cnt->nb_v4_tun != 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_DIP_SIP] = sa_cnt->nb_v6_tun * 5 / 4;
+
+	if ((sa_cnt->nb_trn != 0) || (sa_cnt->nb_v6_tun != 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..e754d57
--- /dev/null
+++ b/examples/ipsec-secgw/sad.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef __SAD_H__
+#define __SAD_H__
+
+#include <rte_ipsec_sad.h>
+
+struct ipsec_sad {
+	struct rte_ipsec_sad *sad_v4;
+	struct rte_ipsec_sad *sad_v6;
+};
+
+int ipsec_sad_create(const char *name, struct ipsec_sad *sad,
+	int socket_id, struct ipsec_sa_cnt *sa_cnt);
+
+int ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa);
+
+static inline void
+sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[],
+	void *sa[], uint16_t nb_pkts)
+{
+	uint32_t i;
+	uint32_t nb_v4 = 0, nb_v6 = 0;
+	struct rte_esp_hdr *esp;
+	struct rte_ipv4_hdr *ipv4;
+	struct rte_ipv6_hdr *ipv6;
+	struct rte_ipsec_sadv4_key	v4[nb_pkts];
+	struct rte_ipsec_sadv6_key	v6[nb_pkts];
+	int v4_idxes[nb_pkts];
+	int v6_idxes[nb_pkts];
+	const union rte_ipsec_sad_key	*keys_v4[nb_pkts];
+	const union rte_ipsec_sad_key	*keys_v6[nb_pkts];
+	void *v4_res[nb_pkts];
+	void *v6_res[nb_pkts];
+
+	for (i = 0; i < nb_pkts; i++) {
+		ipv4 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv4_hdr *);
+		esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *,
+				pkts[i]->l3_len);
+		if ((ipv4->version_ihl >> 4) == IPVERSION) {
+			v4[nb_v4].spi = esp->spi;
+			v4[nb_v4].dip = ipv4->dst_addr;
+			v4[nb_v4].sip = ipv4->src_addr;
+			keys_v4[nb_v4] = (const union rte_ipsec_sad_key *)
+						&v4[nb_v4];
+			v4_idxes[nb_v4++] = i;
+		} else {
+			ipv6 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv6_hdr *);
+			v6[nb_v6].spi = esp->spi;
+			memcpy(v6[nb_v6].dip, ipv6->dst_addr,
+					sizeof(ipv6->dst_addr));
+			memcpy(v6[nb_v6].sip, ipv6->src_addr,
+					sizeof(ipv6->src_addr));
+			keys_v6[nb_v6] = (const union rte_ipsec_sad_key *)
+						&v6[nb_v6];
+			v6_idxes[nb_v6++] = i;
+		}
+	}
+
+	if (nb_v4 != 0)
+		rte_ipsec_sad_lookup(sad->sad_v4, keys_v4, v4_res, nb_v4);
+	if (nb_v6 != 0)
+		rte_ipsec_sad_lookup(sad->sad_v6, keys_v6, v6_res, nb_v6);
+
+	for (i = 0; i < nb_v4; i++)
+		sa[v4_idxes[i]] = v4_res[i];
+
+	for (i = 0; i < nb_v6; i++)
+		sa[v6_idxes[i]] = v6_res[i];
+}
+
+#endif /* __SAD_H__ */
-- 
2.7.4