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(ð.hdr, td->plain_pkt.data, RTE_ETHER_HDR_LEN); 331 else 332 memcpy(ð.hdr, td->secure_pkt.data, RTE_ETHER_HDR_LEN); 333 334 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; 335 pattern[0].spec = ð 336 pattern[0].mask = ð_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