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