[dpdk-dev] [PATCH v5 4/6] examples/ipsec-secgw: get rid of maximum sa limitation

Vladimir Medvedkin vladimir.medvedkin at intel.com
Wed Jan 29 15:06:06 CET 2020


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 <vladimir.medvedkin at intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev at intel.com>
---
 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);
+}
-- 
2.7.4



More information about the dev mailing list