xref: /dpdk/app/test/test_security_inline_macsec.c (revision 63bf81a617ac25017e23441521743af7877a38fa)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2023 Marvell.
3  */
4 
5 #include <stdio.h>
6 #include <inttypes.h>
7 
8 #include <rte_ethdev.h>
9 #include <rte_malloc.h>
10 #include <rte_security.h>
11 
12 #include "test.h"
13 #include "test_security_inline_macsec_vectors.h"
14 
15 #ifdef RTE_EXEC_ENV_WINDOWS
16 static int
17 test_inline_macsec(void)
18 {
19 	printf("Inline MACsec not supported on Windows, skipping test\n");
20 	return TEST_SKIPPED;
21 }
22 
23 #else
24 
25 #define NB_ETHPORTS_USED		1
26 #define MEMPOOL_CACHE_SIZE		32
27 #define RTE_TEST_RX_DESC_DEFAULT	1024
28 #define RTE_TEST_TX_DESC_DEFAULT	1024
29 #define RTE_PORT_ALL		(~(uint16_t)0x0)
30 
31 #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
32 #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */
33 #define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */
34 
35 #define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */
36 #define TX_HTHRESH 0  /**< Default values of TX host threshold reg. */
37 #define TX_WTHRESH 0  /**< Default values of TX write-back threshold reg. */
38 
39 #define MAX_TRAFFIC_BURST		2048
40 #define NB_MBUF				10240
41 
42 #define MCS_INVALID_SA			0xFFFF
43 #define MCS_DEFAULT_PN_THRESHOLD	0xFFFFF
44 
45 static struct rte_mempool *mbufpool;
46 static struct rte_mempool *sess_pool;
47 /* ethernet addresses of ports */
48 static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
49 
50 struct mcs_test_opts {
51 	int val_frames;
52 	int nb_td;
53 	uint16_t mtu;
54 	uint8_t sa_in_use;
55 	bool encrypt;
56 	bool protect_frames;
57 	uint8_t sectag_insert_mode;
58 	uint8_t nb_vlan;
59 	uint32_t replay_win_sz;
60 	uint8_t replay_protect;
61 	uint8_t rekey_en;
62 	const struct mcs_test_vector *rekey_td;
63 	const struct mcs_test_vector *ar_td[3];
64 	bool dump_all_stats;
65 	uint8_t check_untagged_rx;
66 	uint8_t check_bad_tag_cnt;
67 	uint8_t check_sa_not_in_use;
68 	uint8_t check_decap_stats;
69 	uint8_t check_verify_only_stats;
70 	uint8_t check_pkts_invalid_stats;
71 	uint8_t check_pkts_unchecked_stats;
72 	uint8_t check_out_pkts_untagged;
73 	uint8_t check_out_pkts_toolong;
74 	uint8_t check_encap_stats;
75 	uint8_t check_auth_only_stats;
76 	uint8_t check_sectag_interrupts;
77 };
78 
79 static struct rte_eth_conf port_conf = {
80 	.rxmode = {
81 		.mq_mode = RTE_ETH_MQ_RX_NONE,
82 		.offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM |
83 			    RTE_ETH_RX_OFFLOAD_MACSEC_STRIP,
84 	},
85 	.txmode = {
86 		.mq_mode = RTE_ETH_MQ_TX_NONE,
87 		.offloads = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE |
88 			    RTE_ETH_TX_OFFLOAD_MACSEC_INSERT,
89 	},
90 	.lpbk_mode = 1,  /* enable loopback */
91 };
92 
93 static struct rte_eth_rxconf rx_conf = {
94 	.rx_thresh = {
95 		.pthresh = RX_PTHRESH,
96 		.hthresh = RX_HTHRESH,
97 		.wthresh = RX_WTHRESH,
98 	},
99 	.rx_free_thresh = 32,
100 };
101 
102 static struct rte_eth_txconf tx_conf = {
103 	.tx_thresh = {
104 		.pthresh = TX_PTHRESH,
105 		.hthresh = TX_HTHRESH,
106 		.wthresh = TX_WTHRESH,
107 	},
108 	.tx_free_thresh = 32, /* Use PMD default values */
109 	.tx_rs_thresh = 32, /* Use PMD default values */
110 };
111 
112 static uint16_t port_id;
113 
114 static uint64_t link_mbps;
115 
116 static struct rte_flow *default_tx_flow[RTE_MAX_ETHPORTS];
117 static struct rte_flow *default_rx_flow[RTE_MAX_ETHPORTS];
118 
119 static struct rte_mbuf **tx_pkts_burst;
120 static struct rte_mbuf **rx_pkts_burst;
121 
122 static inline struct rte_mbuf *
123 init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len)
124 {
125 	struct rte_mbuf *pkt;
126 
127 	pkt = rte_pktmbuf_alloc(mp);
128 	if (pkt == NULL)
129 		return NULL;
130 
131 	rte_memcpy(rte_pktmbuf_append(pkt, len), data, len);
132 
133 	return pkt;
134 }
135 
136 static int
137 init_mempools(unsigned int nb_mbuf)
138 {
139 	struct rte_security_ctx *sec_ctx;
140 	uint16_t nb_sess = 512;
141 	uint32_t sess_sz;
142 	char s[64];
143 
144 	if (mbufpool == NULL) {
145 		snprintf(s, sizeof(s), "mbuf_pool");
146 		mbufpool = rte_pktmbuf_pool_create(s, nb_mbuf,
147 				MEMPOOL_CACHE_SIZE, 0,
148 				RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY);
149 		if (mbufpool == NULL) {
150 			printf("Cannot init mbuf pool\n");
151 			return TEST_FAILED;
152 		}
153 		printf("Allocated mbuf pool\n");
154 	}
155 
156 	sec_ctx = rte_eth_dev_get_sec_ctx(port_id);
157 	if (sec_ctx == NULL) {
158 		printf("Device does not support Security ctx\n");
159 		return TEST_SKIPPED;
160 	}
161 	sess_sz = rte_security_session_get_size(sec_ctx);
162 	if (sess_pool == NULL) {
163 		snprintf(s, sizeof(s), "sess_pool");
164 		sess_pool = rte_mempool_create(s, nb_sess, sess_sz,
165 				MEMPOOL_CACHE_SIZE, 0,
166 				NULL, NULL, NULL, NULL,
167 				SOCKET_ID_ANY, 0);
168 		if (sess_pool == NULL) {
169 			printf("Cannot init sess pool\n");
170 			return TEST_FAILED;
171 		}
172 		printf("Allocated sess pool\n");
173 	}
174 
175 	return 0;
176 }
177 
178 static void
179 fill_macsec_sa_conf(const struct mcs_test_vector *td, struct rte_security_macsec_sa *sa,
180 			enum rte_security_macsec_direction dir, uint8_t an, uint8_t tci_off)
181 {
182 	sa->dir = dir;
183 
184 	sa->key.data = td->sa_key.data;
185 	sa->key.length = td->sa_key.len;
186 
187 	memcpy((uint8_t *)sa->salt, (const uint8_t *)td->salt, RTE_SECURITY_MACSEC_SALT_LEN);
188 
189 	/* AN is set as per the value in secure packet in test vector */
190 	sa->an = an & RTE_MACSEC_AN_MASK;
191 
192 	sa->ssci = td->ssci;
193 	sa->xpn = td->xpn;
194 	/* Starting packet number which is expected to come next.
195 	 * It is take from the test vector so that we can match the out packet.
196 	 */
197 	sa->next_pn = *(const uint32_t *)(&td->secure_pkt.data[tci_off + 2]);
198 }
199 
200 static void
201 fill_macsec_sc_conf(const struct mcs_test_vector *td,
202 		    struct rte_security_macsec_sc *sc_conf,
203 		    const struct mcs_test_opts *opts,
204 		    enum rte_security_macsec_direction dir,
205 		    uint16_t sa_id[], uint8_t tci_off)
206 {
207 	uint8_t i;
208 
209 	sc_conf->dir = dir;
210 	sc_conf->pn_threshold = ((uint64_t)td->xpn << 32) |
211 		rte_be_to_cpu_32(*(const uint32_t *)(&td->secure_pkt.data[tci_off + 2]));
212 	if (dir == RTE_SECURITY_MACSEC_DIR_TX) {
213 		sc_conf->sc_tx.sa_id = sa_id[0];
214 		if (sa_id[1] != MCS_INVALID_SA) {
215 			sc_conf->sc_tx.sa_id_rekey = sa_id[1];
216 			sc_conf->sc_tx.re_key_en = 1;
217 		}
218 		sc_conf->sc_tx.active = 1;
219 		/* is SCI valid */
220 		if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) {
221 			memcpy(&sc_conf->sc_tx.sci, &td->secure_pkt.data[tci_off + 6],
222 					sizeof(sc_conf->sc_tx.sci));
223 			sc_conf->sc_tx.sci = rte_be_to_cpu_64(sc_conf->sc_tx.sci);
224 		} else if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) {
225 			/* sci = source_mac + port_id when ES.bit = 1 & SC.bit = 0 */
226 			const uint8_t *smac = td->plain_pkt.data + RTE_ETHER_ADDR_LEN;
227 			uint8_t *ptr = (uint8_t *)&sc_conf->sc_tx.sci;
228 
229 			ptr[0] = 0x01;
230 			ptr[1] = 0;
231 			for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
232 				ptr[2 + i] = smac[RTE_ETHER_ADDR_LEN - 1 - i];
233 		} else {
234 			/* use some default SCI */
235 			sc_conf->sc_tx.sci = 0xf1341e023a2b1c5d;
236 		}
237 		if (td->xpn > 0)
238 			sc_conf->sc_tx.is_xpn = 1;
239 	} else {
240 		for (i = 0; i < RTE_SECURITY_MACSEC_NUM_AN; i++) {
241 			sc_conf->sc_rx.sa_id[i] = sa_id[i];
242 			sc_conf->sc_rx.sa_in_use[i] = opts->sa_in_use;
243 		}
244 		sc_conf->sc_rx.active = 1;
245 		if (td->xpn > 0)
246 			sc_conf->sc_rx.is_xpn = 1;
247 	}
248 }
249 
250 
251 /* Create Inline MACsec session */
252 static int
253 fill_session_conf(const struct mcs_test_vector *td, uint16_t portid __rte_unused,
254 		const struct mcs_test_opts *opts,
255 		struct rte_security_session_conf *sess_conf,
256 		enum rte_security_macsec_direction dir,
257 		uint16_t sc_id,
258 		uint8_t tci_off)
259 {
260 	sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
261 	sess_conf->protocol = RTE_SECURITY_PROTOCOL_MACSEC;
262 	sess_conf->macsec.dir = dir;
263 	sess_conf->macsec.alg = td->alg;
264 	sess_conf->macsec.cipher_off = 0;
265 	if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) {
266 		sess_conf->macsec.sci = rte_be_to_cpu_64(*(const uint64_t *)
267 					(&td->secure_pkt.data[tci_off + 6]));
268 	} else if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) {
269 		/* sci = source_mac + port_id when ES.bit = 1 & SC.bit = 0 */
270 		const uint8_t *smac = td->plain_pkt.data + RTE_ETHER_ADDR_LEN;
271 		uint8_t *ptr = (uint8_t *)&sess_conf->macsec.sci;
272 		uint8_t j;
273 
274 		ptr[0] = 0x01;
275 		ptr[1] = 0;
276 		for (j = 0; j < RTE_ETHER_ADDR_LEN; j++)
277 			ptr[2 + j] = smac[RTE_ETHER_ADDR_LEN - 1 - j];
278 	}
279 	sess_conf->macsec.sc_id = sc_id;
280 	if (dir == RTE_SECURITY_MACSEC_DIR_TX) {
281 		sess_conf->macsec.tx_secy.mtu = opts->mtu;
282 		sess_conf->macsec.tx_secy.sectag_off = (opts->sectag_insert_mode == 1) ?
283 							2 * RTE_ETHER_ADDR_LEN :
284 							RTE_VLAN_HLEN;
285 		sess_conf->macsec.tx_secy.sectag_insert_mode = opts->sectag_insert_mode;
286 		sess_conf->macsec.tx_secy.ctrl_port_enable = 1;
287 		sess_conf->macsec.tx_secy.sectag_version = 0;
288 		sess_conf->macsec.tx_secy.end_station =
289 					(td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) >> 6;
290 		sess_conf->macsec.tx_secy.send_sci =
291 					(td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) >> 5;
292 		sess_conf->macsec.tx_secy.scb =
293 					(td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SCB) >> 4;
294 		sess_conf->macsec.tx_secy.encrypt = opts->encrypt;
295 		sess_conf->macsec.tx_secy.protect_frames = opts->protect_frames;
296 		sess_conf->macsec.tx_secy.icv_include_da_sa = 1;
297 	} else {
298 		sess_conf->macsec.rx_secy.replay_win_sz = opts->replay_win_sz;
299 		sess_conf->macsec.rx_secy.replay_protect = opts->replay_protect;
300 		sess_conf->macsec.rx_secy.icv_include_da_sa = 1;
301 		sess_conf->macsec.rx_secy.ctrl_port_enable = 1;
302 		sess_conf->macsec.rx_secy.preserve_sectag = 0;
303 		sess_conf->macsec.rx_secy.preserve_icv = 0;
304 		sess_conf->macsec.rx_secy.validate_frames = opts->val_frames;
305 	}
306 
307 	return 0;
308 }
309 
310 static int
311 create_default_flow(const struct mcs_test_vector *td, uint16_t portid,
312 		    enum rte_security_macsec_direction dir, void *sess)
313 {
314 	struct rte_flow_action action[2];
315 	struct rte_flow_item pattern[2];
316 	struct rte_flow_attr attr = {0};
317 	struct rte_flow_error err;
318 	struct rte_flow *flow;
319 	struct rte_flow_item_eth eth = { .hdr.ether_type = 0, };
320 	static const struct rte_flow_item_eth eth_mask = {
321 		.hdr.dst_addr.addr_bytes = "\x00\x00\x00\x00\x00\x00",
322 		.hdr.src_addr.addr_bytes = "\x00\x00\x00\x00\x00\x00",
323 		.hdr.ether_type = RTE_BE16(0x0000),
324 	};
325 
326 	int ret;
327 
328 	eth.has_vlan = 0;
329 	if (dir == RTE_SECURITY_MACSEC_DIR_TX)
330 		memcpy(&eth.hdr, td->plain_pkt.data, RTE_ETHER_HDR_LEN);
331 	else
332 		memcpy(&eth.hdr, td->secure_pkt.data, RTE_ETHER_HDR_LEN);
333 
334 	pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
335 	pattern[0].spec = &eth;
336 	pattern[0].mask = &eth_mask;
337 	pattern[0].last = NULL;
338 	pattern[1].type = RTE_FLOW_ITEM_TYPE_END;
339 
340 	action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;
341 	action[0].conf = sess;
342 	action[1].type = RTE_FLOW_ACTION_TYPE_END;
343 	action[1].conf = NULL;
344 
345 	attr.ingress = (dir == RTE_SECURITY_MACSEC_DIR_RX) ? 1 : 0;
346 	attr.egress = (dir == RTE_SECURITY_MACSEC_DIR_TX) ? 1 : 0;
347 
348 	ret = rte_flow_validate(portid, &attr, pattern, action, &err);
349 	if (ret) {
350 		printf("\nValidate flow failed, ret = %d\n", ret);
351 		return -1;
352 	}
353 	flow = rte_flow_create(portid, &attr, pattern, action, &err);
354 	if (flow == NULL) {
355 		printf("\nDefault flow rule create failed\n");
356 		return -1;
357 	}
358 
359 	if (dir == RTE_SECURITY_MACSEC_DIR_TX)
360 		default_tx_flow[portid] = flow;
361 	else
362 		default_rx_flow[portid] = flow;
363 
364 	return 0;
365 }
366 
367 static void
368 destroy_default_flow(uint16_t portid)
369 {
370 	struct rte_flow_error err;
371 	int ret;
372 
373 	if (default_tx_flow[portid]) {
374 		ret = rte_flow_destroy(portid, default_tx_flow[portid], &err);
375 		if (ret) {
376 			printf("\nDefault Tx flow rule destroy failed\n");
377 			return;
378 		}
379 		default_tx_flow[portid] = NULL;
380 	}
381 	if (default_rx_flow[portid]) {
382 		ret = rte_flow_destroy(portid, default_rx_flow[portid], &err);
383 		if (ret) {
384 			printf("\nDefault Rx flow rule destroy failed\n");
385 			return;
386 		}
387 		default_rx_flow[portid] = NULL;
388 	}
389 }
390 
391 static void
392 print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)
393 {
394 	char buf[RTE_ETHER_ADDR_FMT_SIZE];
395 	rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
396 	printf("%s%s", name, buf);
397 }
398 
399 /* Check the link status of all ports in up to 3s, and print them finally */
400 static void
401 check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)
402 {
403 #define CHECK_INTERVAL 100 /* 100ms */
404 #define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */
405 	uint16_t portid;
406 	uint8_t count, all_ports_up, print_flag = 0;
407 	struct rte_eth_link link;
408 	int ret;
409 	char link_status[RTE_ETH_LINK_MAX_STR_LEN];
410 
411 	printf("Checking link statuses...\n");
412 	fflush(stdout);
413 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
414 		all_ports_up = 1;
415 		for (portid = 0; portid < port_num; portid++) {
416 			if ((port_mask & (1 << portid)) == 0)
417 				continue;
418 			memset(&link, 0, sizeof(link));
419 			ret = rte_eth_link_get_nowait(portid, &link);
420 			if (ret < 0) {
421 				all_ports_up = 0;
422 				if (print_flag == 1)
423 					printf("Port %u link get failed: %s\n",
424 						portid, rte_strerror(-ret));
425 				continue;
426 			}
427 
428 			/* print link status if flag set */
429 			if (print_flag == 1) {
430 				if (link.link_status && link_mbps == 0)
431 					link_mbps = link.link_speed;
432 
433 				rte_eth_link_to_str(link_status,
434 					sizeof(link_status), &link);
435 				printf("Port %d %s\n", portid, link_status);
436 				continue;
437 			}
438 			/* clear all_ports_up flag if any link down */
439 			if (link.link_status == RTE_ETH_LINK_DOWN) {
440 				all_ports_up = 0;
441 				break;
442 			}
443 		}
444 		/* after finally printing all link status, get out */
445 		if (print_flag == 1)
446 			break;
447 
448 		if (all_ports_up == 0)
449 			fflush(stdout);
450 
451 		/* set the print_flag if all ports up or timeout */
452 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1))
453 			print_flag = 1;
454 	}
455 }
456 
457 static int
458 test_macsec_post_process(struct rte_mbuf *m, const struct mcs_test_vector *td,
459 			enum mcs_op op, uint8_t check_out_pkts_untagged)
460 {
461 	const uint8_t *dptr;
462 	uint16_t pkt_len;
463 
464 	if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
465 			op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY ||
466 			check_out_pkts_untagged == 1) {
467 		dptr = td->plain_pkt.data;
468 		pkt_len = td->plain_pkt.len;
469 	} else {
470 		dptr = td->secure_pkt.data;
471 		pkt_len = td->secure_pkt.len;
472 	}
473 
474 	if (memcmp(rte_pktmbuf_mtod(m, uint8_t *), dptr, pkt_len)) {
475 		printf("\nData comparison failed for td.");
476 		rte_pktmbuf_dump(stdout, m, m->pkt_len);
477 		rte_hexdump(stdout, "expected_data", dptr, pkt_len);
478 		return TEST_FAILED;
479 	}
480 
481 	return TEST_SUCCESS;
482 }
483 
484 static void
485 mcs_stats_dump(struct rte_security_ctx *ctx, enum mcs_op op,
486 	       void *rx_sess, void *tx_sess,
487 	       uint8_t rx_sc_id, uint8_t tx_sc_id,
488 	       uint16_t rx_sa_id[], uint16_t tx_sa_id[])
489 {
490 	struct rte_security_stats sess_stats = {0};
491 	struct rte_security_macsec_secy_stats *secy_stat;
492 	struct rte_security_macsec_sc_stats sc_stat = {0};
493 	struct rte_security_macsec_sa_stats sa_stat = {0};
494 	int i;
495 
496 	if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
497 			op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
498 		printf("\n********* RX SECY STATS ************\n");
499 		rte_security_session_stats_get(ctx, rx_sess, &sess_stats);
500 		secy_stat = &sess_stats.macsec;
501 
502 		if (secy_stat->ctl_pkt_bcast_cnt)
503 			printf("RX: ctl_pkt_bcast_cnt: 0x%" PRIx64 "\n",
504 					secy_stat->ctl_pkt_bcast_cnt);
505 		if (secy_stat->ctl_pkt_mcast_cnt)
506 			printf("RX: ctl_pkt_mcast_cnt: 0x%" PRIx64 "\n",
507 					secy_stat->ctl_pkt_mcast_cnt);
508 		if (secy_stat->ctl_pkt_ucast_cnt)
509 			printf("RX: ctl_pkt_ucast_cnt: 0x%" PRIx64 "\n",
510 					secy_stat->ctl_pkt_ucast_cnt);
511 		if (secy_stat->ctl_octet_cnt)
512 			printf("RX: ctl_octet_cnt: 0x%" PRIx64 "\n", secy_stat->ctl_octet_cnt);
513 		if (secy_stat->unctl_pkt_bcast_cnt)
514 			printf("RX: unctl_pkt_bcast_cnt: 0x%" PRIx64 "\n",
515 					secy_stat->unctl_pkt_bcast_cnt);
516 		if (secy_stat->unctl_pkt_mcast_cnt)
517 			printf("RX: unctl_pkt_mcast_cnt: 0x%" PRIx64 "\n",
518 					secy_stat->unctl_pkt_mcast_cnt);
519 		if (secy_stat->unctl_pkt_ucast_cnt)
520 			printf("RX: unctl_pkt_ucast_cnt: 0x%" PRIx64 "\n",
521 					secy_stat->unctl_pkt_ucast_cnt);
522 		if (secy_stat->unctl_octet_cnt)
523 			printf("RX: unctl_octet_cnt: 0x%" PRIx64 "\n", secy_stat->unctl_octet_cnt);
524 		/* Valid only for RX */
525 		if (secy_stat->octet_decrypted_cnt)
526 			printf("RX: octet_decrypted_cnt: 0x%" PRIx64 "\n",
527 					secy_stat->octet_decrypted_cnt);
528 		if (secy_stat->octet_validated_cnt)
529 			printf("RX: octet_validated_cnt: 0x%" PRIx64 "\n",
530 					secy_stat->octet_validated_cnt);
531 		if (secy_stat->pkt_port_disabled_cnt)
532 			printf("RX: pkt_port_disabled_cnt: 0x%" PRIx64 "\n",
533 					secy_stat->pkt_port_disabled_cnt);
534 		if (secy_stat->pkt_badtag_cnt)
535 			printf("RX: pkt_badtag_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_badtag_cnt);
536 		if (secy_stat->pkt_nosa_cnt)
537 			printf("RX: pkt_nosa_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_nosa_cnt);
538 		if (secy_stat->pkt_nosaerror_cnt)
539 			printf("RX: pkt_nosaerror_cnt: 0x%" PRIx64 "\n",
540 					secy_stat->pkt_nosaerror_cnt);
541 		if (secy_stat->pkt_tagged_ctl_cnt)
542 			printf("RX: pkt_tagged_ctl_cnt: 0x%" PRIx64 "\n",
543 					secy_stat->pkt_tagged_ctl_cnt);
544 		if (secy_stat->pkt_untaged_cnt)
545 			printf("RX: pkt_untaged_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_untaged_cnt);
546 		if (secy_stat->pkt_ctl_cnt)
547 			printf("RX: pkt_ctl_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_ctl_cnt);
548 		if (secy_stat->pkt_notag_cnt)
549 			printf("RX: pkt_notag_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_notag_cnt);
550 		printf("\n");
551 		printf("\n********** RX SC[%u] STATS **************\n", rx_sc_id);
552 
553 		rte_security_macsec_sc_stats_get(ctx, rx_sc_id, RTE_SECURITY_MACSEC_DIR_RX,
554 						 &sc_stat);
555 		/* RX */
556 		if (sc_stat.hit_cnt)
557 			printf("RX hit_cnt: 0x%" PRIx64 "\n", sc_stat.hit_cnt);
558 		if (sc_stat.pkt_invalid_cnt)
559 			printf("RX pkt_invalid_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_invalid_cnt);
560 		if (sc_stat.pkt_late_cnt)
561 			printf("RX pkt_late_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_late_cnt);
562 		if (sc_stat.pkt_notvalid_cnt)
563 			printf("RX pkt_notvalid_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_notvalid_cnt);
564 		if (sc_stat.pkt_unchecked_cnt)
565 			printf("RX pkt_unchecked_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_unchecked_cnt);
566 		if (sc_stat.pkt_delay_cnt)
567 			printf("RX pkt_delay_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_delay_cnt);
568 		if (sc_stat.pkt_ok_cnt)
569 			printf("RX pkt_ok_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_ok_cnt);
570 		if (sc_stat.octet_decrypt_cnt)
571 			printf("RX octet_decrypt_cnt: 0x%" PRIx64 "\n", sc_stat.octet_decrypt_cnt);
572 		if (sc_stat.octet_validate_cnt)
573 			printf("RX octet_validate_cnt: 0x%" PRIx64 "\n",
574 					sc_stat.octet_validate_cnt);
575 		printf("\n");
576 		for (i = 0; i < RTE_SECURITY_MACSEC_NUM_AN; i++) {
577 			printf("\n********** RX SA[%u] STATS ****************\n", rx_sa_id[i]);
578 			memset(&sa_stat, 0, sizeof(struct rte_security_macsec_sa_stats));
579 			rte_security_macsec_sa_stats_get(ctx, rx_sa_id[i],
580 					RTE_SECURITY_MACSEC_DIR_RX, &sa_stat);
581 
582 			/* RX */
583 			if (sa_stat.pkt_invalid_cnt)
584 				printf("RX pkt_invalid_cnt: 0x%" PRIx64 "\n",
585 						sa_stat.pkt_invalid_cnt);
586 			if (sa_stat.pkt_nosaerror_cnt)
587 				printf("RX pkt_nosaerror_cnt: 0x%" PRIx64 "\n",
588 						sa_stat.pkt_nosaerror_cnt);
589 			if (sa_stat.pkt_notvalid_cnt)
590 				printf("RX pkt_notvalid_cnt: 0x%" PRIx64 "\n",
591 						sa_stat.pkt_notvalid_cnt);
592 			if (sa_stat.pkt_ok_cnt)
593 				printf("RX pkt_ok_cnt: 0x%" PRIx64 "\n", sa_stat.pkt_ok_cnt);
594 			if (sa_stat.pkt_nosa_cnt)
595 				printf("RX pkt_nosa_cnt: 0x%" PRIx64 "\n", sa_stat.pkt_nosa_cnt);
596 			printf("\n");
597 		}
598 	}
599 
600 	if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
601 			op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
602 		memset(&sess_stats, 0, sizeof(struct rte_security_stats));
603 		rte_security_session_stats_get(ctx, tx_sess, &sess_stats);
604 		secy_stat = &sess_stats.macsec;
605 
606 		printf("\n********* TX SECY STATS ************\n");
607 		if (secy_stat->ctl_pkt_bcast_cnt)
608 			printf("TX: ctl_pkt_bcast_cnt: 0x%" PRIx64 "\n",
609 					secy_stat->ctl_pkt_bcast_cnt);
610 		if (secy_stat->ctl_pkt_mcast_cnt)
611 			printf("TX: ctl_pkt_mcast_cnt: 0x%" PRIx64 "\n",
612 					secy_stat->ctl_pkt_mcast_cnt);
613 		if (secy_stat->ctl_pkt_ucast_cnt)
614 			printf("TX: ctl_pkt_ucast_cnt: 0x%" PRIx64 "\n",
615 					secy_stat->ctl_pkt_ucast_cnt);
616 		if (secy_stat->ctl_octet_cnt)
617 			printf("TX: ctl_octet_cnt: 0x%" PRIx64 "\n", secy_stat->ctl_octet_cnt);
618 		if (secy_stat->unctl_pkt_bcast_cnt)
619 			printf("TX: unctl_pkt_bcast_cnt: 0x%" PRIx64 "\n",
620 					secy_stat->unctl_pkt_bcast_cnt);
621 		if (secy_stat->unctl_pkt_mcast_cnt)
622 			printf("TX: unctl_pkt_mcast_cnt: 0x%" PRIx64 "\n",
623 					secy_stat->unctl_pkt_mcast_cnt);
624 		if (secy_stat->unctl_pkt_ucast_cnt)
625 			printf("TX: unctl_pkt_ucast_cnt: 0x%" PRIx64 "\n",
626 					secy_stat->unctl_pkt_ucast_cnt);
627 		if (secy_stat->unctl_octet_cnt)
628 			printf("TX: unctl_octet_cnt: 0x%" PRIx64 "\n",
629 					secy_stat->unctl_octet_cnt);
630 		/* Valid only for TX */
631 		if (secy_stat->octet_encrypted_cnt)
632 			printf("TX: octet_encrypted_cnt: 0x%" PRIx64 "\n",
633 					secy_stat->octet_encrypted_cnt);
634 		if (secy_stat->octet_protected_cnt)
635 			printf("TX: octet_protected_cnt: 0x%" PRIx64 "\n",
636 					secy_stat->octet_protected_cnt);
637 		if (secy_stat->pkt_noactivesa_cnt)
638 			printf("TX: pkt_noactivesa_cnt: 0x%" PRIx64 "\n",
639 					secy_stat->pkt_noactivesa_cnt);
640 		if (secy_stat->pkt_toolong_cnt)
641 			printf("TX: pkt_toolong_cnt: 0x%" PRIx64 "\n", secy_stat->pkt_toolong_cnt);
642 		if (secy_stat->pkt_untagged_cnt)
643 			printf("TX: pkt_untagged_cnt: 0x%" PRIx64 "\n",
644 					secy_stat->pkt_untagged_cnt);
645 
646 
647 		memset(&sc_stat, 0, sizeof(struct rte_security_macsec_sc_stats));
648 		rte_security_macsec_sc_stats_get(ctx, tx_sc_id, RTE_SECURITY_MACSEC_DIR_TX,
649 						 &sc_stat);
650 		printf("\n********** TX SC[%u] STATS **************\n", tx_sc_id);
651 		if (sc_stat.pkt_encrypt_cnt)
652 			printf("TX pkt_encrypt_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_encrypt_cnt);
653 		if (sc_stat.pkt_protected_cnt)
654 			printf("TX pkt_protected_cnt: 0x%" PRIx64 "\n", sc_stat.pkt_protected_cnt);
655 		if (sc_stat.octet_encrypt_cnt)
656 			printf("TX octet_encrypt_cnt: 0x%" PRIx64 "\n", sc_stat.octet_encrypt_cnt);
657 
658 		memset(&sa_stat, 0, sizeof(struct rte_security_macsec_sa_stats));
659 		rte_security_macsec_sa_stats_get(ctx, tx_sa_id[0],
660 				RTE_SECURITY_MACSEC_DIR_TX, &sa_stat);
661 		printf("\n********** TX SA[%u] STATS ****************\n", tx_sa_id[0]);
662 		if (sa_stat.pkt_encrypt_cnt)
663 			printf("TX pkt_encrypt_cnt: 0x%" PRIx64 "\n", sa_stat.pkt_encrypt_cnt);
664 		if (sa_stat.pkt_protected_cnt)
665 			printf("TX pkt_protected_cnt: 0x%" PRIx64 "\n", sa_stat.pkt_protected_cnt);
666 	}
667 }
668 
669 static int
670 mcs_stats_check(struct rte_security_ctx *ctx, enum mcs_op op,
671 		const struct mcs_test_opts *opts,
672 		const struct mcs_test_vector *td,
673 		void *rx_sess, void *tx_sess,
674 		uint8_t rx_sc_id, uint8_t tx_sc_id,
675 		uint16_t rx_sa_id[], uint16_t tx_sa_id[])
676 {
677 	struct rte_security_stats sess_stats = {0};
678 	struct rte_security_macsec_secy_stats *secy_stat;
679 	struct rte_security_macsec_sc_stats sc_stat = {0};
680 	struct rte_security_macsec_sa_stats sa_stat = {0};
681 	int i;
682 
683 	if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
684 			op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
685 		rte_security_session_stats_get(ctx, rx_sess, &sess_stats);
686 		secy_stat = &sess_stats.macsec;
687 
688 		if ((opts->check_untagged_rx && secy_stat->pkt_notag_cnt != 1) ||
689 				(opts->check_untagged_rx && secy_stat->pkt_untaged_cnt != 1))
690 			return TEST_FAILED;
691 
692 		if (opts->check_bad_tag_cnt && secy_stat->pkt_badtag_cnt != 1)
693 			return TEST_FAILED;
694 
695 		if (opts->check_sa_not_in_use && secy_stat->pkt_nosaerror_cnt != 1)
696 			return TEST_FAILED;
697 
698 		if (opts->check_decap_stats && secy_stat->octet_decrypted_cnt !=
699 				(uint16_t)(td->plain_pkt.len - 2 * RTE_ETHER_ADDR_LEN))
700 			return TEST_FAILED;
701 
702 		if (opts->check_verify_only_stats && secy_stat->octet_validated_cnt !=
703 				(uint16_t)(td->plain_pkt.len - 2 * RTE_ETHER_ADDR_LEN))
704 			return TEST_FAILED;
705 
706 		rte_security_macsec_sc_stats_get(ctx, rx_sc_id,
707 				RTE_SECURITY_MACSEC_DIR_RX, &sc_stat);
708 
709 		if ((opts->check_decap_stats || opts->check_verify_only_stats) &&
710 				sc_stat.pkt_ok_cnt != 1)
711 			return TEST_FAILED;
712 
713 		if (opts->check_pkts_invalid_stats && sc_stat.pkt_notvalid_cnt != 1)
714 			return TEST_FAILED;
715 
716 		if (opts->check_pkts_unchecked_stats && sc_stat.pkt_unchecked_cnt != 1)
717 			return TEST_FAILED;
718 
719 		if (opts->replay_protect) {
720 			if (opts->replay_win_sz == 0 &&
721 					sc_stat.pkt_late_cnt != 2)
722 				return TEST_FAILED;
723 			else if (opts->replay_win_sz == 32 &&
724 					sc_stat.pkt_late_cnt != 1)
725 				return TEST_FAILED;
726 		}
727 
728 		for (i = 0; i < RTE_SECURITY_MACSEC_NUM_AN; i++) {
729 			memset(&sa_stat, 0, sizeof(struct rte_security_macsec_sa_stats));
730 			rte_security_macsec_sa_stats_get(ctx, rx_sa_id[i],
731 					RTE_SECURITY_MACSEC_DIR_RX, &sa_stat);
732 
733 		}
734 	}
735 
736 	if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
737 			op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
738 		memset(&sess_stats, 0, sizeof(struct rte_security_stats));
739 		rte_security_session_stats_get(ctx, tx_sess, &sess_stats);
740 		secy_stat = &sess_stats.macsec;
741 
742 		if (opts->check_out_pkts_untagged && secy_stat->pkt_untagged_cnt != 1)
743 			return TEST_FAILED;
744 
745 		if (opts->check_out_pkts_toolong && secy_stat->pkt_toolong_cnt != 1)
746 			return TEST_FAILED;
747 
748 		if (opts->check_encap_stats && secy_stat->octet_encrypted_cnt !=
749 				(uint16_t)(td->plain_pkt.len - 2 * RTE_ETHER_ADDR_LEN))
750 			return TEST_FAILED;
751 
752 		if (opts->check_auth_only_stats && secy_stat->octet_protected_cnt !=
753 				(uint16_t)(td->plain_pkt.len - 2 * RTE_ETHER_ADDR_LEN))
754 			return TEST_FAILED;
755 
756 
757 		memset(&sc_stat, 0, sizeof(struct rte_security_macsec_sc_stats));
758 		rte_security_macsec_sc_stats_get(ctx, tx_sc_id, RTE_SECURITY_MACSEC_DIR_TX,
759 						 &sc_stat);
760 
761 		if (opts->check_encap_stats && sc_stat.pkt_encrypt_cnt != 1)
762 			return TEST_FAILED;
763 
764 		if (opts->check_auth_only_stats && sc_stat.pkt_protected_cnt != 1)
765 			return TEST_FAILED;
766 
767 		memset(&sa_stat, 0, sizeof(struct rte_security_macsec_sa_stats));
768 		rte_security_macsec_sa_stats_get(ctx, tx_sa_id[0],
769 				RTE_SECURITY_MACSEC_DIR_TX, &sa_stat);
770 	}
771 
772 	return 0;
773 }
774 
775 static int
776 test_macsec_event_callback(uint16_t port_id, enum rte_eth_event_type type,
777 			   void *param, void *ret_param)
778 {
779 	struct mcs_err_vector *vector = (struct mcs_err_vector *)param;
780 	struct rte_eth_event_macsec_desc *event_desc = NULL;
781 
782 	RTE_SET_USED(port_id);
783 
784 	if (type != RTE_ETH_EVENT_MACSEC)
785 		return -1;
786 
787 	event_desc = ret_param;
788 	if (event_desc == NULL) {
789 		printf("Event descriptor not set\n");
790 		return -1;
791 	}
792 	vector->notify_event = true;
793 
794 	switch (event_desc->type) {
795 	case RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR:
796 		vector->event = RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR;
797 		switch (event_desc->subtype) {
798 		case RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1:
799 			vector->event_subtype = RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1;
800 			break;
801 		case RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1:
802 			vector->event_subtype = RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1;
803 			break;
804 		case RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48:
805 			vector->event_subtype = RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48;
806 			break;
807 		case RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1:
808 			vector->event_subtype = RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1;
809 			break;
810 		case RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1:
811 			vector->event_subtype = RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1;
812 			break;
813 		default:
814 			printf("\nUnknown Macsec event subtype: %d", event_desc->subtype);
815 		}
816 		break;
817 	case RTE_ETH_EVENT_MACSEC_RX_SA_PN_HARD_EXP:
818 		vector->event = RTE_ETH_EVENT_MACSEC_RX_SA_PN_HARD_EXP;
819 		break;
820 	case RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP:
821 		vector->event = RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP;
822 		break;
823 	case RTE_ETH_EVENT_MACSEC_TX_SA_PN_HARD_EXP:
824 		vector->event = RTE_ETH_EVENT_MACSEC_TX_SA_PN_HARD_EXP;
825 		break;
826 	case RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP:
827 		vector->event = RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP;
828 		break;
829 	case RTE_ETH_EVENT_MACSEC_SA_NOT_VALID:
830 		vector->event = RTE_ETH_EVENT_MACSEC_SA_NOT_VALID;
831 		break;
832 	default:
833 		printf("Invalid MACsec event reported\n");
834 		return -1;
835 	}
836 
837 	return 0;
838 }
839 
840 static int
841 test_macsec(const struct mcs_test_vector *td[], enum mcs_op op, const struct mcs_test_opts *opts)
842 {
843 	uint16_t rx_sa_id[MCS_MAX_FLOWS][RTE_SECURITY_MACSEC_NUM_AN] = {{0}};
844 	uint16_t tx_sa_id[MCS_MAX_FLOWS][2] = {{0}};
845 	uint16_t rx_sc_id[MCS_MAX_FLOWS] = {0};
846 	uint16_t tx_sc_id[MCS_MAX_FLOWS] = {0};
847 	void *rx_sess[MCS_MAX_FLOWS] = {0};
848 	void *tx_sess[MCS_MAX_FLOWS] = {0};
849 	struct rte_security_session_conf sess_conf = {0};
850 	struct rte_security_macsec_sa sa_conf = {0};
851 	struct rte_security_macsec_sc sc_conf = {0};
852 	struct mcs_err_vector err_vector = {0};
853 	struct rte_security_ctx *ctx;
854 	int nb_rx = 0, nb_sent;
855 	int i, j = 0, ret, id, an = 0;
856 	uint8_t tci_off;
857 	int k;
858 
859 	memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * opts->nb_td);
860 
861 	ctx = (struct rte_security_ctx *)rte_eth_dev_get_sec_ctx(port_id);
862 	if (ctx == NULL) {
863 		printf("Ethernet device doesn't support security features.\n");
864 		return TEST_SKIPPED;
865 	}
866 
867 	tci_off = (opts->sectag_insert_mode == 1) ? RTE_ETHER_HDR_LEN :
868 			RTE_ETHER_HDR_LEN + (opts->nb_vlan * RTE_VLAN_HLEN);
869 
870 	for (i = 0, j = 0; i < opts->nb_td; i++) {
871 		if (op == MCS_DECAP || op == MCS_VERIFY_ONLY)
872 			tx_pkts_burst[j] = init_packet(mbufpool, td[i]->secure_pkt.data,
873 							td[i]->secure_pkt.len);
874 		else {
875 			tx_pkts_burst[j] = init_packet(mbufpool, td[i]->plain_pkt.data,
876 							td[i]->plain_pkt.len);
877 
878 			tx_pkts_burst[j]->ol_flags |= RTE_MBUF_F_TX_MACSEC;
879 		}
880 		if (tx_pkts_burst[j] == NULL) {
881 			while (j--)
882 				rte_pktmbuf_free(tx_pkts_burst[j]);
883 			ret = TEST_FAILED;
884 			goto out;
885 		}
886 		j++;
887 
888 		if (opts->replay_protect) {
889 			for (k = 0; k < 3; k++, j++) {
890 				tx_pkts_burst[j] = init_packet(mbufpool,
891 					opts->ar_td[k]->secure_pkt.data,
892 					opts->ar_td[k]->secure_pkt.len);
893 				if (tx_pkts_burst[j] == NULL) {
894 					while (j--)
895 						rte_pktmbuf_free(tx_pkts_burst[j]);
896 					ret = TEST_FAILED;
897 					goto out;
898 				}
899 			}
900 		}
901 
902 		if (opts->rekey_en) {
903 
904 			err_vector.td = td[i];
905 			err_vector.rekey_td = opts->rekey_td;
906 			err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN;
907 			err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN;
908 			rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC,
909 					test_macsec_event_callback, &err_vector);
910 			if (op == MCS_DECAP || op == MCS_VERIFY_ONLY)
911 				tx_pkts_burst[j] = init_packet(mbufpool,
912 						opts->rekey_td->secure_pkt.data,
913 						opts->rekey_td->secure_pkt.len);
914 			else {
915 				tx_pkts_burst[j] = init_packet(mbufpool,
916 						opts->rekey_td->plain_pkt.data,
917 						opts->rekey_td->plain_pkt.len);
918 
919 				tx_pkts_burst[j]->ol_flags |= RTE_MBUF_F_TX_MACSEC;
920 			}
921 			if (tx_pkts_burst[j] == NULL) {
922 				while (j--)
923 					rte_pktmbuf_free(tx_pkts_burst[j]);
924 				ret = TEST_FAILED;
925 				goto out;
926 			}
927 			j++;
928 		}
929 
930 		if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
931 				op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
932 			for (an = 0; an < RTE_SECURITY_MACSEC_NUM_AN; an++) {
933 				if (opts->rekey_en && an ==
934 						(opts->rekey_td->secure_pkt.data[tci_off] &
935 						RTE_MACSEC_AN_MASK))
936 					fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
937 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
938 				else
939 				/* For simplicity, using same SA conf for all AN */
940 					fill_macsec_sa_conf(td[i], &sa_conf,
941 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
942 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
943 				if (id < 0) {
944 					printf("MACsec SA create failed : %d.\n", id);
945 					return TEST_FAILED;
946 				}
947 				rx_sa_id[i][an] = (uint16_t)id;
948 			}
949 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
950 					RTE_SECURITY_MACSEC_DIR_RX, rx_sa_id[i], tci_off);
951 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
952 			if (id < 0) {
953 				printf("MACsec SC create failed : %d.\n", id);
954 				goto out;
955 			}
956 			rx_sc_id[i] = (uint16_t)id;
957 
958 			/* Create Inline IPsec session. */
959 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
960 					RTE_SECURITY_MACSEC_DIR_RX, rx_sc_id[i], tci_off);
961 			if (ret)
962 				return TEST_FAILED;
963 
964 			rx_sess[i] = rte_security_session_create(ctx, &sess_conf,
965 					sess_pool);
966 			if (rx_sess[i] == NULL) {
967 				printf("SEC Session init failed.\n");
968 				return TEST_FAILED;
969 			}
970 			ret = create_default_flow(td[i], port_id,
971 					RTE_SECURITY_MACSEC_DIR_RX, rx_sess[i]);
972 			if (ret)
973 				goto out;
974 		}
975 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
976 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
977 			int id;
978 
979 			fill_macsec_sa_conf(td[i], &sa_conf,
980 					RTE_SECURITY_MACSEC_DIR_TX,
981 					td[i]->secure_pkt.data[tci_off] & RTE_MACSEC_AN_MASK,
982 					tci_off);
983 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
984 			if (id < 0) {
985 				printf("MACsec SA create failed : %d.\n", id);
986 				return TEST_FAILED;
987 			}
988 			tx_sa_id[i][0] = (uint16_t)id;
989 			tx_sa_id[i][1] = MCS_INVALID_SA;
990 			if (opts->rekey_en) {
991 				memset(&sa_conf, 0, sizeof(struct rte_security_macsec_sa));
992 				fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
993 					RTE_SECURITY_MACSEC_DIR_TX,
994 					opts->rekey_td->secure_pkt.data[tci_off] &
995 						RTE_MACSEC_AN_MASK,
996 					tci_off);
997 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
998 				if (id < 0) {
999 					printf("MACsec rekey SA create failed : %d.\n", id);
1000 					goto out;
1001 				}
1002 				tx_sa_id[i][1] = (uint16_t)id;
1003 			}
1004 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
1005 					RTE_SECURITY_MACSEC_DIR_TX, tx_sa_id[i], tci_off);
1006 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
1007 			if (id < 0) {
1008 				printf("MACsec SC create failed : %d.\n", id);
1009 				goto out;
1010 			}
1011 			tx_sc_id[i] = (uint16_t)id;
1012 
1013 			/* Create Inline IPsec session. */
1014 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
1015 					RTE_SECURITY_MACSEC_DIR_TX, tx_sc_id[i], tci_off);
1016 			if (ret)
1017 				return TEST_FAILED;
1018 
1019 			tx_sess[i] = rte_security_session_create(ctx, &sess_conf,
1020 					sess_pool);
1021 			if (tx_sess[i] == NULL) {
1022 				printf("SEC Session init failed.\n");
1023 				return TEST_FAILED;
1024 			}
1025 			ret = create_default_flow(td[i], port_id,
1026 					RTE_SECURITY_MACSEC_DIR_TX, tx_sess[i]);
1027 			if (ret)
1028 				goto out;
1029 		}
1030 	}
1031 
1032 	/* Send packet to ethdev for inline MACsec processing. */
1033 	nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, j);
1034 
1035 	if (nb_sent != j) {
1036 		printf("\nUnable to TX %d packets, sent: %i", j, nb_sent);
1037 		for ( ; nb_sent < j; nb_sent++)
1038 			rte_pktmbuf_free(tx_pkts_burst[nb_sent]);
1039 		ret = TEST_FAILED;
1040 		goto out;
1041 	}
1042 
1043 	rte_pause();
1044 
1045 	/* Receive back packet on loopback interface. */
1046 	do {
1047 		nb_rx += rte_eth_rx_burst(port_id, 0,
1048 				&rx_pkts_burst[nb_rx],
1049 				nb_sent - nb_rx);
1050 		if (nb_rx >= nb_sent)
1051 			break;
1052 		rte_delay_ms(1);
1053 	} while (j++ < 5 && nb_rx == 0);
1054 
1055 	if (nb_rx != nb_sent) {
1056 		printf("\nUnable to RX all %d packets, received(%i)",
1057 				nb_sent, nb_rx);
1058 		while (--nb_rx >= 0)
1059 			rte_pktmbuf_free(rx_pkts_burst[nb_rx]);
1060 		ret = TEST_FAILED;
1061 		if (opts->check_sectag_interrupts == 1)
1062 			ret = TEST_SUCCESS;
1063 		goto out;
1064 	}
1065 
1066 	if (opts->rekey_en) {
1067 		switch (err_vector.event) {
1068 		case RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP:
1069 			printf("Received RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP event\n");
1070 			/* The first sa is active now, so the 0th sa can be
1071 			 * reconfigured. Using the same key as zeroeth sa, but
1072 			 * other key can also be configured.
1073 			 */
1074 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[0][0],
1075 					RTE_SECURITY_MACSEC_DIR_TX);
1076 			fill_macsec_sa_conf(td[0], &sa_conf,
1077 					RTE_SECURITY_MACSEC_DIR_TX,
1078 					td[0]->secure_pkt.data[tci_off] &
1079 					RTE_MACSEC_AN_MASK, tci_off);
1080 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
1081 			if (id < 0) {
1082 				printf("MACsec SA create failed : %d.\n", id);
1083 				return TEST_FAILED;
1084 			}
1085 			tx_sa_id[0][0] = (uint16_t)id;
1086 			break;
1087 		case RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP:
1088 			printf("Received RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP event\n");
1089 			break;
1090 		default:
1091 			printf("Received unsupported event\n");
1092 		}
1093 	}
1094 
1095 	if (opts->replay_protect) {
1096 		for (i = 0; i < nb_rx; i++) {
1097 			rte_pktmbuf_free(rx_pkts_burst[i]);
1098 			rx_pkts_burst[i] = NULL;
1099 		}
1100 		ret = TEST_SUCCESS;
1101 		goto out;
1102 	}
1103 
1104 	for (i = 0; i < nb_rx; i++) {
1105 		if (opts->rekey_en && i == 1) {
1106 			/* The second received packet is matched with
1107 			 * rekey td
1108 			 */
1109 			ret = test_macsec_post_process(rx_pkts_burst[i],
1110 					opts->rekey_td, op,
1111 					opts->check_out_pkts_untagged);
1112 		} else {
1113 			ret = test_macsec_post_process(rx_pkts_burst[i], td[i],
1114 					op, opts->check_out_pkts_untagged);
1115 		}
1116 		if (ret != TEST_SUCCESS) {
1117 			for ( ; i < nb_rx; i++)
1118 				rte_pktmbuf_free(rx_pkts_burst[i]);
1119 			goto out;
1120 		}
1121 
1122 		rte_pktmbuf_free(rx_pkts_burst[i]);
1123 		rx_pkts_burst[i] = NULL;
1124 	}
1125 out:
1126 	if (opts->check_out_pkts_toolong == 1 ||
1127 			opts->check_sa_not_in_use == 1 ||
1128 			opts->check_bad_tag_cnt == 1)
1129 		ret = TEST_SUCCESS;
1130 
1131 	for (i = 0; i < opts->nb_td; i++) {
1132 		if (opts->dump_all_stats) {
1133 			mcs_stats_dump(ctx, op,
1134 					rx_sess[i], tx_sess[i],
1135 					rx_sc_id[i], tx_sc_id[i],
1136 					rx_sa_id[i], tx_sa_id[i]);
1137 		} else {
1138 			if (ret == TEST_SUCCESS)
1139 				ret = mcs_stats_check(ctx, op, opts, td[i],
1140 					rx_sess[i], tx_sess[i],
1141 					rx_sc_id[i], tx_sc_id[i],
1142 					rx_sa_id[i], tx_sa_id[i]);
1143 		}
1144 	}
1145 
1146 	destroy_default_flow(port_id);
1147 
1148 	if (opts->rekey_en)
1149 		rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
1150 					test_macsec_event_callback, &err_vector);
1151 
1152 	/* Destroy session so that other cases can create the session again */
1153 	for (i = 0; i < opts->nb_td; i++) {
1154 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
1155 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
1156 			rte_security_session_destroy(ctx, tx_sess[i]);
1157 			tx_sess[i] = NULL;
1158 			rte_security_macsec_sc_destroy(ctx, tx_sc_id[i],
1159 						RTE_SECURITY_MACSEC_DIR_TX);
1160 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][0],
1161 						RTE_SECURITY_MACSEC_DIR_TX);
1162 			if (opts->rekey_en) {
1163 				rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][1],
1164 						RTE_SECURITY_MACSEC_DIR_TX);
1165 			}
1166 		}
1167 		if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
1168 				op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
1169 			rte_security_session_destroy(ctx, rx_sess[i]);
1170 			rx_sess[i] = NULL;
1171 			rte_security_macsec_sc_destroy(ctx, rx_sc_id[i],
1172 						RTE_SECURITY_MACSEC_DIR_RX);
1173 			for (j = 0; j < RTE_SECURITY_MACSEC_NUM_AN; j++) {
1174 				rte_security_macsec_sa_destroy(ctx, rx_sa_id[i][j],
1175 						RTE_SECURITY_MACSEC_DIR_RX);
1176 			}
1177 		}
1178 	}
1179 
1180 	return ret;
1181 }
1182 
1183 static int
1184 test_inline_macsec_encap_all(void)
1185 {
1186 	const struct mcs_test_vector *cur_td;
1187 	struct mcs_test_opts opts = {0};
1188 	int err, all_err = 0;
1189 	int i, size;
1190 
1191 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1192 	opts.encrypt = true;
1193 	opts.protect_frames = true;
1194 	opts.sa_in_use = 1;
1195 	opts.nb_td = 1;
1196 	opts.sectag_insert_mode = 1;
1197 	opts.mtu = RTE_ETHER_MTU;
1198 
1199 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1200 	for (i = 0; i < size; i++) {
1201 		cur_td = &list_mcs_cipher_vectors[i];
1202 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1203 		if (err) {
1204 			printf("\nCipher Auth Encryption case %d failed", cur_td->test_idx);
1205 			err = -1;
1206 		} else {
1207 			printf("\nCipher Auth Encryption case %d Passed", cur_td->test_idx);
1208 			err = 0;
1209 		}
1210 		all_err += err;
1211 	}
1212 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1213 
1214 	return all_err;
1215 }
1216 
1217 static int
1218 test_inline_macsec_decap_all(void)
1219 {
1220 	const struct mcs_test_vector *cur_td;
1221 	struct mcs_test_opts opts = {0};
1222 	int err, all_err = 0;
1223 	int i, size;
1224 
1225 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1226 	opts.sa_in_use = 1;
1227 	opts.nb_td = 1;
1228 	opts.sectag_insert_mode = 1;
1229 	opts.mtu = RTE_ETHER_MTU;
1230 
1231 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1232 	for (i = 0; i < size; i++) {
1233 		cur_td = &list_mcs_cipher_vectors[i];
1234 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1235 		if (err) {
1236 			printf("\nCipher Auth Decryption case %d failed", cur_td->test_idx);
1237 			err = -1;
1238 		} else {
1239 			printf("\nCipher Auth Decryption case %d Passed", cur_td->test_idx);
1240 			err = 0;
1241 		}
1242 		all_err += err;
1243 	}
1244 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1245 
1246 	return all_err;
1247 }
1248 
1249 static int
1250 test_inline_macsec_auth_only_all(void)
1251 {
1252 	const struct mcs_test_vector *cur_td;
1253 	struct mcs_test_opts opts = {0};
1254 	int err, all_err = 0;
1255 	int i, size;
1256 
1257 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1258 	opts.protect_frames = true;
1259 	opts.sa_in_use = 1;
1260 	opts.nb_td = 1;
1261 	opts.sectag_insert_mode = 1;
1262 	opts.mtu = RTE_ETHER_MTU;
1263 
1264 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1265 
1266 	for (i = 0; i < size; i++) {
1267 		cur_td = &list_mcs_integrity_vectors[i];
1268 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
1269 		if (err) {
1270 			printf("\nAuth Generate case %d failed", cur_td->test_idx);
1271 			err = -1;
1272 		} else {
1273 			printf("\nAuth Generate case %d Passed", cur_td->test_idx);
1274 			err = 0;
1275 		}
1276 		all_err += err;
1277 	}
1278 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1279 
1280 	return all_err;
1281 }
1282 
1283 static int
1284 test_inline_macsec_verify_only_all(void)
1285 {
1286 	const struct mcs_test_vector *cur_td;
1287 	struct mcs_test_opts opts = {0};
1288 	int err, all_err = 0;
1289 	int i, size;
1290 
1291 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1292 	opts.sa_in_use = 1;
1293 	opts.nb_td = 1;
1294 	opts.sectag_insert_mode = 1;
1295 	opts.mtu = RTE_ETHER_MTU;
1296 
1297 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1298 
1299 	for (i = 0; i < size; i++) {
1300 		cur_td = &list_mcs_integrity_vectors[i];
1301 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1302 		if (err) {
1303 			printf("\nAuth Verify case %d failed", cur_td->test_idx);
1304 			err = -1;
1305 		} else {
1306 			printf("\nAuth Verify case %d Passed", cur_td->test_idx);
1307 			err = 0;
1308 		}
1309 		all_err += err;
1310 	}
1311 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1312 
1313 	return all_err;
1314 }
1315 
1316 static int
1317 test_inline_macsec_encap_decap_all(void)
1318 {
1319 	const struct mcs_test_vector *cur_td;
1320 	struct mcs_test_opts opts = {0};
1321 	int err, all_err = 0;
1322 	int i, size;
1323 
1324 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1325 	opts.encrypt = true;
1326 	opts.protect_frames = true;
1327 	opts.sa_in_use = 1;
1328 	opts.nb_td = 1;
1329 	opts.sectag_insert_mode = 1;
1330 	opts.mtu = RTE_ETHER_MTU;
1331 
1332 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1333 
1334 	for (i = 0; i < size; i++) {
1335 		cur_td = &list_mcs_cipher_vectors[i];
1336 		err = test_macsec(&cur_td, MCS_ENCAP_DECAP, &opts);
1337 		if (err) {
1338 			printf("\nCipher Auth Encap-decap case %d failed", cur_td->test_idx);
1339 			err = -1;
1340 		} else {
1341 			printf("\nCipher Auth Encap-decap case %d Passed", cur_td->test_idx);
1342 			err = 0;
1343 		}
1344 		all_err += err;
1345 	}
1346 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1347 
1348 	return all_err;
1349 }
1350 
1351 
1352 static int
1353 test_inline_macsec_auth_verify_all(void)
1354 {
1355 	const struct mcs_test_vector *cur_td;
1356 	struct mcs_test_opts opts = {0};
1357 	int err, all_err = 0;
1358 	int i, size;
1359 
1360 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1361 	opts.protect_frames = true;
1362 	opts.sa_in_use = 1;
1363 	opts.nb_td = 1;
1364 	opts.sectag_insert_mode = 1;
1365 	opts.mtu = RTE_ETHER_MTU;
1366 
1367 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1368 
1369 	for (i = 0; i < size; i++) {
1370 		cur_td = &list_mcs_integrity_vectors[i];
1371 		err = test_macsec(&cur_td, MCS_AUTH_VERIFY, &opts);
1372 		if (err) {
1373 			printf("\nAuth Generate + Verify case %d failed", cur_td->test_idx);
1374 			err = -1;
1375 		} else {
1376 			printf("\nAuth Generate + Verify case %d Passed", cur_td->test_idx);
1377 			err = 0;
1378 		}
1379 		all_err += err;
1380 	}
1381 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1382 
1383 	return all_err;
1384 }
1385 
1386 static int
1387 test_inline_macsec_multi_flow(void)
1388 {
1389 	const struct mcs_test_vector *tv[MCS_MAX_FLOWS];
1390 	struct mcs_test_vector iter[MCS_MAX_FLOWS];
1391 	struct mcs_test_opts opts = {0};
1392 	int i, err;
1393 
1394 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1395 	opts.encrypt = true;
1396 	opts.protect_frames = true;
1397 	opts.sa_in_use = 1;
1398 	opts.nb_td = MCS_MAX_FLOWS;
1399 	opts.sectag_insert_mode = 1;
1400 	opts.mtu = RTE_ETHER_MTU;
1401 
1402 	for (i = 0; i < MCS_MAX_FLOWS; i++) {
1403 		memcpy(&iter[i].sa_key.data, sa_key, MCS_MULTI_FLOW_TD_KEY_SZ);
1404 		memcpy(&iter[i].plain_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1405 		memcpy(&iter[i].plain_pkt.data[2 * RTE_ETHER_ADDR_LEN], plain_user_data,
1406 		       MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ);
1407 		memcpy(&iter[i].secure_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1408 		memcpy(&iter[i].secure_pkt.data[2 * RTE_ETHER_ADDR_LEN], secure_user_data,
1409 		       MCS_MULTI_FLOW_TD_SECURE_DATA_SZ);
1410 		iter[i].sa_key.len = MCS_MULTI_FLOW_TD_KEY_SZ;
1411 		iter[i].plain_pkt.len = MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ +
1412 					(2 * RTE_ETHER_ADDR_LEN);
1413 		iter[i].secure_pkt.len = MCS_MULTI_FLOW_TD_SECURE_DATA_SZ +
1414 					(2 * RTE_ETHER_ADDR_LEN);
1415 		iter[i].alg = RTE_SECURITY_MACSEC_ALG_GCM_128;
1416 		iter[i].ssci = 0x0;
1417 		iter[i].xpn = 0x0;
1418 		tv[i] = (const struct mcs_test_vector *)&iter[i];
1419 	}
1420 	err = test_macsec(tv, MCS_ENCAP_DECAP, &opts);
1421 	if (err) {
1422 		printf("\nCipher Auth Encryption multi flow failed");
1423 		err = -1;
1424 	} else {
1425 		printf("\nCipher Auth Encryption multi flow Passed");
1426 		err = 0;
1427 	}
1428 	return err;
1429 }
1430 
1431 static int
1432 test_inline_macsec_with_vlan(void)
1433 {
1434 	const struct mcs_test_vector *cur_td;
1435 	struct mcs_test_opts opts = {0};
1436 	int err, all_err = 0;
1437 	int i, size;
1438 
1439 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1440 	opts.protect_frames = true;
1441 	opts.sa_in_use = 1;
1442 	opts.nb_td = 1;
1443 	opts.mtu = RTE_ETHER_MTU;
1444 
1445 	size = (sizeof(list_mcs_vlan_vectors) / sizeof((list_mcs_vlan_vectors)[0]));
1446 
1447 	for (i = 0; i < size; i++) {
1448 		cur_td = &list_mcs_vlan_vectors[i];
1449 		if (i == 0) {
1450 			opts.sectag_insert_mode = 1;
1451 		} else if (i == 1) {
1452 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1453 			opts.nb_vlan = 1;
1454 		} else if (i == 2) {
1455 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1456 			opts.nb_vlan = 2;
1457 		}
1458 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1459 		if (err) {
1460 			printf("\n VLAN Encap case %d failed", cur_td->test_idx);
1461 			err = -1;
1462 		} else {
1463 			printf("\n VLAN Encap case %d passed", cur_td->test_idx);
1464 			err = 0;
1465 		}
1466 		all_err += err;
1467 	}
1468 	for (i = 0; i < size; i++) {
1469 		cur_td = &list_mcs_vlan_vectors[i];
1470 		if (i == 0) {
1471 			opts.sectag_insert_mode = 1;
1472 		} else if (i == 1) {
1473 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1474 			opts.nb_vlan = 1;
1475 		} else if (i == 2) {
1476 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1477 			opts.nb_vlan = 2;
1478 		}
1479 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1480 		if (err) {
1481 			printf("\n VLAN Decap case %d failed", cur_td->test_idx);
1482 			err = -1;
1483 		} else {
1484 			printf("\n VLAN Decap case %d passed", cur_td->test_idx);
1485 			err = 0;
1486 		}
1487 		all_err += err;
1488 	}
1489 
1490 	printf("\n%s: Success: %d, Failure: %d\n", __func__, (2 * size) + all_err, -all_err);
1491 	return all_err;
1492 }
1493 
1494 static int
1495 test_inline_macsec_pkt_drop(void)
1496 {
1497 	const struct mcs_test_vector *cur_td;
1498 	struct mcs_test_opts opts = {0};
1499 	int err, all_err = 0;
1500 	int i, size;
1501 
1502 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1503 	opts.encrypt = true;
1504 	opts.protect_frames = true;
1505 	opts.sa_in_use = 1;
1506 	opts.nb_td = 1;
1507 	opts.sectag_insert_mode = 1;
1508 	opts.mtu = RTE_ETHER_MTU;
1509 
1510 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1511 
1512 	for (i = 0; i < size; i++) {
1513 		cur_td = &list_mcs_err_cipher_vectors[i];
1514 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1515 		if (err) {
1516 			printf("\nPacket drop case %d passed", cur_td->test_idx);
1517 			err = 0;
1518 		} else {
1519 			printf("\nPacket drop case %d failed", cur_td->test_idx);
1520 			err = -1;
1521 		}
1522 		all_err += err;
1523 	}
1524 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1525 
1526 	return all_err;
1527 }
1528 
1529 static int
1530 test_inline_macsec_untagged_rx(void)
1531 {
1532 	const struct mcs_test_vector *cur_td;
1533 	struct mcs_test_opts opts = {0};
1534 	int err, all_err = 0;
1535 	int i, size;
1536 
1537 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1538 	opts.sa_in_use = 1;
1539 	opts.nb_td = 1;
1540 	opts.sectag_insert_mode = 1;
1541 	opts.mtu = RTE_ETHER_MTU;
1542 	opts.check_untagged_rx = 1;
1543 
1544 	size = (sizeof(list_mcs_untagged_cipher_vectors) /
1545 		sizeof((list_mcs_untagged_cipher_vectors)[0]));
1546 
1547 	for (i = 0; i < size; i++) {
1548 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1549 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1550 		if (err)
1551 			err = 0;
1552 		else
1553 			err = -1;
1554 
1555 		all_err += err;
1556 	}
1557 
1558 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
1559 	for (i = 0; i < size; i++) {
1560 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1561 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1562 		if (err)
1563 			err = 0;
1564 		else
1565 			err = -1;
1566 
1567 		all_err += err;
1568 	}
1569 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1570 
1571 	return all_err;
1572 }
1573 
1574 static int
1575 test_inline_macsec_bad_tag_rx(void)
1576 {
1577 	const struct mcs_test_vector *cur_td;
1578 	struct mcs_test_opts opts = {0};
1579 	int err, all_err = 0;
1580 	int i, size;
1581 
1582 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1583 	opts.protect_frames = true;
1584 	opts.sa_in_use = 1;
1585 	opts.nb_td = 1;
1586 	opts.sectag_insert_mode = 1;
1587 	opts.mtu = RTE_ETHER_MTU;
1588 	opts.check_bad_tag_cnt = 1;
1589 
1590 	size = (sizeof(list_mcs_bad_tag_vectors) / sizeof((list_mcs_bad_tag_vectors)[0]));
1591 
1592 	for (i = 0; i < size; i++) {
1593 		cur_td = &list_mcs_bad_tag_vectors[i];
1594 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1595 		if (err)
1596 			err = -1;
1597 		else
1598 			err = 0;
1599 
1600 		all_err += err;
1601 	}
1602 
1603 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1604 
1605 	return all_err;
1606 }
1607 
1608 static int
1609 test_inline_macsec_sa_not_in_use(void)
1610 {
1611 	const struct mcs_test_vector *cur_td;
1612 	struct mcs_test_opts opts = {0};
1613 	int err, all_err = 0;
1614 	int i, size;
1615 
1616 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1617 	opts.protect_frames = true;
1618 	opts.sa_in_use = 0;
1619 	opts.nb_td = 1;
1620 	opts.sectag_insert_mode = 1;
1621 	opts.mtu = RTE_ETHER_MTU;
1622 	opts.check_sa_not_in_use = 1;
1623 
1624 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1625 
1626 	for (i = 0; i < size; i++) {
1627 		cur_td = &list_mcs_cipher_vectors[i];
1628 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1629 		if (err)
1630 			err = -1;
1631 		else
1632 			err = 0;
1633 
1634 		all_err += err;
1635 	}
1636 
1637 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1638 
1639 	return all_err;
1640 }
1641 
1642 static int
1643 test_inline_macsec_decap_stats(void)
1644 {
1645 	const struct mcs_test_vector *cur_td;
1646 	struct mcs_test_opts opts = {0};
1647 	int err, all_err = 0;
1648 	int i, size;
1649 
1650 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1651 	opts.protect_frames = true;
1652 	opts.sa_in_use = 1;
1653 	opts.nb_td = 1;
1654 	opts.sectag_insert_mode = 1;
1655 	opts.mtu = RTE_ETHER_MTU;
1656 	opts.check_decap_stats = 1;
1657 
1658 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1659 
1660 	for (i = 0; i < size; i++) {
1661 		cur_td = &list_mcs_cipher_vectors[i];
1662 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1663 		if (err) {
1664 			printf("\nDecap stats case %d failed", cur_td->test_idx);
1665 			err = -1;
1666 		} else {
1667 			printf("\nDecap stats case %d passed", cur_td->test_idx);
1668 			err = 0;
1669 		}
1670 		all_err += err;
1671 	}
1672 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1673 
1674 	return all_err;
1675 }
1676 
1677 static int
1678 test_inline_macsec_verify_only_stats(void)
1679 {
1680 	const struct mcs_test_vector *cur_td;
1681 	struct mcs_test_opts opts = {0};
1682 	int err, all_err = 0;
1683 	int i, size;
1684 
1685 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1686 	opts.protect_frames = true;
1687 	opts.sa_in_use = 1;
1688 	opts.nb_td = 1;
1689 	opts.sectag_insert_mode = 1;
1690 	opts.mtu = RTE_ETHER_MTU;
1691 	opts.check_verify_only_stats = 1;
1692 
1693 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1694 
1695 	for (i = 0; i < size; i++) {
1696 		cur_td = &list_mcs_integrity_vectors[i];
1697 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1698 		if (err) {
1699 			printf("\nVerify only stats case %d failed", cur_td->test_idx);
1700 			err = -1;
1701 		} else {
1702 			printf("\nVerify only stats case %d Passed", cur_td->test_idx);
1703 			err = 0;
1704 		}
1705 		all_err += err;
1706 	}
1707 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1708 
1709 	return all_err;
1710 }
1711 
1712 static int
1713 test_inline_macsec_pkts_invalid_stats(void)
1714 {
1715 	const struct mcs_test_vector *cur_td;
1716 	struct mcs_test_opts opts = {0};
1717 	int err, all_err = 0;
1718 	int i, size;
1719 
1720 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1721 	opts.protect_frames = true;
1722 	opts.sa_in_use = 1;
1723 	opts.nb_td = 1;
1724 	opts.sectag_insert_mode = 1;
1725 	opts.mtu = RTE_ETHER_MTU;
1726 
1727 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1728 
1729 	for (i = 0; i < size; i++) {
1730 		cur_td = &list_mcs_err_cipher_vectors[i];
1731 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1732 		if (err)
1733 			err = 0;
1734 		else
1735 			err = -1;
1736 
1737 		all_err += err;
1738 	}
1739 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1740 	return all_err;
1741 }
1742 
1743 static int
1744 test_inline_macsec_pkts_unchecked_stats(void)
1745 {
1746 	const struct mcs_test_vector *cur_td;
1747 	struct mcs_test_opts opts = {0};
1748 	int err, all_err = 0;
1749 	int i, size;
1750 
1751 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_DISABLE;
1752 	opts.protect_frames = true;
1753 	opts.sa_in_use = 1;
1754 	opts.nb_td = 1;
1755 	opts.sectag_insert_mode = 1;
1756 	opts.mtu = RTE_ETHER_MTU;
1757 	opts.check_pkts_unchecked_stats = 1;
1758 
1759 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1760 
1761 	for (i = 0; i < size; i++) {
1762 		cur_td = &list_mcs_integrity_vectors[i];
1763 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1764 		if (err)
1765 			err = -1;
1766 		else
1767 			err = 0;
1768 
1769 		all_err += err;
1770 	}
1771 
1772 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1773 	return all_err;
1774 }
1775 
1776 static int
1777 test_inline_macsec_out_pkts_untagged(void)
1778 {
1779 	const struct mcs_test_vector *cur_td;
1780 	struct mcs_test_opts opts = {0};
1781 	int err, all_err = 0;
1782 	int i, size;
1783 
1784 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1785 	opts.encrypt = false;
1786 	opts.protect_frames = false;
1787 	opts.sa_in_use = 1;
1788 	opts.nb_td = 1;
1789 	opts.sectag_insert_mode = 1;
1790 	opts.mtu = RTE_ETHER_MTU;
1791 	opts.check_out_pkts_untagged = 1;
1792 
1793 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1794 	for (i = 0; i < size; i++) {
1795 		cur_td = &list_mcs_cipher_vectors[i];
1796 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1797 		if (err)
1798 			err = -1;
1799 		else
1800 			err = 0;
1801 
1802 		all_err += err;
1803 	}
1804 
1805 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1806 	return all_err;
1807 }
1808 
1809 static int
1810 test_inline_macsec_out_pkts_toolong(void)
1811 {
1812 	const struct mcs_test_vector *cur_td;
1813 	struct mcs_test_opts opts = {0};
1814 	int err, all_err = 0;
1815 	int i, size;
1816 
1817 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
1818 	opts.encrypt = true;
1819 	opts.protect_frames = true;
1820 	opts.sa_in_use = 1;
1821 	opts.nb_td = 1;
1822 	opts.sectag_insert_mode = 1;
1823 	opts.mtu = 50;
1824 	opts.check_out_pkts_toolong = 1;
1825 
1826 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1827 	for (i = 0; i < size; i++) {
1828 		cur_td = &list_mcs_cipher_vectors[i];
1829 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1830 		if (err)
1831 			err = -1;
1832 		else
1833 			err = 0;
1834 
1835 		all_err += err;
1836 	}
1837 
1838 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1839 	return all_err;
1840 }
1841 
1842 static int
1843 test_inline_macsec_encap_stats(void)
1844 {
1845 	const struct mcs_test_vector *cur_td;
1846 	struct mcs_test_opts opts = {0};
1847 	int err, all_err = 0;
1848 	int i, size;
1849 
1850 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1851 	opts.encrypt = true;
1852 	opts.protect_frames = true;
1853 	opts.sa_in_use = 1;
1854 	opts.nb_td = 1;
1855 	opts.sectag_insert_mode = 1;
1856 	opts.mtu = RTE_ETHER_MTU;
1857 	opts.check_encap_stats = 1;
1858 
1859 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1860 	for (i = 0; i < size; i++) {
1861 		cur_td = &list_mcs_cipher_vectors[i];
1862 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1863 		if (err)
1864 			err = -1;
1865 		else
1866 			err = 0;
1867 		all_err += err;
1868 	}
1869 
1870 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1871 	return all_err;
1872 }
1873 
1874 static int
1875 test_inline_macsec_auth_only_stats(void)
1876 {
1877 	const struct mcs_test_vector *cur_td;
1878 	struct mcs_test_opts opts = {0};
1879 	int err, all_err = 0;
1880 	int i, size;
1881 
1882 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1883 	opts.protect_frames = true;
1884 	opts.sa_in_use = 1;
1885 	opts.nb_td = 1;
1886 	opts.sectag_insert_mode = 1;
1887 	opts.mtu = RTE_ETHER_MTU;
1888 	opts.check_auth_only_stats = 1;
1889 
1890 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1891 
1892 	for (i = 0; i < size; i++) {
1893 		cur_td = &list_mcs_integrity_vectors[i];
1894 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
1895 		if (err)
1896 			err = -1;
1897 		else
1898 			err = 0;
1899 		all_err += err;
1900 	}
1901 
1902 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1903 	return all_err;
1904 }
1905 
1906 static int
1907 test_inline_macsec_interrupts_all(void)
1908 {
1909 	struct mcs_err_vector err_vector = {0};
1910 	const struct mcs_test_vector *cur_td;
1911 	struct mcs_test_opts opts = {0};
1912 	int i, size;
1913 	int err, all_err = 0;
1914 	enum rte_eth_event_macsec_subtype subtype[] =  {
1915 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1,
1916 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1,
1917 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48,
1918 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1,
1919 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1,
1920 	};
1921 
1922 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1923 	opts.protect_frames = true;
1924 	opts.sa_in_use = 1;
1925 	opts.nb_td = 1;
1926 	opts.sectag_insert_mode = 1;
1927 	opts.mtu = RTE_ETHER_MTU;
1928 	opts.check_sectag_interrupts = 1;
1929 
1930 	err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN;
1931 	err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN;
1932 	rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC,
1933 			test_macsec_event_callback, &err_vector);
1934 
1935 	size = (sizeof(list_mcs_intr_test_vectors) / sizeof((list_mcs_intr_test_vectors)[0]));
1936 
1937 	for (i = 0; i < size; i++) {
1938 		cur_td = &list_mcs_intr_test_vectors[i];
1939 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1940 		if ((err_vector.event == RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR) &&
1941 		    (err_vector.event_subtype == subtype[i])) {
1942 			printf("\nSectag val err interrupt test case %d passed",
1943 			       cur_td->test_idx);
1944 			err = 0;
1945 		} else {
1946 			printf("\nSectag val err interrupt test case %d failed",
1947 			       cur_td->test_idx);
1948 			err = -1;
1949 		}
1950 		all_err += err;
1951 	}
1952 	rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
1953 			test_macsec_event_callback, &err_vector);
1954 
1955 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1956 	return all_err;
1957 }
1958 
1959 static int
1960 test_inline_macsec_rekey_tx(void)
1961 {
1962 	const struct mcs_test_vector *cur_td;
1963 	struct mcs_test_opts opts = {0};
1964 	int err, all_err = 0;
1965 	int i, size;
1966 
1967 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1968 	opts.protect_frames = true;
1969 	opts.encrypt = true;
1970 	opts.sa_in_use = 1;
1971 	opts.nb_td = 1;
1972 	opts.sectag_insert_mode = 1;
1973 	opts.mtu = RTE_ETHER_MTU;
1974 	opts.rekey_en = 1;
1975 
1976 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
1977 
1978 	for (i = 0; i < size; i++) {
1979 		cur_td = &list_mcs_rekey_vectors[i];
1980 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
1981 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1982 		if (err) {
1983 			printf("Tx hw rekey test case %d failed\n", i);
1984 			err = -1;
1985 		} else {
1986 			printf("Tx hw rekey test case %d passed\n", i);
1987 			err = 0;
1988 		}
1989 		all_err += err;
1990 	}
1991 
1992 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1993 	return all_err;
1994 }
1995 
1996 static int
1997 test_inline_macsec_rekey_rx(void)
1998 {
1999 	const struct mcs_test_vector *cur_td;
2000 	struct mcs_test_opts opts = {0};
2001 	int err, all_err = 0;
2002 	int i, size;
2003 
2004 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2005 	opts.protect_frames = true;
2006 	opts.sa_in_use = 1;
2007 	opts.nb_td = 1;
2008 	opts.sectag_insert_mode = 1;
2009 	opts.mtu = RTE_ETHER_MTU;
2010 	opts.rekey_en = 1;
2011 
2012 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
2013 	for (i = 0; i < size; i++) {
2014 		cur_td = &list_mcs_rekey_vectors[i];
2015 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
2016 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
2017 		if (err) {
2018 			printf("Rx rekey test case %d failed\n", i);
2019 			err = -1;
2020 		} else {
2021 			printf("Rx rekey test case %d passed\n", i);
2022 			err = 0;
2023 		}
2024 		all_err += err;
2025 	}
2026 
2027 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
2028 	return all_err;
2029 }
2030 
2031 static int
2032 test_inline_macsec_anti_replay(void)
2033 {
2034 	const struct mcs_test_vector *cur_td;
2035 	struct mcs_test_opts opts = {0};
2036 	uint16_t replay_win_sz[2] = {32, 0};
2037 	int err, all_err = 0;
2038 	int i, size;
2039 	int j;
2040 
2041 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2042 	opts.sa_in_use = 1;
2043 	opts.nb_td = 1;
2044 	opts.sectag_insert_mode = 1;
2045 	opts.replay_protect = 1;
2046 
2047 	size = (sizeof(list_mcs_anti_replay_vectors) / sizeof((list_mcs_anti_replay_vectors)[0]));
2048 
2049 	for (j = 0; j < 2; j++) {
2050 		opts.replay_win_sz = replay_win_sz[j];
2051 
2052 		for (i = 0; i < size; i++) {
2053 			cur_td = &list_mcs_anti_replay_vectors[i];
2054 			opts.ar_td[0] = &list_mcs_anti_replay_vectors[++i];
2055 			opts.ar_td[1] = &list_mcs_anti_replay_vectors[++i];
2056 			opts.ar_td[2] = &list_mcs_anti_replay_vectors[++i];
2057 			err = test_macsec(&cur_td, MCS_DECAP, &opts);
2058 			if (err) {
2059 				printf("Replay window: %u, Anti replay test case %d failed\n",
2060 				       opts.replay_win_sz, i);
2061 				err = -1;
2062 			} else {
2063 				printf("Replay window: %u, Anti replay test case %d passed\n",
2064 				       opts.replay_win_sz, i);
2065 				err = 0;
2066 			}
2067 			all_err += err;
2068 		}
2069 	}
2070 
2071 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
2072 	return all_err;
2073 }
2074 
2075 static int
2076 ut_setup_inline_macsec(void)
2077 {
2078 	int ret;
2079 
2080 	/* Start device */
2081 	ret = rte_eth_dev_start(port_id);
2082 	if (ret < 0) {
2083 		printf("rte_eth_dev_start: err=%d, port=%d\n",
2084 			ret, port_id);
2085 		return ret;
2086 	}
2087 	/* always enable promiscuous */
2088 	ret = rte_eth_promiscuous_enable(port_id);
2089 	if (ret != 0) {
2090 		printf("rte_eth_promiscuous_enable: err=%s, port=%d\n",
2091 			rte_strerror(-ret), port_id);
2092 		return ret;
2093 	}
2094 
2095 	check_all_ports_link_status(1, RTE_PORT_ALL);
2096 
2097 	return 0;
2098 }
2099 
2100 static void
2101 ut_teardown_inline_macsec(void)
2102 {
2103 	uint16_t portid;
2104 	int ret;
2105 
2106 	/* port tear down */
2107 	RTE_ETH_FOREACH_DEV(portid) {
2108 		ret = rte_eth_dev_stop(portid);
2109 		if (ret != 0)
2110 			printf("rte_eth_dev_stop: err=%s, port=%u\n",
2111 			       rte_strerror(-ret), portid);
2112 
2113 	}
2114 }
2115 
2116 static int
2117 inline_macsec_testsuite_setup(void)
2118 {
2119 	uint16_t nb_rxd;
2120 	uint16_t nb_txd;
2121 	uint16_t nb_ports;
2122 	int ret;
2123 	uint16_t nb_rx_queue = 1, nb_tx_queue = 1;
2124 
2125 	printf("Start inline MACsec test.\n");
2126 
2127 	nb_ports = rte_eth_dev_count_avail();
2128 	if (nb_ports < NB_ETHPORTS_USED) {
2129 		printf("At least %u port(s) used for test\n",
2130 		       NB_ETHPORTS_USED);
2131 		return TEST_SKIPPED;
2132 	}
2133 
2134 	ret = init_mempools(NB_MBUF);
2135 	if (ret)
2136 		return ret;
2137 
2138 	if (tx_pkts_burst == NULL) {
2139 		tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff",
2140 					  MAX_TRAFFIC_BURST,
2141 					  sizeof(void *),
2142 					  RTE_CACHE_LINE_SIZE);
2143 		if (!tx_pkts_burst)
2144 			return TEST_FAILED;
2145 
2146 		rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff",
2147 					  MAX_TRAFFIC_BURST,
2148 					  sizeof(void *),
2149 					  RTE_CACHE_LINE_SIZE);
2150 		if (!rx_pkts_burst)
2151 			return TEST_FAILED;
2152 	}
2153 
2154 	printf("Generate %d packets\n", MAX_TRAFFIC_BURST);
2155 
2156 	nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
2157 	nb_txd = RTE_TEST_TX_DESC_DEFAULT;
2158 
2159 	/* configuring port 0 for the test is enough */
2160 	port_id = 0;
2161 	/* port configure */
2162 	ret = rte_eth_dev_configure(port_id, nb_rx_queue,
2163 				    nb_tx_queue, &port_conf);
2164 	if (ret < 0) {
2165 		printf("Cannot configure device: err=%d, port=%d\n",
2166 			 ret, port_id);
2167 		return ret;
2168 	}
2169 	ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]);
2170 	if (ret < 0) {
2171 		printf("Cannot get mac address: err=%d, port=%d\n",
2172 			 ret, port_id);
2173 		return ret;
2174 	}
2175 	printf("Port %u ", port_id);
2176 	print_ethaddr("Address:", &ports_eth_addr[port_id]);
2177 	printf("\n");
2178 
2179 	/* tx queue setup */
2180 	ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
2181 				     SOCKET_ID_ANY, &tx_conf);
2182 	if (ret < 0) {
2183 		printf("rte_eth_tx_queue_setup: err=%d, port=%d\n",
2184 				ret, port_id);
2185 		return ret;
2186 	}
2187 	/* rx queue steup */
2188 	ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY,
2189 				     &rx_conf, mbufpool);
2190 	if (ret < 0) {
2191 		printf("rte_eth_rx_queue_setup: err=%d, port=%d\n",
2192 				ret, port_id);
2193 		return ret;
2194 	}
2195 
2196 	return 0;
2197 }
2198 
2199 static void
2200 inline_macsec_testsuite_teardown(void)
2201 {
2202 	uint16_t portid;
2203 	int ret;
2204 
2205 	/* port tear down */
2206 	RTE_ETH_FOREACH_DEV(portid) {
2207 		ret = rte_eth_dev_reset(portid);
2208 		if (ret != 0)
2209 			printf("rte_eth_dev_reset: err=%s, port=%u\n",
2210 			       rte_strerror(-ret), port_id);
2211 	}
2212 	rte_free(tx_pkts_burst);
2213 	rte_free(rx_pkts_burst);
2214 }
2215 
2216 
2217 static struct unit_test_suite inline_macsec_testsuite  = {
2218 	.suite_name = "Inline MACsec Ethernet Device Unit Test Suite",
2219 	.unit_test_cases = {
2220 		TEST_CASE_NAMED_ST(
2221 			"MACsec Encap + decap Multi flow",
2222 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2223 			test_inline_macsec_multi_flow),
2224 		TEST_CASE_NAMED_ST(
2225 			"MACsec encap(Cipher+Auth) known vector",
2226 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2227 			test_inline_macsec_encap_all),
2228 		TEST_CASE_NAMED_ST(
2229 			"MACsec decap(De-cipher+verify) known vector",
2230 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2231 			test_inline_macsec_decap_all),
2232 		TEST_CASE_NAMED_ST(
2233 			"MACsec auth only known vector",
2234 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2235 			test_inline_macsec_auth_only_all),
2236 		TEST_CASE_NAMED_ST(
2237 			"MACsec verify only known vector",
2238 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2239 			test_inline_macsec_verify_only_all),
2240 		TEST_CASE_NAMED_ST(
2241 			"MACsec encap + decap known vector",
2242 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2243 			test_inline_macsec_encap_decap_all),
2244 		TEST_CASE_NAMED_ST(
2245 			"MACsec auth + verify known vector",
2246 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2247 			test_inline_macsec_auth_verify_all),
2248 		TEST_CASE_NAMED_ST(
2249 			"MACsec Encap and decap with VLAN",
2250 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2251 			test_inline_macsec_with_vlan),
2252 		TEST_CASE_NAMED_ST(
2253 			"MACsec packet drop",
2254 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2255 			test_inline_macsec_pkt_drop),
2256 		TEST_CASE_NAMED_ST(
2257 			"MACsec untagged Rx",
2258 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2259 			test_inline_macsec_untagged_rx),
2260 		TEST_CASE_NAMED_ST(
2261 			"MACsec bad tag Rx",
2262 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2263 			test_inline_macsec_bad_tag_rx),
2264 		TEST_CASE_NAMED_ST(
2265 			"MACsec SA not in use",
2266 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2267 			test_inline_macsec_sa_not_in_use),
2268 		TEST_CASE_NAMED_ST(
2269 			"MACsec decap stats",
2270 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2271 			test_inline_macsec_decap_stats),
2272 		TEST_CASE_NAMED_ST(
2273 			"MACsec verify only stats",
2274 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2275 			test_inline_macsec_verify_only_stats),
2276 		TEST_CASE_NAMED_ST(
2277 			"MACsec pkts invalid stats",
2278 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2279 			test_inline_macsec_pkts_invalid_stats),
2280 		TEST_CASE_NAMED_ST(
2281 			"MACsec pkts unchecked stats",
2282 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2283 			test_inline_macsec_pkts_unchecked_stats),
2284 		TEST_CASE_NAMED_ST(
2285 			"MACsec out pkts untagged",
2286 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2287 			test_inline_macsec_out_pkts_untagged),
2288 		TEST_CASE_NAMED_ST(
2289 			"MACsec out pkts too long",
2290 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2291 			test_inline_macsec_out_pkts_toolong),
2292 		TEST_CASE_NAMED_ST(
2293 			"MACsec Encap stats",
2294 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2295 			test_inline_macsec_encap_stats),
2296 		TEST_CASE_NAMED_ST(
2297 			"MACsec auth only stats",
2298 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2299 			test_inline_macsec_auth_only_stats),
2300 		TEST_CASE_NAMED_ST(
2301 			"MACsec interrupts all",
2302 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2303 			test_inline_macsec_interrupts_all),
2304 		TEST_CASE_NAMED_ST(
2305 			"MACsec re-key Tx",
2306 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2307 			test_inline_macsec_rekey_tx),
2308 		TEST_CASE_NAMED_ST(
2309 			"MACsec re-key Rx",
2310 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2311 			test_inline_macsec_rekey_rx),
2312 		TEST_CASE_NAMED_ST(
2313 			"MACsec anti-replay",
2314 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2315 			test_inline_macsec_anti_replay),
2316 
2317 		TEST_CASES_END() /**< NULL terminate unit test array */
2318 	},
2319 };
2320 
2321 static int
2322 test_inline_macsec(void)
2323 {
2324 	inline_macsec_testsuite.setup = inline_macsec_testsuite_setup;
2325 	inline_macsec_testsuite.teardown = inline_macsec_testsuite_teardown;
2326 	return unit_test_suite_runner(&inline_macsec_testsuite);
2327 }
2328 
2329 #endif /* !RTE_EXEC_ENV_WINDOWS */
2330 
2331 REGISTER_TEST_COMMAND(inline_macsec_autotest, test_inline_macsec);
2332