xref: /dpdk/app/test/test_security_inline_macsec.c (revision e0d947a1e6c2f80aa039a4f7082a8aa16797d8b9)
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 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
322 		.hdr.src_addr.addr_bytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 			rte_pktmbuf_free_bulk(tx_pkts_burst, j);
956 			ret = TEST_FAILED;
957 			goto out;
958 		}
959 		j++;
960 
961 		if (opts->replay_protect) {
962 			for (k = 0; k < 3; k++, j++) {
963 				tx_pkts_burst[j] = init_packet(mbufpool,
964 					opts->ar_td[k]->secure_pkt.data,
965 					opts->ar_td[k]->secure_pkt.len);
966 				if (tx_pkts_burst[j] == NULL) {
967 					rte_pktmbuf_free_bulk(tx_pkts_burst, j);
968 					ret = TEST_FAILED;
969 					goto out;
970 				}
971 			}
972 		}
973 
974 		if (opts->rekey_en) {
975 
976 			err_vector.td = td[i];
977 			err_vector.rekey_td = opts->rekey_td;
978 			err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN;
979 			err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN;
980 			rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC,
981 					test_macsec_event_callback, &err_vector);
982 			if (op == MCS_DECAP || op == MCS_VERIFY_ONLY)
983 				tx_pkts_burst[j] = init_packet(mbufpool,
984 						opts->rekey_td->secure_pkt.data,
985 						opts->rekey_td->secure_pkt.len);
986 			else {
987 				tx_pkts_burst[j] = init_packet(mbufpool,
988 						opts->rekey_td->plain_pkt.data,
989 						opts->rekey_td->plain_pkt.len);
990 
991 				tx_pkts_burst[j]->ol_flags |= RTE_MBUF_F_TX_MACSEC;
992 			}
993 			if (tx_pkts_burst[j] == NULL) {
994 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
995 				ret = TEST_FAILED;
996 				goto out;
997 			}
998 			j++;
999 		}
1000 
1001 		if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
1002 				op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
1003 			for (an = 0; an < RTE_SECURITY_MACSEC_NUM_AN; an++) {
1004 				if (opts->rekey_en && an ==
1005 						(opts->rekey_td->secure_pkt.data[tci_off] &
1006 						RTE_MACSEC_AN_MASK))
1007 					fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
1008 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
1009 				else
1010 				/* For simplicity, using same SA conf for all AN */
1011 					fill_macsec_sa_conf(td[i], &sa_conf,
1012 						RTE_SECURITY_MACSEC_DIR_RX, an, tci_off);
1013 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
1014 				if (id < 0) {
1015 					printf("MACsec SA create failed : %d.\n", id);
1016 					rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1017 					ret = TEST_FAILED;
1018 					goto out;
1019 				}
1020 				rx_sa_id[i][an] = (uint16_t)id;
1021 			}
1022 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
1023 					RTE_SECURITY_MACSEC_DIR_RX, rx_sa_id[i], tci_off);
1024 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
1025 			if (id < 0) {
1026 				printf("MACsec SC create failed : %d.\n", id);
1027 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1028 				ret = TEST_FAILED;
1029 				goto out;
1030 			}
1031 			rx_sc_id[i] = (uint16_t)id;
1032 
1033 			/* Create Inline IPsec session. */
1034 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
1035 					RTE_SECURITY_MACSEC_DIR_RX, rx_sc_id[i], tci_off);
1036 			if (ret) {
1037 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1038 				ret = TEST_FAILED;
1039 				goto out;
1040 			}
1041 			rx_sess[i] = rte_security_session_create(ctx, &sess_conf,
1042 					sess_pool);
1043 			if (rx_sess[i] == NULL) {
1044 				printf("SEC Session init failed.\n");
1045 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1046 				ret = TEST_FAILED;
1047 				goto out;
1048 			}
1049 			ret = create_default_flow(td[i], port_id,
1050 					RTE_SECURITY_MACSEC_DIR_RX, rx_sess[i]);
1051 			if (ret) {
1052 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1053 				ret = TEST_FAILED;
1054 				goto out;
1055 			}
1056 		}
1057 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
1058 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
1059 			int id;
1060 
1061 			fill_macsec_sa_conf(td[i], &sa_conf,
1062 					RTE_SECURITY_MACSEC_DIR_TX,
1063 					td[i]->secure_pkt.data[tci_off] & RTE_MACSEC_AN_MASK,
1064 					tci_off);
1065 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
1066 			if (id < 0) {
1067 				printf("MACsec SA create failed : %d.\n", id);
1068 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1069 				ret = TEST_FAILED;
1070 				goto out;
1071 			}
1072 			tx_sa_id[i][0] = (uint16_t)id;
1073 			tx_sa_id[i][1] = MCS_INVALID_SA;
1074 			if (opts->rekey_en) {
1075 				memset(&sa_conf, 0, sizeof(struct rte_security_macsec_sa));
1076 				fill_macsec_sa_conf(opts->rekey_td, &sa_conf,
1077 					RTE_SECURITY_MACSEC_DIR_TX,
1078 					opts->rekey_td->secure_pkt.data[tci_off] &
1079 						RTE_MACSEC_AN_MASK,
1080 					tci_off);
1081 				id = rte_security_macsec_sa_create(ctx, &sa_conf);
1082 				if (id < 0) {
1083 					printf("MACsec rekey SA create failed : %d.\n", id);
1084 					rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1085 					ret = TEST_FAILED;
1086 					goto out;
1087 				}
1088 				tx_sa_id[i][1] = (uint16_t)id;
1089 			}
1090 			fill_macsec_sc_conf(td[i], &sc_conf, opts,
1091 					RTE_SECURITY_MACSEC_DIR_TX, tx_sa_id[i], tci_off);
1092 			id = rte_security_macsec_sc_create(ctx, &sc_conf);
1093 			if (id < 0) {
1094 				printf("MACsec SC create failed : %d.\n", id);
1095 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1096 				ret = TEST_FAILED;
1097 				goto out;
1098 			}
1099 			tx_sc_id[i] = (uint16_t)id;
1100 
1101 			/* Create Inline IPsec session. */
1102 			ret = fill_session_conf(td[i], port_id, opts, &sess_conf,
1103 					RTE_SECURITY_MACSEC_DIR_TX, tx_sc_id[i], tci_off);
1104 			if (ret) {
1105 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1106 				ret = TEST_FAILED;
1107 				goto out;
1108 			}
1109 			tx_sess[i] = rte_security_session_create(ctx, &sess_conf,
1110 					sess_pool);
1111 			if (tx_sess[i] == NULL) {
1112 				printf("SEC Session init failed.\n");
1113 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1114 				ret = TEST_FAILED;
1115 				goto out;
1116 			}
1117 			ret = create_default_flow(td[i], port_id,
1118 					RTE_SECURITY_MACSEC_DIR_TX, tx_sess[i]);
1119 			if (ret) {
1120 				rte_pktmbuf_free_bulk(tx_pkts_burst, j);
1121 				ret = TEST_FAILED;
1122 				goto out;
1123 			}
1124 		}
1125 	}
1126 
1127 	/* Send packet to ethdev for inline MACsec processing. */
1128 	nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, j);
1129 
1130 	if (nb_sent != j) {
1131 		printf("\nUnable to TX %d packets, sent: %i", j, nb_sent);
1132 		for ( ; nb_sent < j; nb_sent++)
1133 			rte_pktmbuf_free(tx_pkts_burst[nb_sent]);
1134 		ret = TEST_FAILED;
1135 		goto out;
1136 	}
1137 
1138 	rte_pause();
1139 
1140 	j = 0;
1141 	/* Receive back packet on loopback interface. */
1142 	do {
1143 		nb_rx += rte_eth_rx_burst(port_id, 0,
1144 				&rx_pkts_burst[nb_rx],
1145 				nb_sent - nb_rx);
1146 		if (nb_rx >= nb_sent)
1147 			break;
1148 		rte_delay_ms(1);
1149 	} while (j++ < 5 && nb_rx == 0);
1150 
1151 	if (nb_rx != nb_sent) {
1152 		printf("\nUnable to RX all %d packets, received(%i)",
1153 				nb_sent, nb_rx);
1154 		rte_pktmbuf_free_bulk(rx_pkts_burst, nb_rx);
1155 		ret = TEST_FAILED;
1156 		if (opts->check_sectag_interrupts == 1)
1157 			ret = TEST_SUCCESS;
1158 		goto out;
1159 	}
1160 
1161 	if (opts->rekey_en) {
1162 		switch (err_vector.event) {
1163 		case RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP:
1164 			printf("Received RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP event\n");
1165 			/* The first sa is active now, so the 0th sa can be
1166 			 * reconfigured. Using the same key as zeroeth sa, but
1167 			 * other key can also be configured.
1168 			 */
1169 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[0][0],
1170 					RTE_SECURITY_MACSEC_DIR_TX);
1171 			fill_macsec_sa_conf(td[0], &sa_conf,
1172 					RTE_SECURITY_MACSEC_DIR_TX,
1173 					td[0]->secure_pkt.data[tci_off] &
1174 					RTE_MACSEC_AN_MASK, tci_off);
1175 			id = rte_security_macsec_sa_create(ctx, &sa_conf);
1176 			if (id < 0) {
1177 				printf("MACsec SA create failed : %d.\n", id);
1178 				rte_pktmbuf_free_bulk(rx_pkts_burst, nb_rx);
1179 				ret = TEST_FAILED;
1180 				goto out;
1181 			}
1182 			tx_sa_id[0][0] = (uint16_t)id;
1183 			break;
1184 		case RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP:
1185 			printf("Received RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP event\n");
1186 			break;
1187 		default:
1188 			printf("Received unsupported event\n");
1189 		}
1190 	}
1191 
1192 	if (opts->replay_protect) {
1193 		for (i = 0; i < nb_rx; i++) {
1194 			rte_pktmbuf_free(rx_pkts_burst[i]);
1195 			rx_pkts_burst[i] = NULL;
1196 		}
1197 		ret = TEST_SUCCESS;
1198 		goto out;
1199 	}
1200 
1201 	for (i = 0; i < nb_rx; i++) {
1202 		if (opts->rekey_en && i == 1) {
1203 			/* The second received packet is matched with
1204 			 * rekey td
1205 			 */
1206 			ret = test_macsec_post_process(rx_pkts_burst[i],
1207 					opts->rekey_td, op,
1208 					opts->check_out_pkts_untagged);
1209 		} else {
1210 			ret = test_macsec_post_process(rx_pkts_burst[i], td[i],
1211 					op, opts->check_out_pkts_untagged);
1212 		}
1213 		if (ret != TEST_SUCCESS) {
1214 			for ( ; i < nb_rx; i++)
1215 				rte_pktmbuf_free(rx_pkts_burst[i]);
1216 			goto out;
1217 		}
1218 
1219 		rte_pktmbuf_free(rx_pkts_burst[i]);
1220 		rx_pkts_burst[i] = NULL;
1221 	}
1222 out:
1223 	if (opts->check_out_pkts_toolong == 1 ||
1224 			opts->check_sa_not_in_use == 1 ||
1225 			opts->check_bad_tag_cnt == 1)
1226 		ret = TEST_SUCCESS;
1227 
1228 	for (i = 0; i < opts->nb_td; i++) {
1229 		if (opts->dump_all_stats) {
1230 			mcs_stats_dump(ctx, op,
1231 					rx_sess[i], tx_sess[i],
1232 					rx_sc_id[i], tx_sc_id[i],
1233 					rx_sa_id[i], tx_sa_id[i]);
1234 		} else {
1235 			if (ret == TEST_SUCCESS)
1236 				ret = mcs_stats_check(ctx, op, opts, td[i],
1237 					rx_sess[i], tx_sess[i],
1238 					rx_sc_id[i], tx_sc_id[i],
1239 					rx_sa_id[i], tx_sa_id[i]);
1240 		}
1241 	}
1242 
1243 	destroy_default_flow(port_id);
1244 
1245 	if (opts->rekey_en)
1246 		rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
1247 					test_macsec_event_callback, &err_vector);
1248 
1249 	/* Destroy session so that other cases can create the session again */
1250 	for (i = 0; i < opts->nb_td; i++) {
1251 		if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP ||
1252 				op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) {
1253 			rte_security_session_destroy(ctx, tx_sess[i]);
1254 			tx_sess[i] = NULL;
1255 			rte_security_macsec_sc_destroy(ctx, tx_sc_id[i],
1256 						RTE_SECURITY_MACSEC_DIR_TX);
1257 			rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][0],
1258 						RTE_SECURITY_MACSEC_DIR_TX);
1259 			if (opts->rekey_en) {
1260 				rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][1],
1261 						RTE_SECURITY_MACSEC_DIR_TX);
1262 			}
1263 		}
1264 		if (op == MCS_DECAP || op == MCS_ENCAP_DECAP ||
1265 				op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) {
1266 			rte_security_session_destroy(ctx, rx_sess[i]);
1267 			rx_sess[i] = NULL;
1268 			rte_security_macsec_sc_destroy(ctx, rx_sc_id[i],
1269 						RTE_SECURITY_MACSEC_DIR_RX);
1270 			for (j = 0; j < RTE_SECURITY_MACSEC_NUM_AN; j++) {
1271 				rte_security_macsec_sa_destroy(ctx, rx_sa_id[i][j],
1272 						RTE_SECURITY_MACSEC_DIR_RX);
1273 			}
1274 		}
1275 	}
1276 
1277 	return ret;
1278 }
1279 
1280 static int
1281 test_inline_macsec_encap_all(void)
1282 {
1283 	const struct mcs_test_vector *cur_td;
1284 	struct mcs_test_opts opts = {0};
1285 	int err, all_err = 0;
1286 	int skipped = 0;
1287 	int i, size;
1288 
1289 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1290 	opts.encrypt = true;
1291 	opts.protect_frames = true;
1292 	opts.sa_in_use = 1;
1293 	opts.nb_td = 1;
1294 	opts.sectag_insert_mode = 1;
1295 	opts.mtu = RTE_ETHER_MTU;
1296 
1297 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1298 	for (i = 0; i < size; i++) {
1299 		cur_td = &list_mcs_cipher_vectors[i];
1300 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1301 		if (err == TEST_SKIPPED) {
1302 			printf("Cipher Auth Encryption case %d skipped\n", cur_td->test_idx);
1303 			skipped += 1;
1304 			err = 0;
1305 		} else if (err) {
1306 			printf("\nCipher Auth Encryption case %d failed", cur_td->test_idx);
1307 			err = -1;
1308 		} else {
1309 			printf("\nCipher Auth Encryption case %d Passed", cur_td->test_idx);
1310 			err = 0;
1311 		}
1312 		all_err += err;
1313 	}
1314 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1315 			size + all_err - skipped, -all_err, skipped);
1316 
1317 	return skipped > 0 ? TEST_SKIPPED : all_err;
1318 }
1319 
1320 static int
1321 test_inline_macsec_decap_all(void)
1322 {
1323 	const struct mcs_test_vector *cur_td;
1324 	struct mcs_test_opts opts = {0};
1325 	int err, all_err = 0;
1326 	int skipped = 0;
1327 	int i, size;
1328 
1329 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1330 	opts.sa_in_use = 1;
1331 	opts.nb_td = 1;
1332 	opts.sectag_insert_mode = 1;
1333 	opts.mtu = RTE_ETHER_MTU;
1334 
1335 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1336 	for (i = 0; i < size; i++) {
1337 		cur_td = &list_mcs_cipher_vectors[i];
1338 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1339 		if (err == TEST_SKIPPED) {
1340 			printf("Cipher Auth Decryption case %d skipped\n", cur_td->test_idx);
1341 			skipped += 1;
1342 			err = 0;
1343 		} else if (err) {
1344 			printf("\nCipher Auth Decryption case %d failed", cur_td->test_idx);
1345 			err = -1;
1346 		} else {
1347 			printf("\nCipher Auth Decryption case %d Passed", cur_td->test_idx);
1348 			err = 0;
1349 		}
1350 		all_err += err;
1351 	}
1352 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1353 			size + all_err - skipped, -all_err, skipped);
1354 
1355 	return skipped > 0 ? TEST_SKIPPED : all_err;
1356 }
1357 
1358 static int
1359 test_inline_macsec_auth_only_all(void)
1360 {
1361 	const struct mcs_test_vector *cur_td;
1362 	struct mcs_test_opts opts = {0};
1363 	int err, all_err = 0;
1364 	int skipped = 0;
1365 	int i, size;
1366 
1367 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1368 	opts.protect_frames = true;
1369 	opts.sa_in_use = 1;
1370 	opts.nb_td = 1;
1371 	opts.sectag_insert_mode = 1;
1372 	opts.mtu = RTE_ETHER_MTU;
1373 
1374 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1375 
1376 	for (i = 0; i < size; i++) {
1377 		cur_td = &list_mcs_integrity_vectors[i];
1378 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
1379 		if (err == TEST_SKIPPED) {
1380 			printf("Auth Generate case %d skipped\n", cur_td->test_idx);
1381 			skipped += 1;
1382 			err = 0;
1383 		} else if (err) {
1384 			printf("\nAuth Generate case %d failed", cur_td->test_idx);
1385 			err = -1;
1386 		} else {
1387 			printf("\nAuth Generate case %d Passed", cur_td->test_idx);
1388 			err = 0;
1389 		}
1390 		all_err += err;
1391 	}
1392 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1393 			size + all_err - skipped, -all_err, skipped);
1394 
1395 	return skipped > 0 ? TEST_SKIPPED : all_err;
1396 }
1397 
1398 static int
1399 test_inline_macsec_verify_only_all(void)
1400 {
1401 	const struct mcs_test_vector *cur_td;
1402 	struct mcs_test_opts opts = {0};
1403 	int err, all_err = 0;
1404 	int skipped = 0;
1405 	int i, size;
1406 
1407 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1408 	opts.sa_in_use = 1;
1409 	opts.nb_td = 1;
1410 	opts.sectag_insert_mode = 1;
1411 	opts.mtu = RTE_ETHER_MTU;
1412 
1413 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1414 
1415 	for (i = 0; i < size; i++) {
1416 		cur_td = &list_mcs_integrity_vectors[i];
1417 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1418 		if (err == TEST_SKIPPED) {
1419 			printf("Auth Verify case %d skipped\n", cur_td->test_idx);
1420 			skipped += 1;
1421 			err = 0;
1422 		} else if (err) {
1423 			printf("\nAuth Verify case %d failed", cur_td->test_idx);
1424 			err = -1;
1425 		} else {
1426 			printf("\nAuth Verify case %d Passed", cur_td->test_idx);
1427 			err = 0;
1428 		}
1429 		all_err += err;
1430 	}
1431 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1432 			size + all_err - skipped, -all_err, skipped);
1433 
1434 	return skipped > 0 ? TEST_SKIPPED : all_err;
1435 }
1436 
1437 static int
1438 test_inline_macsec_encap_decap_all(void)
1439 {
1440 	const struct mcs_test_vector *cur_td;
1441 	struct mcs_test_opts opts = {0};
1442 	int err, all_err = 0;
1443 	int skipped = 0;
1444 	int i, size;
1445 
1446 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1447 	opts.encrypt = true;
1448 	opts.protect_frames = true;
1449 	opts.sa_in_use = 1;
1450 	opts.nb_td = 1;
1451 	opts.sectag_insert_mode = 1;
1452 	opts.mtu = RTE_ETHER_MTU;
1453 
1454 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1455 
1456 	for (i = 0; i < size; i++) {
1457 		cur_td = &list_mcs_cipher_vectors[i];
1458 		err = test_macsec(&cur_td, MCS_ENCAP_DECAP, &opts);
1459 		if (err == TEST_SKIPPED) {
1460 			printf("Cipher Auth Encap-decap case %d skipped\n", cur_td->test_idx);
1461 			skipped += 1;
1462 			err = 0;
1463 		} else if (err) {
1464 			printf("\nCipher Auth Encap-decap case %d failed", cur_td->test_idx);
1465 			err = -1;
1466 		} else {
1467 			printf("\nCipher Auth Encap-decap case %d Passed", cur_td->test_idx);
1468 			err = 0;
1469 		}
1470 		all_err += err;
1471 	}
1472 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1473 			size + all_err - skipped, -all_err, skipped);
1474 
1475 	return skipped > 0 ? TEST_SKIPPED : all_err;
1476 }
1477 
1478 
1479 static int
1480 test_inline_macsec_auth_verify_all(void)
1481 {
1482 	const struct mcs_test_vector *cur_td;
1483 	struct mcs_test_opts opts = {0};
1484 	int err, all_err = 0;
1485 	int skipped = 0;
1486 	int i, size;
1487 
1488 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1489 	opts.protect_frames = true;
1490 	opts.sa_in_use = 1;
1491 	opts.nb_td = 1;
1492 	opts.sectag_insert_mode = 1;
1493 	opts.mtu = RTE_ETHER_MTU;
1494 
1495 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1496 
1497 	for (i = 0; i < size; i++) {
1498 		cur_td = &list_mcs_integrity_vectors[i];
1499 		err = test_macsec(&cur_td, MCS_AUTH_VERIFY, &opts);
1500 		if (err == TEST_SKIPPED) {
1501 			printf("Auth Generate + Verify case %d skipped\n", cur_td->test_idx);
1502 			skipped += 1;
1503 			err = 0;
1504 		} else if (err) {
1505 			printf("\nAuth Generate + Verify case %d failed", cur_td->test_idx);
1506 			err = -1;
1507 		} else {
1508 			printf("\nAuth Generate + Verify case %d Passed", cur_td->test_idx);
1509 			err = 0;
1510 		}
1511 		all_err += err;
1512 	}
1513 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1514 			size + all_err - skipped, -all_err, skipped);
1515 
1516 	return skipped > 0 ? TEST_SKIPPED : all_err;
1517 }
1518 
1519 static int
1520 test_inline_macsec_multi_flow(void)
1521 {
1522 	const struct mcs_test_vector *tv[MCS_MAX_FLOWS];
1523 	struct mcs_test_vector iter[MCS_MAX_FLOWS];
1524 	struct mcs_test_opts opts = {0};
1525 	int i, err;
1526 
1527 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1528 	opts.encrypt = true;
1529 	opts.protect_frames = true;
1530 	opts.sa_in_use = 1;
1531 	opts.nb_td = MCS_MAX_FLOWS;
1532 	opts.sectag_insert_mode = 1;
1533 	opts.mtu = RTE_ETHER_MTU;
1534 
1535 	for (i = 0; i < MCS_MAX_FLOWS; i++) {
1536 		memcpy(&iter[i].sa_key.data, sa_key, MCS_MULTI_FLOW_TD_KEY_SZ);
1537 		memcpy(&iter[i].plain_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1538 		memcpy(&iter[i].plain_pkt.data[2 * RTE_ETHER_ADDR_LEN], plain_user_data,
1539 		       MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ);
1540 		memcpy(&iter[i].secure_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN);
1541 		memcpy(&iter[i].secure_pkt.data[2 * RTE_ETHER_ADDR_LEN], secure_user_data,
1542 		       MCS_MULTI_FLOW_TD_SECURE_DATA_SZ);
1543 		iter[i].sa_key.len = MCS_MULTI_FLOW_TD_KEY_SZ;
1544 		iter[i].plain_pkt.len = MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ +
1545 					(2 * RTE_ETHER_ADDR_LEN);
1546 		iter[i].secure_pkt.len = MCS_MULTI_FLOW_TD_SECURE_DATA_SZ +
1547 					(2 * RTE_ETHER_ADDR_LEN);
1548 		iter[i].alg = RTE_SECURITY_MACSEC_ALG_GCM_128;
1549 		iter[i].ssci = 0x0;
1550 		iter[i].xpn = 0x0;
1551 		tv[i] = (const struct mcs_test_vector *)&iter[i];
1552 	}
1553 	err = test_macsec(tv, MCS_ENCAP_DECAP, &opts);
1554 	if (err == TEST_SKIPPED) {
1555 		printf("Cipher Auth Encryption multi flow skipped\n");
1556 	} else if (err) {
1557 		printf("\nCipher Auth Encryption multi flow failed");
1558 		err = -1;
1559 	} else {
1560 		printf("\nCipher Auth Encryption multi flow Passed");
1561 		err = 0;
1562 	}
1563 	return err;
1564 }
1565 
1566 static int
1567 test_inline_macsec_with_vlan(void)
1568 {
1569 	const struct mcs_test_vector *cur_td;
1570 	struct mcs_test_opts opts = {0};
1571 	int err, all_err = 0;
1572 	int skipped = 0;
1573 	int i, size;
1574 
1575 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1576 	opts.protect_frames = true;
1577 	opts.sa_in_use = 1;
1578 	opts.nb_td = 1;
1579 	opts.mtu = RTE_ETHER_MTU;
1580 
1581 	size = (sizeof(list_mcs_vlan_vectors) / sizeof((list_mcs_vlan_vectors)[0]));
1582 
1583 	for (i = 0; i < size; i++) {
1584 		cur_td = &list_mcs_vlan_vectors[i];
1585 		if (i == 0) {
1586 			opts.sectag_insert_mode = 1;
1587 		} else if (i == 1) {
1588 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1589 			opts.nb_vlan = 1;
1590 		} else if (i == 2) {
1591 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1592 			opts.nb_vlan = 2;
1593 		}
1594 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1595 		if (err == TEST_SKIPPED) {
1596 			printf("VLAN Encap case %d skipped", cur_td->test_idx);
1597 			skipped += 1;
1598 			err = 0;
1599 		} else if (err) {
1600 			printf("\n VLAN Encap case %d failed", cur_td->test_idx);
1601 			err = -1;
1602 		} else {
1603 			printf("\n VLAN Encap case %d passed", cur_td->test_idx);
1604 			err = 0;
1605 		}
1606 		all_err += err;
1607 	}
1608 	for (i = 0; i < size; i++) {
1609 		cur_td = &list_mcs_vlan_vectors[i];
1610 		if (i == 0) {
1611 			opts.sectag_insert_mode = 1;
1612 		} else if (i == 1) {
1613 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1614 			opts.nb_vlan = 1;
1615 		} else if (i == 2) {
1616 			opts.sectag_insert_mode = 0; /* offset from special E-type */
1617 			opts.nb_vlan = 2;
1618 		}
1619 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1620 		if (err == TEST_SKIPPED) {
1621 			printf("VLAN Decap case %d skipped", cur_td->test_idx);
1622 			skipped += 1;
1623 			err = 0;
1624 		} else if (err) {
1625 			printf("\n VLAN Decap case %d failed", cur_td->test_idx);
1626 			err = -1;
1627 		} else {
1628 			printf("\n VLAN Decap case %d passed", cur_td->test_idx);
1629 			err = 0;
1630 		}
1631 		all_err += err;
1632 	}
1633 
1634 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1635 			2 * size + all_err - skipped, -all_err, skipped);
1636 	return skipped > 0 ? TEST_SKIPPED : all_err;
1637 }
1638 
1639 static int
1640 test_inline_macsec_pkt_drop(void)
1641 {
1642 	const struct mcs_test_vector *cur_td;
1643 	struct mcs_test_opts opts = {0};
1644 	int err, all_err = 0;
1645 	int skipped = 0;
1646 	int i, size;
1647 
1648 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1649 	opts.encrypt = true;
1650 	opts.protect_frames = true;
1651 	opts.sa_in_use = 1;
1652 	opts.nb_td = 1;
1653 	opts.sectag_insert_mode = 1;
1654 	opts.mtu = RTE_ETHER_MTU;
1655 
1656 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1657 
1658 	for (i = 0; i < size; i++) {
1659 		cur_td = &list_mcs_err_cipher_vectors[i];
1660 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1661 		if (err == TEST_SKIPPED) {
1662 			printf("Packet drop case %d skipped", cur_td->test_idx);
1663 			skipped += 1;
1664 			err = 0;
1665 		} else if (err) {
1666 			printf("\nPacket drop case %d passed", cur_td->test_idx);
1667 			err = 0;
1668 		} else {
1669 			printf("\nPacket drop case %d failed", cur_td->test_idx);
1670 			err = -1;
1671 		}
1672 		all_err += err;
1673 	}
1674 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1675 			size + all_err - skipped, -all_err, skipped);
1676 
1677 	return skipped > 0 ? TEST_SKIPPED : all_err;
1678 }
1679 
1680 static int
1681 test_inline_macsec_untagged_rx(void)
1682 {
1683 	const struct mcs_test_vector *cur_td;
1684 	struct mcs_test_opts opts = {0};
1685 	int err, all_err = 0;
1686 	int skipped = 0;
1687 	int i, size;
1688 
1689 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1690 	opts.sa_in_use = 1;
1691 	opts.nb_td = 1;
1692 	opts.sectag_insert_mode = 1;
1693 	opts.mtu = RTE_ETHER_MTU;
1694 	opts.check_untagged_rx = 1;
1695 
1696 	size = (sizeof(list_mcs_untagged_cipher_vectors) /
1697 		sizeof((list_mcs_untagged_cipher_vectors)[0]));
1698 
1699 	for (i = 0; i < size; i++) {
1700 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1701 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1702 		if (err == TEST_SKIPPED) {
1703 			skipped += 1;
1704 			err = 0;
1705 		} else if (err)
1706 			err = 0;
1707 		else
1708 			err = -1;
1709 
1710 		all_err += err;
1711 	}
1712 
1713 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
1714 	for (i = 0; i < size; i++) {
1715 		cur_td = &list_mcs_untagged_cipher_vectors[i];
1716 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1717 		if (err == TEST_SKIPPED) {
1718 			skipped += 1;
1719 			err = 0;
1720 		} else if (err)
1721 			err = 0;
1722 		else
1723 			err = -1;
1724 
1725 		all_err += err;
1726 	}
1727 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1728 			2 * size + all_err - skipped, -all_err, skipped);
1729 
1730 	return skipped > 0 ? TEST_SKIPPED : all_err;
1731 }
1732 
1733 static int
1734 test_inline_macsec_bad_tag_rx(void)
1735 {
1736 	const struct mcs_test_vector *cur_td;
1737 	struct mcs_test_opts opts = {0};
1738 	int err, all_err = 0;
1739 	int skipped = 0;
1740 	int i, size;
1741 
1742 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1743 	opts.protect_frames = true;
1744 	opts.sa_in_use = 1;
1745 	opts.nb_td = 1;
1746 	opts.sectag_insert_mode = 1;
1747 	opts.mtu = RTE_ETHER_MTU;
1748 	opts.check_bad_tag_cnt = 1;
1749 
1750 	size = (sizeof(list_mcs_bad_tag_vectors) / sizeof((list_mcs_bad_tag_vectors)[0]));
1751 
1752 	for (i = 0; i < size; i++) {
1753 		cur_td = &list_mcs_bad_tag_vectors[i];
1754 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1755 		if (err == TEST_SKIPPED) {
1756 			skipped += 1;
1757 			err = 0;
1758 		} else if (err)
1759 			err = -1;
1760 		else
1761 			err = 0;
1762 
1763 		all_err += err;
1764 	}
1765 
1766 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1767 			size + all_err - skipped, -all_err, skipped);
1768 
1769 	return skipped > 0 ? TEST_SKIPPED : all_err;
1770 }
1771 
1772 static int
1773 test_inline_macsec_sa_not_in_use(void)
1774 {
1775 	const struct mcs_test_vector *cur_td;
1776 	struct mcs_test_opts opts = {0};
1777 	int err, all_err = 0;
1778 	int skipped = 0;
1779 	int i, size;
1780 
1781 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1782 	opts.protect_frames = true;
1783 	opts.sa_in_use = 0;
1784 	opts.nb_td = 1;
1785 	opts.sectag_insert_mode = 1;
1786 	opts.mtu = RTE_ETHER_MTU;
1787 	opts.check_sa_not_in_use = 1;
1788 
1789 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1790 
1791 	for (i = 0; i < size; i++) {
1792 		cur_td = &list_mcs_cipher_vectors[i];
1793 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1794 		if (err == TEST_SKIPPED) {
1795 			skipped += 1;
1796 			err = 0;
1797 		} else if (err)
1798 			err = -1;
1799 		else
1800 			err = 0;
1801 
1802 		all_err += err;
1803 	}
1804 
1805 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1806 			size + all_err - skipped, -all_err, skipped);
1807 
1808 	return skipped > 0 ? TEST_SKIPPED : all_err;
1809 }
1810 
1811 static int
1812 test_inline_macsec_decap_stats(void)
1813 {
1814 	const struct mcs_test_vector *cur_td;
1815 	struct mcs_test_opts opts = {0};
1816 	int err, all_err = 0;
1817 	int skipped = 0;
1818 	int i, size;
1819 
1820 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1821 	opts.protect_frames = true;
1822 	opts.sa_in_use = 1;
1823 	opts.nb_td = 1;
1824 	opts.sectag_insert_mode = 1;
1825 	opts.mtu = RTE_ETHER_MTU;
1826 	opts.check_decap_stats = 1;
1827 
1828 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1829 
1830 	for (i = 0; i < size; i++) {
1831 		cur_td = &list_mcs_cipher_vectors[i];
1832 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1833 		if (err == TEST_SKIPPED) {
1834 			printf("Decap stats case %d skipped\n", cur_td->test_idx);
1835 			skipped += 1;
1836 			err = 0;
1837 		} else if (err) {
1838 			printf("\nDecap stats case %d failed", cur_td->test_idx);
1839 			err = -1;
1840 		} else {
1841 			printf("\nDecap stats case %d passed", cur_td->test_idx);
1842 			err = 0;
1843 		}
1844 		all_err += err;
1845 	}
1846 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1847 			size + all_err - skipped, -all_err, skipped);
1848 
1849 	return skipped > 0 ? TEST_SKIPPED : all_err;
1850 }
1851 
1852 static int
1853 test_inline_macsec_verify_only_stats(void)
1854 {
1855 	const struct mcs_test_vector *cur_td;
1856 	struct mcs_test_opts opts = {0};
1857 	int err, all_err = 0;
1858 	int skipped = 0;
1859 	int i, size;
1860 
1861 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1862 	opts.protect_frames = true;
1863 	opts.sa_in_use = 1;
1864 	opts.nb_td = 1;
1865 	opts.sectag_insert_mode = 1;
1866 	opts.mtu = RTE_ETHER_MTU;
1867 	opts.check_verify_only_stats = 1;
1868 
1869 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1870 
1871 	for (i = 0; i < size; i++) {
1872 		cur_td = &list_mcs_integrity_vectors[i];
1873 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1874 		if (err == TEST_SKIPPED) {
1875 			printf("Verify only stats case %d skipped\n", cur_td->test_idx);
1876 			skipped += 1;
1877 			err = 0;
1878 		} else if (err) {
1879 			printf("\nVerify only stats case %d failed", cur_td->test_idx);
1880 			err = -1;
1881 		} else {
1882 			printf("\nVerify only stats case %d Passed", cur_td->test_idx);
1883 			err = 0;
1884 		}
1885 		all_err += err;
1886 	}
1887 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1888 			size + all_err - skipped, -all_err, skipped);
1889 
1890 	return skipped > 0 ? TEST_SKIPPED : all_err;
1891 }
1892 
1893 static int
1894 test_inline_macsec_pkts_invalid_stats(void)
1895 {
1896 	const struct mcs_test_vector *cur_td;
1897 	struct mcs_test_opts opts = {0};
1898 	int err, all_err = 0;
1899 	int skipped = 0;
1900 	int i, size;
1901 
1902 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1903 	opts.protect_frames = true;
1904 	opts.sa_in_use = 1;
1905 	opts.nb_td = 1;
1906 	opts.sectag_insert_mode = 1;
1907 	opts.mtu = RTE_ETHER_MTU;
1908 
1909 	size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0]));
1910 
1911 	for (i = 0; i < size; i++) {
1912 		cur_td = &list_mcs_err_cipher_vectors[i];
1913 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
1914 		if (err == TEST_SKIPPED) {
1915 			skipped += 1;
1916 			err = 0;
1917 		} else if (err)
1918 			err = 0;
1919 		else
1920 			err = -1;
1921 
1922 		all_err += err;
1923 	}
1924 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1925 			size + all_err - skipped, -all_err, skipped);
1926 	return skipped > 0 ? TEST_SKIPPED : all_err;
1927 }
1928 
1929 static int
1930 test_inline_macsec_pkts_unchecked_stats(void)
1931 {
1932 	const struct mcs_test_vector *cur_td;
1933 	struct mcs_test_opts opts = {0};
1934 	int err, all_err = 0;
1935 	int skipped = 0;
1936 	int i, size;
1937 
1938 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_DISABLE;
1939 	opts.protect_frames = true;
1940 	opts.sa_in_use = 1;
1941 	opts.nb_td = 1;
1942 	opts.sectag_insert_mode = 1;
1943 	opts.mtu = RTE_ETHER_MTU;
1944 	opts.check_pkts_unchecked_stats = 1;
1945 
1946 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
1947 
1948 	for (i = 0; i < size; i++) {
1949 		cur_td = &list_mcs_integrity_vectors[i];
1950 		err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts);
1951 		if (err == TEST_SKIPPED) {
1952 			skipped += 1;
1953 			err = 0;
1954 		} else if (err)
1955 			err = -1;
1956 		else
1957 			err = 0;
1958 
1959 		all_err += err;
1960 	}
1961 
1962 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
1963 			size + all_err - skipped, -all_err, skipped);
1964 	return skipped > 0 ? TEST_SKIPPED : all_err;
1965 }
1966 
1967 static int
1968 test_inline_macsec_out_pkts_untagged(void)
1969 {
1970 	const struct mcs_test_vector *cur_td;
1971 	struct mcs_test_opts opts = {0};
1972 	int err, all_err = 0;
1973 	int skipped = 0;
1974 	int i, size;
1975 
1976 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
1977 	opts.encrypt = false;
1978 	opts.protect_frames = false;
1979 	opts.sa_in_use = 1;
1980 	opts.nb_td = 1;
1981 	opts.sectag_insert_mode = 1;
1982 	opts.mtu = RTE_ETHER_MTU;
1983 	opts.check_out_pkts_untagged = 1;
1984 
1985 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
1986 	for (i = 0; i < size; i++) {
1987 		cur_td = &list_mcs_cipher_vectors[i];
1988 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
1989 		if (err == TEST_SKIPPED) {
1990 			skipped += 1;
1991 			err = 0;
1992 		} else if (err)
1993 			err = -1;
1994 		else
1995 			err = 0;
1996 
1997 		all_err += err;
1998 	}
1999 
2000 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2001 			size + all_err - skipped, -all_err, skipped);
2002 	return skipped > 0 ? TEST_SKIPPED : all_err;
2003 }
2004 
2005 static int
2006 test_inline_macsec_out_pkts_toolong(void)
2007 {
2008 	const struct mcs_test_vector *cur_td;
2009 	struct mcs_test_opts opts = {0};
2010 	int err, all_err = 0;
2011 	int skipped = 0;
2012 	int i, size;
2013 
2014 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD;
2015 	opts.encrypt = true;
2016 	opts.protect_frames = true;
2017 	opts.sa_in_use = 1;
2018 	opts.nb_td = 1;
2019 	opts.sectag_insert_mode = 1;
2020 	opts.mtu = 50;
2021 	opts.check_out_pkts_toolong = 1;
2022 
2023 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
2024 	for (i = 0; i < size; i++) {
2025 		cur_td = &list_mcs_cipher_vectors[i];
2026 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
2027 		if (err == TEST_SKIPPED) {
2028 			skipped += 1;
2029 			err = 0;
2030 		} else if (err)
2031 			err = -1;
2032 		else
2033 			err = 0;
2034 
2035 		all_err += err;
2036 	}
2037 
2038 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2039 			size + all_err - skipped, -all_err, skipped);
2040 	return skipped > 0 ? TEST_SKIPPED : all_err;
2041 }
2042 
2043 static int
2044 test_inline_macsec_encap_stats(void)
2045 {
2046 	const struct mcs_test_vector *cur_td;
2047 	struct mcs_test_opts opts = {0};
2048 	int err, all_err = 0;
2049 	int skipped = 0;
2050 	int i, size;
2051 
2052 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2053 	opts.encrypt = true;
2054 	opts.protect_frames = true;
2055 	opts.sa_in_use = 1;
2056 	opts.nb_td = 1;
2057 	opts.sectag_insert_mode = 1;
2058 	opts.mtu = RTE_ETHER_MTU;
2059 	opts.check_encap_stats = 1;
2060 
2061 	size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0]));
2062 	for (i = 0; i < size; i++) {
2063 		cur_td = &list_mcs_cipher_vectors[i];
2064 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
2065 		if (err == TEST_SKIPPED) {
2066 			skipped += 1;
2067 			err = 0;
2068 		} else if (err)
2069 			err = -1;
2070 		else
2071 			err = 0;
2072 
2073 		all_err += err;
2074 	}
2075 
2076 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2077 			size + all_err - skipped, -all_err, skipped);
2078 	return skipped > 0 ? TEST_SKIPPED : all_err;
2079 }
2080 
2081 static int
2082 test_inline_macsec_auth_only_stats(void)
2083 {
2084 	const struct mcs_test_vector *cur_td;
2085 	struct mcs_test_opts opts = {0};
2086 	int err, all_err = 0;
2087 	int skipped = 0;
2088 	int i, size;
2089 
2090 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2091 	opts.protect_frames = true;
2092 	opts.sa_in_use = 1;
2093 	opts.nb_td = 1;
2094 	opts.sectag_insert_mode = 1;
2095 	opts.mtu = RTE_ETHER_MTU;
2096 	opts.check_auth_only_stats = 1;
2097 
2098 	size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0]));
2099 
2100 	for (i = 0; i < size; i++) {
2101 		cur_td = &list_mcs_integrity_vectors[i];
2102 		err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts);
2103 		if (err == TEST_SKIPPED) {
2104 			skipped += 1;
2105 			err = 0;
2106 		} else if (err)
2107 			err = -1;
2108 		else
2109 			err = 0;
2110 
2111 		all_err += err;
2112 	}
2113 
2114 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2115 			size + all_err - skipped, -all_err, skipped);
2116 	return skipped > 0 ? TEST_SKIPPED : all_err;
2117 }
2118 
2119 static int
2120 test_inline_macsec_interrupts_all(void)
2121 {
2122 	struct mcs_err_vector err_vector = {0};
2123 	const struct mcs_test_vector *cur_td;
2124 	struct mcs_test_opts opts = {0};
2125 	int skipped = 0;
2126 	int i, size;
2127 	int err, all_err = 0;
2128 	enum rte_eth_event_macsec_subtype subtype[] =  {
2129 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1,
2130 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1,
2131 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48,
2132 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1,
2133 		RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1,
2134 	};
2135 
2136 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2137 	opts.protect_frames = true;
2138 	opts.sa_in_use = 1;
2139 	opts.nb_td = 1;
2140 	opts.sectag_insert_mode = 1;
2141 	opts.mtu = RTE_ETHER_MTU;
2142 	opts.check_sectag_interrupts = 1;
2143 
2144 	err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN;
2145 	err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN;
2146 	rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC,
2147 			test_macsec_event_callback, &err_vector);
2148 
2149 	size = (sizeof(list_mcs_intr_test_vectors) / sizeof((list_mcs_intr_test_vectors)[0]));
2150 
2151 	for (i = 0; i < size; i++) {
2152 		cur_td = &list_mcs_intr_test_vectors[i];
2153 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
2154 		if (err == TEST_SKIPPED) {
2155 			printf("Sectag val err interrupt test case %d skipped",
2156 			       cur_td->test_idx);
2157 			skipped += 1;
2158 			err = 0;
2159 		} else if ((err_vector.event == RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR) &&
2160 			   (err_vector.event_subtype == subtype[i])) {
2161 			printf("\nSectag val err interrupt test case %d passed",
2162 			       cur_td->test_idx);
2163 			err = 0;
2164 		} else {
2165 			printf("\nSectag val err interrupt test case %d failed",
2166 			       cur_td->test_idx);
2167 			err = -1;
2168 		}
2169 		all_err += err;
2170 	}
2171 	rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC,
2172 			test_macsec_event_callback, &err_vector);
2173 
2174 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2175 			size + all_err - skipped, -all_err, skipped);
2176 	return skipped > 0 ? TEST_SKIPPED : all_err;
2177 }
2178 
2179 static int
2180 test_inline_macsec_rekey_tx(void)
2181 {
2182 	const struct mcs_test_vector *cur_td;
2183 	struct mcs_test_opts opts = {0};
2184 	int err, all_err = 0;
2185 	int skipped = 0;
2186 	int i, size;
2187 
2188 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2189 	opts.protect_frames = true;
2190 	opts.encrypt = true;
2191 	opts.sa_in_use = 1;
2192 	opts.nb_td = 1;
2193 	opts.sectag_insert_mode = 1;
2194 	opts.mtu = RTE_ETHER_MTU;
2195 	opts.rekey_en = 1;
2196 
2197 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
2198 
2199 	for (i = 0; i < size; i++) {
2200 		cur_td = &list_mcs_rekey_vectors[i];
2201 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
2202 		err = test_macsec(&cur_td, MCS_ENCAP, &opts);
2203 		if (err == TEST_SKIPPED) {
2204 			printf("Tx hw rekey test case %d skipped\n", i);
2205 			skipped += 1;
2206 			err = 0;
2207 		} else if (err) {
2208 			printf("Tx hw rekey test case %d failed\n", i);
2209 			err = -1;
2210 		} else {
2211 			printf("Tx hw rekey test case %d passed\n", i);
2212 			err = 0;
2213 		}
2214 		all_err += err;
2215 	}
2216 
2217 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2218 			size / 2 + all_err - skipped, -all_err, skipped);
2219 	return skipped > 0 ? TEST_SKIPPED : all_err;
2220 }
2221 
2222 static int
2223 test_inline_macsec_rekey_rx(void)
2224 {
2225 	const struct mcs_test_vector *cur_td;
2226 	struct mcs_test_opts opts = {0};
2227 	int err, all_err = 0;
2228 	int skipped = 0;
2229 	int i, size;
2230 
2231 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2232 	opts.protect_frames = true;
2233 	opts.sa_in_use = 1;
2234 	opts.nb_td = 1;
2235 	opts.sectag_insert_mode = 1;
2236 	opts.mtu = RTE_ETHER_MTU;
2237 	opts.rekey_en = 1;
2238 
2239 	size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0]));
2240 	for (i = 0; i < size; i++) {
2241 		cur_td = &list_mcs_rekey_vectors[i];
2242 		opts.rekey_td = &list_mcs_rekey_vectors[++i];
2243 		err = test_macsec(&cur_td, MCS_DECAP, &opts);
2244 		if (err == TEST_SKIPPED) {
2245 			printf("Rx rekey test case %d skipped\n", i);
2246 			skipped += 1;
2247 			err = 0;
2248 		} else if (err) {
2249 			printf("Rx rekey test case %d failed\n", i);
2250 			err = -1;
2251 		} else {
2252 			printf("Rx rekey test case %d passed\n", i);
2253 			err = 0;
2254 		}
2255 		all_err += err;
2256 	}
2257 
2258 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2259 			size / 2 + all_err - skipped, -all_err, skipped);
2260 	return skipped > 0 ? TEST_SKIPPED : all_err;
2261 }
2262 
2263 static int
2264 test_inline_macsec_anti_replay(void)
2265 {
2266 	const struct mcs_test_vector *cur_td;
2267 	struct mcs_test_opts opts = {0};
2268 	uint16_t replay_win_sz[2] = {32, 0};
2269 	int err, all_err = 0;
2270 	int skipped = 0;
2271 	int i, size;
2272 	int j;
2273 
2274 	opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT;
2275 	opts.sa_in_use = 1;
2276 	opts.nb_td = 1;
2277 	opts.sectag_insert_mode = 1;
2278 	opts.replay_protect = 1;
2279 
2280 	size = (sizeof(list_mcs_anti_replay_vectors) / sizeof((list_mcs_anti_replay_vectors)[0]));
2281 
2282 	for (j = 0; j < 2; j++) {
2283 		opts.replay_win_sz = replay_win_sz[j];
2284 
2285 		for (i = 0; i < size; i++) {
2286 			cur_td = &list_mcs_anti_replay_vectors[i];
2287 			opts.ar_td[0] = &list_mcs_anti_replay_vectors[++i];
2288 			opts.ar_td[1] = &list_mcs_anti_replay_vectors[++i];
2289 			opts.ar_td[2] = &list_mcs_anti_replay_vectors[++i];
2290 			err = test_macsec(&cur_td, MCS_DECAP, &opts);
2291 			if (err == TEST_SKIPPED) {
2292 				printf("Replay window: %u, Anti replay test "
2293 				       "case %d skipped\n", opts.replay_win_sz,
2294 				       i);
2295 				skipped += 1;
2296 				err = 0;
2297 			} else if (err) {
2298 				printf("Replay window: %u, Anti replay test "
2299 				       "case %d failed\n", opts.replay_win_sz,
2300 				       i);
2301 				err = -1;
2302 			} else {
2303 				printf("Replay window: %u, Anti replay test "
2304 				       "case %d passed\n", opts.replay_win_sz,
2305 				       i);
2306 				err = 0;
2307 			}
2308 			all_err += err;
2309 		}
2310 	}
2311 
2312 	printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__,
2313 			size / 2 + all_err - skipped, -all_err, skipped);
2314 	return skipped > 0 ? TEST_SKIPPED : all_err;
2315 }
2316 
2317 static int
2318 ut_setup_inline_macsec(void)
2319 {
2320 	int ret;
2321 
2322 	/* Start device */
2323 	ret = rte_eth_dev_start(port_id);
2324 	if (ret < 0) {
2325 		printf("rte_eth_dev_start: err=%d, port=%d\n",
2326 			ret, port_id);
2327 		return ret;
2328 	}
2329 	/* always enable promiscuous */
2330 	ret = rte_eth_promiscuous_enable(port_id);
2331 	if (ret != 0) {
2332 		printf("rte_eth_promiscuous_enable: err=%s, port=%d\n",
2333 			rte_strerror(-ret), port_id);
2334 		return ret;
2335 	}
2336 
2337 	check_all_ports_link_status(1, RTE_PORT_ALL);
2338 
2339 	return 0;
2340 }
2341 
2342 static void
2343 ut_teardown_inline_macsec(void)
2344 {
2345 	uint16_t portid;
2346 	int ret;
2347 
2348 	/* port tear down */
2349 	RTE_ETH_FOREACH_DEV(portid) {
2350 		ret = rte_eth_dev_stop(portid);
2351 		if (ret != 0)
2352 			printf("rte_eth_dev_stop: err=%s, port=%u\n",
2353 			       rte_strerror(-ret), portid);
2354 
2355 	}
2356 }
2357 
2358 static int
2359 inline_macsec_testsuite_setup(void)
2360 {
2361 	uint16_t nb_rxd;
2362 	uint16_t nb_txd;
2363 	uint16_t nb_ports;
2364 	int ret;
2365 	uint16_t nb_rx_queue = 1, nb_tx_queue = 1;
2366 
2367 	printf("Start inline MACsec test.\n");
2368 
2369 	nb_ports = rte_eth_dev_count_avail();
2370 	if (nb_ports < NB_ETHPORTS_USED) {
2371 		printf("At least %u port(s) used for test\n",
2372 		       NB_ETHPORTS_USED);
2373 		return TEST_SKIPPED;
2374 	}
2375 
2376 	ret = init_mempools(NB_MBUF);
2377 	if (ret)
2378 		return ret;
2379 
2380 	if (tx_pkts_burst == NULL) {
2381 		tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff",
2382 					  MAX_TRAFFIC_BURST,
2383 					  sizeof(void *),
2384 					  RTE_CACHE_LINE_SIZE);
2385 		if (!tx_pkts_burst)
2386 			return TEST_FAILED;
2387 
2388 		rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff",
2389 					  MAX_TRAFFIC_BURST,
2390 					  sizeof(void *),
2391 					  RTE_CACHE_LINE_SIZE);
2392 		if (!rx_pkts_burst)
2393 			return TEST_FAILED;
2394 	}
2395 
2396 	printf("Generate %d packets\n", MAX_TRAFFIC_BURST);
2397 
2398 	nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
2399 	nb_txd = RTE_TEST_TX_DESC_DEFAULT;
2400 
2401 	/* configuring port 0 for the test is enough */
2402 	port_id = 0;
2403 	/* port configure */
2404 	ret = rte_eth_dev_configure(port_id, nb_rx_queue,
2405 				    nb_tx_queue, &port_conf);
2406 	if (ret < 0) {
2407 		printf("Cannot configure device: err=%d, port=%d\n",
2408 			 ret, port_id);
2409 		return ret;
2410 	}
2411 	ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]);
2412 	if (ret < 0) {
2413 		printf("Cannot get mac address: err=%d, port=%d\n",
2414 			 ret, port_id);
2415 		return ret;
2416 	}
2417 	printf("Port %u ", port_id);
2418 	print_ethaddr("Address:", &ports_eth_addr[port_id]);
2419 	printf("\n");
2420 
2421 	/* tx queue setup */
2422 	ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
2423 				     SOCKET_ID_ANY, &tx_conf);
2424 	if (ret < 0) {
2425 		printf("rte_eth_tx_queue_setup: err=%d, port=%d\n",
2426 				ret, port_id);
2427 		return ret;
2428 	}
2429 	/* rx queue steup */
2430 	ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY,
2431 				     &rx_conf, mbufpool);
2432 	if (ret < 0) {
2433 		printf("rte_eth_rx_queue_setup: err=%d, port=%d\n",
2434 				ret, port_id);
2435 		return ret;
2436 	}
2437 
2438 	return 0;
2439 }
2440 
2441 static void
2442 inline_macsec_testsuite_teardown(void)
2443 {
2444 	uint16_t portid;
2445 	int ret;
2446 
2447 	/* port tear down */
2448 	RTE_ETH_FOREACH_DEV(portid) {
2449 		ret = rte_eth_dev_reset(portid);
2450 		if (ret != 0)
2451 			printf("rte_eth_dev_reset: err=%s, port=%u\n",
2452 			       rte_strerror(-ret), port_id);
2453 	}
2454 	rte_free(tx_pkts_burst);
2455 	rte_free(rx_pkts_burst);
2456 }
2457 
2458 
2459 static struct unit_test_suite inline_macsec_testsuite  = {
2460 	.suite_name = "Inline MACsec Ethernet Device Unit Test Suite",
2461 	.unit_test_cases = {
2462 		TEST_CASE_NAMED_ST(
2463 			"MACsec Encap + decap Multi flow",
2464 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2465 			test_inline_macsec_multi_flow),
2466 		TEST_CASE_NAMED_ST(
2467 			"MACsec encap(Cipher+Auth) known vector",
2468 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2469 			test_inline_macsec_encap_all),
2470 		TEST_CASE_NAMED_ST(
2471 			"MACsec decap(De-cipher+verify) known vector",
2472 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2473 			test_inline_macsec_decap_all),
2474 		TEST_CASE_NAMED_ST(
2475 			"MACsec auth only known vector",
2476 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2477 			test_inline_macsec_auth_only_all),
2478 		TEST_CASE_NAMED_ST(
2479 			"MACsec verify only known vector",
2480 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2481 			test_inline_macsec_verify_only_all),
2482 		TEST_CASE_NAMED_ST(
2483 			"MACsec encap + decap known vector",
2484 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2485 			test_inline_macsec_encap_decap_all),
2486 		TEST_CASE_NAMED_ST(
2487 			"MACsec auth + verify known vector",
2488 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2489 			test_inline_macsec_auth_verify_all),
2490 		TEST_CASE_NAMED_ST(
2491 			"MACsec Encap and decap with VLAN",
2492 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2493 			test_inline_macsec_with_vlan),
2494 		TEST_CASE_NAMED_ST(
2495 			"MACsec packet drop",
2496 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2497 			test_inline_macsec_pkt_drop),
2498 		TEST_CASE_NAMED_ST(
2499 			"MACsec untagged Rx",
2500 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2501 			test_inline_macsec_untagged_rx),
2502 		TEST_CASE_NAMED_ST(
2503 			"MACsec bad tag Rx",
2504 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2505 			test_inline_macsec_bad_tag_rx),
2506 		TEST_CASE_NAMED_ST(
2507 			"MACsec SA not in use",
2508 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2509 			test_inline_macsec_sa_not_in_use),
2510 		TEST_CASE_NAMED_ST(
2511 			"MACsec decap stats",
2512 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2513 			test_inline_macsec_decap_stats),
2514 		TEST_CASE_NAMED_ST(
2515 			"MACsec verify only stats",
2516 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2517 			test_inline_macsec_verify_only_stats),
2518 		TEST_CASE_NAMED_ST(
2519 			"MACsec pkts invalid stats",
2520 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2521 			test_inline_macsec_pkts_invalid_stats),
2522 		TEST_CASE_NAMED_ST(
2523 			"MACsec pkts unchecked stats",
2524 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2525 			test_inline_macsec_pkts_unchecked_stats),
2526 		TEST_CASE_NAMED_ST(
2527 			"MACsec out pkts untagged",
2528 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2529 			test_inline_macsec_out_pkts_untagged),
2530 		TEST_CASE_NAMED_ST(
2531 			"MACsec out pkts too long",
2532 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2533 			test_inline_macsec_out_pkts_toolong),
2534 		TEST_CASE_NAMED_ST(
2535 			"MACsec Encap stats",
2536 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2537 			test_inline_macsec_encap_stats),
2538 		TEST_CASE_NAMED_ST(
2539 			"MACsec auth only stats",
2540 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2541 			test_inline_macsec_auth_only_stats),
2542 		TEST_CASE_NAMED_ST(
2543 			"MACsec interrupts all",
2544 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2545 			test_inline_macsec_interrupts_all),
2546 		TEST_CASE_NAMED_ST(
2547 			"MACsec re-key Tx",
2548 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2549 			test_inline_macsec_rekey_tx),
2550 		TEST_CASE_NAMED_ST(
2551 			"MACsec re-key Rx",
2552 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2553 			test_inline_macsec_rekey_rx),
2554 		TEST_CASE_NAMED_ST(
2555 			"MACsec anti-replay",
2556 			ut_setup_inline_macsec, ut_teardown_inline_macsec,
2557 			test_inline_macsec_anti_replay),
2558 
2559 		TEST_CASES_END() /**< NULL terminate unit test array */
2560 	},
2561 };
2562 
2563 static int
2564 test_inline_macsec(void)
2565 {
2566 	inline_macsec_testsuite.setup = inline_macsec_testsuite_setup;
2567 	inline_macsec_testsuite.teardown = inline_macsec_testsuite_teardown;
2568 	return unit_test_suite_runner(&inline_macsec_testsuite);
2569 }
2570 
2571 #endif /* !RTE_EXEC_ENV_WINDOWS */
2572 
2573 REGISTER_TEST_COMMAND(inline_macsec_autotest, test_inline_macsec);
2574