xref: /f-stack/dpdk/app/test/test_ipsec_perf.c (revision 2d9fd380)
1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(c) 2020 Intel Corporation
3*2d9fd380Sjfb8856606  */
4*2d9fd380Sjfb8856606 
5*2d9fd380Sjfb8856606 #include <stdio.h>
6*2d9fd380Sjfb8856606 #include <rte_ip.h>
7*2d9fd380Sjfb8856606 #include <rte_malloc.h>
8*2d9fd380Sjfb8856606 #include <rte_ring.h>
9*2d9fd380Sjfb8856606 #include <rte_mbuf.h>
10*2d9fd380Sjfb8856606 #include <rte_cycles.h>
11*2d9fd380Sjfb8856606 #include <rte_ipsec.h>
12*2d9fd380Sjfb8856606 #include <rte_random.h>
13*2d9fd380Sjfb8856606 
14*2d9fd380Sjfb8856606 #include "test.h"
15*2d9fd380Sjfb8856606 #include "test_cryptodev.h"
16*2d9fd380Sjfb8856606 
17*2d9fd380Sjfb8856606 #define RING_SIZE	4096
18*2d9fd380Sjfb8856606 #define BURST_SIZE	64
19*2d9fd380Sjfb8856606 #define NUM_MBUF	4095
20*2d9fd380Sjfb8856606 #define DEFAULT_SPI     7
21*2d9fd380Sjfb8856606 
22*2d9fd380Sjfb8856606 struct ipsec_test_cfg {
23*2d9fd380Sjfb8856606 	uint32_t replay_win_sz;
24*2d9fd380Sjfb8856606 	uint32_t esn;
25*2d9fd380Sjfb8856606 	uint64_t flags;
26*2d9fd380Sjfb8856606 	enum rte_crypto_sym_xform_type type;
27*2d9fd380Sjfb8856606 };
28*2d9fd380Sjfb8856606 
29*2d9fd380Sjfb8856606 struct rte_mempool *mbuf_pool, *cop_pool;
30*2d9fd380Sjfb8856606 
31*2d9fd380Sjfb8856606 struct stats_counter {
32*2d9fd380Sjfb8856606 	uint64_t nb_prepare_call;
33*2d9fd380Sjfb8856606 	uint64_t nb_prepare_pkt;
34*2d9fd380Sjfb8856606 	uint64_t nb_process_call;
35*2d9fd380Sjfb8856606 	uint64_t nb_process_pkt;
36*2d9fd380Sjfb8856606 	uint64_t prepare_ticks_elapsed;
37*2d9fd380Sjfb8856606 	uint64_t process_ticks_elapsed;
38*2d9fd380Sjfb8856606 };
39*2d9fd380Sjfb8856606 
40*2d9fd380Sjfb8856606 struct ipsec_sa {
41*2d9fd380Sjfb8856606 	struct rte_ipsec_session ss[2];
42*2d9fd380Sjfb8856606 	struct rte_ipsec_sa_prm sa_prm;
43*2d9fd380Sjfb8856606 	struct rte_security_ipsec_xform ipsec_xform;
44*2d9fd380Sjfb8856606 	struct rte_crypto_sym_xform cipher_xform;
45*2d9fd380Sjfb8856606 	struct rte_crypto_sym_xform auth_xform;
46*2d9fd380Sjfb8856606 	struct rte_crypto_sym_xform aead_xform;
47*2d9fd380Sjfb8856606 	struct rte_crypto_sym_xform *crypto_xforms;
48*2d9fd380Sjfb8856606 	struct rte_crypto_op *cop[BURST_SIZE];
49*2d9fd380Sjfb8856606 	enum rte_crypto_sym_xform_type type;
50*2d9fd380Sjfb8856606 	struct stats_counter cnt;
51*2d9fd380Sjfb8856606 	uint32_t replay_win_sz;
52*2d9fd380Sjfb8856606 	uint32_t sa_flags;
53*2d9fd380Sjfb8856606 };
54*2d9fd380Sjfb8856606 
55*2d9fd380Sjfb8856606 static const struct ipsec_test_cfg test_cfg[] = {
56*2d9fd380Sjfb8856606 	{0, 0, 0, RTE_CRYPTO_SYM_XFORM_AEAD},
57*2d9fd380Sjfb8856606 	{0, 0, 0, RTE_CRYPTO_SYM_XFORM_CIPHER},
58*2d9fd380Sjfb8856606 	{128, 1, 0, RTE_CRYPTO_SYM_XFORM_AEAD},
59*2d9fd380Sjfb8856606 	{128, 1, 0, RTE_CRYPTO_SYM_XFORM_CIPHER},
60*2d9fd380Sjfb8856606 
61*2d9fd380Sjfb8856606 };
62*2d9fd380Sjfb8856606 
63*2d9fd380Sjfb8856606 static struct rte_ipv4_hdr ipv4_outer  = {
64*2d9fd380Sjfb8856606 	.version_ihl = IPVERSION << 4 |
65*2d9fd380Sjfb8856606 		sizeof(ipv4_outer) / RTE_IPV4_IHL_MULTIPLIER,
66*2d9fd380Sjfb8856606 	.time_to_live = IPDEFTTL,
67*2d9fd380Sjfb8856606 	.next_proto_id = IPPROTO_ESP,
68*2d9fd380Sjfb8856606 	.src_addr = RTE_IPV4(192, 168, 1, 100),
69*2d9fd380Sjfb8856606 	.dst_addr = RTE_IPV4(192, 168, 2, 100),
70*2d9fd380Sjfb8856606 };
71*2d9fd380Sjfb8856606 
72*2d9fd380Sjfb8856606 static struct rte_ring *ring_inb_prepare;
73*2d9fd380Sjfb8856606 static struct rte_ring *ring_inb_process;
74*2d9fd380Sjfb8856606 static struct rte_ring *ring_outb_prepare;
75*2d9fd380Sjfb8856606 static struct rte_ring *ring_outb_process;
76*2d9fd380Sjfb8856606 
77*2d9fd380Sjfb8856606 struct supported_cipher_algo {
78*2d9fd380Sjfb8856606 	const char *keyword;
79*2d9fd380Sjfb8856606 	enum rte_crypto_cipher_algorithm algo;
80*2d9fd380Sjfb8856606 	uint16_t iv_len;
81*2d9fd380Sjfb8856606 	uint16_t block_size;
82*2d9fd380Sjfb8856606 	uint16_t key_len;
83*2d9fd380Sjfb8856606 };
84*2d9fd380Sjfb8856606 
85*2d9fd380Sjfb8856606 struct supported_auth_algo {
86*2d9fd380Sjfb8856606 	const char *keyword;
87*2d9fd380Sjfb8856606 	enum rte_crypto_auth_algorithm algo;
88*2d9fd380Sjfb8856606 	uint16_t digest_len;
89*2d9fd380Sjfb8856606 	uint16_t key_len;
90*2d9fd380Sjfb8856606 	uint8_t key_not_req;
91*2d9fd380Sjfb8856606 };
92*2d9fd380Sjfb8856606 
93*2d9fd380Sjfb8856606 struct supported_aead_algo {
94*2d9fd380Sjfb8856606 	const char *keyword;
95*2d9fd380Sjfb8856606 	enum rte_crypto_aead_algorithm algo;
96*2d9fd380Sjfb8856606 	uint16_t iv_len;
97*2d9fd380Sjfb8856606 	uint16_t block_size;
98*2d9fd380Sjfb8856606 	uint16_t digest_len;
99*2d9fd380Sjfb8856606 	uint16_t key_len;
100*2d9fd380Sjfb8856606 	uint8_t aad_len;
101*2d9fd380Sjfb8856606 };
102*2d9fd380Sjfb8856606 
103*2d9fd380Sjfb8856606 const struct supported_cipher_algo cipher_algo[] = {
104*2d9fd380Sjfb8856606 	{
105*2d9fd380Sjfb8856606 		.keyword = "aes-128-cbc",
106*2d9fd380Sjfb8856606 		.algo = RTE_CRYPTO_CIPHER_AES_CBC,
107*2d9fd380Sjfb8856606 		.iv_len = 16,
108*2d9fd380Sjfb8856606 		.block_size = 16,
109*2d9fd380Sjfb8856606 		.key_len = 16
110*2d9fd380Sjfb8856606 	}
111*2d9fd380Sjfb8856606 };
112*2d9fd380Sjfb8856606 
113*2d9fd380Sjfb8856606 const struct supported_auth_algo auth_algo[] = {
114*2d9fd380Sjfb8856606 	{
115*2d9fd380Sjfb8856606 		.keyword = "sha1-hmac",
116*2d9fd380Sjfb8856606 		.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
117*2d9fd380Sjfb8856606 		.digest_len = 12,
118*2d9fd380Sjfb8856606 		.key_len = 20
119*2d9fd380Sjfb8856606 	}
120*2d9fd380Sjfb8856606 };
121*2d9fd380Sjfb8856606 
122*2d9fd380Sjfb8856606 const struct supported_aead_algo aead_algo[] = {
123*2d9fd380Sjfb8856606 	{
124*2d9fd380Sjfb8856606 		.keyword = "aes-128-gcm",
125*2d9fd380Sjfb8856606 		.algo = RTE_CRYPTO_AEAD_AES_GCM,
126*2d9fd380Sjfb8856606 		.iv_len = 8,
127*2d9fd380Sjfb8856606 		.block_size = 4,
128*2d9fd380Sjfb8856606 		.key_len = 20,
129*2d9fd380Sjfb8856606 		.digest_len = 16,
130*2d9fd380Sjfb8856606 		.aad_len = 8,
131*2d9fd380Sjfb8856606 	}
132*2d9fd380Sjfb8856606 };
133*2d9fd380Sjfb8856606 
generate_mbuf_data(struct rte_mempool * mpool)134*2d9fd380Sjfb8856606 static struct rte_mbuf *generate_mbuf_data(struct rte_mempool *mpool)
135*2d9fd380Sjfb8856606 {
136*2d9fd380Sjfb8856606 	struct rte_mbuf *mbuf = rte_pktmbuf_alloc(mpool);
137*2d9fd380Sjfb8856606 
138*2d9fd380Sjfb8856606 	if (mbuf) {
139*2d9fd380Sjfb8856606 		mbuf->data_len = 64;
140*2d9fd380Sjfb8856606 		mbuf->pkt_len  = 64;
141*2d9fd380Sjfb8856606 	}
142*2d9fd380Sjfb8856606 
143*2d9fd380Sjfb8856606 	return mbuf;
144*2d9fd380Sjfb8856606 }
145*2d9fd380Sjfb8856606 
146*2d9fd380Sjfb8856606 static int
fill_ipsec_param(struct ipsec_sa * sa)147*2d9fd380Sjfb8856606 fill_ipsec_param(struct ipsec_sa *sa)
148*2d9fd380Sjfb8856606 {
149*2d9fd380Sjfb8856606 	struct rte_ipsec_sa_prm *prm = &sa->sa_prm;
150*2d9fd380Sjfb8856606 
151*2d9fd380Sjfb8856606 	memset(prm, 0, sizeof(*prm));
152*2d9fd380Sjfb8856606 
153*2d9fd380Sjfb8856606 	prm->flags = sa->sa_flags;
154*2d9fd380Sjfb8856606 
155*2d9fd380Sjfb8856606 	/* setup ipsec xform */
156*2d9fd380Sjfb8856606 	prm->ipsec_xform = sa->ipsec_xform;
157*2d9fd380Sjfb8856606 	prm->ipsec_xform.salt = (uint32_t)rte_rand();
158*2d9fd380Sjfb8856606 	prm->ipsec_xform.replay_win_sz = sa->replay_win_sz;
159*2d9fd380Sjfb8856606 
160*2d9fd380Sjfb8856606 	/* setup tunnel related fields */
161*2d9fd380Sjfb8856606 	prm->tun.hdr_len = sizeof(ipv4_outer);
162*2d9fd380Sjfb8856606 	prm->tun.next_proto = IPPROTO_IPIP;
163*2d9fd380Sjfb8856606 	prm->tun.hdr = &ipv4_outer;
164*2d9fd380Sjfb8856606 
165*2d9fd380Sjfb8856606 	if (sa->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
166*2d9fd380Sjfb8856606 		sa->aead_xform.type = sa->type;
167*2d9fd380Sjfb8856606 		sa->aead_xform.aead.algo = aead_algo->algo;
168*2d9fd380Sjfb8856606 		sa->aead_xform.next = NULL;
169*2d9fd380Sjfb8856606 		sa->aead_xform.aead.digest_length = aead_algo->digest_len;
170*2d9fd380Sjfb8856606 		sa->aead_xform.aead.iv.offset = IV_OFFSET;
171*2d9fd380Sjfb8856606 		sa->aead_xform.aead.iv.length = 12;
172*2d9fd380Sjfb8856606 
173*2d9fd380Sjfb8856606 		if (sa->ipsec_xform.direction ==
174*2d9fd380Sjfb8856606 				RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
175*2d9fd380Sjfb8856606 			sa->aead_xform.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
176*2d9fd380Sjfb8856606 		} else {
177*2d9fd380Sjfb8856606 			sa->aead_xform.aead.op = RTE_CRYPTO_AEAD_OP_ENCRYPT;
178*2d9fd380Sjfb8856606 		}
179*2d9fd380Sjfb8856606 
180*2d9fd380Sjfb8856606 		sa->crypto_xforms = &sa->aead_xform;
181*2d9fd380Sjfb8856606 	} else {
182*2d9fd380Sjfb8856606 		sa->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
183*2d9fd380Sjfb8856606 		sa->cipher_xform.cipher.algo = cipher_algo->algo;
184*2d9fd380Sjfb8856606 		sa->cipher_xform.cipher.iv.offset = IV_OFFSET;
185*2d9fd380Sjfb8856606 		sa->cipher_xform.cipher.iv.length = 12;
186*2d9fd380Sjfb8856606 		sa->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
187*2d9fd380Sjfb8856606 		sa->auth_xform.auth.algo = auth_algo->algo;
188*2d9fd380Sjfb8856606 		sa->auth_xform.auth.digest_length = auth_algo->digest_len;
189*2d9fd380Sjfb8856606 
190*2d9fd380Sjfb8856606 
191*2d9fd380Sjfb8856606 		if (sa->ipsec_xform.direction ==
192*2d9fd380Sjfb8856606 				RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
193*2d9fd380Sjfb8856606 			sa->cipher_xform.cipher.op =
194*2d9fd380Sjfb8856606 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
195*2d9fd380Sjfb8856606 			sa->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
196*2d9fd380Sjfb8856606 			sa->cipher_xform.next = NULL;
197*2d9fd380Sjfb8856606 			sa->auth_xform.next = &sa->cipher_xform;
198*2d9fd380Sjfb8856606 			sa->crypto_xforms = &sa->auth_xform;
199*2d9fd380Sjfb8856606 		} else {
200*2d9fd380Sjfb8856606 			sa->cipher_xform.cipher.op =
201*2d9fd380Sjfb8856606 				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
202*2d9fd380Sjfb8856606 			sa->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
203*2d9fd380Sjfb8856606 			sa->auth_xform.next = NULL;
204*2d9fd380Sjfb8856606 			sa->cipher_xform.next = &sa->auth_xform;
205*2d9fd380Sjfb8856606 			sa->crypto_xforms = &sa->cipher_xform;
206*2d9fd380Sjfb8856606 		}
207*2d9fd380Sjfb8856606 	}
208*2d9fd380Sjfb8856606 
209*2d9fd380Sjfb8856606 	prm->crypto_xform = sa->crypto_xforms;
210*2d9fd380Sjfb8856606 
211*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
212*2d9fd380Sjfb8856606 }
213*2d9fd380Sjfb8856606 
214*2d9fd380Sjfb8856606 static int
create_sa(enum rte_security_session_action_type action_type,struct ipsec_sa * sa)215*2d9fd380Sjfb8856606 create_sa(enum rte_security_session_action_type action_type,
216*2d9fd380Sjfb8856606 	  struct ipsec_sa *sa)
217*2d9fd380Sjfb8856606 {
218*2d9fd380Sjfb8856606 	static struct rte_cryptodev_sym_session dummy_ses;
219*2d9fd380Sjfb8856606 	size_t sz;
220*2d9fd380Sjfb8856606 	int rc;
221*2d9fd380Sjfb8856606 
222*2d9fd380Sjfb8856606 	memset(&sa->ss[0], 0, sizeof(sa->ss[0]));
223*2d9fd380Sjfb8856606 
224*2d9fd380Sjfb8856606 	rc = fill_ipsec_param(sa);
225*2d9fd380Sjfb8856606 	if (rc != 0) {
226*2d9fd380Sjfb8856606 		printf("failed to fill ipsec param\n");
227*2d9fd380Sjfb8856606 		return TEST_FAILED;
228*2d9fd380Sjfb8856606 	}
229*2d9fd380Sjfb8856606 
230*2d9fd380Sjfb8856606 	sz = rte_ipsec_sa_size(&sa->sa_prm);
231*2d9fd380Sjfb8856606 	TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n");
232*2d9fd380Sjfb8856606 
233*2d9fd380Sjfb8856606 	sa->ss[0].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
234*2d9fd380Sjfb8856606 	TEST_ASSERT_NOT_NULL(sa->ss[0].sa,
235*2d9fd380Sjfb8856606 		"failed to allocate memory for rte_ipsec_sa\n");
236*2d9fd380Sjfb8856606 
237*2d9fd380Sjfb8856606 	sa->ss[0].type = action_type;
238*2d9fd380Sjfb8856606 	sa->ss[0].crypto.ses = &dummy_ses;
239*2d9fd380Sjfb8856606 
240*2d9fd380Sjfb8856606 	rc = rte_ipsec_sa_init(sa->ss[0].sa, &sa->sa_prm, sz);
241*2d9fd380Sjfb8856606 	rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL;
242*2d9fd380Sjfb8856606 
243*2d9fd380Sjfb8856606 	if (rc == 0)
244*2d9fd380Sjfb8856606 		rc = rte_ipsec_session_prepare(&sa->ss[0]);
245*2d9fd380Sjfb8856606 	else
246*2d9fd380Sjfb8856606 		return TEST_FAILED;
247*2d9fd380Sjfb8856606 
248*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
249*2d9fd380Sjfb8856606 }
250*2d9fd380Sjfb8856606 
251*2d9fd380Sjfb8856606 static int
packet_prepare(struct rte_mbuf ** buf,struct ipsec_sa * sa,uint16_t num_pkts)252*2d9fd380Sjfb8856606 packet_prepare(struct rte_mbuf **buf, struct ipsec_sa *sa,
253*2d9fd380Sjfb8856606 	       uint16_t num_pkts)
254*2d9fd380Sjfb8856606 {
255*2d9fd380Sjfb8856606 	uint64_t time_stamp;
256*2d9fd380Sjfb8856606 	uint16_t k = 0, i;
257*2d9fd380Sjfb8856606 
258*2d9fd380Sjfb8856606 	for (i = 0; i < num_pkts; i++) {
259*2d9fd380Sjfb8856606 
260*2d9fd380Sjfb8856606 		sa->cop[i] = rte_crypto_op_alloc(cop_pool,
261*2d9fd380Sjfb8856606 				RTE_CRYPTO_OP_TYPE_SYMMETRIC);
262*2d9fd380Sjfb8856606 
263*2d9fd380Sjfb8856606 		if (sa->cop[i] == NULL) {
264*2d9fd380Sjfb8856606 
265*2d9fd380Sjfb8856606 			RTE_LOG(ERR, USER1,
266*2d9fd380Sjfb8856606 			"Failed to allocate symmetric crypto op\n");
267*2d9fd380Sjfb8856606 
268*2d9fd380Sjfb8856606 			return k;
269*2d9fd380Sjfb8856606 		}
270*2d9fd380Sjfb8856606 	}
271*2d9fd380Sjfb8856606 
272*2d9fd380Sjfb8856606 	time_stamp = rte_rdtsc_precise();
273*2d9fd380Sjfb8856606 
274*2d9fd380Sjfb8856606 	k = rte_ipsec_pkt_crypto_prepare(&sa->ss[0], buf,
275*2d9fd380Sjfb8856606 		sa->cop, num_pkts);
276*2d9fd380Sjfb8856606 
277*2d9fd380Sjfb8856606 	time_stamp = rte_rdtsc_precise() - time_stamp;
278*2d9fd380Sjfb8856606 
279*2d9fd380Sjfb8856606 	if (k != num_pkts) {
280*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
281*2d9fd380Sjfb8856606 		return k;
282*2d9fd380Sjfb8856606 	}
283*2d9fd380Sjfb8856606 
284*2d9fd380Sjfb8856606 	sa->cnt.prepare_ticks_elapsed += time_stamp;
285*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_call++;
286*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_pkt += k;
287*2d9fd380Sjfb8856606 
288*2d9fd380Sjfb8856606 	for (i = 0; i < num_pkts; i++)
289*2d9fd380Sjfb8856606 		rte_crypto_op_free(sa->cop[i]);
290*2d9fd380Sjfb8856606 
291*2d9fd380Sjfb8856606 	return k;
292*2d9fd380Sjfb8856606 }
293*2d9fd380Sjfb8856606 
294*2d9fd380Sjfb8856606 static int
packet_process(struct rte_mbuf ** buf,struct ipsec_sa * sa,uint16_t num_pkts)295*2d9fd380Sjfb8856606 packet_process(struct rte_mbuf **buf, struct ipsec_sa *sa,
296*2d9fd380Sjfb8856606 	       uint16_t num_pkts)
297*2d9fd380Sjfb8856606 {
298*2d9fd380Sjfb8856606 	uint64_t time_stamp;
299*2d9fd380Sjfb8856606 	uint16_t k = 0;
300*2d9fd380Sjfb8856606 
301*2d9fd380Sjfb8856606 	time_stamp = rte_rdtsc_precise();
302*2d9fd380Sjfb8856606 
303*2d9fd380Sjfb8856606 	k = rte_ipsec_pkt_process(&sa->ss[0], buf, num_pkts);
304*2d9fd380Sjfb8856606 
305*2d9fd380Sjfb8856606 	time_stamp = rte_rdtsc_precise() - time_stamp;
306*2d9fd380Sjfb8856606 
307*2d9fd380Sjfb8856606 	if (k != num_pkts) {
308*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
309*2d9fd380Sjfb8856606 		return k;
310*2d9fd380Sjfb8856606 	}
311*2d9fd380Sjfb8856606 
312*2d9fd380Sjfb8856606 	sa->cnt.process_ticks_elapsed += time_stamp;
313*2d9fd380Sjfb8856606 	sa->cnt.nb_process_call++;
314*2d9fd380Sjfb8856606 	sa->cnt.nb_process_pkt += k;
315*2d9fd380Sjfb8856606 
316*2d9fd380Sjfb8856606 	return k;
317*2d9fd380Sjfb8856606 }
318*2d9fd380Sjfb8856606 
319*2d9fd380Sjfb8856606 static int
create_traffic(struct ipsec_sa * sa,struct rte_ring * deq_ring,struct rte_ring * enq_ring,struct rte_ring * ring)320*2d9fd380Sjfb8856606 create_traffic(struct ipsec_sa *sa, struct rte_ring *deq_ring,
321*2d9fd380Sjfb8856606 	       struct rte_ring *enq_ring, struct rte_ring *ring)
322*2d9fd380Sjfb8856606 {
323*2d9fd380Sjfb8856606 	struct rte_mbuf *mbuf[BURST_SIZE];
324*2d9fd380Sjfb8856606 	uint16_t num_pkts, n;
325*2d9fd380Sjfb8856606 
326*2d9fd380Sjfb8856606 	while (rte_ring_empty(deq_ring) == 0) {
327*2d9fd380Sjfb8856606 
328*2d9fd380Sjfb8856606 		num_pkts = rte_ring_sc_dequeue_burst(deq_ring, (void **)mbuf,
329*2d9fd380Sjfb8856606 						     RTE_DIM(mbuf), NULL);
330*2d9fd380Sjfb8856606 
331*2d9fd380Sjfb8856606 		if (num_pkts == 0)
332*2d9fd380Sjfb8856606 			return TEST_FAILED;
333*2d9fd380Sjfb8856606 
334*2d9fd380Sjfb8856606 		n = packet_prepare(mbuf, sa, num_pkts);
335*2d9fd380Sjfb8856606 		if (n != num_pkts)
336*2d9fd380Sjfb8856606 			return TEST_FAILED;
337*2d9fd380Sjfb8856606 
338*2d9fd380Sjfb8856606 		num_pkts = rte_ring_sp_enqueue_burst(enq_ring, (void **)mbuf,
339*2d9fd380Sjfb8856606 						     num_pkts, NULL);
340*2d9fd380Sjfb8856606 		if (num_pkts == 0)
341*2d9fd380Sjfb8856606 			return TEST_FAILED;
342*2d9fd380Sjfb8856606 	}
343*2d9fd380Sjfb8856606 
344*2d9fd380Sjfb8856606 	deq_ring = enq_ring;
345*2d9fd380Sjfb8856606 	enq_ring = ring;
346*2d9fd380Sjfb8856606 
347*2d9fd380Sjfb8856606 	while (rte_ring_empty(deq_ring) == 0) {
348*2d9fd380Sjfb8856606 
349*2d9fd380Sjfb8856606 		num_pkts = rte_ring_sc_dequeue_burst(deq_ring, (void **)mbuf,
350*2d9fd380Sjfb8856606 					       RTE_DIM(mbuf), NULL);
351*2d9fd380Sjfb8856606 		if (num_pkts == 0)
352*2d9fd380Sjfb8856606 			return TEST_FAILED;
353*2d9fd380Sjfb8856606 
354*2d9fd380Sjfb8856606 		n = packet_process(mbuf, sa, num_pkts);
355*2d9fd380Sjfb8856606 		if (n != num_pkts)
356*2d9fd380Sjfb8856606 			return TEST_FAILED;
357*2d9fd380Sjfb8856606 
358*2d9fd380Sjfb8856606 		num_pkts = rte_ring_sp_enqueue_burst(enq_ring, (void **)mbuf,
359*2d9fd380Sjfb8856606 					       num_pkts, NULL);
360*2d9fd380Sjfb8856606 		if (num_pkts == 0)
361*2d9fd380Sjfb8856606 			return TEST_FAILED;
362*2d9fd380Sjfb8856606 	}
363*2d9fd380Sjfb8856606 
364*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
365*2d9fd380Sjfb8856606 }
366*2d9fd380Sjfb8856606 
367*2d9fd380Sjfb8856606 static void
fill_ipsec_sa_out(const struct ipsec_test_cfg * test_cfg,struct ipsec_sa * sa)368*2d9fd380Sjfb8856606 fill_ipsec_sa_out(const struct ipsec_test_cfg *test_cfg,
369*2d9fd380Sjfb8856606 		  struct ipsec_sa *sa)
370*2d9fd380Sjfb8856606 {
371*2d9fd380Sjfb8856606 	sa->ipsec_xform.spi = DEFAULT_SPI;
372*2d9fd380Sjfb8856606 	sa->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
373*2d9fd380Sjfb8856606 	sa->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
374*2d9fd380Sjfb8856606 	sa->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
375*2d9fd380Sjfb8856606 	sa->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
376*2d9fd380Sjfb8856606 	sa->ipsec_xform.options.esn = test_cfg->esn;
377*2d9fd380Sjfb8856606 	sa->type = test_cfg->type;
378*2d9fd380Sjfb8856606 	sa->replay_win_sz = test_cfg->replay_win_sz;
379*2d9fd380Sjfb8856606 	sa->sa_flags = test_cfg->flags;
380*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_call = 0;
381*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_pkt = 0;
382*2d9fd380Sjfb8856606 	sa->cnt.nb_process_call = 0;
383*2d9fd380Sjfb8856606 	sa->cnt.nb_process_pkt = 0;
384*2d9fd380Sjfb8856606 	sa->cnt.process_ticks_elapsed = 0;
385*2d9fd380Sjfb8856606 	sa->cnt.prepare_ticks_elapsed = 0;
386*2d9fd380Sjfb8856606 
387*2d9fd380Sjfb8856606 }
388*2d9fd380Sjfb8856606 
389*2d9fd380Sjfb8856606 static void
fill_ipsec_sa_in(const struct ipsec_test_cfg * test_cfg,struct ipsec_sa * sa)390*2d9fd380Sjfb8856606 fill_ipsec_sa_in(const struct ipsec_test_cfg *test_cfg,
391*2d9fd380Sjfb8856606 		  struct ipsec_sa *sa)
392*2d9fd380Sjfb8856606 {
393*2d9fd380Sjfb8856606 	sa->ipsec_xform.spi = DEFAULT_SPI;
394*2d9fd380Sjfb8856606 	sa->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
395*2d9fd380Sjfb8856606 	sa->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
396*2d9fd380Sjfb8856606 	sa->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
397*2d9fd380Sjfb8856606 	sa->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
398*2d9fd380Sjfb8856606 	sa->ipsec_xform.options.esn = test_cfg->esn;
399*2d9fd380Sjfb8856606 	sa->type = test_cfg->type;
400*2d9fd380Sjfb8856606 	sa->replay_win_sz = test_cfg->replay_win_sz;
401*2d9fd380Sjfb8856606 	sa->sa_flags = test_cfg->flags;
402*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_call = 0;
403*2d9fd380Sjfb8856606 	sa->cnt.nb_prepare_pkt = 0;
404*2d9fd380Sjfb8856606 	sa->cnt.nb_process_call = 0;
405*2d9fd380Sjfb8856606 	sa->cnt.nb_process_pkt = 0;
406*2d9fd380Sjfb8856606 	sa->cnt.process_ticks_elapsed = 0;
407*2d9fd380Sjfb8856606 	sa->cnt.prepare_ticks_elapsed = 0;
408*2d9fd380Sjfb8856606 }
409*2d9fd380Sjfb8856606 
410*2d9fd380Sjfb8856606 static int
init_sa_session(const struct ipsec_test_cfg * test_cfg,struct ipsec_sa * sa_out,struct ipsec_sa * sa_in)411*2d9fd380Sjfb8856606 init_sa_session(const struct ipsec_test_cfg *test_cfg,
412*2d9fd380Sjfb8856606 		struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
413*2d9fd380Sjfb8856606 {
414*2d9fd380Sjfb8856606 
415*2d9fd380Sjfb8856606 	int rc;
416*2d9fd380Sjfb8856606 
417*2d9fd380Sjfb8856606 	fill_ipsec_sa_in(test_cfg, sa_in);
418*2d9fd380Sjfb8856606 	fill_ipsec_sa_out(test_cfg, sa_out);
419*2d9fd380Sjfb8856606 
420*2d9fd380Sjfb8856606 	rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, sa_out);
421*2d9fd380Sjfb8856606 	if (rc != 0) {
422*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "out bound create_sa failed, cfg\n");
423*2d9fd380Sjfb8856606 		return TEST_FAILED;
424*2d9fd380Sjfb8856606 	}
425*2d9fd380Sjfb8856606 
426*2d9fd380Sjfb8856606 	rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE, sa_in);
427*2d9fd380Sjfb8856606 	if (rc != 0) {
428*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "out bound create_sa failed, cfg\n");
429*2d9fd380Sjfb8856606 		return TEST_FAILED;
430*2d9fd380Sjfb8856606 	}
431*2d9fd380Sjfb8856606 
432*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
433*2d9fd380Sjfb8856606 }
434*2d9fd380Sjfb8856606 
435*2d9fd380Sjfb8856606 static int
testsuite_setup(void)436*2d9fd380Sjfb8856606 testsuite_setup(void)
437*2d9fd380Sjfb8856606 {
438*2d9fd380Sjfb8856606 	struct rte_mbuf *mbuf;
439*2d9fd380Sjfb8856606 	int i;
440*2d9fd380Sjfb8856606 
441*2d9fd380Sjfb8856606 	mbuf_pool = rte_pktmbuf_pool_create("IPSEC_PERF_MBUFPOOL",
442*2d9fd380Sjfb8856606 			NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
443*2d9fd380Sjfb8856606 			rte_socket_id());
444*2d9fd380Sjfb8856606 	if (mbuf_pool == NULL) {
445*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Can't create MBUFPOOL\n");
446*2d9fd380Sjfb8856606 		return TEST_FAILED;
447*2d9fd380Sjfb8856606 	}
448*2d9fd380Sjfb8856606 
449*2d9fd380Sjfb8856606 	cop_pool = rte_crypto_op_pool_create(
450*2d9fd380Sjfb8856606 			"MBUF_CRYPTO_SYM_OP_POOL",
451*2d9fd380Sjfb8856606 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
452*2d9fd380Sjfb8856606 			NUM_MBUFS, MBUF_CACHE_SIZE,
453*2d9fd380Sjfb8856606 			DEFAULT_NUM_XFORMS *
454*2d9fd380Sjfb8856606 			sizeof(struct rte_crypto_sym_xform) +
455*2d9fd380Sjfb8856606 			MAXIMUM_IV_LENGTH,
456*2d9fd380Sjfb8856606 			rte_socket_id());
457*2d9fd380Sjfb8856606 	if (cop_pool == NULL) {
458*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
459*2d9fd380Sjfb8856606 		return TEST_FAILED;
460*2d9fd380Sjfb8856606 	}
461*2d9fd380Sjfb8856606 
462*2d9fd380Sjfb8856606 	ring_inb_prepare = rte_ring_create("ipsec_test_ring_inb_prepare",
463*2d9fd380Sjfb8856606 					   RING_SIZE, SOCKET_ID_ANY, 0);
464*2d9fd380Sjfb8856606 	if (ring_inb_prepare == NULL)
465*2d9fd380Sjfb8856606 		return TEST_FAILED;
466*2d9fd380Sjfb8856606 
467*2d9fd380Sjfb8856606 	ring_inb_process = rte_ring_create("ipsec_test_ring_inb_process",
468*2d9fd380Sjfb8856606 					   RING_SIZE, SOCKET_ID_ANY, 0);
469*2d9fd380Sjfb8856606 	if (ring_inb_process == NULL)
470*2d9fd380Sjfb8856606 		return TEST_FAILED;
471*2d9fd380Sjfb8856606 
472*2d9fd380Sjfb8856606 	ring_outb_prepare = rte_ring_create("ipsec_test_ring_outb_prepare",
473*2d9fd380Sjfb8856606 					    RING_SIZE, SOCKET_ID_ANY, 0);
474*2d9fd380Sjfb8856606 	if (ring_outb_prepare == NULL)
475*2d9fd380Sjfb8856606 		return TEST_FAILED;
476*2d9fd380Sjfb8856606 
477*2d9fd380Sjfb8856606 	ring_outb_process = rte_ring_create("ipsec_test_ring_outb_process",
478*2d9fd380Sjfb8856606 					    RING_SIZE, SOCKET_ID_ANY, 0);
479*2d9fd380Sjfb8856606 	if (ring_outb_process == NULL)
480*2d9fd380Sjfb8856606 		return TEST_FAILED;
481*2d9fd380Sjfb8856606 
482*2d9fd380Sjfb8856606 	for (i = 0; i < NUM_MBUF; i++) {
483*2d9fd380Sjfb8856606 		mbuf = generate_mbuf_data(mbuf_pool);
484*2d9fd380Sjfb8856606 
485*2d9fd380Sjfb8856606 		if (mbuf && rte_ring_sp_enqueue_bulk(ring_inb_prepare,
486*2d9fd380Sjfb8856606 			   (void **)&mbuf, 1, NULL))
487*2d9fd380Sjfb8856606 			continue;
488*2d9fd380Sjfb8856606 		else
489*2d9fd380Sjfb8856606 			return TEST_FAILED;
490*2d9fd380Sjfb8856606 	}
491*2d9fd380Sjfb8856606 
492*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
493*2d9fd380Sjfb8856606 }
494*2d9fd380Sjfb8856606 
495*2d9fd380Sjfb8856606 static int
measure_performance(struct ipsec_sa * sa_out,struct ipsec_sa * sa_in)496*2d9fd380Sjfb8856606 measure_performance(struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
497*2d9fd380Sjfb8856606 {
498*2d9fd380Sjfb8856606 	uint64_t time_diff = 0;
499*2d9fd380Sjfb8856606 	uint64_t begin = 0;
500*2d9fd380Sjfb8856606 	uint64_t hz = rte_get_timer_hz();
501*2d9fd380Sjfb8856606 
502*2d9fd380Sjfb8856606 	begin = rte_get_timer_cycles();
503*2d9fd380Sjfb8856606 
504*2d9fd380Sjfb8856606 	do {
505*2d9fd380Sjfb8856606 		if (create_traffic(sa_out, ring_inb_prepare, ring_inb_process,
506*2d9fd380Sjfb8856606 				   ring_outb_prepare) < 0)
507*2d9fd380Sjfb8856606 			return TEST_FAILED;
508*2d9fd380Sjfb8856606 
509*2d9fd380Sjfb8856606 		if (create_traffic(sa_in, ring_outb_prepare, ring_outb_process,
510*2d9fd380Sjfb8856606 				   ring_inb_prepare) < 0)
511*2d9fd380Sjfb8856606 			return TEST_FAILED;
512*2d9fd380Sjfb8856606 
513*2d9fd380Sjfb8856606 		time_diff = rte_get_timer_cycles() - begin;
514*2d9fd380Sjfb8856606 
515*2d9fd380Sjfb8856606 	} while (time_diff < (hz * 10));
516*2d9fd380Sjfb8856606 
517*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
518*2d9fd380Sjfb8856606 }
519*2d9fd380Sjfb8856606 
520*2d9fd380Sjfb8856606 static void
print_metrics(const struct ipsec_test_cfg * test_cfg,struct ipsec_sa * sa_out,struct ipsec_sa * sa_in)521*2d9fd380Sjfb8856606 print_metrics(const struct ipsec_test_cfg *test_cfg,
522*2d9fd380Sjfb8856606 	      struct ipsec_sa *sa_out, struct ipsec_sa *sa_in)
523*2d9fd380Sjfb8856606 {
524*2d9fd380Sjfb8856606 	printf("\nMetrics of libipsec prepare/process api:\n");
525*2d9fd380Sjfb8856606 
526*2d9fd380Sjfb8856606 	printf("replay window size = %u\n", test_cfg->replay_win_sz);
527*2d9fd380Sjfb8856606 	if (test_cfg->esn)
528*2d9fd380Sjfb8856606 		printf("replay esn is enabled\n");
529*2d9fd380Sjfb8856606 	else
530*2d9fd380Sjfb8856606 		printf("replay esn is disabled\n");
531*2d9fd380Sjfb8856606 	if (test_cfg->type == RTE_CRYPTO_SYM_XFORM_AEAD)
532*2d9fd380Sjfb8856606 		printf("AEAD algo is AES_GCM\n");
533*2d9fd380Sjfb8856606 	else
534*2d9fd380Sjfb8856606 		printf("CIPHER/AUTH algo is AES_CBC/SHA1\n");
535*2d9fd380Sjfb8856606 
536*2d9fd380Sjfb8856606 
537*2d9fd380Sjfb8856606 	printf("avg cycles for a pkt prepare in outbound is = %.2Lf\n",
538*2d9fd380Sjfb8856606 	(long double)sa_out->cnt.prepare_ticks_elapsed
539*2d9fd380Sjfb8856606 		    / sa_out->cnt.nb_prepare_pkt);
540*2d9fd380Sjfb8856606 	printf("avg cycles for a pkt process in outbound is = %.2Lf\n",
541*2d9fd380Sjfb8856606 	(long double)sa_out->cnt.process_ticks_elapsed
542*2d9fd380Sjfb8856606 		     / sa_out->cnt.nb_process_pkt);
543*2d9fd380Sjfb8856606 	printf("avg cycles for a pkt prepare in inbound is = %.2Lf\n",
544*2d9fd380Sjfb8856606 	(long double)sa_in->cnt.prepare_ticks_elapsed
545*2d9fd380Sjfb8856606 		     / sa_in->cnt.nb_prepare_pkt);
546*2d9fd380Sjfb8856606 	printf("avg cycles for a pkt process in inbound is = %.2Lf\n",
547*2d9fd380Sjfb8856606 	(long double)sa_in->cnt.process_ticks_elapsed
548*2d9fd380Sjfb8856606 		     / sa_in->cnt.nb_process_pkt);
549*2d9fd380Sjfb8856606 
550*2d9fd380Sjfb8856606 }
551*2d9fd380Sjfb8856606 
552*2d9fd380Sjfb8856606 static void
testsuite_teardown(void)553*2d9fd380Sjfb8856606 testsuite_teardown(void)
554*2d9fd380Sjfb8856606 {
555*2d9fd380Sjfb8856606 	if (mbuf_pool != NULL) {
556*2d9fd380Sjfb8856606 		RTE_LOG(DEBUG, USER1, "MBUFPOOL count %u\n",
557*2d9fd380Sjfb8856606 		rte_mempool_avail_count(mbuf_pool));
558*2d9fd380Sjfb8856606 		rte_mempool_free(mbuf_pool);
559*2d9fd380Sjfb8856606 		mbuf_pool = NULL;
560*2d9fd380Sjfb8856606 	}
561*2d9fd380Sjfb8856606 
562*2d9fd380Sjfb8856606 	if (cop_pool != NULL) {
563*2d9fd380Sjfb8856606 		RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
564*2d9fd380Sjfb8856606 		rte_mempool_avail_count(cop_pool));
565*2d9fd380Sjfb8856606 		rte_mempool_free(cop_pool);
566*2d9fd380Sjfb8856606 		cop_pool = NULL;
567*2d9fd380Sjfb8856606 	}
568*2d9fd380Sjfb8856606 
569*2d9fd380Sjfb8856606 	rte_ring_free(ring_inb_prepare);
570*2d9fd380Sjfb8856606 	rte_ring_free(ring_inb_process);
571*2d9fd380Sjfb8856606 	rte_ring_free(ring_outb_prepare);
572*2d9fd380Sjfb8856606 	rte_ring_free(ring_outb_process);
573*2d9fd380Sjfb8856606 
574*2d9fd380Sjfb8856606 	ring_inb_prepare = NULL;
575*2d9fd380Sjfb8856606 	ring_inb_process = NULL;
576*2d9fd380Sjfb8856606 	ring_outb_prepare = NULL;
577*2d9fd380Sjfb8856606 	ring_outb_process = NULL;
578*2d9fd380Sjfb8856606 }
579*2d9fd380Sjfb8856606 
580*2d9fd380Sjfb8856606 static int
test_libipsec_perf(void)581*2d9fd380Sjfb8856606 test_libipsec_perf(void)
582*2d9fd380Sjfb8856606 {
583*2d9fd380Sjfb8856606 	struct ipsec_sa sa_out;
584*2d9fd380Sjfb8856606 	struct ipsec_sa sa_in;
585*2d9fd380Sjfb8856606 	uint32_t i;
586*2d9fd380Sjfb8856606 	int ret;
587*2d9fd380Sjfb8856606 
588*2d9fd380Sjfb8856606 	if (testsuite_setup() < 0) {
589*2d9fd380Sjfb8856606 		testsuite_teardown();
590*2d9fd380Sjfb8856606 		return TEST_FAILED;
591*2d9fd380Sjfb8856606 	}
592*2d9fd380Sjfb8856606 
593*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_DIM(test_cfg) ; i++) {
594*2d9fd380Sjfb8856606 
595*2d9fd380Sjfb8856606 		ret = init_sa_session(&test_cfg[i], &sa_out, &sa_in);
596*2d9fd380Sjfb8856606 		if (ret != 0) {
597*2d9fd380Sjfb8856606 			testsuite_teardown();
598*2d9fd380Sjfb8856606 			return TEST_FAILED;
599*2d9fd380Sjfb8856606 		}
600*2d9fd380Sjfb8856606 
601*2d9fd380Sjfb8856606 		if (measure_performance(&sa_out, &sa_in) < 0) {
602*2d9fd380Sjfb8856606 			testsuite_teardown();
603*2d9fd380Sjfb8856606 			return TEST_FAILED;
604*2d9fd380Sjfb8856606 		}
605*2d9fd380Sjfb8856606 
606*2d9fd380Sjfb8856606 		print_metrics(&test_cfg[i], &sa_out, &sa_in);
607*2d9fd380Sjfb8856606 	}
608*2d9fd380Sjfb8856606 
609*2d9fd380Sjfb8856606 	testsuite_teardown();
610*2d9fd380Sjfb8856606 
611*2d9fd380Sjfb8856606 	return TEST_SUCCESS;
612*2d9fd380Sjfb8856606 }
613*2d9fd380Sjfb8856606 
614*2d9fd380Sjfb8856606 REGISTER_TEST_COMMAND(ipsec_perf_autotest, test_libipsec_perf);
615