All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h
@ 2019-12-11 16:13 Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD Vladimir Medvedkin
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2019-12-11 16:13 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE

Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
 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_<name>" */
 #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 */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD
  2019-12-11 16:13 [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Vladimir Medvedkin
@ 2019-12-11 16:13 ` Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 3/4] examples/ipsec-secgw: integrate " Vladimir Medvedkin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2019-12-11 16:13 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

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   | 90 ++++++++++++++++++++++++++++++++++++++++++++
 examples/ipsec-secgw/sad.h   | 74 ++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+)
 create mode 100644 examples/ipsec-secgw/sad.c
 create mode 100644 examples/ipsec-secgw/sad.h

diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 8e07521..132286c 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -53,6 +53,17 @@ struct ipsec_xform;
 struct rte_mbuf;
 
 struct ipsec_sa;
+/*
+ * Keeps number of configured SA's of each type:
+ * transport
+ * v4 tunnel
+ * v6 tunnel
+ */
+struct ipsec_sa_cnt {
+	uint32_t	nb_trn;
+	uint32_t	nb_v4_tun;
+	uint32_t	nb_v6_tun;
+};
 
 typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa,
 		struct rte_crypto_op *cop);
diff --git a/examples/ipsec-secgw/sad.c b/examples/ipsec-secgw/sad.c
new file mode 100644
index 0000000..bcac462
--- /dev/null
+++ b/examples/ipsec-secgw/sad.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#include <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;
+
+	sad->sad_v4 = rte_ipsec_sad_create(sad_name, &sad_conf);
+	if (sad->sad_v4 == NULL)
+		return -rte_errno;
+
+	ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v6", name);
+	if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
+		return -ENAMETOOLONG;
+	sad_conf.flags = RTE_IPSEC_SAD_FLAG_IPV6;
+	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = sa_cnt->nb_v6_tun * 5 / 4;
+
+	sad->sad_v6 = rte_ipsec_sad_create(name, &sad_conf);
+	if (sad->sad_v6 == NULL)
+		return -rte_errno;
+
+	return 0;
+}
diff --git a/examples/ipsec-secgw/sad.h b/examples/ipsec-secgw/sad.h
new file mode 100644
index 0000000..e754d57
--- /dev/null
+++ b/examples/ipsec-secgw/sad.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef __SAD_H__
+#define __SAD_H__
+
+#include <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


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [dpdk-dev] [PATCH 3/4] examples/ipsec-secgw: integrate inbound SAD
  2019-12-11 16:13 [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD Vladimir Medvedkin
@ 2019-12-11 16:13 ` Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation Vladimir Medvedkin
  2019-12-11 16:43 ` [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Medvedkin, Vladimir
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2019-12-11 16:13 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

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 <vladimir.medvedkin@intel.com>
---
 examples/ipsec-secgw/Makefile      |   1 +
 examples/ipsec-secgw/ipsec-secgw.c |   4 +-
 examples/ipsec-secgw/ipsec.h       |   2 +-
 examples/ipsec-secgw/meson.build   |   2 +-
 examples/ipsec-secgw/sa.c          | 160 +++++++++++++++++--------------------
 examples/ipsec-secgw/sp4.c         |  24 +++---
 examples/ipsec-secgw/sp6.c         |  24 +++---
 7 files changed, 110 insertions(+), 107 deletions(-)

diff --git a/examples/ipsec-secgw/Makefile b/examples/ipsec-secgw/Makefile
index 851123b..8734b15 100644
--- a/examples/ipsec-secgw/Makefile
+++ b/examples/ipsec-secgw/Makefile
@@ -12,6 +12,7 @@ SRCS-y += esp.c
 SRCS-y += sp4.c
 SRCS-y += sp6.c
 SRCS-y += sa.c
+SRCS-y += sad.c
 SRCS-y += rt.c
 SRCS-y += ipsec_process.c
 SRCS-y += ipsec-secgw.c
diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c
index 3b5aaf6..3e5f82e 100644
--- a/examples/ipsec-secgw/ipsec-secgw.c
+++ b/examples/ipsec-secgw/ipsec-secgw.c
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,
 			continue;
 		}
 
-		sa_idx = SPI2IDX(res);
+		sa_idx = res - 1;
 		if (!inbound_sa_check(sa, m, sa_idx)) {
 			rte_pktmbuf_free(m);
 			continue;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip,
 	j = 0;
 	for (i = 0; i < ip->num; i++) {
 		m = ip->pkts[i];
-		sa_idx = SPI2IDX(ip->res[i]);
+		sa_idx = ip->res[i] - 1;
 		if (ip->res[i] == DISCARD)
 			rte_pktmbuf_free(m);
 		else if (ip->res[i] == BYPASS)
diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
index 132286c..f731bf8 100644
--- a/examples/ipsec-secgw/ipsec.h
+++ b/examples/ipsec-secgw/ipsec.h
@@ -363,7 +363,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
  * or -ENOENT otherwise.
  */
 int
-sa_spi_present(uint32_t spi, int inbound);
+sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound);
 
 void
 sa_init(struct socket_ctx *ctx, int32_t socket_id);
diff --git a/examples/ipsec-secgw/meson.build b/examples/ipsec-secgw/meson.build
index 9ece345..6bd5b78 100644
--- a/examples/ipsec-secgw/meson.build
+++ b/examples/ipsec-secgw/meson.build
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec']
 allow_experimental_apis = true
 sources = files(
 	'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c',
-	'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c'
+	'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c'
 )
diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 7f046e3..8cc7b17 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -24,6 +24,7 @@
 #include "ipsec.h"
 #include "esp.h"
 #include "parser.h"
+#include "sad.h"
 
 #define IPDEFTTL 64
 
@@ -134,9 +135,11 @@ const struct supported_aead_algo aead_algos[] = {
 
 static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES];
 static uint32_t nb_sa_out;
+static struct ipsec_sa_cnt sa_out_cnt;
 
 static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES];
 static uint32_t nb_sa_in;
+static struct ipsec_sa_cnt sa_in_cnt;
 
 static const struct supported_cipher_algo *
 find_match_cipher_algo(const char *cipher_keyword)
@@ -229,6 +232,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	struct rte_ipsec_session *ips;
 	uint32_t ti; /*token index*/
 	uint32_t *ri /*rule index*/;
+	struct ipsec_sa_cnt *sa_cnt;
 	uint32_t cipher_algo_p = 0;
 	uint32_t auth_algo_p = 0;
 	uint32_t aead_algo_p = 0;
@@ -241,6 +245,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
+		sa_cnt = &sa_in_cnt;
 
 		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
 			"too many sa rules, abort insertion\n");
@@ -251,6 +256,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
 	} else {
 		ri = &nb_sa_out;
+		sa_cnt = &sa_out_cnt;
 
 		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
 			"too many sa rules, abort insertion\n");
@@ -280,13 +286,16 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 			if (status->status < 0)
 				return;
 
-			if (strcmp(tokens[ti], "ipv4-tunnel") == 0)
+			if (strcmp(tokens[ti], "ipv4-tunnel") == 0) {
+				sa_cnt->nb_v4_tun++;
 				rule->flags = IP4_TUNNEL;
-			else if (strcmp(tokens[ti], "ipv6-tunnel") == 0)
+			} else if (strcmp(tokens[ti], "ipv6-tunnel") == 0) {
+				sa_cnt->nb_v6_tun++;
 				rule->flags = IP6_TUNNEL;
-			else if (strcmp(tokens[ti], "transport") == 0)
+			} else if (strcmp(tokens[ti], "transport") == 0) {
+				sa_cnt->nb_trn++;
 				rule->flags = TRANSPORT;
-			else {
+			} else {
 				APP_CHECK(0, status, "unrecognized "
 					"input \"%s\"", tokens[ti]);
 				return;
@@ -772,19 +781,21 @@ print_one_sa_rule(const struct ipsec_sa *sa, int inbound)
 	printf("\n");
 }
 
+struct ipsec_xf {
+	struct rte_crypto_sym_xform a;
+	struct rte_crypto_sym_xform b;
+};
+
 struct sa_ctx {
 	void *satbl; /* pointer to array of rte_ipsec_sa objects*/
-	struct ipsec_sa sa[IPSEC_SA_MAX_ENTRIES];
-	union {
-		struct {
-			struct rte_crypto_sym_xform a;
-			struct rte_crypto_sym_xform b;
-		};
-	} xf[IPSEC_SA_MAX_ENTRIES];
+	struct ipsec_sad sad;
+	struct ipsec_xf *xf;
+	uint32_t nb_sa;
+	struct ipsec_sa sa[];
 };
 
 static struct sa_ctx *
-sa_create(const char *name, int32_t socket_id)
+sa_create(const char *name, int32_t socket_id, uint32_t nb_sa)
 {
 	char s[PATH_MAX];
 	struct sa_ctx *sa_ctx;
@@ -793,20 +804,31 @@ sa_create(const char *name, int32_t socket_id)
 
 	snprintf(s, sizeof(s), "%s_%u", name, socket_id);
 
-	/* Create SA array table */
+	/* Create SA context */
 	printf("Creating SA context with %u maximum entries on socket %d\n",
-			IPSEC_SA_MAX_ENTRIES, socket_id);
+			nb_sa, socket_id);
 
-	mz_size = sizeof(struct sa_ctx);
+	mz_size = sizeof(struct ipsec_xf) * nb_sa;
 	mz = rte_memzone_reserve(s, mz_size, socket_id,
 			RTE_MEMZONE_1GB | RTE_MEMZONE_SIZE_HINT_ONLY);
 	if (mz == NULL) {
-		printf("Failed to allocate SA DB memory\n");
+		printf("Failed to allocate SA XFORM memory\n");
 		rte_errno = ENOMEM;
 		return NULL;
 	}
 
-	sa_ctx = (struct sa_ctx *)mz->addr;
+	sa_ctx = rte_malloc(NULL, sizeof(struct sa_ctx) +
+		sizeof(struct ipsec_sa) * nb_sa, RTE_CACHE_LINE_SIZE);
+
+	if (sa_ctx == NULL) {
+		printf("Failed to allocate SA CTX memory\n");
+		rte_errno = ENOMEM;
+		rte_memzone_free(mz);
+		return NULL;
+	}
+
+	sa_ctx->xf = (struct ipsec_xf *)mz->addr;
+	sa_ctx->nb_sa = nb_sa;
 
 	return sa_ctx;
 }
@@ -949,7 +971,7 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 	aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
 
 	for (i = 0; i < nb_entries; i++) {
-		idx = SPI2IDX(entries[i].spi);
+		idx = i;
 		sa = &sa_ctx->sa[idx];
 		if (sa->spi != 0) {
 			printf("Index %u already in use by SPI %u\n",
@@ -957,6 +979,13 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 			return -EINVAL;
 		}
 		*sa = entries[i];
+
+		if (inbound) {
+			rc = ipsec_sad_add(&sa_ctx->sad, sa);
+			if (rc != 0)
+				return rc;
+		}
+
 		sa->seq = 0;
 		ips = ipsec_get_primary_session(sa);
 
@@ -1237,8 +1266,7 @@ ipsec_sa_init(struct ipsec_sa *lsa, struct rte_ipsec_sa *sa, uint32_t sa_size)
  * one per session.
  */
 static int
-ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent,
-	uint32_t nb_ent, int32_t socket)
+ipsec_satbl_init(struct sa_ctx *ctx, uint32_t nb_ent, int32_t socket)
 {
 	int32_t rc, sz;
 	uint32_t i, idx;
@@ -1248,7 +1276,7 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent,
 	struct rte_ipsec_sa_prm prm;
 
 	/* determine SA size */
-	idx = SPI2IDX(ent[0].spi);
+	idx = 0;
 	fill_ipsec_sa_prm(&prm, ctx->sa + idx, NULL, NULL);
 	sz = rte_ipsec_sa_size(&prm);
 	if (sz < 0) {
@@ -1271,7 +1299,7 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent,
 	rc = 0;
 	for (i = 0; i != nb_ent && rc == 0; i++) {
 
-		idx = SPI2IDX(ent[i].spi);
+		idx = i;
 
 		sa = (struct rte_ipsec_sa *)((uintptr_t)ctx->satbl + sz * i);
 		lsa = ctx->sa + idx;
@@ -1286,18 +1314,16 @@ ipsec_satbl_init(struct sa_ctx *ctx, const struct ipsec_sa *ent,
  * Walk through all SA rules to find an SA with given SPI
  */
 int
-sa_spi_present(uint32_t spi, int inbound)
+sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound)
 {
 	uint32_t i, num;
 	const struct ipsec_sa *sar;
 
-	if (inbound != 0) {
-		sar = sa_in;
+	sar = sa_ctx->sa;
+	if (inbound != 0)
 		num = nb_sa_in;
-	} else {
-		sar = sa_out;
+	else
 		num = nb_sa_out;
-	}
 
 	for (i = 0; i != num; i++) {
 		if (sar[i].spi == spi)
@@ -1326,16 +1352,21 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 
 	if (nb_sa_in > 0) {
 		name = "sa_in";
-		ctx->sa_in = sa_create(name, socket_id);
+		ctx->sa_in = sa_create(name, socket_id, nb_sa_in);
 		if (ctx->sa_in == NULL)
 			rte_exit(EXIT_FAILURE, "Error [%d] creating SA "
 				"context %s in socket %d\n", rte_errno,
 				name, socket_id);
 
+		rc = ipsec_sad_create(name, &ctx->sa_in->sad, socket_id,
+				&sa_in_cnt);
+		if (rc != 0)
+			rte_exit(EXIT_FAILURE, "failed to init SAD\n");
+
 		sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx);
 
 		if (app_sa_prm.enable != 0) {
-			rc = ipsec_satbl_init(ctx->sa_in, sa_in, nb_sa_in,
+			rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in,
 				socket_id);
 			if (rc != 0)
 				rte_exit(EXIT_FAILURE,
@@ -1346,7 +1377,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 
 	if (nb_sa_out > 0) {
 		name = "sa_out";
-		ctx->sa_out = sa_create(name, socket_id);
+		ctx->sa_out = sa_create(name, socket_id, nb_sa_out);
 		if (ctx->sa_out == NULL)
 			rte_exit(EXIT_FAILURE, "Error [%d] creating SA "
 				"context %s in socket %d\n", rte_errno,
@@ -1355,7 +1386,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 		sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx);
 
 		if (app_sa_prm.enable != 0) {
-			rc = ipsec_satbl_init(ctx->sa_out, sa_out, nb_sa_out,
+			rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out,
 				socket_id);
 			if (rc != 0)
 				rte_exit(EXIT_FAILURE,
@@ -1381,28 +1412,13 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)
 	return 0;
 }
 
-static inline void
-single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
-		void **sa_ret)
+void
+inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
+		void *sa[], uint16_t nb_pkts)
 {
-	struct rte_esp_hdr *esp;
-	struct ip *ip;
-	uint32_t *src4_addr;
-	uint8_t *src6_addr;
-	struct ipsec_sa *sa;
-	void *result_sa;
+	uint32_t i;
 
-	*sa_ret = NULL;
-
-	ip = rte_pktmbuf_mtod(pkt, struct ip *);
-	esp = rte_pktmbuf_mtod_offset(pkt, struct rte_esp_hdr *, pkt->l3_len);
-
-	if (esp->spi == INVALID_SPI)
-		return;
-
-	result_sa = sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))];
-	if (rte_be_to_cpu_32(esp->spi) != sa->spi)
-		return;
+	sad_lookup(&sa_ctx->sad, pkts, sa, nb_pkts);
 
 	/*
 	 * Mark need for inline offload fallback on the LSB of SA pointer.
@@ -1413,40 +1429,14 @@ single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt,
 	 * pointer to prevent from unintentional use. Use ipsec_mask_saptr
 	 * to get valid struct pointer.
 	 */
-	if (MBUF_NO_SEC_OFFLOAD(pkt) && sa->fallback_sessions > 0) {
-		uintptr_t intsa = (uintptr_t)sa;
-		intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
-		result_sa = (void *)intsa;
+	for (i = 0; i < nb_pkts; i++) {
+		if (MBUF_NO_SEC_OFFLOAD(pkts[i]) && (sa[i] != NULL) &&
+			((struct ipsec_sa *)sa[i])->fallback_sessions > 0) {
+			uintptr_t intsa = (uintptr_t)sa[i];
+			intsa |= IPSEC_SA_OFFLOAD_FALLBACK_FLAG;
+			sa[i] = (void *)intsa;
+		}
 	}
-
-	switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
-	case IP4_TUNNEL:
-		src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src));
-		if ((ip->ip_v == IPVERSION) &&
-				(sa->src.ip.ip4 == *src4_addr) &&
-				(sa->dst.ip.ip4 == *(src4_addr + 1)))
-			*sa_ret = result_sa;
-		break;
-	case IP6_TUNNEL:
-		src6_addr = RTE_PTR_ADD(ip, offsetof(struct ip6_hdr, ip6_src));
-		if ((ip->ip_v == IP6_VERSION) &&
-				!memcmp(&sa->src.ip.ip6.ip6, src6_addr, 16) &&
-				!memcmp(&sa->dst.ip.ip6.ip6, src6_addr + 16, 16))
-			*sa_ret = result_sa;
-		break;
-	case TRANSPORT:
-		*sa_ret = result_sa;
-	}
-}
-
-void
-inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
-		void *sa[], uint16_t nb_pkts)
-{
-	uint32_t i;
-
-	for (i = 0; i < nb_pkts; i++)
-		single_inbound_lookup(sa_ctx->sa, pkts[i], &sa[i]);
 }
 
 void
diff --git a/examples/ipsec-secgw/sp4.c b/examples/ipsec-secgw/sp4.c
index 3871c6c..1dcec52 100644
--- a/examples/ipsec-secgw/sp4.c
+++ b/examples/ipsec-secgw/sp4.c
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,
  * check that for each rule it's SPI has a correspondent entry in SAD
  */
 static int
-check_spi_value(int inbound)
+check_spi_value(struct sa_ctx *sa_ctx, int inbound)
 {
 	uint32_t i, num, spi;
-	const struct acl4_rules *acr;
+	int32_t spi_idx;
+	struct acl4_rules *acr;
 
 	if (inbound != 0) {
 		acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)
 
 	for (i = 0; i != num; i++) {
 		spi = acr[i].data.userdata;
-		if (spi != DISCARD && spi != BYPASS &&
-				sa_spi_present(spi, inbound) < 0) {
-			RTE_LOG(ERR, IPSEC, "SPI %u is not present in SAD\n",
-				spi);
-			return -ENOENT;
+		if (spi != DISCARD && spi != BYPASS) {
+			spi_idx = sa_spi_present(sa_ctx, spi, inbound);
+			if (spi_idx < 0) {
+				RTE_LOG(ERR, IPSEC,
+					"SPI %u is not present in SAD\n",
+					spi);
+				return -ENOENT;
+			}
+			/* Update userdata with spi index */
+			acr[i].data.userdata = spi_idx + 1;
 		}
 	}
 
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)
 		rte_exit(EXIT_FAILURE, "Outbound SP DB for socket %u already "
 				"initialized\n", socket_id);
 
-	if (check_spi_value(1) < 0)
+	if (check_spi_value(ctx->sa_in, 1) < 0)
 		rte_exit(EXIT_FAILURE,
 			"Inbound IPv4 SP DB has unmatched in SAD SPIs\n");
 
-	if (check_spi_value(0) < 0)
+	if (check_spi_value(ctx->sa_out, 0) < 0)
 		rte_exit(EXIT_FAILURE,
 			"Outbound IPv4 SP DB has unmatched in SAD SPIs\n");
 
diff --git a/examples/ipsec-secgw/sp6.c b/examples/ipsec-secgw/sp6.c
index d8be6b1..b489e15 100644
--- a/examples/ipsec-secgw/sp6.c
+++ b/examples/ipsec-secgw/sp6.c
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,
  * check that for each rule it's SPI has a correspondent entry in SAD
  */
 static int
-check_spi_value(int inbound)
+check_spi_value(struct sa_ctx *sa_ctx, int inbound)
 {
 	uint32_t i, num, spi;
-	const struct acl6_rules *acr;
+	int32_t spi_idx;
+	struct acl6_rules *acr;
 
 	if (inbound != 0) {
 		acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)
 
 	for (i = 0; i != num; i++) {
 		spi = acr[i].data.userdata;
-		if (spi != DISCARD && spi != BYPASS &&
-				sa_spi_present(spi, inbound) < 0) {
-			RTE_LOG(ERR, IPSEC, "SPI %u is not present in SAD\n",
-				spi);
-			return -ENOENT;
+		if (spi != DISCARD && spi != BYPASS) {
+			spi_idx = sa_spi_present(sa_ctx, spi, inbound);
+			if (spi_idx < 0) {
+				RTE_LOG(ERR, IPSEC,
+					"SPI %u is not present in SAD\n",
+					spi);
+				return -ENOENT;
+			}
+			/* Update userdata with spi index */
+			acr[i].data.userdata = spi_idx + 1;
 		}
 	}
 
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)
 		rte_exit(EXIT_FAILURE, "Outbound IPv6 SP DB for socket %u "
 				"already initialized\n", socket_id);
 
-	if (check_spi_value(1) < 0)
+	if (check_spi_value(ctx->sa_in, 1) < 0)
 		rte_exit(EXIT_FAILURE,
 			"Inbound IPv6 SP DB has unmatched in SAD SPIs\n");
 
-	if (check_spi_value(0) < 0)
+	if (check_spi_value(ctx->sa_out, 0) < 0)
 		rte_exit(EXIT_FAILURE,
 			"Outbound IPv6 SP DB has unmatched in SAD SPIs\n");
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation
  2019-12-11 16:13 [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD Vladimir Medvedkin
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 3/4] examples/ipsec-secgw: integrate " Vladimir Medvedkin
@ 2019-12-11 16:13 ` Vladimir Medvedkin
  2019-12-11 16:43 ` [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Medvedkin, Vladimir
  3 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2019-12-11 16:13 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

Parse config file and save SA's into linked list
instead of flat array with predefined size.

Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
 examples/ipsec-secgw/sa.c | 78 +++++++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 8cc7b17..32919fe 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -20,6 +20,7 @@
 #include <rte_random.h>
 #include <rte_ethdev.h>
 #include <rte_malloc.h>
+#include <sys/queue.h>
 
 #include "ipsec.h"
 #include "esp.h"
@@ -133,11 +134,17 @@ const struct supported_aead_algo aead_algos[] = {
 	}
 };
 
-static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES];
+struct ipsec_sa_mgmt {
+	STAILQ_ENTRY(ipsec_sa_mgmt) next;
+	struct ipsec_sa         sa;
+};
+STAILQ_HEAD(sa_head, ipsec_sa_mgmt);
+
+static struct sa_head sa_out_head = STAILQ_HEAD_INITIALIZER(sa_out_head);
 static uint32_t nb_sa_out;
 static struct ipsec_sa_cnt sa_out_cnt;
 
-static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES];
+static struct sa_head sa_in_head = STAILQ_HEAD_INITIALIZER(sa_in_head);
 static uint32_t nb_sa_in;
 static struct ipsec_sa_cnt sa_in_cnt;
 
@@ -228,6 +235,8 @@ void
 parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	struct parse_status *status)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
+	struct sa_head *head;
 	struct ipsec_sa *rule = NULL;
 	struct rte_ipsec_session *ips;
 	uint32_t ti; /*token index*/
@@ -243,27 +252,21 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	uint32_t portid_p = 0;
 	uint32_t fallback_p = 0;
 
+	sa_mgmt = calloc(1, sizeof(struct ipsec_sa_mgmt));
+	if (sa_mgmt == NULL)
+		return;
+
+	rule = &sa_mgmt->sa;
+
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
 		sa_cnt = &sa_in_cnt;
-
-		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
-			"too many sa rules, abort insertion\n");
-		if (status->status < 0)
-			return;
-
-		rule = &sa_in[*ri];
+		head = &sa_in_head;
 		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
 	} else {
 		ri = &nb_sa_out;
 		sa_cnt = &sa_out_cnt;
-
-		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
-			"too many sa rules, abort insertion\n");
-		if (status->status < 0)
-			return;
-
-		rule = &sa_out[*ri];
+		head = &sa_out_head;
 		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
 	}
 
@@ -687,6 +690,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 		rule->portid = -1;
 	}
 
+	STAILQ_INSERT_TAIL(head, sa_mgmt, next);
 	*ri = *ri + 1;
 }
 
@@ -956,12 +960,13 @@ sa_add_address_inline_crypto(struct ipsec_sa *sa)
 }
 
 static int
-sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, uint32_t inbound,
 		struct socket_ctx *skt_ctx)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
 	struct ipsec_sa *sa;
-	uint32_t i, idx;
+	uint32_t idx;
 	uint16_t iv_length, aad_length;
 	int inline_status;
 	int32_t rc;
@@ -970,15 +975,18 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 	/* for ESN upper 32 bits of SQN also need to be part of AAD */
 	aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
 
-	for (i = 0; i < nb_entries; i++) {
-		idx = i;
+	sa_mgmt = STAILQ_FIRST(entries);
+	for (idx = 0; idx < nb_entries; idx++) {
+		if (sa_mgmt == NULL)
+			rte_exit(EXIT_FAILURE, "SA mgmt queue is broken\n");
+
 		sa = &sa_ctx->sa[idx];
 		if (sa->spi != 0) {
 			printf("Index %u already in use by SPI %u\n",
 					idx, sa->spi);
 			return -EINVAL;
 		}
-		*sa = entries[i];
+		*sa = sa_mgmt->sa;
 
 		if (inbound) {
 			rc = ipsec_sad_add(&sa_ctx->sad, sa);
@@ -1114,20 +1122,29 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			print_one_sa_rule(sa, inbound);
 		}
+		sa_mgmt = STAILQ_NEXT(sa_mgmt, next);
 	}
 
+	for (sa_mgmt = STAILQ_FIRST(entries); sa_mgmt != NULL;
+			sa_mgmt = STAILQ_FIRST(entries)) {
+		STAILQ_REMOVE_HEAD(entries, next);
+		free(sa_mgmt);
+	}
+
+	STAILQ_INIT(entries);
+
 	return 0;
 }
 
 static inline int
-sa_out_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_out_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, struct socket_ctx *skt_ctx)
 {
 	return sa_add_rules(sa_ctx, entries, nb_entries, 0, skt_ctx);
 }
 
 static inline int
-sa_in_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_in_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, struct socket_ctx *skt_ctx)
 {
 	return sa_add_rules(sa_ctx, entries, nb_entries, 1, skt_ctx);
@@ -1363,7 +1380,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 		if (rc != 0)
 			rte_exit(EXIT_FAILURE, "failed to init SAD\n");
 
-		sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx);
+		sa_in_add_rules(ctx->sa_in, &sa_in_head, nb_sa_in, ctx);
 
 		if (app_sa_prm.enable != 0) {
 			rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in,
@@ -1383,7 +1400,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 				"context %s in socket %d\n", rte_errno,
 				name, socket_id);
 
-		sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx);
+		sa_out_add_rules(ctx->sa_out, &sa_out_head, nb_sa_out, ctx);
 
 		if (app_sa_prm.enable != 0) {
 			rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out,
@@ -1451,21 +1468,22 @@ outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
 
 /*
  * Select HW offloads to be used.
+ * Called before sa_init, so working with mgmt queue
  */
 int
 sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 		uint64_t *tx_offloads)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
 	struct ipsec_sa *rule;
-	uint32_t idx_sa;
 	enum rte_security_session_action_type rule_type;
 
 	*rx_offloads = 0;
 	*tx_offloads = 0;
 
 	/* Check for inbound rules that use offloads and use this port */
-	for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) {
-		rule = &sa_in[idx_sa];
+	STAILQ_FOREACH(sa_mgmt, &sa_in_head, next) {
+		rule = &sa_mgmt->sa;
 		rule_type = ipsec_get_action_type(rule);
 		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 				rule_type ==
@@ -1475,8 +1493,8 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	}
 
 	/* Check for outbound rules that use offloads and use this port */
-	for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) {
-		rule = &sa_out[idx_sa];
+	STAILQ_FOREACH(sa_mgmt, &sa_out_head, next) {
+		rule = &sa_mgmt->sa;
 		rule_type = ipsec_get_action_type(rule);
 		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 				rule_type ==
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h
  2019-12-11 16:13 [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Vladimir Medvedkin
                   ` (2 preceding siblings ...)
  2019-12-11 16:13 ` [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation Vladimir Medvedkin
@ 2019-12-11 16:43 ` Medvedkin, Vladimir
  3 siblings, 0 replies; 6+ messages in thread
From: Medvedkin, Vladimir @ 2019-12-11 16:43 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

Self NACK for series

Forgot cover letter, will resend again.

On 11/12/2019 16:13, Vladimir Medvedkin wrote:
> Move IPSEC_SAD_NAMESIZE into public header
> and rename it to RTE_IPSEC_SAD_NAMESIZE
>
> Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> ---
>   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_<name>" */
>   #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 */

-- 
Regards,
Vladimir


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation
  2019-12-11 16:45 [dpdk-dev] [PATCH 0/4] integrate librte_ipsec SAD into ipsec-secgw Vladimir Medvedkin
@ 2019-12-11 16:45 ` Vladimir Medvedkin
  0 siblings, 0 replies; 6+ messages in thread
From: Vladimir Medvedkin @ 2019-12-11 16:45 UTC (permalink / raw
  To: dev; +Cc: konstantin.ananyev, akhil.goyal

Parse config file and save SA's into linked list
instead of flat array with predefined size.

Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
 examples/ipsec-secgw/sa.c | 78 +++++++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c
index 8cc7b17..32919fe 100644
--- a/examples/ipsec-secgw/sa.c
+++ b/examples/ipsec-secgw/sa.c
@@ -20,6 +20,7 @@
 #include <rte_random.h>
 #include <rte_ethdev.h>
 #include <rte_malloc.h>
+#include <sys/queue.h>
 
 #include "ipsec.h"
 #include "esp.h"
@@ -133,11 +134,17 @@ const struct supported_aead_algo aead_algos[] = {
 	}
 };
 
-static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES];
+struct ipsec_sa_mgmt {
+	STAILQ_ENTRY(ipsec_sa_mgmt) next;
+	struct ipsec_sa         sa;
+};
+STAILQ_HEAD(sa_head, ipsec_sa_mgmt);
+
+static struct sa_head sa_out_head = STAILQ_HEAD_INITIALIZER(sa_out_head);
 static uint32_t nb_sa_out;
 static struct ipsec_sa_cnt sa_out_cnt;
 
-static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES];
+static struct sa_head sa_in_head = STAILQ_HEAD_INITIALIZER(sa_in_head);
 static uint32_t nb_sa_in;
 static struct ipsec_sa_cnt sa_in_cnt;
 
@@ -228,6 +235,8 @@ void
 parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	struct parse_status *status)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
+	struct sa_head *head;
 	struct ipsec_sa *rule = NULL;
 	struct rte_ipsec_session *ips;
 	uint32_t ti; /*token index*/
@@ -243,27 +252,21 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 	uint32_t portid_p = 0;
 	uint32_t fallback_p = 0;
 
+	sa_mgmt = calloc(1, sizeof(struct ipsec_sa_mgmt));
+	if (sa_mgmt == NULL)
+		return;
+
+	rule = &sa_mgmt->sa;
+
 	if (strcmp(tokens[0], "in") == 0) {
 		ri = &nb_sa_in;
 		sa_cnt = &sa_in_cnt;
-
-		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
-			"too many sa rules, abort insertion\n");
-		if (status->status < 0)
-			return;
-
-		rule = &sa_in[*ri];
+		head = &sa_in_head;
 		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
 	} else {
 		ri = &nb_sa_out;
 		sa_cnt = &sa_out_cnt;
-
-		APP_CHECK(*ri <= IPSEC_SA_MAX_ENTRIES - 1, status,
-			"too many sa rules, abort insertion\n");
-		if (status->status < 0)
-			return;
-
-		rule = &sa_out[*ri];
+		head = &sa_out_head;
 		rule->direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
 	}
 
@@ -687,6 +690,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,
 		rule->portid = -1;
 	}
 
+	STAILQ_INSERT_TAIL(head, sa_mgmt, next);
 	*ri = *ri + 1;
 }
 
@@ -956,12 +960,13 @@ sa_add_address_inline_crypto(struct ipsec_sa *sa)
 }
 
 static int
-sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, uint32_t inbound,
 		struct socket_ctx *skt_ctx)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
 	struct ipsec_sa *sa;
-	uint32_t i, idx;
+	uint32_t idx;
 	uint16_t iv_length, aad_length;
 	int inline_status;
 	int32_t rc;
@@ -970,15 +975,18 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 	/* for ESN upper 32 bits of SQN also need to be part of AAD */
 	aad_length = (app_sa_prm.enable_esn != 0) ? sizeof(uint32_t) : 0;
 
-	for (i = 0; i < nb_entries; i++) {
-		idx = i;
+	sa_mgmt = STAILQ_FIRST(entries);
+	for (idx = 0; idx < nb_entries; idx++) {
+		if (sa_mgmt == NULL)
+			rte_exit(EXIT_FAILURE, "SA mgmt queue is broken\n");
+
 		sa = &sa_ctx->sa[idx];
 		if (sa->spi != 0) {
 			printf("Index %u already in use by SPI %u\n",
 					idx, sa->spi);
 			return -EINVAL;
 		}
-		*sa = entries[i];
+		*sa = sa_mgmt->sa;
 
 		if (inbound) {
 			rc = ipsec_sad_add(&sa_ctx->sad, sa);
@@ -1114,20 +1122,29 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
 
 			print_one_sa_rule(sa, inbound);
 		}
+		sa_mgmt = STAILQ_NEXT(sa_mgmt, next);
 	}
 
+	for (sa_mgmt = STAILQ_FIRST(entries); sa_mgmt != NULL;
+			sa_mgmt = STAILQ_FIRST(entries)) {
+		STAILQ_REMOVE_HEAD(entries, next);
+		free(sa_mgmt);
+	}
+
+	STAILQ_INIT(entries);
+
 	return 0;
 }
 
 static inline int
-sa_out_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_out_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, struct socket_ctx *skt_ctx)
 {
 	return sa_add_rules(sa_ctx, entries, nb_entries, 0, skt_ctx);
 }
 
 static inline int
-sa_in_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],
+sa_in_add_rules(struct sa_ctx *sa_ctx, struct sa_head *entries,
 		uint32_t nb_entries, struct socket_ctx *skt_ctx)
 {
 	return sa_add_rules(sa_ctx, entries, nb_entries, 1, skt_ctx);
@@ -1363,7 +1380,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 		if (rc != 0)
 			rte_exit(EXIT_FAILURE, "failed to init SAD\n");
 
-		sa_in_add_rules(ctx->sa_in, sa_in, nb_sa_in, ctx);
+		sa_in_add_rules(ctx->sa_in, &sa_in_head, nb_sa_in, ctx);
 
 		if (app_sa_prm.enable != 0) {
 			rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in,
@@ -1383,7 +1400,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)
 				"context %s in socket %d\n", rte_errno,
 				name, socket_id);
 
-		sa_out_add_rules(ctx->sa_out, sa_out, nb_sa_out, ctx);
+		sa_out_add_rules(ctx->sa_out, &sa_out_head, nb_sa_out, ctx);
 
 		if (app_sa_prm.enable != 0) {
 			rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out,
@@ -1451,21 +1468,22 @@ outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
 
 /*
  * Select HW offloads to be used.
+ * Called before sa_init, so working with mgmt queue
  */
 int
 sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 		uint64_t *tx_offloads)
 {
+	struct ipsec_sa_mgmt *sa_mgmt;
 	struct ipsec_sa *rule;
-	uint32_t idx_sa;
 	enum rte_security_session_action_type rule_type;
 
 	*rx_offloads = 0;
 	*tx_offloads = 0;
 
 	/* Check for inbound rules that use offloads and use this port */
-	for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) {
-		rule = &sa_in[idx_sa];
+	STAILQ_FOREACH(sa_mgmt, &sa_in_head, next) {
+		rule = &sa_mgmt->sa;
 		rule_type = ipsec_get_action_type(rule);
 		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 				rule_type ==
@@ -1475,8 +1493,8 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
 	}
 
 	/* Check for outbound rules that use offloads and use this port */
-	for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) {
-		rule = &sa_out[idx_sa];
+	STAILQ_FOREACH(sa_mgmt, &sa_out_head, next) {
+		rule = &sa_mgmt->sa;
 		rule_type = ipsec_get_action_type(rule);
 		if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||
 				rule_type ==
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-12-11 16:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-12-11 16:13 [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Vladimir Medvedkin
2019-12-11 16:13 ` [dpdk-dev] [PATCH 2/4] examples/ipsec-secgw: implement inbound SAD Vladimir Medvedkin
2019-12-11 16:13 ` [dpdk-dev] [PATCH 3/4] examples/ipsec-secgw: integrate " Vladimir Medvedkin
2019-12-11 16:13 ` [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation Vladimir Medvedkin
2019-12-11 16:43 ` [dpdk-dev] [PATCH 1/4] ipsec: move ipsec sad name length into .h Medvedkin, Vladimir
  -- strict thread matches above, loose matches on Subject: below --
2019-12-11 16:45 [dpdk-dev] [PATCH 0/4] integrate librte_ipsec SAD into ipsec-secgw Vladimir Medvedkin
2019-12-11 16:45 ` [dpdk-dev] [PATCH 4/4] examples/ipsec-secgw: get rid of maximum sa limitation Vladimir Medvedkin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.