All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: "Medvedkin, Vladimir" <vladimir.medvedkin@intel.com>,
	"dev@dpdk.org" <dev@dpdk.org>
Cc: "Iremonger, Bernard" <bernard.iremonger@intel.com>,
	"akhil.goyal@nxp.com" <akhil.goyal@nxp.com>
Subject: Re: [dpdk-dev] [PATCH v2 5/5] app: add test-sad application
Date: Wed, 2 Oct 2019 13:27:42 +0000	[thread overview]
Message-ID: <2601191342CEEE43887BDE71AB977258019196FE09@irsmsx105.ger.corp.intel.com> (raw)
In-Reply-To: <6219bf15a9f0f474f1d25f9237db4dbe4b95d08a.1569867491.git.vladimir.medvedkin@intel.com>



> 
> Usage example and performance evaluation for the ipsec SAD library

That's seems way too laconic :)

May be at least:
"Introduce new application to provide user to evaluate and perform
custom functional and performance tests for IPsec SAD implementation." 
?

Few more nits inline.

> 
> Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> ---
>  app/Makefile             |   1 +
>  app/meson.build          |   3 +-
>  app/test-sad/Makefile    |  18 ++
>  app/test-sad/main.c      | 662 +++++++++++++++++++++++++++++++++++++++++++++++
>  app/test-sad/meson.build |   6 +
>  5 files changed, 689 insertions(+), 1 deletion(-)
>  create mode 100644 app/test-sad/Makefile
>  create mode 100644 app/test-sad/main.c
>  create mode 100644 app/test-sad/meson.build
> 
> diff --git a/app/Makefile b/app/Makefile
> index 28acbce..db9d2d5 100644
> --- a/app/Makefile
> +++ b/app/Makefile
> @@ -10,6 +10,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += pdump
>  DIRS-$(CONFIG_RTE_LIBRTE_ACL) += test-acl
>  DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test-cmdline
>  DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += test-pipeline
> +DIRS-$(CONFIG_RTE_LIBRTE_IPSEC) += test-sad
> 
>  ifeq ($(CONFIG_RTE_LIBRTE_BBDEV),y)
>  DIRS-$(CONFIG_RTE_TEST_BBDEV) += test-bbdev
> diff --git a/app/meson.build b/app/meson.build
> index b0e6afb..71109cc 100644
> --- a/app/meson.build
> +++ b/app/meson.build
> @@ -15,7 +15,8 @@ apps = [
>  	'test-crypto-perf',
>  	'test-eventdev',
>  	'test-pipeline',
> -	'test-pmd']
> +	'test-pmd',
> +	'test-sad']
> 
>  # for BSD only
>  lib_execinfo = cc.find_library('execinfo', required: false)
> diff --git a/app/test-sad/Makefile b/app/test-sad/Makefile
> new file mode 100644
> index 0000000..9b35413
> --- /dev/null
> +++ b/app/test-sad/Makefile
> @@ -0,0 +1,18 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2010-2014 Intel Corporation
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +ifeq ($(CONFIG_RTE_LIBRTE_IPSEC),y)
> +
> +APP = testsad
> +
> +CFLAGS += $(WERROR_FLAGS)
> +CFLAGS += -DALLOW_EXPERIMENTAL_API
> +
> +# all source are stored in SRCS-y
> +SRCS-y := main.c
> +
> +include $(RTE_SDK)/mk/rte.app.mk
> +
> +endif
> diff --git a/app/test-sad/main.c b/app/test-sad/main.c
> new file mode 100644
> index 0000000..753721e
> --- /dev/null
> +++ b/app/test-sad/main.c
> @@ -0,0 +1,662 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2019 Intel Corporation
> + */
> +
> +#include <rte_string_fns.h>
> +#include <rte_ipsec_sad.h>
> +#include <getopt.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
> +
> +#include <rte_cycles.h>
> +#include <rte_errno.h>
> +#include <rte_ip.h>
> +#include <rte_random.h>
> +#include <rte_malloc.h>
> +#include <rte_ipsec_sad.h>
> +
> +#define	PRINT_USAGE_START	"%s [EAL options] --\n"
> +
> +#define GET_CB_FIELD(in, fd, base, lim, dlm)	do {		\
> +	unsigned long val;					\
> +	char *end_fld;						\
> +	errno = 0;						\
> +	val = strtoul((in), &end_fld, (base));			\
> +	if (errno != 0 || end_fld[0] != (dlm) || val > (lim))	\
> +		return -EINVAL;					\
> +	(fd) = (typeof(fd))val;					\
> +	(in) = end_fld + 1;					\
> +} while (0)
> +
> +#define	DEF_RULE_NUM		0x10000
> +#define	DEF_TUPLES_NUM	0x100000
> +#define BURST_SZ	64
> +
> +static struct {
> +	const char	*prgname;
> +	const char	*rules_file;
> +	const char	*tuples_file;
> +	uint32_t	nb_rules;
> +	uint32_t	nb_tuples;
> +	uint32_t	nb_rules_32;
> +	uint32_t	nb_rules_64;
> +	uint32_t	nb_rules_96;
> +	uint32_t	nb_tuples_rnd;
> +	uint32_t	burst_sz;
> +	uint8_t		fract_32;
> +	uint8_t		fract_64;
> +	uint8_t		fract_96;
> +	uint8_t		fract_rnd_tuples;
> +	int		ipv6;
> +	int		verbose;
> +} config = {
> +	.rules_file = NULL,
> +	.tuples_file = NULL,
> +	.nb_rules = DEF_RULE_NUM,
> +	.nb_tuples = DEF_TUPLES_NUM,
> +	.nb_rules_32 = 0,
> +	.nb_rules_64 = 0,
> +	.nb_rules_96 = 0,
> +	.nb_tuples_rnd = 0,
> +	.burst_sz = BURST_SZ,
> +	.fract_32 = 90,
> +	.fract_64 = 9,
> +	.fract_96 = 1,
> +	.fract_rnd_tuples = 0,
> +	.ipv6 = 0,
> +	.verbose = 0
> +};
> +
> +enum {
> +	CB_RULE_SPI,
> +	CB_RULE_DIP,
> +	CB_RULE_SIP,
> +	CB_RULE_LEN,
> +	CB_RULE_NUM,
> +};
> +
> +static char line[LINE_MAX];
> +struct rule {
> +	union rte_ipsec_sad_key	tuple;
> +	int rule_type;
> +};
> +
> +static struct rule *rules_tbl;
> +static struct rule *tuples_tbl;
> +
> +static int
> +parse_distrib(const char *in)
> +{
> +	int a, b, c;
> +
> +	GET_CB_FIELD(in, a, 0, UINT8_MAX, '/');
> +	GET_CB_FIELD(in, b, 0, UINT8_MAX, '/');
> +	GET_CB_FIELD(in, c, 0, UINT8_MAX, 0);
> +
> +	if ((a + b + c) != 100)
> +		return -EINVAL;
> +
> +	config.fract_32 = a;
> +	config.fract_64 = b;
> +	config.fract_96 = c;
> +
> +	return 0;
> +}
> +
> +static void
> +print_config(void)
> +{
> +	fprintf(stdout,
> +		"Rules total: %u\n"
> +		"Configured rules distribution SPI/SPI_DIP/SIP_DIP_SIP:"
> +		"%u/%u/%u\n"
> +		"SPI only rules: %u\n"
> +		"SPI_DIP  rules: %u\n"
> +		"SPI_DIP_SIP rules: %u\n"
> +		"Lookup tuples: %u\n"
> +		"Lookup burst size %u\n"
> +		"Configured fraction of random tuples: %u\n"
> +		"Random lookup tuples: %u\n",
> +		config.nb_rules, config.fract_32, config.fract_64,
> +		config.fract_96, config.nb_rules_32, config.nb_rules_64,
> +		config.nb_rules_96, config.nb_tuples, config.burst_sz,
> +		config.fract_rnd_tuples, config.nb_tuples_rnd);
> +}
> +
> +static void
> +print_usage(void)
> +{
> +	fprintf(stdout,
> +		PRINT_USAGE_START
> +		"[-f <rules file>]\n"
> +		"[-t <tuples file for lookup>]\n"
> +		"[-n <rules number (if -f is not specified)>]\n"
> +		"[-l <lookup tuples number (if -t is not specified)>]\n"
> +		"[-6 <ipv6 tests>]\n"
> +		"[-d <\"/\" separated rules length distribution"
> +		"(if -f is not specified)>]\n"
> +		"[-r <random tuples fraction to lookup"
> +		"(if -t is not specified)>]\n"
> +		"[-b <lookup burst size: 1-64 >]\n"
> +		"[-v <verbose, print results on lookup>]\n",
> +		config.prgname);
> +
> +}
> +
> +static int
> +get_str_num(FILE *f, int num)
> +{
> +	int n_lines = 0;
> +
> +	if (f != NULL) {
> +		while (fgets(line, sizeof(line), f) != NULL)
> +			n_lines++;
> +		rewind(f);
> +	} else {
> +		n_lines = num;
> +	}
> +	return n_lines;
> +}
> +
> +static int
> +parse_file(FILE *f, struct rule *tbl, int rule_tbl)
> +{
> +	int ret, i, j = 0;
> +	char *s, *sp, *in[CB_RULE_NUM];
> +	static const char *dlm = " \t\n";
> +	int string_tok_nb = RTE_DIM(in);
> +
> +	string_tok_nb -= (rule_tbl == 0) ? 1 : 0;
> +	while (fgets(line, sizeof(line), f) != NULL) {
> +		s = line;
> +		for (i = 0; i != string_tok_nb; i++) {
> +			in[i] = strtok_r(s, dlm, &sp);
> +			if (in[i] == NULL)
> +				return -EINVAL;
> +			s = NULL;
> +		}
> +		GET_CB_FIELD(in[CB_RULE_SPI], tbl[j].tuple.v4.spi, 0,
> +				UINT32_MAX, 0);
> +
> +		if (config.ipv6)
> +			ret = inet_pton(AF_INET6, in[CB_RULE_DIP],
> +				&tbl[j].tuple.v6.dip);
> +		else
> +			ret = inet_pton(AF_INET, in[CB_RULE_DIP],
> +				&tbl[j].tuple.v4.dip);
> +		if (ret != 1)
> +			return -EINVAL;
> +		if (config.ipv6)
> +			ret = inet_pton(AF_INET6, in[CB_RULE_SIP],
> +				&tbl[j].tuple.v6.sip);
> +		else
> +			ret = inet_pton(AF_INET, in[CB_RULE_SIP],
> +				&tbl[j].tuple.v4.sip);
> +		if (ret != 1)
> +			return -EINVAL;
> +		if ((rule_tbl) && (in[CB_RULE_LEN] != NULL)) {
> +			if (strcmp(in[CB_RULE_LEN], "SPI_DIP_SIP") == 0) {
> +				tbl[j].rule_type = RTE_IPSEC_SAD_SPI_DIP_SIP;
> +				config.nb_rules_96++;
> +			} else if (strcmp(in[CB_RULE_LEN], "SPI_DIP") == 0) {
> +				tbl[j].rule_type = RTE_IPSEC_SAD_SPI_DIP;
> +				config.nb_rules_64++;
> +			} else if (strcmp(in[CB_RULE_LEN], "SPI") == 0) {
> +				tbl[j].rule_type = RTE_IPSEC_SAD_SPI_ONLY;
> +				config.nb_rules_32++;
> +			} else {
> +				return -EINVAL;
> +			}
> +		}
> +		j++;
> +	}
> +	return 0;
> +}
> +
> +static uint64_t
> +get_rnd_rng(uint64_t l, uint64_t u)
> +{
> +	if (l == u)
> +		return l;
> +	else
> +		return (rte_rand() % (u - l) + l);
> +}
> +
> +static void
> +get_random_rules(struct rule *tbl, uint32_t nb_rules, int rule_tbl)
> +{
> +	unsigned i, j, rnd;
> +	int rule_type;
> +	double edge = 0;
> +	double step;
> +
> +	step = (double)UINT32_MAX / nb_rules;
> +	for (i = 0; i < nb_rules; i++, edge += step) {
> +		rnd = rte_rand() % 100;
> +		if (rule_tbl) {
> +			tbl[i].tuple.v4.spi = get_rnd_rng((uint64_t)edge,
> +						(uint64_t)(edge + step));
> +			if (config.ipv6) {
> +				for (j = 0; j < 16; j++) {
> +					tbl[i].tuple.v6.dip[j] = rte_rand();
> +					tbl[i].tuple.v6.sip[j] = rte_rand();
> +				}
> +			} else {
> +				tbl[i].tuple.v4.dip = rte_rand();
> +				tbl[i].tuple.v4.sip = rte_rand();
> +			}
> +			if (rnd >= (100UL - config.fract_32)) {
> +				rule_type = RTE_IPSEC_SAD_SPI_ONLY;
> +				config.nb_rules_32++;
> +			} else if (rnd >= (100UL - (config.fract_32 +
> +					config.fract_64))) {
> +				rule_type = RTE_IPSEC_SAD_SPI_DIP;
> +				config.nb_rules_64++;
> +			} else {
> +				rule_type = RTE_IPSEC_SAD_SPI_DIP_SIP;
> +				config.nb_rules_96++;
> +			}
> +			tbl[i].rule_type = rule_type;
> +		} else {
> +			if (rnd >= 100UL - config.fract_rnd_tuples) {
> +				tbl[i].tuple.v4.spi =
> +					get_rnd_rng((uint64_t)edge,
> +					(uint64_t)(edge + step));
> +				if (config.ipv6) {
> +					for (j = 0; j < 16; j++) {
> +						tbl[i].tuple.v6.dip[j] =
> +								rte_rand();
> +						tbl[i].tuple.v6.sip[j] =
> +								rte_rand();
> +					}
> +				} else {
> +					tbl[i].tuple.v4.dip = rte_rand();
> +					tbl[i].tuple.v4.sip = rte_rand();
> +				}
> +				config.nb_tuples_rnd++;
> +			} else {
> +				tbl[i].tuple.v4.spi = rules_tbl[i %
> +					config.nb_rules].tuple.v4.spi;
> +				if (config.ipv6) {
> +					int r_idx = i % config.nb_rules;
> +					memcpy(tbl[i].tuple.v6.dip,
> +						rules_tbl[r_idx].tuple.v6.dip,
> +						sizeof(tbl[i].tuple.v6.dip));
> +					memcpy(tbl[i].tuple.v6.sip,
> +						rules_tbl[r_idx].tuple.v6.sip,
> +						sizeof(tbl[i].tuple.v6.sip));
> +				} else {
> +					tbl[i].tuple.v4.dip = rules_tbl[i %
> +						config.nb_rules].tuple.v4.dip;
> +					tbl[i].tuple.v4.sip = rules_tbl[i %
> +						config.nb_rules].tuple.v4.sip;
> +				}
> +			}
> +		}
> +	}
> +}
> +
> +static void
> +tbl_init(struct rule **tbl, uint32_t *n_entries,
> +	const char *file_name, int rule_tbl)
> +{
> +	FILE *f = NULL;
> +	int ret;
> +	const char *rules = "rules";
> +	const char *tuples = "tuples";
> +
> +	if (file_name != NULL) {
> +		f = fopen(file_name, "r");
> +		if (f == NULL)
> +			rte_exit(-EINVAL, "failed to open file: %s\n",
> +				file_name);
> +	}
> +
> +	printf("init %s table...", (rule_tbl) ? rules : tuples);
> +	*n_entries = get_str_num(f, *n_entries);
> +	printf("%d entries\n", *n_entries);
> +	*tbl = rte_zmalloc(NULL, sizeof(struct rule) * *n_entries,
> +		RTE_CACHE_LINE_SIZE);
> +	if (*tbl == NULL)
> +		rte_exit(-ENOMEM, "failed to allocate tbl\n");
> +
> +	if (f != NULL) {
> +		printf("parse file %s\n", file_name);
> +		ret = parse_file(f, *tbl, rule_tbl);
> +		if (ret != 0)
> +			rte_exit(-EINVAL, "failed to parse file %s\n"
> +				"rules file must be: "
> +				"<uint32_t: spi> <space> "
> +				"<ip_addr: dip> <space> "
> +				"<ip_addr: sip> <space> "
> +				"<string: SPI|SPI_DIP|SIP_DIP_SIP>\n"
> +				"tuples file must be: "
> +				"<uint32_t: spi> <space> "
> +				"<ip_addr: dip> <space> "
> +				"<ip_addr: sip>\n",
> +				file_name);
> +	} else {
> +		printf("generate random values in %s table\n",
> +			(rule_tbl) ? rules : tuples);
> +		get_random_rules(*tbl, *n_entries, rule_tbl);
> +	}
> +	if (f != NULL)
> +		fclose(f);
> +}
> +
> +static void
> +parse_opts(int argc, char **argv)
> +{
> +	int opt, ret;
> +	char *endptr;
> +
> +	while ((opt = getopt(argc, argv, "f:t:n:d:l:r:6b:v")) != -1) {
> +		switch (opt) {
> +		case 'f':
> +			config.rules_file = optarg;
> +			break;
> +		case 't':
> +			config.tuples_file = optarg;
> +			break;
> +		case 'n':
> +			errno = 0;
> +			config.nb_rules = strtoul(optarg, &endptr, 10);
> +			if ((errno != 0) || (config.nb_rules == 0) ||
> +					(endptr[0] != 0)) {
> +				print_usage();
> +				rte_exit(-EINVAL, "Invalid option -n\n");
> +			}
> +			break;
> +		case 'd':
> +			ret = parse_distrib(optarg);
> +			if (ret != 0) {
> +				print_usage();
> +				rte_exit(-EINVAL, "Invalid option -d\n");
> +			}
> +			break;
> +		case 'b':
> +			errno = 0;
> +			config.burst_sz = strtoul(optarg, &endptr, 10);
> +			if ((errno != 0) || (config.burst_sz == 0) ||
> +					(config.burst_sz > 64) ||
> +					(endptr[0] != 0)) {
> +				print_usage();
> +				rte_exit(-EINVAL, "Invalid option -b\n");
> +			}
> +			break;
> +		case 'l':
> +			errno = 0;
> +			config.nb_tuples = strtoul(optarg, &endptr, 10);
> +			if ((errno != 0) || (config.nb_tuples == 0) ||
> +					(endptr[0] != 0)) {
> +				print_usage();
> +				rte_exit(-EINVAL, "Invalid option -l\n");
> +			}
> +			break;
> +		case 'r':
> +			errno = 0;
> +			config.fract_rnd_tuples = strtoul(optarg, &endptr, 10);
> +			if ((errno != 0) || (config.fract_rnd_tuples == 0) ||
> +					(config.fract_rnd_tuples >= 100) ||
> +					(endptr[0] != 0)) {
> +				print_usage();
> +				rte_exit(-EINVAL, "Invalid option -r\n");
> +			}
> +			break;
> +		case '6':
> +			config.ipv6 = 1;
> +			break;
> +		case 'v':
> +			config.verbose = 1;
> +			break;
> +		default:
> +			print_usage();
> +			rte_exit(-EINVAL, "Invalid options\n");
> +		}
> +	}
> +}
> +
> +static void
> +print_addr(int af, const uint8_t *addr)
> +{
> +	int i;

Why not use inet_ntop inside that function?

> +
> +	if (af == AF_INET) {
> +		for (i = 0; i < 3; i++)
> +			printf("%d.", addr[i]);
> +		printf("%d", addr[i]);
> +	} else {
> +		for (i = 0; i < 7; i++)
> +			printf("%04x:", addr[2 * i] << 8 | addr[2 * i + 1]);
> +		printf("%04x", addr[2 * i] << 8 | addr[2 * i + 1]);
> +	}
> +
> +}
> +
> +static void
> +print_result(const union rte_ipsec_sad_key *key, void *res)
> +{
> +	struct rule *rule = res;
> +	const struct rte_ipsec_sadv4_key *v4;
> +	const struct rte_ipsec_sadv6_key *v6;
> +	const char *spi_only = "SPI_ONLY";
> +	const char *spi_dip = "SPI_DIP";
> +	const char *spi_dip_sip = "SPI_DIP_SIP";
> +	const char *rule_type;
> +
> +	if (res == NULL) {
> +		if (config.ipv6) {
> +			v6 = &key->v6;
> +			printf("TUPLE: < SPI: %u DIP: ", v6->spi);
> +			print_addr(AF_INET6, v6->dip);
> +			printf(" SIP: ");
> +			print_addr(AF_INET6, v6->sip);
> +			printf(" > not found\n");
> +		} else {
> +			v4 = &key->v4;
> +			printf("TUPLE: < SPI: %u DIP: ", v4->spi);
> +			print_addr(AF_INET, (const uint8_t *)&v4->dip);
> +			printf(" SIP: ");
> +			print_addr(AF_INET, (const uint8_t *)&v4->sip);
> +			printf(" > not found\n");
> +		}
> +		return;
> +	}
> +
> +	switch (rule->rule_type) {
> +	case RTE_IPSEC_SAD_SPI_ONLY:
> +		rule_type = spi_only;
> +		break;
> +	case RTE_IPSEC_SAD_SPI_DIP:
> +		rule_type = spi_dip;
> +		break;
> +	case RTE_IPSEC_SAD_SPI_DIP_SIP:
> +		rule_type = spi_dip_sip;
> +		break;
> +	default:
> +		return;
> +	}
> +
> +	if (config.ipv6) {
> +		v6 = &key->v6;
> +		printf("TUPLE: < SPI: %u DIP: ", v6->spi);
> +		print_addr(AF_INET6, v6->dip);
> +		printf(" SIP: ");
> +		print_addr(AF_INET6, v6->sip);
> +		printf(" >\n");

That looks identical to the code above for NULL result.
Could be squeezed together I think.
Another alternative: define 2 new fucntions (print_tuple, print_rule) and use it here
to reduce code duplication.

> +		v6 = &rule->tuple.v6;
> +		printf("\tpoints to RULE ID %zu < SPI: %u DIP: ",
> +			RTE_PTR_DIFF(res, rules_tbl)/sizeof(struct rule),
> +			v6->spi);
> +		print_addr(AF_INET6, v6->dip);
> +		printf(" SIP: ");
> +		print_addr(AF_INET6, v6->sip);
> +		printf("/%s >\n", rule_type);
> +	} else {
> +		v4 = &key->v4;
> +		printf("TUPLE: < SPI: %u DIP: ", v4->spi);
> +		print_addr(AF_INET, (const uint8_t *)&v4->dip);
> +		printf(" SIP: ");
> +		print_addr(AF_INET, (const uint8_t *)&v4->sip);
> +		printf(" >\n");
> +		v4 = &rule->tuple.v4;
> +		printf("\tpoints to RULE ID %zu < SPI: %u DIP: ",
> +			RTE_PTR_DIFF(res, rules_tbl)/sizeof(struct rule),
> +			v4->spi);
> +		print_addr(AF_INET, (const uint8_t *)&v4->dip);
> +		printf(" SIP: ");
> +		print_addr(AF_INET, (const uint8_t *)&v4->sip);
> +		printf("/%s >\n", rule_type);
> +	}
> +}
> +
> +static void
> +lookup(struct rte_ipsec_sad *sad, uint32_t burst_sz)
> +{
> +	int ret;
> +	unsigned int i, j;
> +	const union rte_ipsec_sad_key *keys[burst_sz];
> +	void *vals[burst_sz];
> +	uint64_t start, acc = 0;
> +
> +	burst_sz = RTE_MIN(burst_sz, config.nb_tuples);
> +	for (i = 0; i < config.nb_tuples; i += burst_sz) {
> +		for (j = 0; j < burst_sz; j++)
> +			keys[j] = (union rte_ipsec_sad_key *)
> +				(&tuples_tbl[i + j].tuple);
> +		start = rte_rdtsc_precise();
> +		ret = rte_ipsec_sad_lookup(sad, keys, vals, burst_sz);
> +		acc += rte_rdtsc_precise() - start;
> +		if (ret < 0)
> +			rte_exit(-EINVAL, "Lookup failed\n");
> +		if (config.verbose) {
> +			for (j = 0; j < burst_sz; j++)
> +				print_result(keys[j], vals[j]);
> +		}
> +	}
> +	printf("Average lookup cycles %.2Lf, lookups/sec: %.2Lf\n",
> +		(long double)acc / config.nb_tuples,
> +		(long double)config.nb_tuples * rte_get_tsc_hz() / acc);
> +}
> +
> +static void
> +add_rules(struct rte_ipsec_sad *sad, uint32_t fract)
> +{
> +	int32_t ret;
> +	uint32_t i, j, f, fn, n;
> +	uint64_t start, tm[fract + 1];
> +	uint32_t nm[fract + 1];
> +
> +	f = (config.nb_rules > fract) ? config.nb_rules / fract : 1;
> +
> +	for (n = 0, j = 0; n != config.nb_rules; n = fn, j++) {
> +
> +		fn = n + f;
> +		fn = fn > config.nb_rules ? config.nb_rules : fn;
> +
> +		start = rte_rdtsc_precise();
> +		for (i = n; i != fn; i++) {
> +			ret = rte_ipsec_sad_add(sad,
> +				&rules_tbl[i].tuple,
> +				rules_tbl[i].rule_type, &rules_tbl[i]);
> +			if (ret != 0)
> +				rte_exit(ret, "%s failed @ %u-th rule\n",
> +					__func__, i);
> +		}
> +		tm[j] = rte_rdtsc_precise() - start;
> +		nm[j] = fn - n;
> +	}
> +
> +	for (i = 0; i != j; i++)
> +		printf("ADD %u rules, %.2Lf cycles/rule, %.2Lf ADD/sec\n",
> +			nm[i], (long double)tm[i] / nm[i],
> +			(long double)nm[i] * rte_get_tsc_hz() / tm[i]);
> +}
> +
> +static void
> +del_rules(struct rte_ipsec_sad *sad, uint32_t fract)
> +{
> +	int32_t ret;
> +	uint32_t i, j, f, fn, n;
> +	uint64_t start, tm[fract + 1];
> +	uint32_t nm[fract + 1];
> +
> +	f = (config.nb_rules > fract) ? config.nb_rules / fract : 1;
> +
> +	for (n = 0, j = 0; n != config.nb_rules; n = fn, j++) {
> +
> +		fn = n + f;
> +		fn = fn > config.nb_rules ? config.nb_rules : fn;
> +
> +		start = rte_rdtsc_precise();
> +		for (i = n; i != fn; i++) {
> +			ret = rte_ipsec_sad_del(sad,
> +				&rules_tbl[i].tuple,
> +				rules_tbl[i].rule_type);
> +			if (ret != 0 && ret != -ENOENT)
> +				rte_exit(ret, "%s failed @ %u-th rule\n",
> +					__func__, i);
> +		}
> +		tm[j] = rte_rdtsc_precise() - start;
> +		nm[j] = fn - n;
> +	}
> +
> +	for (i = 0; i != j; i++)
> +		printf("DEL %u rules, %.2Lf cycles/rule, %.2Lf DEL/sec\n",
> +			nm[i], (long double)tm[i] / nm[i],
> +			(long double)nm[i] * rte_get_tsc_hz() / tm[i]);
> +}
> +
> +int
> +main(int argc, char **argv)
> +{
> +	int ret;
> +	struct rte_ipsec_sad *sad;
> +	struct rte_ipsec_sad_conf conf;
> +
> +	ret = rte_eal_init(argc, argv);
> +	if (ret < 0)
> +		rte_panic("Cannot init EAL\n");
> +
> +	argc -= ret;
> +	argv += ret;
> +
> +	config.prgname = argv[0];
> +
> +	parse_opts(argc, argv);
> +	tbl_init(&rules_tbl, &config.nb_rules, config.rules_file, 1);
> +	tbl_init(&tuples_tbl, &config.nb_tuples, config.tuples_file, 0);
> +	if (config.rules_file != NULL) {
> +		config.fract_32 = (100 * config.nb_rules_32) / config.nb_rules;
> +		config.fract_64 = (100 * config.nb_rules_64) / config.nb_rules;
> +		config.fract_96 = (100 * config.nb_rules_96) / config.nb_rules;
> +	}
> +	if (config.tuples_file != NULL) {
> +		config.fract_rnd_tuples = 0;
> +		config.nb_tuples_rnd = 0;
> +	}
> +	conf.socket_id = -1;
> +	conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = config.nb_rules_32 * 5 / 4;
> +	conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = config.nb_rules_64 * 5 / 4;
> +	conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = config.nb_rules_96 * 5 / 4;
> +	if (config.ipv6)
> +		conf.flags = RTE_IPSEC_SAD_FLAG_IPV6|
> +			RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY;
> +	else
> +		conf.flags = RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY;
> +	sad = rte_ipsec_sad_create("test", &conf);
> +	if (sad == NULL)
> +		rte_exit(-rte_errno, "can not allocate SAD table\n");
> +
> +	print_config();
> +
> +	add_rules(sad, 10);
> +	lookup(sad, config.burst_sz);
> +	del_rules(sad, 10);
> +
> +	return 0;
> +}
> diff --git a/app/test-sad/meson.build b/app/test-sad/meson.build
> new file mode 100644
> index 0000000..31f9aab
> --- /dev/null
> +++ b/app/test-sad/meson.build
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2019 Intel Corporation
> +
> +allow_experimental_apis = true
> +sources = files('main.c')
> +deps += ['ipsec', 'net']
> --

Apart from the nits above:

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> 2.7.4


  reply	other threads:[~2019-10-02 13:27 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-13 15:13 [dpdk-dev] [RFC 0/5] ipsec: add inbound SAD Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 2/5] ipsec: add SAD create/free API Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-08-13 15:13 ` [dpdk-dev] [RFC 5/5] app: add test-sad application Vladimir Medvedkin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 0/5] ipsec: add inbound SAD Vladimir Medvedkin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 " Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 " Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 " Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 " Vladimir Medvedkin
2019-10-11 11:34           ` Akhil Goyal
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 0/6] " Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 0/5] " Vladimir Medvedkin
2019-10-22  7:53               ` Akhil Goyal
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-21 14:35             ` [dpdk-dev] [PATCH v7 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 1/6] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-17 15:47           ` [dpdk-dev] [PATCH v6 2/6] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 3/6] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 4/6] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 5/6] app: add test-sad application Vladimir Medvedkin
2019-10-21  9:57             ` Akhil Goyal
2019-10-17 15:48           ` [dpdk-dev] [PATCH v6 6/6] doc/ipsec: update ipsec programmer's guide Vladimir Medvedkin
2019-10-18 10:09             ` Ananyev, Konstantin
2019-10-21  8:19             ` Akhil Goyal
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-11 10:42           ` Akhil Goyal
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-10 16:49         ` [dpdk-dev] [PATCH v5 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-09 10:49         ` Ananyev, Konstantin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-09 10:56         ` Ananyev, Konstantin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-08 16:55       ` [dpdk-dev] [PATCH v4 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-08  9:40     ` [dpdk-dev] [PATCH v3 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-10-02 11:24     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 2/5] ipsec: add SAD create/destroy implementation Vladimir Medvedkin
2019-10-02 11:55     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-10-02 12:04     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-10-02 11:16     ` Ananyev, Konstantin
2019-10-01 17:25   ` [dpdk-dev] [PATCH v2 5/5] app: add test-sad application Vladimir Medvedkin
2019-10-02 13:27     ` Ananyev, Konstantin [this message]
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 1/5] ipsec: add inbound SAD API Vladimir Medvedkin
2019-09-14 23:05   ` Ananyev, Konstantin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 2/5] ipsec: add SAD create/free API Vladimir Medvedkin
2019-09-12 18:08   ` Ananyev, Konstantin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 3/5] ipsec: add SAD add/delete/lookup implementation Vladimir Medvedkin
2019-09-12 17:58   ` Ananyev, Konstantin
2019-10-01 17:24     ` Medvedkin, Vladimir
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 4/5] test/ipsec: add ipsec SAD autotests Vladimir Medvedkin
2019-09-03 16:55 ` [dpdk-dev] [PATCH v1 5/5] app: add test-sad application Vladimir Medvedkin
2019-09-12 18:30   ` Ananyev, Konstantin
2019-09-12 18:33     ` Ananyev, Konstantin
2019-09-12 18:34 ` [dpdk-dev] [RFC 0/5] ipsec: add inbound SAD Ananyev, Konstantin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2601191342CEEE43887BDE71AB977258019196FE09@irsmsx105.ger.corp.intel.com \
    --to=konstantin.ananyev@intel.com \
    --cc=akhil.goyal@nxp.com \
    --cc=bernard.iremonger@intel.com \
    --cc=dev@dpdk.org \
    --cc=vladimir.medvedkin@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.