xref: /dpdk/app/test-security-perf/test_security_perf.c (revision 1f5cfe964eefe96b5f8de1fadf9cc8fd1e214240)
1*1f5cfe96SAnoob Joseph /* SPDX-License-Identifier: BSD-3-Clause
2*1f5cfe96SAnoob Joseph  * Copyright(c) 2022, Marvell
3*1f5cfe96SAnoob Joseph  */
4*1f5cfe96SAnoob Joseph 
5*1f5cfe96SAnoob Joseph #include <getopt.h>
6*1f5cfe96SAnoob Joseph #include <stdlib.h>
7*1f5cfe96SAnoob Joseph #include <unistd.h>
8*1f5cfe96SAnoob Joseph 
9*1f5cfe96SAnoob Joseph #include <rte_common.h>
10*1f5cfe96SAnoob Joseph #include <rte_cryptodev.h>
11*1f5cfe96SAnoob Joseph #include <rte_eal.h>
12*1f5cfe96SAnoob Joseph #include <rte_lcore.h>
13*1f5cfe96SAnoob Joseph #include <rte_malloc.h>
14*1f5cfe96SAnoob Joseph #include <rte_security.h>
15*1f5cfe96SAnoob Joseph 
16*1f5cfe96SAnoob Joseph #include <app/test/test_cryptodev.h>
17*1f5cfe96SAnoob Joseph #include <app/test/test_cryptodev_security_ipsec.h>
18*1f5cfe96SAnoob Joseph #include <app/test/test_cryptodev_security_ipsec_test_vectors.h>
19*1f5cfe96SAnoob Joseph 
20*1f5cfe96SAnoob Joseph #define NB_DESC 4096
21*1f5cfe96SAnoob Joseph #define DEF_NB_SESSIONS (16 * 10 * 1024) /* 16 * 10K tunnels */
22*1f5cfe96SAnoob Joseph 
23*1f5cfe96SAnoob Joseph struct lcore_conf {
24*1f5cfe96SAnoob Joseph 	struct rte_crypto_sym_xform cipher_xform;
25*1f5cfe96SAnoob Joseph 	struct rte_crypto_sym_xform auth_xform;
26*1f5cfe96SAnoob Joseph 	struct rte_crypto_sym_xform aead_xform;
27*1f5cfe96SAnoob Joseph 	uint8_t dev_id;
28*1f5cfe96SAnoob Joseph 	uint8_t qp_id;
29*1f5cfe96SAnoob Joseph 	struct test_ctx *ctx;
30*1f5cfe96SAnoob Joseph };
31*1f5cfe96SAnoob Joseph 
32*1f5cfe96SAnoob Joseph struct test_ctx {
33*1f5cfe96SAnoob Joseph 	struct lcore_conf lconf[RTE_MAX_LCORE];
34*1f5cfe96SAnoob Joseph 	void *sec_ctx;
35*1f5cfe96SAnoob Joseph 	struct rte_mempool *sess_mp;
36*1f5cfe96SAnoob Joseph 	struct ipsec_test_data *td;
37*1f5cfe96SAnoob Joseph 	int nb_sess;
38*1f5cfe96SAnoob Joseph 	unsigned long td_idx;
39*1f5cfe96SAnoob Joseph 	uint8_t nb_lcores;
40*1f5cfe96SAnoob Joseph 	uint8_t nb_cryptodevs;
41*1f5cfe96SAnoob Joseph 	uint8_t enabled_cdevs[RTE_CRYPTO_MAX_DEVS];
42*1f5cfe96SAnoob Joseph 	bool is_inbound;
43*1f5cfe96SAnoob Joseph };
44*1f5cfe96SAnoob Joseph 
45*1f5cfe96SAnoob Joseph static struct test_ctx ctx;
46*1f5cfe96SAnoob Joseph 
47*1f5cfe96SAnoob Joseph static int
48*1f5cfe96SAnoob Joseph cryptodev_init(struct test_ctx *ctx, uint8_t nb_lcores)
49*1f5cfe96SAnoob Joseph {
50*1f5cfe96SAnoob Joseph 	const char dev_names[][RTE_CRYPTODEV_NAME_MAX_LEN] = {
51*1f5cfe96SAnoob Joseph 		"crypto_cn10k",
52*1f5cfe96SAnoob Joseph 		"crypto_cn9k",
53*1f5cfe96SAnoob Joseph 		"crypto_dpaa_sec",
54*1f5cfe96SAnoob Joseph 		"crypto_dpaa2_sec",
55*1f5cfe96SAnoob Joseph 	};
56*1f5cfe96SAnoob Joseph 	struct rte_cryptodev_qp_conf qp_conf;
57*1f5cfe96SAnoob Joseph 	struct rte_cryptodev_info dev_info;
58*1f5cfe96SAnoob Joseph 	struct rte_cryptodev_config config;
59*1f5cfe96SAnoob Joseph 	unsigned int j, nb_qp, qps_reqd;
60*1f5cfe96SAnoob Joseph 	uint8_t socket_id;
61*1f5cfe96SAnoob Joseph 	uint32_t dev_cnt;
62*1f5cfe96SAnoob Joseph 	int ret, core_id;
63*1f5cfe96SAnoob Joseph 	void *sec_ctx;
64*1f5cfe96SAnoob Joseph 	uint64_t i;
65*1f5cfe96SAnoob Joseph 
66*1f5cfe96SAnoob Joseph 	i = 0;
67*1f5cfe96SAnoob Joseph 	do {
68*1f5cfe96SAnoob Joseph 		dev_cnt = rte_cryptodev_devices_get(dev_names[i],
69*1f5cfe96SAnoob Joseph 						     ctx->enabled_cdevs,
70*1f5cfe96SAnoob Joseph 						     RTE_CRYPTO_MAX_DEVS);
71*1f5cfe96SAnoob Joseph 		i++;
72*1f5cfe96SAnoob Joseph 	} while (dev_cnt == 0 && i < RTE_DIM(dev_names));
73*1f5cfe96SAnoob Joseph 
74*1f5cfe96SAnoob Joseph 	if (dev_cnt == 0)
75*1f5cfe96SAnoob Joseph 		return -1;
76*1f5cfe96SAnoob Joseph 
77*1f5cfe96SAnoob Joseph 	/* Check first device for capabilities */
78*1f5cfe96SAnoob Joseph 	rte_cryptodev_info_get(0, &dev_info);
79*1f5cfe96SAnoob Joseph 	if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_SECURITY)) {
80*1f5cfe96SAnoob Joseph 		RTE_LOG(ERR, USER1,
81*1f5cfe96SAnoob Joseph 			"Security not supported by the cryptodev\n");
82*1f5cfe96SAnoob Joseph 		return -1;
83*1f5cfe96SAnoob Joseph 	}
84*1f5cfe96SAnoob Joseph 
85*1f5cfe96SAnoob Joseph 	sec_ctx = rte_cryptodev_get_sec_ctx(0);
86*1f5cfe96SAnoob Joseph 	ctx->sec_ctx = sec_ctx;
87*1f5cfe96SAnoob Joseph 
88*1f5cfe96SAnoob Joseph 	socket_id = rte_socket_id();
89*1f5cfe96SAnoob Joseph 	qps_reqd = nb_lcores;
90*1f5cfe96SAnoob Joseph 	core_id = 0;
91*1f5cfe96SAnoob Joseph 	i = 0;
92*1f5cfe96SAnoob Joseph 
93*1f5cfe96SAnoob Joseph 	do {
94*1f5cfe96SAnoob Joseph 		rte_cryptodev_info_get(i, &dev_info);
95*1f5cfe96SAnoob Joseph 		qps_reqd = RTE_MIN(dev_info.max_nb_queue_pairs, qps_reqd);
96*1f5cfe96SAnoob Joseph 
97*1f5cfe96SAnoob Joseph 		for (j = 0; j < qps_reqd; j++) {
98*1f5cfe96SAnoob Joseph 			ctx->lconf[core_id].dev_id = i;
99*1f5cfe96SAnoob Joseph 			ctx->lconf[core_id].qp_id = j;
100*1f5cfe96SAnoob Joseph 			ctx->lconf[core_id].ctx = ctx;
101*1f5cfe96SAnoob Joseph 			core_id++;
102*1f5cfe96SAnoob Joseph 			if (core_id == RTE_MAX_LCORE)
103*1f5cfe96SAnoob Joseph 				break;
104*1f5cfe96SAnoob Joseph 		}
105*1f5cfe96SAnoob Joseph 
106*1f5cfe96SAnoob Joseph 		nb_qp = j;
107*1f5cfe96SAnoob Joseph 
108*1f5cfe96SAnoob Joseph 		memset(&config, 0, sizeof(config));
109*1f5cfe96SAnoob Joseph 		config.nb_queue_pairs = nb_qp;
110*1f5cfe96SAnoob Joseph 		config.socket_id = socket_id;
111*1f5cfe96SAnoob Joseph 
112*1f5cfe96SAnoob Joseph 		ret = rte_cryptodev_configure(i, &config);
113*1f5cfe96SAnoob Joseph 		if (ret < 0) {
114*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1,
115*1f5cfe96SAnoob Joseph 				"Could not configure cryptodev - %" PRIu64 "\n",
116*1f5cfe96SAnoob Joseph 				i);
117*1f5cfe96SAnoob Joseph 			return -1;
118*1f5cfe96SAnoob Joseph 		}
119*1f5cfe96SAnoob Joseph 
120*1f5cfe96SAnoob Joseph 		memset(&qp_conf, 0, sizeof(qp_conf));
121*1f5cfe96SAnoob Joseph 		qp_conf.nb_descriptors = NB_DESC;
122*1f5cfe96SAnoob Joseph 
123*1f5cfe96SAnoob Joseph 		for (j = 0; j < nb_qp; j++) {
124*1f5cfe96SAnoob Joseph 			ret = rte_cryptodev_queue_pair_setup(i, j, &qp_conf,
125*1f5cfe96SAnoob Joseph 							     socket_id);
126*1f5cfe96SAnoob Joseph 			if (ret < 0) {
127*1f5cfe96SAnoob Joseph 				RTE_LOG(ERR, USER1,
128*1f5cfe96SAnoob Joseph 					"Could not configure queue pair:"
129*1f5cfe96SAnoob Joseph 					" %" PRIu64 " - %d\n", i, j);
130*1f5cfe96SAnoob Joseph 				return -1;
131*1f5cfe96SAnoob Joseph 			}
132*1f5cfe96SAnoob Joseph 		}
133*1f5cfe96SAnoob Joseph 
134*1f5cfe96SAnoob Joseph 		ret = rte_cryptodev_start(i);
135*1f5cfe96SAnoob Joseph 		if (ret < 0) {
136*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1, "Could not start cryptodev\n");
137*1f5cfe96SAnoob Joseph 			return -1;
138*1f5cfe96SAnoob Joseph 		}
139*1f5cfe96SAnoob Joseph 
140*1f5cfe96SAnoob Joseph 		i++;
141*1f5cfe96SAnoob Joseph 		qps_reqd -= j;
142*1f5cfe96SAnoob Joseph 
143*1f5cfe96SAnoob Joseph 	} while (i < dev_cnt && core_id < RTE_MAX_LCORE);
144*1f5cfe96SAnoob Joseph 
145*1f5cfe96SAnoob Joseph 	ctx->nb_cryptodevs = i;
146*1f5cfe96SAnoob Joseph 
147*1f5cfe96SAnoob Joseph 	return 0;
148*1f5cfe96SAnoob Joseph }
149*1f5cfe96SAnoob Joseph 
150*1f5cfe96SAnoob Joseph static int
151*1f5cfe96SAnoob Joseph cryptodev_fini(struct test_ctx *ctx)
152*1f5cfe96SAnoob Joseph {
153*1f5cfe96SAnoob Joseph 	int i, ret = 0;
154*1f5cfe96SAnoob Joseph 
155*1f5cfe96SAnoob Joseph 	for (i = 0; i < ctx->nb_cryptodevs &&
156*1f5cfe96SAnoob Joseph 			i < RTE_CRYPTO_MAX_DEVS; i++) {
157*1f5cfe96SAnoob Joseph 		rte_cryptodev_stop(ctx->enabled_cdevs[i]);
158*1f5cfe96SAnoob Joseph 		ret = rte_cryptodev_close(ctx->enabled_cdevs[i]);
159*1f5cfe96SAnoob Joseph 		if (ret)
160*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1,
161*1f5cfe96SAnoob Joseph 					"Crypto device close error %d\n", ret);
162*1f5cfe96SAnoob Joseph 	}
163*1f5cfe96SAnoob Joseph 
164*1f5cfe96SAnoob Joseph 	return ret;
165*1f5cfe96SAnoob Joseph }
166*1f5cfe96SAnoob Joseph 
167*1f5cfe96SAnoob Joseph static int
168*1f5cfe96SAnoob Joseph mempool_init(struct test_ctx *ctx, uint8_t nb_lcores)
169*1f5cfe96SAnoob Joseph {
170*1f5cfe96SAnoob Joseph 	struct rte_mempool *sess_mpool;
171*1f5cfe96SAnoob Joseph 	unsigned int sec_sess_sz;
172*1f5cfe96SAnoob Joseph 	int nb_sess_total;
173*1f5cfe96SAnoob Joseph 
174*1f5cfe96SAnoob Joseph 	nb_sess_total = ctx->nb_sess + RTE_MEMPOOL_CACHE_MAX_SIZE * nb_lcores;
175*1f5cfe96SAnoob Joseph 
176*1f5cfe96SAnoob Joseph 	sec_sess_sz = rte_security_session_get_size(ctx->sec_ctx);
177*1f5cfe96SAnoob Joseph 
178*1f5cfe96SAnoob Joseph 	sess_mpool = rte_cryptodev_sym_session_pool_create("test_sess_mp",
179*1f5cfe96SAnoob Joseph 			nb_sess_total, sec_sess_sz, RTE_MEMPOOL_CACHE_MAX_SIZE,
180*1f5cfe96SAnoob Joseph 			0, SOCKET_ID_ANY);
181*1f5cfe96SAnoob Joseph 	if (sess_mpool == NULL) {
182*1f5cfe96SAnoob Joseph 		RTE_LOG(ERR, USER1, "Could not create mempool\n");
183*1f5cfe96SAnoob Joseph 		return -1;
184*1f5cfe96SAnoob Joseph 	}
185*1f5cfe96SAnoob Joseph 
186*1f5cfe96SAnoob Joseph 	ctx->sess_mp = sess_mpool;
187*1f5cfe96SAnoob Joseph 
188*1f5cfe96SAnoob Joseph 	return 0;
189*1f5cfe96SAnoob Joseph }
190*1f5cfe96SAnoob Joseph 
191*1f5cfe96SAnoob Joseph static int
192*1f5cfe96SAnoob Joseph mempool_fini(struct test_ctx *ctx)
193*1f5cfe96SAnoob Joseph {
194*1f5cfe96SAnoob Joseph 	rte_mempool_free(ctx->sess_mp);
195*1f5cfe96SAnoob Joseph 
196*1f5cfe96SAnoob Joseph 	return 0;
197*1f5cfe96SAnoob Joseph }
198*1f5cfe96SAnoob Joseph 
199*1f5cfe96SAnoob Joseph static int
200*1f5cfe96SAnoob Joseph sec_conf_init(struct lcore_conf *conf,
201*1f5cfe96SAnoob Joseph 	      struct rte_security_session_conf *sess_conf,
202*1f5cfe96SAnoob Joseph 	      struct rte_security_ipsec_xform *ipsec_xform,
203*1f5cfe96SAnoob Joseph 	      const struct ipsec_test_data *td)
204*1f5cfe96SAnoob Joseph {
205*1f5cfe96SAnoob Joseph 	uint16_t v6_src[8] = {0x2607, 0xf8b0, 0x400c, 0x0c03, 0x0000, 0x0000,
206*1f5cfe96SAnoob Joseph 				0x0000, 0x001a};
207*1f5cfe96SAnoob Joseph 	uint16_t v6_dst[8] = {0x2001, 0x0470, 0xe5bf, 0xdead, 0x4957, 0x2174,
208*1f5cfe96SAnoob Joseph 				0xe82c, 0x4887};
209*1f5cfe96SAnoob Joseph 	const struct rte_ipv4_hdr *ipv4 =
210*1f5cfe96SAnoob Joseph 			(const struct rte_ipv4_hdr *)td->output_text.data;
211*1f5cfe96SAnoob Joseph 	struct rte_security_capability_idx sec_cap_idx;
212*1f5cfe96SAnoob Joseph 	const struct rte_security_capability *sec_cap;
213*1f5cfe96SAnoob Joseph 	enum rte_security_ipsec_sa_direction dir;
214*1f5cfe96SAnoob Joseph 	uint32_t src, dst;
215*1f5cfe96SAnoob Joseph 	int salt_len;
216*1f5cfe96SAnoob Joseph 
217*1f5cfe96SAnoob Joseph 	/* Copy IPsec xform */
218*1f5cfe96SAnoob Joseph 	memcpy(ipsec_xform, &td->ipsec_xform, sizeof(*ipsec_xform));
219*1f5cfe96SAnoob Joseph 
220*1f5cfe96SAnoob Joseph 	dir = ipsec_xform->direction;
221*1f5cfe96SAnoob Joseph 
222*1f5cfe96SAnoob Joseph 	memcpy(&src, &ipv4->src_addr, sizeof(ipv4->src_addr));
223*1f5cfe96SAnoob Joseph 	memcpy(&dst, &ipv4->dst_addr, sizeof(ipv4->dst_addr));
224*1f5cfe96SAnoob Joseph 
225*1f5cfe96SAnoob Joseph 	if (td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
226*1f5cfe96SAnoob Joseph 		if (td->ipsec_xform.tunnel.type ==
227*1f5cfe96SAnoob Joseph 				RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
228*1f5cfe96SAnoob Joseph 			memcpy(&ipsec_xform->tunnel.ipv4.src_ip, &src,
229*1f5cfe96SAnoob Joseph 			       sizeof(src));
230*1f5cfe96SAnoob Joseph 			memcpy(&ipsec_xform->tunnel.ipv4.dst_ip, &dst,
231*1f5cfe96SAnoob Joseph 			       sizeof(dst));
232*1f5cfe96SAnoob Joseph 
233*1f5cfe96SAnoob Joseph 		} else {
234*1f5cfe96SAnoob Joseph 			memcpy(&ipsec_xform->tunnel.ipv6.src_addr, &v6_src,
235*1f5cfe96SAnoob Joseph 			       sizeof(v6_src));
236*1f5cfe96SAnoob Joseph 			memcpy(&ipsec_xform->tunnel.ipv6.dst_addr, &v6_dst,
237*1f5cfe96SAnoob Joseph 			       sizeof(v6_dst));
238*1f5cfe96SAnoob Joseph 		}
239*1f5cfe96SAnoob Joseph 	}
240*1f5cfe96SAnoob Joseph 
241*1f5cfe96SAnoob Joseph 	sec_cap_idx.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
242*1f5cfe96SAnoob Joseph 	sec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_IPSEC;
243*1f5cfe96SAnoob Joseph 	sec_cap_idx.ipsec.proto = ipsec_xform->proto;
244*1f5cfe96SAnoob Joseph 	sec_cap_idx.ipsec.mode = ipsec_xform->mode;
245*1f5cfe96SAnoob Joseph 	sec_cap_idx.ipsec.direction = ipsec_xform->direction;
246*1f5cfe96SAnoob Joseph 
247*1f5cfe96SAnoob Joseph 	sec_cap = rte_security_capability_get(conf->ctx->sec_ctx, &sec_cap_idx);
248*1f5cfe96SAnoob Joseph 	if (sec_cap == NULL) {
249*1f5cfe96SAnoob Joseph 		RTE_LOG(ERR, USER1, "Could not get capabilities\n");
250*1f5cfe96SAnoob Joseph 		return -1;
251*1f5cfe96SAnoob Joseph 	}
252*1f5cfe96SAnoob Joseph 
253*1f5cfe96SAnoob Joseph 	/* Copy cipher session parameters */
254*1f5cfe96SAnoob Joseph 	if (td[0].aead) {
255*1f5cfe96SAnoob Joseph 		memcpy(&conf->aead_xform, &td[0].xform.aead,
256*1f5cfe96SAnoob Joseph 		       sizeof(conf->aead_xform));
257*1f5cfe96SAnoob Joseph 		conf->aead_xform.aead.key.data = td[0].key.data;
258*1f5cfe96SAnoob Joseph 		conf->aead_xform.aead.iv.offset = IV_OFFSET;
259*1f5cfe96SAnoob Joseph 
260*1f5cfe96SAnoob Joseph 		/* Verify crypto capabilities */
261*1f5cfe96SAnoob Joseph 		if (test_ipsec_crypto_caps_aead_verify(
262*1f5cfe96SAnoob Joseph 				sec_cap,
263*1f5cfe96SAnoob Joseph 				&conf->aead_xform) != 0) {
264*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1,
265*1f5cfe96SAnoob Joseph 				"Crypto capabilities not supported\n");
266*1f5cfe96SAnoob Joseph 			return -1;
267*1f5cfe96SAnoob Joseph 		}
268*1f5cfe96SAnoob Joseph 	} else if (td[0].auth_only) {
269*1f5cfe96SAnoob Joseph 		memcpy(&conf->auth_xform, &td[0].xform.chain.auth,
270*1f5cfe96SAnoob Joseph 		       sizeof(conf->auth_xform));
271*1f5cfe96SAnoob Joseph 		conf->auth_xform.auth.key.data = td[0].auth_key.data;
272*1f5cfe96SAnoob Joseph 
273*1f5cfe96SAnoob Joseph 		if (test_ipsec_crypto_caps_auth_verify(
274*1f5cfe96SAnoob Joseph 				sec_cap,
275*1f5cfe96SAnoob Joseph 				&conf->auth_xform) != 0) {
276*1f5cfe96SAnoob Joseph 			RTE_LOG(INFO, USER1,
277*1f5cfe96SAnoob Joseph 				"Auth crypto capabilities not supported\n");
278*1f5cfe96SAnoob Joseph 			return -1;
279*1f5cfe96SAnoob Joseph 		}
280*1f5cfe96SAnoob Joseph 	} else {
281*1f5cfe96SAnoob Joseph 		memcpy(&conf->cipher_xform, &td[0].xform.chain.cipher,
282*1f5cfe96SAnoob Joseph 		       sizeof(conf->cipher_xform));
283*1f5cfe96SAnoob Joseph 		memcpy(&conf->auth_xform, &td[0].xform.chain.auth,
284*1f5cfe96SAnoob Joseph 		       sizeof(conf->auth_xform));
285*1f5cfe96SAnoob Joseph 		conf->cipher_xform.cipher.key.data = td[0].key.data;
286*1f5cfe96SAnoob Joseph 		conf->cipher_xform.cipher.iv.offset = IV_OFFSET;
287*1f5cfe96SAnoob Joseph 		conf->auth_xform.auth.key.data = td[0].auth_key.data;
288*1f5cfe96SAnoob Joseph 
289*1f5cfe96SAnoob Joseph 		/* Verify crypto capabilities */
290*1f5cfe96SAnoob Joseph 
291*1f5cfe96SAnoob Joseph 		if (test_ipsec_crypto_caps_cipher_verify(
292*1f5cfe96SAnoob Joseph 				sec_cap,
293*1f5cfe96SAnoob Joseph 				&conf->cipher_xform) != 0) {
294*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1,
295*1f5cfe96SAnoob Joseph 				"Cipher crypto capabilities not supported\n");
296*1f5cfe96SAnoob Joseph 			return -1;
297*1f5cfe96SAnoob Joseph 		}
298*1f5cfe96SAnoob Joseph 
299*1f5cfe96SAnoob Joseph 		if (test_ipsec_crypto_caps_auth_verify(
300*1f5cfe96SAnoob Joseph 				sec_cap,
301*1f5cfe96SAnoob Joseph 				&conf->auth_xform) != 0) {
302*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1,
303*1f5cfe96SAnoob Joseph 				"Auth crypto capabilities not supported\n");
304*1f5cfe96SAnoob Joseph 			return -1;
305*1f5cfe96SAnoob Joseph 		}
306*1f5cfe96SAnoob Joseph 	}
307*1f5cfe96SAnoob Joseph 
308*1f5cfe96SAnoob Joseph 	if (test_ipsec_sec_caps_verify(ipsec_xform, sec_cap, 0) != 0)
309*1f5cfe96SAnoob Joseph 		return -1;
310*1f5cfe96SAnoob Joseph 
311*1f5cfe96SAnoob Joseph 	sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL;
312*1f5cfe96SAnoob Joseph 	sess_conf->protocol = RTE_SECURITY_PROTOCOL_IPSEC;
313*1f5cfe96SAnoob Joseph 
314*1f5cfe96SAnoob Joseph 	if (td[0].aead || td[0].aes_gmac) {
315*1f5cfe96SAnoob Joseph 		salt_len = RTE_MIN(sizeof(ipsec_xform->salt), td[0].salt.len);
316*1f5cfe96SAnoob Joseph 		memcpy(&ipsec_xform->salt, td[0].salt.data, salt_len);
317*1f5cfe96SAnoob Joseph 	}
318*1f5cfe96SAnoob Joseph 
319*1f5cfe96SAnoob Joseph 	if (td[0].aead) {
320*1f5cfe96SAnoob Joseph 		sess_conf->ipsec = *ipsec_xform;
321*1f5cfe96SAnoob Joseph 		sess_conf->crypto_xform = &conf->aead_xform;
322*1f5cfe96SAnoob Joseph 	} else if (td[0].auth_only) {
323*1f5cfe96SAnoob Joseph 		sess_conf->ipsec = *ipsec_xform;
324*1f5cfe96SAnoob Joseph 		sess_conf->crypto_xform = &conf->auth_xform;
325*1f5cfe96SAnoob Joseph 	} else {
326*1f5cfe96SAnoob Joseph 		sess_conf->ipsec = *ipsec_xform;
327*1f5cfe96SAnoob Joseph 		if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
328*1f5cfe96SAnoob Joseph 			sess_conf->crypto_xform = &conf->cipher_xform;
329*1f5cfe96SAnoob Joseph 			conf->cipher_xform.next = &conf->auth_xform;
330*1f5cfe96SAnoob Joseph 		} else {
331*1f5cfe96SAnoob Joseph 			sess_conf->crypto_xform = &conf->auth_xform;
332*1f5cfe96SAnoob Joseph 			conf->auth_xform.next = &conf->cipher_xform;
333*1f5cfe96SAnoob Joseph 		}
334*1f5cfe96SAnoob Joseph 	}
335*1f5cfe96SAnoob Joseph 
336*1f5cfe96SAnoob Joseph 	return 0;
337*1f5cfe96SAnoob Joseph }
338*1f5cfe96SAnoob Joseph 
339*1f5cfe96SAnoob Joseph static int
340*1f5cfe96SAnoob Joseph test_security_session_perf(void *arg)
341*1f5cfe96SAnoob Joseph {
342*1f5cfe96SAnoob Joseph 	uint64_t tsc_start, tsc_mid, tsc_end, tsc_setup_dur, tsc_destroy_dur;
343*1f5cfe96SAnoob Joseph 	struct rte_security_ipsec_xform ipsec_xform;
344*1f5cfe96SAnoob Joseph 	struct rte_security_session_conf sess_conf;
345*1f5cfe96SAnoob Joseph 	int i, ret, nb_sessions, nb_sess_total;
346*1f5cfe96SAnoob Joseph 	struct rte_security_session **sess;
347*1f5cfe96SAnoob Joseph 	struct rte_security_ctx *sec_ctx;
348*1f5cfe96SAnoob Joseph 	double setup_rate, destroy_rate;
349*1f5cfe96SAnoob Joseph 	uint64_t setup_ms, destroy_ms;
350*1f5cfe96SAnoob Joseph 	struct lcore_conf *conf = arg;
351*1f5cfe96SAnoob Joseph 	struct rte_mempool *sess_mp;
352*1f5cfe96SAnoob Joseph 	uint8_t nb_lcores;
353*1f5cfe96SAnoob Joseph 
354*1f5cfe96SAnoob Joseph 	nb_lcores = conf->ctx->nb_lcores;
355*1f5cfe96SAnoob Joseph 	nb_sess_total = conf->ctx->nb_sess;
356*1f5cfe96SAnoob Joseph 	sec_ctx = conf->ctx->sec_ctx;
357*1f5cfe96SAnoob Joseph 	sess_mp = conf->ctx->sess_mp;
358*1f5cfe96SAnoob Joseph 
359*1f5cfe96SAnoob Joseph 	nb_sessions = nb_sess_total / nb_lcores;
360*1f5cfe96SAnoob Joseph 
361*1f5cfe96SAnoob Joseph 	if (conf->qp_id == 0)
362*1f5cfe96SAnoob Joseph 		nb_sessions += (nb_sess_total - nb_sessions * nb_lcores);
363*1f5cfe96SAnoob Joseph 
364*1f5cfe96SAnoob Joseph 	ret = sec_conf_init(conf, &sess_conf, &ipsec_xform,
365*1f5cfe96SAnoob Joseph 			    &ctx.td[ctx.td_idx]);
366*1f5cfe96SAnoob Joseph 	if (ret) {
367*1f5cfe96SAnoob Joseph 		RTE_LOG(ERR, USER1, "Could not initialize session conf\n");
368*1f5cfe96SAnoob Joseph 		return EXIT_FAILURE;
369*1f5cfe96SAnoob Joseph 	}
370*1f5cfe96SAnoob Joseph 
371*1f5cfe96SAnoob Joseph 	sess = rte_zmalloc(NULL, sizeof(void *) * nb_sessions, 0);
372*1f5cfe96SAnoob Joseph 
373*1f5cfe96SAnoob Joseph 	tsc_start = rte_rdtsc_precise();
374*1f5cfe96SAnoob Joseph 
375*1f5cfe96SAnoob Joseph 	for (i = 0; i < nb_sessions; i++) {
376*1f5cfe96SAnoob Joseph 		sess[i] = rte_security_session_create(sec_ctx,
377*1f5cfe96SAnoob Joseph 						      &sess_conf,
378*1f5cfe96SAnoob Joseph 						      sess_mp);
379*1f5cfe96SAnoob Joseph 		if (unlikely(sess[i] == NULL)) {
380*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1, "Could not create session\n");
381*1f5cfe96SAnoob Joseph 			return EXIT_FAILURE;
382*1f5cfe96SAnoob Joseph 		}
383*1f5cfe96SAnoob Joseph 	}
384*1f5cfe96SAnoob Joseph 
385*1f5cfe96SAnoob Joseph 	tsc_mid = rte_rdtsc_precise();
386*1f5cfe96SAnoob Joseph 
387*1f5cfe96SAnoob Joseph 	for (i = 0; i < nb_sessions; i++) {
388*1f5cfe96SAnoob Joseph 		ret = rte_security_session_destroy(sec_ctx, sess[i]);
389*1f5cfe96SAnoob Joseph 		if (unlikely(ret < 0)) {
390*1f5cfe96SAnoob Joseph 			RTE_LOG(ERR, USER1, "Could not destroy session\n");
391*1f5cfe96SAnoob Joseph 			return EXIT_FAILURE;
392*1f5cfe96SAnoob Joseph 		}
393*1f5cfe96SAnoob Joseph 	}
394*1f5cfe96SAnoob Joseph 
395*1f5cfe96SAnoob Joseph 	tsc_end = rte_rdtsc_precise();
396*1f5cfe96SAnoob Joseph 
397*1f5cfe96SAnoob Joseph 	tsc_setup_dur = tsc_mid - tsc_start;
398*1f5cfe96SAnoob Joseph 	tsc_destroy_dur = tsc_end - tsc_mid;
399*1f5cfe96SAnoob Joseph 
400*1f5cfe96SAnoob Joseph 	setup_ms = tsc_setup_dur * 1000 / rte_get_tsc_hz();
401*1f5cfe96SAnoob Joseph 	destroy_ms = tsc_destroy_dur * 1000 / rte_get_tsc_hz();
402*1f5cfe96SAnoob Joseph 
403*1f5cfe96SAnoob Joseph 	setup_rate = (double)nb_sessions * rte_get_tsc_hz() / tsc_setup_dur;
404*1f5cfe96SAnoob Joseph 	destroy_rate = (double)nb_sessions * rte_get_tsc_hz() / tsc_destroy_dur;
405*1f5cfe96SAnoob Joseph 
406*1f5cfe96SAnoob Joseph 	printf("%20u%20u%20"PRIu64"%20"PRIu64"%20.2f%20.2f\n",
407*1f5cfe96SAnoob Joseph 			rte_lcore_id(),
408*1f5cfe96SAnoob Joseph 			nb_sessions,
409*1f5cfe96SAnoob Joseph 			setup_ms,
410*1f5cfe96SAnoob Joseph 			destroy_ms,
411*1f5cfe96SAnoob Joseph 			setup_rate,
412*1f5cfe96SAnoob Joseph 			destroy_rate);
413*1f5cfe96SAnoob Joseph 
414*1f5cfe96SAnoob Joseph 	return EXIT_SUCCESS;
415*1f5cfe96SAnoob Joseph }
416*1f5cfe96SAnoob Joseph 
417*1f5cfe96SAnoob Joseph static void
418*1f5cfe96SAnoob Joseph usage(char *progname)
419*1f5cfe96SAnoob Joseph {
420*1f5cfe96SAnoob Joseph 	printf("\nusage: %s\n", progname);
421*1f5cfe96SAnoob Joseph 	printf("  --help     : display this message and exit\n"
422*1f5cfe96SAnoob Joseph 	       "  --inbound  : test for inbound direction\n"
423*1f5cfe96SAnoob Joseph 		"           default outbound direction is tested\n"
424*1f5cfe96SAnoob Joseph 	       "  --nb-sess=N: to set the number of sessions\n"
425*1f5cfe96SAnoob Joseph 		"           to be created, default is %d\n", DEF_NB_SESSIONS);
426*1f5cfe96SAnoob Joseph }
427*1f5cfe96SAnoob Joseph 
428*1f5cfe96SAnoob Joseph static void
429*1f5cfe96SAnoob Joseph args_parse(int argc, char **argv)
430*1f5cfe96SAnoob Joseph {
431*1f5cfe96SAnoob Joseph 	char **argvopt;
432*1f5cfe96SAnoob Joseph 	int n, opt;
433*1f5cfe96SAnoob Joseph 	int opt_idx;
434*1f5cfe96SAnoob Joseph 
435*1f5cfe96SAnoob Joseph 	static const struct option lgopts[] = {
436*1f5cfe96SAnoob Joseph 		/* Control */
437*1f5cfe96SAnoob Joseph 		{ "help",    0, 0, 0 },
438*1f5cfe96SAnoob Joseph 		{ "inbound", 0, 0, 0 },
439*1f5cfe96SAnoob Joseph 		{ "nb-sess", 1, 0, 0 },
440*1f5cfe96SAnoob Joseph 		{ NULL, 0, 0, 0 }
441*1f5cfe96SAnoob Joseph 	};
442*1f5cfe96SAnoob Joseph 
443*1f5cfe96SAnoob Joseph 	argvopt = argv;
444*1f5cfe96SAnoob Joseph 
445*1f5cfe96SAnoob Joseph 	while ((opt = getopt_long(argc, argvopt, "",
446*1f5cfe96SAnoob Joseph 				lgopts, &opt_idx)) != EOF) {
447*1f5cfe96SAnoob Joseph 		switch (opt) {
448*1f5cfe96SAnoob Joseph 		case 0:
449*1f5cfe96SAnoob Joseph 			if (strcmp(lgopts[opt_idx].name, "help") == 0) {
450*1f5cfe96SAnoob Joseph 				usage(argv[0]);
451*1f5cfe96SAnoob Joseph 				exit(EXIT_SUCCESS);
452*1f5cfe96SAnoob Joseph 			}
453*1f5cfe96SAnoob Joseph 
454*1f5cfe96SAnoob Joseph 			if (strcmp(lgopts[opt_idx].name, "nb-sess") == 0) {
455*1f5cfe96SAnoob Joseph 				n = atoi(optarg);
456*1f5cfe96SAnoob Joseph 				if (n >= 0)
457*1f5cfe96SAnoob Joseph 					ctx.nb_sess = n;
458*1f5cfe96SAnoob Joseph 				else
459*1f5cfe96SAnoob Joseph 					rte_exit(EXIT_FAILURE,
460*1f5cfe96SAnoob Joseph 						"nb-sess should be >= 0\n");
461*1f5cfe96SAnoob Joseph 				printf("nb-sess %d / ", ctx.nb_sess);
462*1f5cfe96SAnoob Joseph 			} else if (strcmp(lgopts[opt_idx].name, "inbound") ==
463*1f5cfe96SAnoob Joseph 				   0) {
464*1f5cfe96SAnoob Joseph 				ctx.is_inbound = true;
465*1f5cfe96SAnoob Joseph 				printf("inbound / ");
466*1f5cfe96SAnoob Joseph 			}
467*1f5cfe96SAnoob Joseph 
468*1f5cfe96SAnoob Joseph 			break;
469*1f5cfe96SAnoob Joseph 
470*1f5cfe96SAnoob Joseph 		default:
471*1f5cfe96SAnoob Joseph 			usage(argv[0]);
472*1f5cfe96SAnoob Joseph 			rte_exit(EXIT_FAILURE, "Invalid option: %s\n",
473*1f5cfe96SAnoob Joseph 					argv[opt_idx - 1]);
474*1f5cfe96SAnoob Joseph 			break;
475*1f5cfe96SAnoob Joseph 		}
476*1f5cfe96SAnoob Joseph 	}
477*1f5cfe96SAnoob Joseph 
478*1f5cfe96SAnoob Joseph 	printf("\n\n");
479*1f5cfe96SAnoob Joseph }
480*1f5cfe96SAnoob Joseph 
481*1f5cfe96SAnoob Joseph int
482*1f5cfe96SAnoob Joseph main(int argc, char **argv)
483*1f5cfe96SAnoob Joseph {
484*1f5cfe96SAnoob Joseph 	struct ipsec_test_data td_outb[RTE_DIM(alg_list)];
485*1f5cfe96SAnoob Joseph 	struct ipsec_test_data td_inb[RTE_DIM(alg_list)];
486*1f5cfe96SAnoob Joseph 	struct ipsec_test_flags flags;
487*1f5cfe96SAnoob Joseph 	uint32_t lcore_id;
488*1f5cfe96SAnoob Joseph 	uint8_t nb_lcores;
489*1f5cfe96SAnoob Joseph 	unsigned long i;
490*1f5cfe96SAnoob Joseph 	int ret;
491*1f5cfe96SAnoob Joseph 
492*1f5cfe96SAnoob Joseph 	memset(&ctx, 0, sizeof(struct test_ctx));
493*1f5cfe96SAnoob Joseph 	memset(&flags, 0, sizeof(flags));
494*1f5cfe96SAnoob Joseph 
495*1f5cfe96SAnoob Joseph 	ret = rte_eal_init(argc, argv);
496*1f5cfe96SAnoob Joseph 	if (ret < 0)
497*1f5cfe96SAnoob Joseph 		rte_exit(EXIT_FAILURE, "Invalid EAL arguments!\n");
498*1f5cfe96SAnoob Joseph 	argc -= ret;
499*1f5cfe96SAnoob Joseph 	argv += ret;
500*1f5cfe96SAnoob Joseph 
501*1f5cfe96SAnoob Joseph 	nb_lcores = rte_lcore_count() - 1;
502*1f5cfe96SAnoob Joseph 	if (nb_lcores < 1) {
503*1f5cfe96SAnoob Joseph 		RTE_LOG(ERR, USER1,
504*1f5cfe96SAnoob Joseph 			"Number of worker cores need to be higher than 1\n");
505*1f5cfe96SAnoob Joseph 		return -EINVAL;
506*1f5cfe96SAnoob Joseph 	}
507*1f5cfe96SAnoob Joseph 
508*1f5cfe96SAnoob Joseph 	ctx.nb_sess = DEF_NB_SESSIONS + RTE_MEMPOOL_CACHE_MAX_SIZE * nb_lcores;
509*1f5cfe96SAnoob Joseph 
510*1f5cfe96SAnoob Joseph 	if (argc > 1)
511*1f5cfe96SAnoob Joseph 		args_parse(argc, argv);
512*1f5cfe96SAnoob Joseph 
513*1f5cfe96SAnoob Joseph 	ctx.nb_lcores = nb_lcores;
514*1f5cfe96SAnoob Joseph 
515*1f5cfe96SAnoob Joseph 	ret = cryptodev_init(&ctx, nb_lcores);
516*1f5cfe96SAnoob Joseph 	if (ret)
517*1f5cfe96SAnoob Joseph 		goto exit;
518*1f5cfe96SAnoob Joseph 
519*1f5cfe96SAnoob Joseph 	ret = mempool_init(&ctx, nb_lcores);
520*1f5cfe96SAnoob Joseph 	if (ret)
521*1f5cfe96SAnoob Joseph 		goto cryptodev_fini;
522*1f5cfe96SAnoob Joseph 
523*1f5cfe96SAnoob Joseph 	test_ipsec_alg_list_populate();
524*1f5cfe96SAnoob Joseph 
525*1f5cfe96SAnoob Joseph 	for (i = 0; i < RTE_DIM(alg_list); i++) {
526*1f5cfe96SAnoob Joseph 		test_ipsec_td_prepare(alg_list[i].param1,
527*1f5cfe96SAnoob Joseph 				      alg_list[i].param2,
528*1f5cfe96SAnoob Joseph 				      &flags,
529*1f5cfe96SAnoob Joseph 				      &td_outb[i],
530*1f5cfe96SAnoob Joseph 				      1);
531*1f5cfe96SAnoob Joseph 		if (ctx.is_inbound)
532*1f5cfe96SAnoob Joseph 			test_ipsec_td_in_from_out(&td_outb[i], &td_inb[i]);
533*1f5cfe96SAnoob Joseph 	}
534*1f5cfe96SAnoob Joseph 
535*1f5cfe96SAnoob Joseph 	ctx.td = td_outb;
536*1f5cfe96SAnoob Joseph 	if (ctx.is_inbound)
537*1f5cfe96SAnoob Joseph 		ctx.td = td_inb;
538*1f5cfe96SAnoob Joseph 
539*1f5cfe96SAnoob Joseph 	for (ctx.td_idx = 0; ctx.td_idx < RTE_DIM(alg_list); ctx.td_idx++) {
540*1f5cfe96SAnoob Joseph 
541*1f5cfe96SAnoob Joseph 		printf("\n\n    Algorithm combination:");
542*1f5cfe96SAnoob Joseph 		test_ipsec_display_alg(alg_list[ctx.td_idx].param1,
543*1f5cfe96SAnoob Joseph 				       alg_list[ctx.td_idx].param2);
544*1f5cfe96SAnoob Joseph 		printf("    ----------------------");
545*1f5cfe96SAnoob Joseph 
546*1f5cfe96SAnoob Joseph 		printf("\n%20s%20s%20s%20s%20s%20s\n\n",
547*1f5cfe96SAnoob Joseph 			"lcore id", "nb_sessions",
548*1f5cfe96SAnoob Joseph 			"Setup time(ms)", "Destroy time(ms)",
549*1f5cfe96SAnoob Joseph 			"Setup rate(sess/s)",
550*1f5cfe96SAnoob Joseph 			"Destroy rate(sess/sec)");
551*1f5cfe96SAnoob Joseph 
552*1f5cfe96SAnoob Joseph 		i = 0;
553*1f5cfe96SAnoob Joseph 		RTE_LCORE_FOREACH_WORKER(lcore_id) {
554*1f5cfe96SAnoob Joseph 			rte_eal_remote_launch(test_security_session_perf,
555*1f5cfe96SAnoob Joseph 					      &ctx.lconf[i],
556*1f5cfe96SAnoob Joseph 					      lcore_id);
557*1f5cfe96SAnoob Joseph 			i++;
558*1f5cfe96SAnoob Joseph 		}
559*1f5cfe96SAnoob Joseph 
560*1f5cfe96SAnoob Joseph 		RTE_LCORE_FOREACH_WORKER(lcore_id) {
561*1f5cfe96SAnoob Joseph 			ret |= rte_eal_wait_lcore(lcore_id);
562*1f5cfe96SAnoob Joseph 		}
563*1f5cfe96SAnoob Joseph 
564*1f5cfe96SAnoob Joseph 	}
565*1f5cfe96SAnoob Joseph 
566*1f5cfe96SAnoob Joseph 	cryptodev_fini(&ctx);
567*1f5cfe96SAnoob Joseph 	mempool_fini(&ctx);
568*1f5cfe96SAnoob Joseph 
569*1f5cfe96SAnoob Joseph 	return EXIT_SUCCESS;
570*1f5cfe96SAnoob Joseph cryptodev_fini:
571*1f5cfe96SAnoob Joseph 	cryptodev_fini(&ctx);
572*1f5cfe96SAnoob Joseph exit:
573*1f5cfe96SAnoob Joseph 	return EXIT_FAILURE;
574*1f5cfe96SAnoob Joseph 
575*1f5cfe96SAnoob Joseph }
576