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