xref: /dpdk/app/test/test_security_inline_macsec.c (revision 4885ba24a05cb21e7f02cf9ecab3b94b4231dc86)
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 				if (opts->rekey_en && an ==
909 						(opts->rekey_td->secure_pkt.data[tci_off] &
910 						RTE_MACSEC_AN_MASK))
911 					fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
912 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
913 				else
914 				/* For simplicity, using same SA conf for all AN */
915 					fill_macsec_sa_conf(td[i], &sa_conf,
916 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
917 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
918 				if (id < 0) {
919 					printf("MACsec SA create failed : %d.\n", id);
920 					return TEST_FAILED;
921 				}
922 				rx_sa_id[i][an] = (uint16_t)id;
923 			}
924 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
925 					RTE_SECURITY_MACSEC_DIR_RX, rx_sa_id[i], tci_off);
926 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
927 			if (id < 0) {
928 				printf("MACsec SC create failed : %d.\n", id);
929 				goto out;
930 			}
931 			rx_sc_id[i] = (uint16_t)id;
932 
933 			/* Create Inline IPsec session. */
934 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
935 					RTE_SECURITY_MACSEC_DIR_RX, rx_sc_id[i], tci_off);
936 			if (ret)
937 				return TEST_FAILED;
938 
939 			rx_sess[i] = rte_security_session_create(ctx, &sess_conf,
940 					sess_pool);
941 			if (rx_sess[i] == NULL) {
942 				printf("SEC Session init failed.\n");
943 				return TEST_FAILED;
944 			}
945 			ret = create_default_flow(td[i], port_id,
946 					RTE_SECURITY_MACSEC_DIR_RX, rx_sess[i]);
947 			if (ret)
948 				goto out;
949 		}
950 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
951 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
952 			int id;
953 
954 			fill_macsec_sa_conf(td[i], &sa_conf,
955 					RTE_SECURITY_MACSEC_DIR_TX,
956 					td[i]->secure_pkt.data[tci_off] & RTE_MACSEC_AN_MASK,
957 					tci_off);
958 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
959 			if (id < 0) {
960 				printf("MACsec SA create failed : %d.\n", id);
961 				return TEST_FAILED;
962 			}
963 			tx_sa_id[i][0] = (uint16_t)id;
964 			tx_sa_id[i][1] = MCS_INVALID_SA;
965 			if (opts->rekey_en) {
966 				memset(&sa_conf, 0, sizeof(struct rte_security_macsec_sa));
967 				fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
968 					RTE_SECURITY_MACSEC_DIR_TX,
969 					opts->rekey_td->secure_pkt.data[tci_off] &
970 						RTE_MACSEC_AN_MASK,
971 					tci_off);
972 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
973 				if (id < 0) {
974 					printf("MACsec rekey SA create failed : %d.\n", id);
975 					goto out;
976 				}
977 				tx_sa_id[i][1] = (uint16_t)id;
978 			}
979 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
980 					RTE_SECURITY_MACSEC_DIR_TX, tx_sa_id[i], tci_off);
981 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
982 			if (id < 0) {
983 				printf("MACsec SC create failed : %d.\n", id);
984 				goto out;
985 			}
986 			tx_sc_id[i] = (uint16_t)id;
987 
988 			/* Create Inline IPsec session. */
989 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
990 					RTE_SECURITY_MACSEC_DIR_TX, tx_sc_id[i], tci_off);
991 			if (ret)
992 				return TEST_FAILED;
993 
994 			tx_sess[i] = rte_security_session_create(ctx, &sess_conf,
995 					sess_pool);
996 			if (tx_sess[i] == NULL) {
997 				printf("SEC Session init failed.\n");
998 				return TEST_FAILED;
999 			}
1000 			ret = create_default_flow(td[i], port_id,
1001 					RTE_SECURITY_MACSEC_DIR_TX, tx_sess[i]);
1002 			if (ret)
1003 				goto out;
1004 		}
1005 	}
1006 
1007 	/* Send packet to ethdev for inline MACsec processing. */
1008 	nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, j);
1009 
1010 	if (nb_sent != j) {
1011 		printf("\nUnable to TX %d packets, sent: %i", j, nb_sent);
1012 		for ( ; nb_sent < j; nb_sent++)
1013 			rte_pktmbuf_free(tx_pkts_burst[nb_sent]);
1014 		ret = TEST_FAILED;
1015 		goto out;
1016 	}
1017 
1018 	rte_pause();
1019 
1020 	/* Receive back packet on loopback interface. */
1021 	do {
1022 		nb_rx += rte_eth_rx_burst(port_id, 0,
1023 				&rx_pkts_burst[nb_rx],
1024 				nb_sent - nb_rx);
1025 		if (nb_rx >= nb_sent)
1026 			break;
1027 		rte_delay_ms(1);
1028 	} while (j++ < 5 && nb_rx == 0);
1029 
1030 	if (nb_rx != nb_sent) {
1031 		printf("\nUnable to RX all %d packets, received(%i)",
1032 				nb_sent, nb_rx);
1033 		while (--nb_rx >= 0)
1034 			rte_pktmbuf_free(rx_pkts_burst[nb_rx]);
1035 		ret = TEST_FAILED;
1036 		if (opts->check_sectag_interrupts == 1)
1037 			ret = TEST_SUCCESS;
1038 		goto out;
1039 	}
1040 
1041 	if (opts->rekey_en) {
1042 		switch (err_vector.event) {
1043 		case RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP:
1044 			printf("Received RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP event\n");
1045 			/* The first sa is active now, so the 0th sa can be
1046 			 * reconfigured. Using the same key as zeroeth sa, but
1047 			 * other key can also be configured.
1048 			 */
1049 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[0][0],
1050 					RTE_SECURITY_MACSEC_DIR_TX);
1051 			fill_macsec_sa_conf(td[0], &sa_conf,
1052 					RTE_SECURITY_MACSEC_DIR_TX,
1053 					td[0]->secure_pkt.data[tci_off] &
1054 					RTE_MACSEC_AN_MASK, tci_off);
1055 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
1056 			if (id < 0) {
1057 				printf("MACsec SA create failed : %d.\n", id);
1058 				return TEST_FAILED;
1059 			}
1060 			tx_sa_id[0][0] = (uint16_t)id;
1061 			break;
1062 		case RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP:
1063 			printf("Received RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP event\n");
1064 			break;
1065 		default:
1066 			printf("Received unsupported event\n");
1067 		}
1068 	}
1069 
1070 	for (i = 0; i < nb_rx; i++) {
1071 		if (opts->rekey_en && i == 1) {
1072 			/* The second received packet is matched with
1073 			 * rekey td
1074 			 */
1075 			ret = test_macsec_post_process(rx_pkts_burst[i],
1076 					opts->rekey_td, op,
1077 					opts->check_out_pkts_untagged);
1078 		} else {
1079 			ret = test_macsec_post_process(rx_pkts_burst[i], td[i],
1080 					op, opts->check_out_pkts_untagged);
1081 		}
1082 		if (ret != TEST_SUCCESS) {
1083 			for ( ; i < nb_rx; i++)
1084 				rte_pktmbuf_free(rx_pkts_burst[i]);
1085 			goto out;
1086 		}
1087 
1088 		rte_pktmbuf_free(rx_pkts_burst[i]);
1089 		rx_pkts_burst[i] = NULL;
1090 	}
1091 out:
1092 	if (opts->check_out_pkts_toolong == 1 ||
1093 			opts->check_sa_not_in_use == 1 ||
1094 			opts->check_bad_tag_cnt == 1)
1095 		ret = TEST_SUCCESS;
1096 
1097 	for (i = 0; i < opts->nb_td; i++) {
1098 		if (opts->dump_all_stats) {
1099 			mcs_stats_dump(ctx, op,
1100 					rx_sess[i], tx_sess[i],
1101 					rx_sc_id[i], tx_sc_id[i],
1102 					rx_sa_id[i], tx_sa_id[i]);
1103 		} else {
1104 			if (ret == TEST_SUCCESS)
1105 				ret = mcs_stats_check(ctx, op, opts, td[i],
1106 					rx_sess[i], tx_sess[i],
1107 					rx_sc_id[i], tx_sc_id[i],
1108 					rx_sa_id[i], tx_sa_id[i]);
1109 		}
1110 	}
1111 
1112 	destroy_default_flow(port_id);
1113 
1114 	if (opts->rekey_en)
1115 		rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
1116 					test_macsec_event_callback, &err_vector);
1117 
1118 	/* Destroy session so that other cases can create the session again */
1119 	for (i = 0; i < opts->nb_td; i++) {
1120 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
1121 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
1122 			rte_security_session_destroy(ctx, tx_sess[i]);
1123 			tx_sess[i] = NULL;
1124 			rte_security_macsec_sc_destroy(ctx, tx_sc_id[i],
1125 						RTE_SECURITY_MACSEC_DIR_TX);
1126 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][0],
1127 						RTE_SECURITY_MACSEC_DIR_TX);
1128 			if (opts->rekey_en) {
1129 				rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][1],
1130 						RTE_SECURITY_MACSEC_DIR_TX);
1131 			}
1132 		}
1133 		if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
1134 				op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
1135 			rte_security_session_destroy(ctx, rx_sess[i]);
1136 			rx_sess[i] = NULL;
1137 			rte_security_macsec_sc_destroy(ctx, rx_sc_id[i],
1138 						RTE_SECURITY_MACSEC_DIR_RX);
1139 			for (j = 0; j < RTE_SECURITY_MACSEC_NUM_AN; j++) {
1140 				rte_security_macsec_sa_destroy(ctx, rx_sa_id[i][j],
1141 						RTE_SECURITY_MACSEC_DIR_RX);
1142 			}
1143 		}
1144 	}
1145 
1146 	return ret;
1147 }
1148 
1149 static int
1150 test_inline_macsec_encap_all(const void *data __rte_unused)
1151 {
1152 	const struct mcs_test_vector *cur_td;
1153 	struct mcs_test_opts opts = {0};
1154 	int err, all_err = 0;
1155 	int i, size;
1156 
1157 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1158 	opts.encrypt = true;
1159 	opts.protect_frames = true;
1160 	opts.sa_in_use = 1;
1161 	opts.nb_td = 1;
1162 	opts.sectag_insert_mode = 1;
1163 	opts.mtu = RTE_ETHER_MTU;
1164 
1165 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1166 	for (i = 0; i < size; i++) {
1167 		cur_td = &list_mcs_cipher_vectors[i];
1168 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1169 		if (err) {
1170 			printf("\nCipher Auth Encryption case %d failed", cur_td->test_idx);
1171 			err = -1;
1172 		} else {
1173 			printf("\nCipher Auth Encryption case %d Passed", cur_td->test_idx);
1174 			err = 0;
1175 		}
1176 		all_err += err;
1177 	}
1178 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1179 
1180 	return all_err;
1181 }
1182 
1183 static int
1184 test_inline_macsec_decap_all(const void *data __rte_unused)
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.sa_in_use = 1;
1193 	opts.nb_td = 1;
1194 	opts.sectag_insert_mode = 1;
1195 	opts.mtu = RTE_ETHER_MTU;
1196 
1197 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1198 	for (i = 0; i < size; i++) {
1199 		cur_td = &list_mcs_cipher_vectors[i];
1200 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1201 		if (err) {
1202 			printf("\nCipher Auth Decryption case %d failed", cur_td->test_idx);
1203 			err = -1;
1204 		} else {
1205 			printf("\nCipher Auth Decryption case %d Passed", cur_td->test_idx);
1206 			err = 0;
1207 		}
1208 		all_err += err;
1209 	}
1210 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1211 
1212 	return all_err;
1213 }
1214 
1215 static int
1216 test_inline_macsec_auth_only_all(const void *data __rte_unused)
1217 {
1218 	const struct mcs_test_vector *cur_td;
1219 	struct mcs_test_opts opts = {0};
1220 	int err, all_err = 0;
1221 	int i, size;
1222 
1223 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1224 	opts.protect_frames = true;
1225 	opts.sa_in_use = 1;
1226 	opts.nb_td = 1;
1227 	opts.sectag_insert_mode = 1;
1228 	opts.mtu = RTE_ETHER_MTU;
1229 
1230 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1231 
1232 	for (i = 0; i < size; i++) {
1233 		cur_td = &list_mcs_integrity_vectors[i];
1234 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
1235 		if (err) {
1236 			printf("\nAuth Generate case %d failed", cur_td->test_idx);
1237 			err = -1;
1238 		} else {
1239 			printf("\nAuth Generate 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_verify_only_all(const void *data __rte_unused)
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.sa_in_use = 1;
1259 	opts.nb_td = 1;
1260 	opts.sectag_insert_mode = 1;
1261 	opts.mtu = RTE_ETHER_MTU;
1262 
1263 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1264 
1265 	for (i = 0; i < size; i++) {
1266 		cur_td = &list_mcs_integrity_vectors[i];
1267 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1268 		if (err) {
1269 			printf("\nAuth Verify case %d failed", cur_td->test_idx);
1270 			err = -1;
1271 		} else {
1272 			printf("\nAuth Verify case %d Passed", cur_td->test_idx);
1273 			err = 0;
1274 		}
1275 		all_err += err;
1276 	}
1277 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1278 
1279 	return all_err;
1280 }
1281 
1282 static int
1283 test_inline_macsec_encap_decap_all(const void *data __rte_unused)
1284 {
1285 	const struct mcs_test_vector *cur_td;
1286 	struct mcs_test_opts opts = {0};
1287 	int err, all_err = 0;
1288 	int i, size;
1289 
1290 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1291 	opts.encrypt = true;
1292 	opts.protect_frames = true;
1293 	opts.sa_in_use = 1;
1294 	opts.nb_td = 1;
1295 	opts.sectag_insert_mode = 1;
1296 	opts.mtu = RTE_ETHER_MTU;
1297 
1298 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1299 
1300 	for (i = 0; i < size; i++) {
1301 		cur_td = &list_mcs_cipher_vectors[i];
1302 		err = test_macsec(&cur_td, MCS_ENCAP_DECAP, &opts);
1303 		if (err) {
1304 			printf("\nCipher Auth Encap-decap case %d failed", cur_td->test_idx);
1305 			err = -1;
1306 		} else {
1307 			printf("\nCipher Auth Encap-decap case %d Passed", cur_td->test_idx);
1308 			err = 0;
1309 		}
1310 		all_err += err;
1311 	}
1312 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1313 
1314 	return all_err;
1315 }
1316 
1317 
1318 static int
1319 test_inline_macsec_auth_verify_all(const void *data __rte_unused)
1320 {
1321 	const struct mcs_test_vector *cur_td;
1322 	struct mcs_test_opts opts = {0};
1323 	int err, all_err = 0;
1324 	int i, size;
1325 
1326 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1327 	opts.protect_frames = true;
1328 	opts.sa_in_use = 1;
1329 	opts.nb_td = 1;
1330 	opts.sectag_insert_mode = 1;
1331 	opts.mtu = RTE_ETHER_MTU;
1332 
1333 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1334 
1335 	for (i = 0; i < size; i++) {
1336 		cur_td = &list_mcs_integrity_vectors[i];
1337 		err = test_macsec(&cur_td, MCS_AUTH_VERIFY, &opts);
1338 		if (err) {
1339 			printf("\nAuth Generate + Verify case %d failed", cur_td->test_idx);
1340 			err = -1;
1341 		} else {
1342 			printf("\nAuth Generate + Verify case %d Passed", cur_td->test_idx);
1343 			err = 0;
1344 		}
1345 		all_err += err;
1346 	}
1347 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1348 
1349 	return all_err;
1350 }
1351 
1352 static int
1353 test_inline_macsec_multi_flow(const void *data __rte_unused)
1354 {
1355 	const struct mcs_test_vector *tv[MCS_MAX_FLOWS];
1356 	struct mcs_test_vector iter[MCS_MAX_FLOWS];
1357 	struct mcs_test_opts opts = {0};
1358 	int i, err;
1359 
1360 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1361 	opts.encrypt = true;
1362 	opts.protect_frames = true;
1363 	opts.sa_in_use = 1;
1364 	opts.nb_td = MCS_MAX_FLOWS;
1365 	opts.sectag_insert_mode = 1;
1366 	opts.mtu = RTE_ETHER_MTU;
1367 
1368 	for (i = 0; i < MCS_MAX_FLOWS; i++) {
1369 		memcpy(&iter[i].sa_key.data, sa_key, MCS_MULTI_FLOW_TD_KEY_SZ);
1370 		memcpy(&iter[i].plain_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1371 		memcpy(&iter[i].plain_pkt.data[2 * RTE_ETHER_ADDR_LEN], plain_user_data,
1372 		       MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ);
1373 		memcpy(&iter[i].secure_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1374 		memcpy(&iter[i].secure_pkt.data[2 * RTE_ETHER_ADDR_LEN], secure_user_data,
1375 		       MCS_MULTI_FLOW_TD_SECURE_DATA_SZ);
1376 		iter[i].sa_key.len = MCS_MULTI_FLOW_TD_KEY_SZ;
1377 		iter[i].plain_pkt.len = MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ +
1378 					(2 * RTE_ETHER_ADDR_LEN);
1379 		iter[i].secure_pkt.len = MCS_MULTI_FLOW_TD_SECURE_DATA_SZ +
1380 					(2 * RTE_ETHER_ADDR_LEN);
1381 		iter[i].alg = RTE_SECURITY_MACSEC_ALG_GCM_128;
1382 		iter[i].ssci = 0x0;
1383 		iter[i].xpn = 0x0;
1384 		tv[i] = (const struct mcs_test_vector *)&iter[i];
1385 	}
1386 	err = test_macsec(tv, MCS_ENCAP_DECAP, &opts);
1387 	if (err) {
1388 		printf("\nCipher Auth Encryption multi flow failed");
1389 		err = -1;
1390 	} else {
1391 		printf("\nCipher Auth Encryption multi flow Passed");
1392 		err = 0;
1393 	}
1394 	return err;
1395 }
1396 
1397 static int
1398 test_inline_macsec_with_vlan(const void *data __rte_unused)
1399 {
1400 	const struct mcs_test_vector *cur_td;
1401 	struct mcs_test_opts opts = {0};
1402 	int err, all_err = 0;
1403 	int i, size;
1404 
1405 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1406 	opts.protect_frames = true;
1407 	opts.sa_in_use = 1;
1408 	opts.nb_td = 1;
1409 	opts.mtu = RTE_ETHER_MTU;
1410 
1411 	size = (sizeof(list_mcs_vlan_vectors) / sizeof((list_mcs_vlan_vectors)[0]));
1412 
1413 	for (i = 0; i < size; i++) {
1414 		cur_td = &list_mcs_vlan_vectors[i];
1415 		if (i == 0) {
1416 			opts.sectag_insert_mode = 1;
1417 		} else if (i == 1) {
1418 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1419 			opts.nb_vlan = 1;
1420 		} else if (i == 2) {
1421 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1422 			opts.nb_vlan = 2;
1423 		}
1424 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1425 		if (err) {
1426 			printf("\n VLAN Encap case %d failed", cur_td->test_idx);
1427 			err = -1;
1428 		} else {
1429 			printf("\n VLAN Encap case %d passed", cur_td->test_idx);
1430 			err = 0;
1431 		}
1432 		all_err += err;
1433 	}
1434 	for (i = 0; i < size; i++) {
1435 		cur_td = &list_mcs_vlan_vectors[i];
1436 		if (i == 0) {
1437 			opts.sectag_insert_mode = 1;
1438 		} else if (i == 1) {
1439 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1440 			opts.nb_vlan = 1;
1441 		} else if (i == 2) {
1442 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1443 			opts.nb_vlan = 2;
1444 		}
1445 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1446 		if (err) {
1447 			printf("\n VLAN Decap case %d failed", cur_td->test_idx);
1448 			err = -1;
1449 		} else {
1450 			printf("\n VLAN Decap case %d passed", cur_td->test_idx);
1451 			err = 0;
1452 		}
1453 		all_err += err;
1454 	}
1455 
1456 	printf("\n%s: Success: %d, Failure: %d\n", __func__, (2 * size) + all_err, -all_err);
1457 	return all_err;
1458 }
1459 
1460 static int
1461 test_inline_macsec_pkt_drop(const void *data __rte_unused)
1462 {
1463 	const struct mcs_test_vector *cur_td;
1464 	struct mcs_test_opts opts = {0};
1465 	int err, all_err = 0;
1466 	int i, size;
1467 
1468 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1469 	opts.encrypt = true;
1470 	opts.protect_frames = true;
1471 	opts.sa_in_use = 1;
1472 	opts.nb_td = 1;
1473 	opts.sectag_insert_mode = 1;
1474 	opts.mtu = RTE_ETHER_MTU;
1475 
1476 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1477 
1478 	for (i = 0; i < size; i++) {
1479 		cur_td = &list_mcs_err_cipher_vectors[i];
1480 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1481 		if (err) {
1482 			printf("\nPacket drop case %d passed", cur_td->test_idx);
1483 			err = 0;
1484 		} else {
1485 			printf("\nPacket drop case %d failed", cur_td->test_idx);
1486 			err = -1;
1487 		}
1488 		all_err += err;
1489 	}
1490 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1491 
1492 	return all_err;
1493 }
1494 
1495 static int
1496 test_inline_macsec_untagged_rx(const void *data __rte_unused)
1497 {
1498 	const struct mcs_test_vector *cur_td;
1499 	struct mcs_test_opts opts = {0};
1500 	int err, all_err = 0;
1501 	int i, size;
1502 
1503 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1504 	opts.sa_in_use = 1;
1505 	opts.nb_td = 1;
1506 	opts.sectag_insert_mode = 1;
1507 	opts.mtu = RTE_ETHER_MTU;
1508 	opts.check_untagged_rx = 1;
1509 
1510 	size = (sizeof(list_mcs_untagged_cipher_vectors) /
1511 		sizeof((list_mcs_untagged_cipher_vectors)[0]));
1512 
1513 	for (i = 0; i < size; i++) {
1514 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1515 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1516 		if (err)
1517 			err = 0;
1518 		else
1519 			err = -1;
1520 
1521 		all_err += err;
1522 	}
1523 
1524 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
1525 	for (i = 0; i < size; i++) {
1526 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1527 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1528 		if (err)
1529 			err = 0;
1530 		else
1531 			err = -1;
1532 
1533 		all_err += err;
1534 	}
1535 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1536 
1537 	return all_err;
1538 }
1539 
1540 static int
1541 test_inline_macsec_bad_tag_rx(const void *data __rte_unused)
1542 {
1543 	const struct mcs_test_vector *cur_td;
1544 	struct mcs_test_opts opts = {0};
1545 	int err, all_err = 0;
1546 	int i, size;
1547 
1548 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1549 	opts.protect_frames = true;
1550 	opts.sa_in_use = 1;
1551 	opts.nb_td = 1;
1552 	opts.sectag_insert_mode = 1;
1553 	opts.mtu = RTE_ETHER_MTU;
1554 	opts.check_bad_tag_cnt = 1;
1555 
1556 	size = (sizeof(list_mcs_bad_tag_vectors) / sizeof((list_mcs_bad_tag_vectors)[0]));
1557 
1558 	for (i = 0; i < size; i++) {
1559 		cur_td = &list_mcs_bad_tag_vectors[i];
1560 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1561 		if (err)
1562 			err = -1;
1563 		else
1564 			err = 0;
1565 
1566 		all_err += err;
1567 	}
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_sa_not_in_use(const void *data __rte_unused)
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 = 0;
1585 	opts.nb_td = 1;
1586 	opts.sectag_insert_mode = 1;
1587 	opts.mtu = RTE_ETHER_MTU;
1588 	opts.check_sa_not_in_use = 1;
1589 
1590 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1591 
1592 	for (i = 0; i < size; i++) {
1593 		cur_td = &list_mcs_cipher_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_decap_stats(const void *data __rte_unused)
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 = 1;
1619 	opts.nb_td = 1;
1620 	opts.sectag_insert_mode = 1;
1621 	opts.mtu = RTE_ETHER_MTU;
1622 	opts.check_decap_stats = 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 			printf("\nDecap stats case %d failed", cur_td->test_idx);
1631 			err = -1;
1632 		} else {
1633 			printf("\nDecap stats case %d passed", cur_td->test_idx);
1634 			err = 0;
1635 		}
1636 		all_err += err;
1637 	}
1638 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1639 
1640 	return all_err;
1641 }
1642 
1643 static int
1644 test_inline_macsec_verify_only_stats(const void *data __rte_unused)
1645 {
1646 	const struct mcs_test_vector *cur_td;
1647 	struct mcs_test_opts opts = {0};
1648 	int err, all_err = 0;
1649 	int i, size;
1650 
1651 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1652 	opts.protect_frames = true;
1653 	opts.sa_in_use = 1;
1654 	opts.nb_td = 1;
1655 	opts.sectag_insert_mode = 1;
1656 	opts.mtu = RTE_ETHER_MTU;
1657 	opts.check_verify_only_stats = 1;
1658 
1659 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1660 
1661 	for (i = 0; i < size; i++) {
1662 		cur_td = &list_mcs_integrity_vectors[i];
1663 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1664 		if (err) {
1665 			printf("\nVerify only stats case %d failed", cur_td->test_idx);
1666 			err = -1;
1667 		} else {
1668 			printf("\nVerify only stats case %d Passed", cur_td->test_idx);
1669 			err = 0;
1670 		}
1671 		all_err += err;
1672 	}
1673 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1674 
1675 	return all_err;
1676 }
1677 
1678 static int
1679 test_inline_macsec_pkts_invalid_stats(const void *data __rte_unused)
1680 {
1681 	const struct mcs_test_vector *cur_td;
1682 	struct mcs_test_opts opts = {0};
1683 	int err, all_err = 0;
1684 	int i, size;
1685 
1686 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1687 	opts.protect_frames = true;
1688 	opts.sa_in_use = 1;
1689 	opts.nb_td = 1;
1690 	opts.sectag_insert_mode = 1;
1691 	opts.mtu = RTE_ETHER_MTU;
1692 
1693 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1694 
1695 	for (i = 0; i < size; i++) {
1696 		cur_td = &list_mcs_err_cipher_vectors[i];
1697 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1698 		if (err)
1699 			err = 0;
1700 		else
1701 			err = -1;
1702 
1703 		all_err += err;
1704 	}
1705 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1706 	return all_err;
1707 }
1708 
1709 static int
1710 test_inline_macsec_pkts_unchecked_stats(const void *data __rte_unused)
1711 {
1712 	const struct mcs_test_vector *cur_td;
1713 	struct mcs_test_opts opts = {0};
1714 	int err, all_err = 0;
1715 	int i, size;
1716 
1717 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_DISABLE;
1718 	opts.protect_frames = true;
1719 	opts.sa_in_use = 1;
1720 	opts.nb_td = 1;
1721 	opts.sectag_insert_mode = 1;
1722 	opts.mtu = RTE_ETHER_MTU;
1723 	opts.check_pkts_unchecked_stats = 1;
1724 
1725 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1726 
1727 	for (i = 0; i < size; i++) {
1728 		cur_td = &list_mcs_integrity_vectors[i];
1729 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1730 		if (err)
1731 			err = -1;
1732 		else
1733 			err = 0;
1734 
1735 		all_err += err;
1736 	}
1737 
1738 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1739 	return all_err;
1740 }
1741 
1742 static int
1743 test_inline_macsec_out_pkts_untagged(const void *data __rte_unused)
1744 {
1745 	const struct mcs_test_vector *cur_td;
1746 	struct mcs_test_opts opts = {0};
1747 	int err, all_err = 0;
1748 	int i, size;
1749 
1750 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1751 	opts.encrypt = false;
1752 	opts.protect_frames = false;
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_out_pkts_untagged = 1;
1758 
1759 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1760 	for (i = 0; i < size; i++) {
1761 		cur_td = &list_mcs_cipher_vectors[i];
1762 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1763 		if (err)
1764 			err = -1;
1765 		else
1766 			err = 0;
1767 
1768 		all_err += err;
1769 	}
1770 
1771 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1772 	return all_err;
1773 }
1774 
1775 static int
1776 test_inline_macsec_out_pkts_toolong(const void *data __rte_unused)
1777 {
1778 	const struct mcs_test_vector *cur_td;
1779 	struct mcs_test_opts opts = {0};
1780 	int err, all_err = 0;
1781 	int i, size;
1782 
1783 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
1784 	opts.encrypt = true;
1785 	opts.protect_frames = true;
1786 	opts.sa_in_use = 1;
1787 	opts.nb_td = 1;
1788 	opts.sectag_insert_mode = 1;
1789 	opts.mtu = 50;
1790 	opts.check_out_pkts_toolong = 1;
1791 
1792 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1793 	for (i = 0; i < size; i++) {
1794 		cur_td = &list_mcs_cipher_vectors[i];
1795 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1796 		if (err)
1797 			err = -1;
1798 		else
1799 			err = 0;
1800 
1801 		all_err += err;
1802 	}
1803 
1804 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1805 	return all_err;
1806 }
1807 
1808 static int
1809 test_inline_macsec_encap_stats(const void *data __rte_unused)
1810 {
1811 	const struct mcs_test_vector *cur_td;
1812 	struct mcs_test_opts opts = {0};
1813 	int err, all_err = 0;
1814 	int i, size;
1815 
1816 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1817 	opts.encrypt = true;
1818 	opts.protect_frames = true;
1819 	opts.sa_in_use = 1;
1820 	opts.nb_td = 1;
1821 	opts.sectag_insert_mode = 1;
1822 	opts.mtu = RTE_ETHER_MTU;
1823 	opts.check_encap_stats = 1;
1824 
1825 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1826 	for (i = 0; i < size; i++) {
1827 		cur_td = &list_mcs_cipher_vectors[i];
1828 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1829 		if (err)
1830 			err = -1;
1831 		else
1832 			err = 0;
1833 		all_err += err;
1834 	}
1835 
1836 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1837 	return all_err;
1838 }
1839 
1840 static int
1841 test_inline_macsec_auth_only_stats(const void *data __rte_unused)
1842 {
1843 	const struct mcs_test_vector *cur_td;
1844 	struct mcs_test_opts opts = {0};
1845 	int err, all_err = 0;
1846 	int i, size;
1847 
1848 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1849 	opts.protect_frames = true;
1850 	opts.sa_in_use = 1;
1851 	opts.nb_td = 1;
1852 	opts.sectag_insert_mode = 1;
1853 	opts.mtu = RTE_ETHER_MTU;
1854 	opts.check_auth_only_stats = 1;
1855 
1856 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1857 
1858 	for (i = 0; i < size; i++) {
1859 		cur_td = &list_mcs_integrity_vectors[i];
1860 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
1861 		if (err)
1862 			err = -1;
1863 		else
1864 			err = 0;
1865 		all_err += err;
1866 	}
1867 
1868 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1869 	return all_err;
1870 }
1871 
1872 static int
1873 test_inline_macsec_interrupts_all(const void *data __rte_unused)
1874 {
1875 	struct mcs_err_vector err_vector = {0};
1876 	const struct mcs_test_vector *cur_td;
1877 	struct mcs_test_opts opts = {0};
1878 	int i, size;
1879 	int err, all_err = 0;
1880 	enum rte_eth_event_macsec_subtype subtype[] =  {
1881 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1,
1882 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1,
1883 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48,
1884 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1,
1885 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1,
1886 	};
1887 
1888 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1889 	opts.protect_frames = true;
1890 	opts.sa_in_use = 1;
1891 	opts.nb_td = 1;
1892 	opts.sectag_insert_mode = 1;
1893 	opts.mtu = RTE_ETHER_MTU;
1894 	opts.check_sectag_interrupts = 1;
1895 
1896 	err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN;
1897 	err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN;
1898 	rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC,
1899 			test_macsec_event_callback, &err_vector);
1900 
1901 	size = (sizeof(list_mcs_intr_test_vectors) / sizeof((list_mcs_intr_test_vectors)[0]));
1902 
1903 	for (i = 0; i < size; i++) {
1904 		cur_td = &list_mcs_intr_test_vectors[i];
1905 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1906 		if ((err_vector.event == RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR) &&
1907 		    (err_vector.event_subtype == subtype[i])) {
1908 			printf("\nSectag val err interrupt test case %d passed",
1909 			       cur_td->test_idx);
1910 			err = 0;
1911 		} else {
1912 			printf("\nSectag val err interrupt test case %d failed",
1913 			       cur_td->test_idx);
1914 			err = -1;
1915 		}
1916 		all_err += err;
1917 	}
1918 	rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
1919 			test_macsec_event_callback, &err_vector);
1920 
1921 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1922 	return all_err;
1923 }
1924 
1925 static int
1926 test_inline_macsec_rekey_tx(const void *data __rte_unused)
1927 {
1928 	const struct mcs_test_vector *cur_td;
1929 	struct mcs_test_opts opts = {0};
1930 	int err, all_err = 0;
1931 	int i, size;
1932 
1933 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1934 	opts.protect_frames = true;
1935 	opts.encrypt = true;
1936 	opts.sa_in_use = 1;
1937 	opts.nb_td = 1;
1938 	opts.sectag_insert_mode = 1;
1939 	opts.mtu = RTE_ETHER_MTU;
1940 	opts.rekey_en = 1;
1941 
1942 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
1943 
1944 	for (i = 0; i < size; i++) {
1945 		cur_td = &list_mcs_rekey_vectors[i];
1946 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
1947 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1948 		if (err) {
1949 			printf("Tx hw rekey test case %d failed\n", i);
1950 			err = -1;
1951 		} else {
1952 			printf("Tx hw rekey test case %d passed\n", i);
1953 			err = 0;
1954 		}
1955 		all_err += err;
1956 	}
1957 
1958 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1959 	return all_err;
1960 }
1961 
1962 static int
1963 test_inline_macsec_rekey_rx(const void *data __rte_unused)
1964 {
1965 	const struct mcs_test_vector *cur_td;
1966 	struct mcs_test_opts opts = {0};
1967 	int err, all_err = 0;
1968 	int i, size;
1969 
1970 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1971 	opts.protect_frames = true;
1972 	opts.sa_in_use = 1;
1973 	opts.nb_td = 1;
1974 	opts.sectag_insert_mode = 1;
1975 	opts.mtu = RTE_ETHER_MTU;
1976 	opts.rekey_en = 1;
1977 
1978 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
1979 	for (i = 0; i < size; i++) {
1980 		cur_td = &list_mcs_rekey_vectors[i];
1981 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
1982 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1983 		if (err) {
1984 			printf("Rx rekey test case %d failed\n", i);
1985 			err = -1;
1986 		} else {
1987 			printf("Rx rekey test case %d passed\n", i);
1988 			err = 0;
1989 		}
1990 		all_err += err;
1991 	}
1992 
1993 	printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err);
1994 	return all_err;
1995 }
1996 
1997 static int
1998 ut_setup_inline_macsec(void)
1999 {
2000 	int ret;
2001 
2002 	/* Start device */
2003 	ret = rte_eth_dev_start(port_id);
2004 	if (ret < 0) {
2005 		printf("rte_eth_dev_start: err=%d, port=%d\n",
2006 			ret, port_id);
2007 		return ret;
2008 	}
2009 	/* always enable promiscuous */
2010 	ret = rte_eth_promiscuous_enable(port_id);
2011 	if (ret != 0) {
2012 		printf("rte_eth_promiscuous_enable: err=%s, port=%d\n",
2013 			rte_strerror(-ret), port_id);
2014 		return ret;
2015 	}
2016 
2017 	check_all_ports_link_status(1, RTE_PORT_ALL);
2018 
2019 	return 0;
2020 }
2021 
2022 static void
2023 ut_teardown_inline_macsec(void)
2024 {
2025 	uint16_t portid;
2026 	int ret;
2027 
2028 	/* port tear down */
2029 	RTE_ETH_FOREACH_DEV(portid) {
2030 		ret = rte_eth_dev_stop(portid);
2031 		if (ret != 0)
2032 			printf("rte_eth_dev_stop: err=%s, port=%u\n",
2033 			       rte_strerror(-ret), portid);
2034 
2035 	}
2036 }
2037 
2038 static int
2039 inline_macsec_testsuite_setup(void)
2040 {
2041 	uint16_t nb_rxd;
2042 	uint16_t nb_txd;
2043 	uint16_t nb_ports;
2044 	int ret;
2045 	uint16_t nb_rx_queue = 1, nb_tx_queue = 1;
2046 
2047 	printf("Start inline MACsec test.\n");
2048 
2049 	nb_ports = rte_eth_dev_count_avail();
2050 	if (nb_ports < NB_ETHPORTS_USED) {
2051 		printf("At least %u port(s) used for test\n",
2052 		       NB_ETHPORTS_USED);
2053 		return TEST_SKIPPED;
2054 	}
2055 
2056 	ret = init_mempools(NB_MBUF);
2057 	if (ret)
2058 		return ret;
2059 
2060 	if (tx_pkts_burst == NULL) {
2061 		tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff",
2062 					  MAX_TRAFFIC_BURST,
2063 					  sizeof(void *),
2064 					  RTE_CACHE_LINE_SIZE);
2065 		if (!tx_pkts_burst)
2066 			return TEST_FAILED;
2067 
2068 		rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff",
2069 					  MAX_TRAFFIC_BURST,
2070 					  sizeof(void *),
2071 					  RTE_CACHE_LINE_SIZE);
2072 		if (!rx_pkts_burst)
2073 			return TEST_FAILED;
2074 	}
2075 
2076 	printf("Generate %d packets\n", MAX_TRAFFIC_BURST);
2077 
2078 	nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
2079 	nb_txd = RTE_TEST_TX_DESC_DEFAULT;
2080 
2081 	/* configuring port 0 for the test is enough */
2082 	port_id = 0;
2083 	/* port configure */
2084 	ret = rte_eth_dev_configure(port_id, nb_rx_queue,
2085 				    nb_tx_queue, &port_conf);
2086 	if (ret < 0) {
2087 		printf("Cannot configure device: err=%d, port=%d\n",
2088 			 ret, port_id);
2089 		return ret;
2090 	}
2091 	ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]);
2092 	if (ret < 0) {
2093 		printf("Cannot get mac address: err=%d, port=%d\n",
2094 			 ret, port_id);
2095 		return ret;
2096 	}
2097 	printf("Port %u ", port_id);
2098 	print_ethaddr("Address:", &ports_eth_addr[port_id]);
2099 	printf("\n");
2100 
2101 	/* tx queue setup */
2102 	ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
2103 				     SOCKET_ID_ANY, &tx_conf);
2104 	if (ret < 0) {
2105 		printf("rte_eth_tx_queue_setup: err=%d, port=%d\n",
2106 				ret, port_id);
2107 		return ret;
2108 	}
2109 	/* rx queue steup */
2110 	ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY,
2111 				     &rx_conf, mbufpool);
2112 	if (ret < 0) {
2113 		printf("rte_eth_rx_queue_setup: err=%d, port=%d\n",
2114 				ret, port_id);
2115 		return ret;
2116 	}
2117 
2118 	return 0;
2119 }
2120 
2121 static void
2122 inline_macsec_testsuite_teardown(void)
2123 {
2124 	uint16_t portid;
2125 	int ret;
2126 
2127 	/* port tear down */
2128 	RTE_ETH_FOREACH_DEV(portid) {
2129 		ret = rte_eth_dev_reset(portid);
2130 		if (ret != 0)
2131 			printf("rte_eth_dev_reset: err=%s, port=%u\n",
2132 			       rte_strerror(-ret), port_id);
2133 	}
2134 	rte_free(tx_pkts_burst);
2135 	rte_free(rx_pkts_burst);
2136 }
2137 
2138 
2139 static struct unit_test_suite inline_macsec_testsuite  = {
2140 	.suite_name = "Inline MACsec Ethernet Device Unit Test Suite",
2141 	.unit_test_cases = {
2142 		TEST_CASE_NAMED_ST(
2143 			"MACsec Encap + decap Multi flow",
2144 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2145 			test_inline_macsec_multi_flow),
2146 		TEST_CASE_NAMED_ST(
2147 			"MACsec encap(Cipher+Auth) known vector",
2148 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2149 			test_inline_macsec_encap_all),
2150 		TEST_CASE_NAMED_ST(
2151 			"MACsec decap(De-cipher+verify) known vector",
2152 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2153 			test_inline_macsec_decap_all),
2154 		TEST_CASE_NAMED_ST(
2155 			"MACsec auth only known vector",
2156 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2157 			test_inline_macsec_auth_only_all),
2158 		TEST_CASE_NAMED_ST(
2159 			"MACsec verify only known vector",
2160 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2161 			test_inline_macsec_verify_only_all),
2162 		TEST_CASE_NAMED_ST(
2163 			"MACsec encap + decap known vector",
2164 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2165 			test_inline_macsec_encap_decap_all),
2166 		TEST_CASE_NAMED_ST(
2167 			"MACsec auth + verify known vector",
2168 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2169 			test_inline_macsec_auth_verify_all),
2170 		TEST_CASE_NAMED_ST(
2171 			"MACsec Encap and decap with VLAN",
2172 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2173 			test_inline_macsec_with_vlan),
2174 		TEST_CASE_NAMED_ST(
2175 			"MACsec packet drop",
2176 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2177 			test_inline_macsec_pkt_drop),
2178 		TEST_CASE_NAMED_ST(
2179 			"MACsec untagged Rx",
2180 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2181 			test_inline_macsec_untagged_rx),
2182 		TEST_CASE_NAMED_ST(
2183 			"MACsec bad tag Rx",
2184 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2185 			test_inline_macsec_bad_tag_rx),
2186 		TEST_CASE_NAMED_ST(
2187 			"MACsec SA not in use",
2188 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2189 			test_inline_macsec_sa_not_in_use),
2190 		TEST_CASE_NAMED_ST(
2191 			"MACsec decap stats",
2192 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2193 			test_inline_macsec_decap_stats),
2194 		TEST_CASE_NAMED_ST(
2195 			"MACsec verify only stats",
2196 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2197 			test_inline_macsec_verify_only_stats),
2198 		TEST_CASE_NAMED_ST(
2199 			"MACsec pkts invalid stats",
2200 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2201 			test_inline_macsec_pkts_invalid_stats),
2202 		TEST_CASE_NAMED_ST(
2203 			"MACsec pkts unchecked stats",
2204 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2205 			test_inline_macsec_pkts_unchecked_stats),
2206 		TEST_CASE_NAMED_ST(
2207 			"MACsec out pkts untagged",
2208 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2209 			test_inline_macsec_out_pkts_untagged),
2210 		TEST_CASE_NAMED_ST(
2211 			"MACsec out pkts too long",
2212 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2213 			test_inline_macsec_out_pkts_toolong),
2214 		TEST_CASE_NAMED_ST(
2215 			"MACsec Encap stats",
2216 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2217 			test_inline_macsec_encap_stats),
2218 		TEST_CASE_NAMED_ST(
2219 			"MACsec auth only stats",
2220 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2221 			test_inline_macsec_auth_only_stats),
2222 		TEST_CASE_NAMED_ST(
2223 			"MACsec interrupts all",
2224 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2225 			test_inline_macsec_interrupts_all),
2226 		TEST_CASE_NAMED_ST(
2227 			"MACsec re-key Tx",
2228 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2229 			test_inline_macsec_rekey_tx),
2230 		TEST_CASE_NAMED_ST(
2231 			"MACsec re-key Rx",
2232 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2233 			test_inline_macsec_rekey_rx),
2234 
2235 		TEST_CASES_END() /**< NULL terminate unit test array */
2236 	},
2237 };
2238 
2239 static int
2240 test_inline_macsec(void)
2241 {
2242 	inline_macsec_testsuite.setup = inline_macsec_testsuite_setup;
2243 	inline_macsec_testsuite.teardown = inline_macsec_testsuite_teardown;
2244 	return unit_test_suite_runner(&inline_macsec_testsuite);
2245 }
2246 
2247 #endif /* !RTE_EXEC_ENV_WINDOWS */
2248 
2249 REGISTER_TEST_COMMAND(inline_macsec_autotest, test_inline_macsec);
2250