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