1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2023 Marvell. 3 */ 4 5 #include <stdio.h> 6 #include <inttypes.h> 7 8 #include <rte_ethdev.h> 9 #include <rte_malloc.h> 10 #include <rte_security.h> 11 12 #include "test.h" 13 #include "test_security_inline_macsec_vectors.h" 14 15 #ifdef RTE_EXEC_ENV_WINDOWS 16 static int 17 test_inline_macsec(void) 18 { 19 printf("Inline MACsec not supported on Windows, skipping test\n"); 20 return TEST_SKIPPED; 21 } 22 23 #else 24 25 #define NB_ETHPORTS_USED 1 26 #define MEMPOOL_CACHE_SIZE 32 27 #define RTE_TEST_RX_DESC_DEFAULT 1024 28 #define RTE_TEST_TX_DESC_DEFAULT 1024 29 #define RTE_PORT_ALL (~(uint16_t)0x0) 30 31 #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ 32 #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ 33 #define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */ 34 35 #define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */ 36 #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ 37 #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ 38 39 #define MAX_TRAFFIC_BURST 2048 40 #define NB_MBUF 10240 41 42 #define MCS_INVALID_SA 0xFFFF 43 #define MCS_DEFAULT_PN_THRESHOLD 0xFFFFF 44 45 static struct rte_mempool *mbufpool; 46 static struct rte_mempool *sess_pool; 47 /* ethernet addresses of ports */ 48 static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 49 50 struct mcs_test_opts { 51 int val_frames; 52 int nb_td; 53 uint16_t mtu; 54 uint8_t sa_in_use; 55 bool encrypt; 56 bool protect_frames; 57 uint8_t sectag_insert_mode; 58 uint8_t nb_vlan; 59 uint32_t replay_win_sz; 60 uint8_t replay_protect; 61 uint8_t rekey_en; 62 const struct mcs_test_vector *rekey_td; 63 const struct mcs_test_vector *ar_td[3]; 64 bool dump_all_stats; 65 uint8_t check_untagged_rx; 66 uint8_t check_bad_tag_cnt; 67 uint8_t check_sa_not_in_use; 68 uint8_t check_decap_stats; 69 uint8_t check_verify_only_stats; 70 uint8_t check_pkts_invalid_stats; 71 uint8_t check_pkts_unchecked_stats; 72 uint8_t check_out_pkts_untagged; 73 uint8_t check_out_pkts_toolong; 74 uint8_t check_encap_stats; 75 uint8_t check_auth_only_stats; 76 uint8_t check_sectag_interrupts; 77 }; 78 79 static struct rte_eth_conf port_conf = { 80 .rxmode = { 81 .mq_mode = RTE_ETH_MQ_RX_NONE, 82 .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM | 83 RTE_ETH_RX_OFFLOAD_MACSEC_STRIP, 84 }, 85 .txmode = { 86 .mq_mode = RTE_ETH_MQ_TX_NONE, 87 .offloads = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE | 88 RTE_ETH_TX_OFFLOAD_MACSEC_INSERT, 89 }, 90 .lpbk_mode = 1, /* enable loopback */ 91 }; 92 93 static struct rte_eth_rxconf rx_conf = { 94 .rx_thresh = { 95 .pthresh = RX_PTHRESH, 96 .hthresh = RX_HTHRESH, 97 .wthresh = RX_WTHRESH, 98 }, 99 .rx_free_thresh = 32, 100 }; 101 102 static struct rte_eth_txconf tx_conf = { 103 .tx_thresh = { 104 .pthresh = TX_PTHRESH, 105 .hthresh = TX_HTHRESH, 106 .wthresh = TX_WTHRESH, 107 }, 108 .tx_free_thresh = 32, /* Use PMD default values */ 109 .tx_rs_thresh = 32, /* Use PMD default values */ 110 }; 111 112 static uint16_t port_id; 113 114 static uint64_t link_mbps; 115 116 static struct rte_flow *default_tx_flow[RTE_MAX_ETHPORTS]; 117 static struct rte_flow *default_rx_flow[RTE_MAX_ETHPORTS]; 118 119 static struct rte_mbuf **tx_pkts_burst; 120 static struct rte_mbuf **rx_pkts_burst; 121 122 static inline struct rte_mbuf * 123 init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len) 124 { 125 struct rte_mbuf *pkt; 126 127 pkt = rte_pktmbuf_alloc(mp); 128 if (pkt == NULL) 129 return NULL; 130 131 rte_memcpy(rte_pktmbuf_append(pkt, len), data, len); 132 133 return pkt; 134 } 135 136 static int 137 init_mempools(unsigned int nb_mbuf) 138 { 139 void *sec_ctx; 140 uint16_t nb_sess = 512; 141 uint32_t sess_sz; 142 char s[64]; 143 144 if (mbufpool == NULL) { 145 snprintf(s, sizeof(s), "mbuf_pool"); 146 mbufpool = rte_pktmbuf_pool_create(s, nb_mbuf, 147 MEMPOOL_CACHE_SIZE, 0, 148 RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY); 149 if (mbufpool == NULL) { 150 printf("Cannot init mbuf pool\n"); 151 return TEST_FAILED; 152 } 153 printf("Allocated mbuf pool\n"); 154 } 155 156 sec_ctx = rte_eth_dev_get_sec_ctx(port_id); 157 if (sec_ctx == NULL) { 158 printf("Device does not support Security ctx\n"); 159 return TEST_SKIPPED; 160 } 161 sess_sz = rte_security_session_get_size(sec_ctx); 162 if (sess_pool == NULL) { 163 snprintf(s, sizeof(s), "sess_pool"); 164 sess_pool = rte_mempool_create(s, nb_sess, sess_sz, 165 MEMPOOL_CACHE_SIZE, 0, 166 NULL, NULL, NULL, NULL, 167 SOCKET_ID_ANY, 0); 168 if (sess_pool == NULL) { 169 printf("Cannot init sess pool\n"); 170 return TEST_FAILED; 171 } 172 printf("Allocated sess pool\n"); 173 } 174 175 return 0; 176 } 177 178 static void 179 fill_macsec_sa_conf(const struct mcs_test_vector *td, struct rte_security_macsec_sa *sa, 180 enum rte_security_macsec_direction dir, uint8_t an, uint8_t tci_off) 181 { 182 sa->dir = dir; 183 184 sa->key.data = td->sa_key.data; 185 sa->key.length = td->sa_key.len; 186 187 memcpy((uint8_t *)sa->salt, (const uint8_t *)td->salt, RTE_SECURITY_MACSEC_SALT_LEN); 188 189 /* AN is set as per the value in secure packet in test vector */ 190 sa->an = an & RTE_MACSEC_AN_MASK; 191 192 sa->ssci = td->ssci; 193 sa->xpn = td->xpn; 194 /* Starting packet number which is expected to come next. 195 * It is take from the test vector so that we can match the out packet. 196 */ 197 sa->next_pn = *(const uint32_t *)(&td->secure_pkt.data[tci_off + 2]); 198 } 199 200 static void 201 fill_macsec_sc_conf(const struct mcs_test_vector *td, 202 struct rte_security_macsec_sc *sc_conf, 203 const struct mcs_test_opts *opts, 204 enum rte_security_macsec_direction dir, 205 uint16_t sa_id[], uint8_t tci_off) 206 { 207 uint8_t i; 208 209 sc_conf->dir = dir; 210 sc_conf->pn_threshold = ((uint64_t)td->xpn << 32) | 211 rte_be_to_cpu_32(*(const uint32_t *)(&td->secure_pkt.data[tci_off + 2])); 212 if (dir == RTE_SECURITY_MACSEC_DIR_TX) { 213 sc_conf->sc_tx.sa_id = sa_id[0]; 214 if (sa_id[1] != MCS_INVALID_SA) { 215 sc_conf->sc_tx.sa_id_rekey = sa_id[1]; 216 sc_conf->sc_tx.re_key_en = 1; 217 } 218 sc_conf->sc_tx.active = 1; 219 /* is SCI valid */ 220 if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) { 221 memcpy(&sc_conf->sc_tx.sci, &td->secure_pkt.data[tci_off + 6], 222 sizeof(sc_conf->sc_tx.sci)); 223 sc_conf->sc_tx.sci = rte_be_to_cpu_64(sc_conf->sc_tx.sci); 224 } else if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) { 225 /* sci = source_mac + port_id when ES.bit = 1 & SC.bit = 0 */ 226 const uint8_t *smac = td->plain_pkt.data + RTE_ETHER_ADDR_LEN; 227 uint8_t *ptr = (uint8_t *)&sc_conf->sc_tx.sci; 228 229 ptr[0] = 0x01; 230 ptr[1] = 0; 231 for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) 232 ptr[2 + i] = smac[RTE_ETHER_ADDR_LEN - 1 - i]; 233 } else { 234 /* use some default SCI */ 235 sc_conf->sc_tx.sci = 0xf1341e023a2b1c5d; 236 } 237 if (td->xpn > 0) 238 sc_conf->sc_tx.is_xpn = 1; 239 } else { 240 for (i = 0; i < RTE_SECURITY_MACSEC_NUM_AN; i++) { 241 sc_conf->sc_rx.sa_id[i] = sa_id[i]; 242 sc_conf->sc_rx.sa_in_use[i] = opts->sa_in_use; 243 } 244 sc_conf->sc_rx.active = 1; 245 if (td->xpn > 0) 246 sc_conf->sc_rx.is_xpn = 1; 247 } 248 } 249 250 251 /* Create Inline MACsec session */ 252 static int 253 fill_session_conf(const struct mcs_test_vector *td, uint16_t portid __rte_unused, 254 const struct mcs_test_opts *opts, 255 struct rte_security_session_conf *sess_conf, 256 enum rte_security_macsec_direction dir, 257 uint16_t sc_id, 258 uint8_t tci_off) 259 { 260 sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL; 261 sess_conf->protocol = RTE_SECURITY_PROTOCOL_MACSEC; 262 sess_conf->macsec.dir = dir; 263 sess_conf->macsec.alg = td->alg; 264 sess_conf->macsec.cipher_off = 0; 265 if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) { 266 sess_conf->macsec.sci = rte_be_to_cpu_64(*(const uint64_t *) 267 (&td->secure_pkt.data[tci_off + 6])); 268 } else if (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) { 269 /* sci = source_mac + port_id when ES.bit = 1 & SC.bit = 0 */ 270 const uint8_t *smac = td->plain_pkt.data + RTE_ETHER_ADDR_LEN; 271 uint8_t *ptr = (uint8_t *)&sess_conf->macsec.sci; 272 uint8_t j; 273 274 ptr[0] = 0x01; 275 ptr[1] = 0; 276 for (j = 0; j < RTE_ETHER_ADDR_LEN; j++) 277 ptr[2 + j] = smac[RTE_ETHER_ADDR_LEN - 1 - j]; 278 } 279 sess_conf->macsec.sc_id = sc_id; 280 if (dir == RTE_SECURITY_MACSEC_DIR_TX) { 281 sess_conf->macsec.tx_secy.mtu = opts->mtu; 282 sess_conf->macsec.tx_secy.sectag_off = (opts->sectag_insert_mode == 1) ? 283 2 * RTE_ETHER_ADDR_LEN : 284 RTE_VLAN_HLEN; 285 sess_conf->macsec.tx_secy.sectag_insert_mode = opts->sectag_insert_mode; 286 sess_conf->macsec.tx_secy.ctrl_port_enable = 1; 287 sess_conf->macsec.tx_secy.sectag_version = 0; 288 sess_conf->macsec.tx_secy.end_station = 289 (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_ES) >> 6; 290 sess_conf->macsec.tx_secy.send_sci = 291 (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SC) >> 5; 292 sess_conf->macsec.tx_secy.scb = 293 (td->secure_pkt.data[tci_off] & RTE_MACSEC_TCI_SCB) >> 4; 294 sess_conf->macsec.tx_secy.encrypt = opts->encrypt; 295 sess_conf->macsec.tx_secy.protect_frames = opts->protect_frames; 296 sess_conf->macsec.tx_secy.icv_include_da_sa = 1; 297 } else { 298 sess_conf->macsec.rx_secy.replay_win_sz = opts->replay_win_sz; 299 sess_conf->macsec.rx_secy.replay_protect = opts->replay_protect; 300 sess_conf->macsec.rx_secy.icv_include_da_sa = 1; 301 sess_conf->macsec.rx_secy.ctrl_port_enable = 1; 302 sess_conf->macsec.rx_secy.preserve_sectag = 0; 303 sess_conf->macsec.rx_secy.preserve_icv = 0; 304 sess_conf->macsec.rx_secy.validate_frames = opts->val_frames; 305 } 306 307 return 0; 308 } 309 310 static int 311 create_default_flow(const struct mcs_test_vector *td, uint16_t portid, 312 enum rte_security_macsec_direction dir, void *sess) 313 { 314 struct rte_flow_action action[2]; 315 struct rte_flow_item pattern[2]; 316 struct rte_flow_attr attr = {0}; 317 struct rte_flow_error err; 318 struct rte_flow *flow; 319 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 320 static const struct rte_flow_item_eth eth_mask = { 321 .hdr.dst_addr.addr_bytes = "\x00\x00\x00\x00\x00\x00", 322 .hdr.src_addr.addr_bytes = "\x00\x00\x00\x00\x00\x00", 323 .hdr.ether_type = RTE_BE16(0x0000), 324 }; 325 326 int ret; 327 328 eth.has_vlan = 0; 329 if (dir == RTE_SECURITY_MACSEC_DIR_TX) 330 memcpy(ð.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 while (j--) 956 rte_pktmbuf_free(tx_pkts_burst[j]); 957 ret = TEST_FAILED; 958 goto out; 959 } 960 j++; 961 962 if (opts->replay_protect) { 963 for (k = 0; k < 3; k++, j++) { 964 tx_pkts_burst[j] = init_packet(mbufpool, 965 opts->ar_td[k]->secure_pkt.data, 966 opts->ar_td[k]->secure_pkt.len); 967 if (tx_pkts_burst[j] == NULL) { 968 while (j--) 969 rte_pktmbuf_free(tx_pkts_burst[j]); 970 ret = TEST_FAILED; 971 goto out; 972 } 973 } 974 } 975 976 if (opts->rekey_en) { 977 978 err_vector.td = td[i]; 979 err_vector.rekey_td = opts->rekey_td; 980 err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN; 981 err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN; 982 rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC, 983 test_macsec_event_callback, &err_vector); 984 if (op == MCS_DECAP || op == MCS_VERIFY_ONLY) 985 tx_pkts_burst[j] = init_packet(mbufpool, 986 opts->rekey_td->secure_pkt.data, 987 opts->rekey_td->secure_pkt.len); 988 else { 989 tx_pkts_burst[j] = init_packet(mbufpool, 990 opts->rekey_td->plain_pkt.data, 991 opts->rekey_td->plain_pkt.len); 992 993 tx_pkts_burst[j]->ol_flags |= RTE_MBUF_F_TX_MACSEC; 994 } 995 if (tx_pkts_burst[j] == NULL) { 996 while (j--) 997 rte_pktmbuf_free(tx_pkts_burst[j]); 998 ret = TEST_FAILED; 999 goto out; 1000 } 1001 j++; 1002 } 1003 1004 if (op == MCS_DECAP || op == MCS_ENCAP_DECAP || 1005 op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) { 1006 for (an = 0; an < RTE_SECURITY_MACSEC_NUM_AN; an++) { 1007 if (opts->rekey_en && an == 1008 (opts->rekey_td->secure_pkt.data[tci_off] & 1009 RTE_MACSEC_AN_MASK)) 1010 fill_macsec_sa_conf(opts->rekey_td, &sa_conf, 1011 RTE_SECURITY_MACSEC_DIR_RX, an, tci_off); 1012 else 1013 /* For simplicity, using same SA conf for all AN */ 1014 fill_macsec_sa_conf(td[i], &sa_conf, 1015 RTE_SECURITY_MACSEC_DIR_RX, an, tci_off); 1016 id = rte_security_macsec_sa_create(ctx, &sa_conf); 1017 if (id < 0) { 1018 printf("MACsec SA create failed : %d.\n", id); 1019 return TEST_FAILED; 1020 } 1021 rx_sa_id[i][an] = (uint16_t)id; 1022 } 1023 fill_macsec_sc_conf(td[i], &sc_conf, opts, 1024 RTE_SECURITY_MACSEC_DIR_RX, rx_sa_id[i], tci_off); 1025 id = rte_security_macsec_sc_create(ctx, &sc_conf); 1026 if (id < 0) { 1027 printf("MACsec SC create failed : %d.\n", id); 1028 goto out; 1029 } 1030 rx_sc_id[i] = (uint16_t)id; 1031 1032 /* Create Inline IPsec session. */ 1033 ret = fill_session_conf(td[i], port_id, opts, &sess_conf, 1034 RTE_SECURITY_MACSEC_DIR_RX, rx_sc_id[i], tci_off); 1035 if (ret) 1036 return TEST_FAILED; 1037 1038 rx_sess[i] = rte_security_session_create(ctx, &sess_conf, 1039 sess_pool); 1040 if (rx_sess[i] == NULL) { 1041 printf("SEC Session init failed.\n"); 1042 return TEST_FAILED; 1043 } 1044 ret = create_default_flow(td[i], port_id, 1045 RTE_SECURITY_MACSEC_DIR_RX, rx_sess[i]); 1046 if (ret) 1047 goto out; 1048 } 1049 if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP || 1050 op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) { 1051 int id; 1052 1053 fill_macsec_sa_conf(td[i], &sa_conf, 1054 RTE_SECURITY_MACSEC_DIR_TX, 1055 td[i]->secure_pkt.data[tci_off] & RTE_MACSEC_AN_MASK, 1056 tci_off); 1057 id = rte_security_macsec_sa_create(ctx, &sa_conf); 1058 if (id < 0) { 1059 printf("MACsec SA create failed : %d.\n", id); 1060 return TEST_FAILED; 1061 } 1062 tx_sa_id[i][0] = (uint16_t)id; 1063 tx_sa_id[i][1] = MCS_INVALID_SA; 1064 if (opts->rekey_en) { 1065 memset(&sa_conf, 0, sizeof(struct rte_security_macsec_sa)); 1066 fill_macsec_sa_conf(opts->rekey_td, &sa_conf, 1067 RTE_SECURITY_MACSEC_DIR_TX, 1068 opts->rekey_td->secure_pkt.data[tci_off] & 1069 RTE_MACSEC_AN_MASK, 1070 tci_off); 1071 id = rte_security_macsec_sa_create(ctx, &sa_conf); 1072 if (id < 0) { 1073 printf("MACsec rekey SA create failed : %d.\n", id); 1074 goto out; 1075 } 1076 tx_sa_id[i][1] = (uint16_t)id; 1077 } 1078 fill_macsec_sc_conf(td[i], &sc_conf, opts, 1079 RTE_SECURITY_MACSEC_DIR_TX, tx_sa_id[i], tci_off); 1080 id = rte_security_macsec_sc_create(ctx, &sc_conf); 1081 if (id < 0) { 1082 printf("MACsec SC create failed : %d.\n", id); 1083 goto out; 1084 } 1085 tx_sc_id[i] = (uint16_t)id; 1086 1087 /* Create Inline IPsec session. */ 1088 ret = fill_session_conf(td[i], port_id, opts, &sess_conf, 1089 RTE_SECURITY_MACSEC_DIR_TX, tx_sc_id[i], tci_off); 1090 if (ret) 1091 return TEST_FAILED; 1092 1093 tx_sess[i] = rte_security_session_create(ctx, &sess_conf, 1094 sess_pool); 1095 if (tx_sess[i] == NULL) { 1096 printf("SEC Session init failed.\n"); 1097 return TEST_FAILED; 1098 } 1099 ret = create_default_flow(td[i], port_id, 1100 RTE_SECURITY_MACSEC_DIR_TX, tx_sess[i]); 1101 if (ret) 1102 goto out; 1103 } 1104 } 1105 1106 /* Send packet to ethdev for inline MACsec processing. */ 1107 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, j); 1108 1109 if (nb_sent != j) { 1110 printf("\nUnable to TX %d packets, sent: %i", j, nb_sent); 1111 for ( ; nb_sent < j; nb_sent++) 1112 rte_pktmbuf_free(tx_pkts_burst[nb_sent]); 1113 ret = TEST_FAILED; 1114 goto out; 1115 } 1116 1117 rte_pause(); 1118 1119 /* Receive back packet on loopback interface. */ 1120 do { 1121 nb_rx += rte_eth_rx_burst(port_id, 0, 1122 &rx_pkts_burst[nb_rx], 1123 nb_sent - nb_rx); 1124 if (nb_rx >= nb_sent) 1125 break; 1126 rte_delay_ms(1); 1127 } while (j++ < 5 && nb_rx == 0); 1128 1129 if (nb_rx != nb_sent) { 1130 printf("\nUnable to RX all %d packets, received(%i)", 1131 nb_sent, nb_rx); 1132 while (--nb_rx >= 0) 1133 rte_pktmbuf_free(rx_pkts_burst[nb_rx]); 1134 ret = TEST_FAILED; 1135 if (opts->check_sectag_interrupts == 1) 1136 ret = TEST_SUCCESS; 1137 goto out; 1138 } 1139 1140 if (opts->rekey_en) { 1141 switch (err_vector.event) { 1142 case RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP: 1143 printf("Received RTE_ETH_EVENT_MACSEC_TX_SA_PN_SOFT_EXP event\n"); 1144 /* The first sa is active now, so the 0th sa can be 1145 * reconfigured. Using the same key as zeroeth sa, but 1146 * other key can also be configured. 1147 */ 1148 rte_security_macsec_sa_destroy(ctx, tx_sa_id[0][0], 1149 RTE_SECURITY_MACSEC_DIR_TX); 1150 fill_macsec_sa_conf(td[0], &sa_conf, 1151 RTE_SECURITY_MACSEC_DIR_TX, 1152 td[0]->secure_pkt.data[tci_off] & 1153 RTE_MACSEC_AN_MASK, tci_off); 1154 id = rte_security_macsec_sa_create(ctx, &sa_conf); 1155 if (id < 0) { 1156 printf("MACsec SA create failed : %d.\n", id); 1157 return TEST_FAILED; 1158 } 1159 tx_sa_id[0][0] = (uint16_t)id; 1160 break; 1161 case RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP: 1162 printf("Received RTE_ETH_EVENT_MACSEC_RX_SA_PN_SOFT_EXP event\n"); 1163 break; 1164 default: 1165 printf("Received unsupported event\n"); 1166 } 1167 } 1168 1169 if (opts->replay_protect) { 1170 for (i = 0; i < nb_rx; i++) { 1171 rte_pktmbuf_free(rx_pkts_burst[i]); 1172 rx_pkts_burst[i] = NULL; 1173 } 1174 ret = TEST_SUCCESS; 1175 goto out; 1176 } 1177 1178 for (i = 0; i < nb_rx; i++) { 1179 if (opts->rekey_en && i == 1) { 1180 /* The second received packet is matched with 1181 * rekey td 1182 */ 1183 ret = test_macsec_post_process(rx_pkts_burst[i], 1184 opts->rekey_td, op, 1185 opts->check_out_pkts_untagged); 1186 } else { 1187 ret = test_macsec_post_process(rx_pkts_burst[i], td[i], 1188 op, opts->check_out_pkts_untagged); 1189 } 1190 if (ret != TEST_SUCCESS) { 1191 for ( ; i < nb_rx; i++) 1192 rte_pktmbuf_free(rx_pkts_burst[i]); 1193 goto out; 1194 } 1195 1196 rte_pktmbuf_free(rx_pkts_burst[i]); 1197 rx_pkts_burst[i] = NULL; 1198 } 1199 out: 1200 if (opts->check_out_pkts_toolong == 1 || 1201 opts->check_sa_not_in_use == 1 || 1202 opts->check_bad_tag_cnt == 1) 1203 ret = TEST_SUCCESS; 1204 1205 for (i = 0; i < opts->nb_td; i++) { 1206 if (opts->dump_all_stats) { 1207 mcs_stats_dump(ctx, op, 1208 rx_sess[i], tx_sess[i], 1209 rx_sc_id[i], tx_sc_id[i], 1210 rx_sa_id[i], tx_sa_id[i]); 1211 } else { 1212 if (ret == TEST_SUCCESS) 1213 ret = mcs_stats_check(ctx, op, opts, td[i], 1214 rx_sess[i], tx_sess[i], 1215 rx_sc_id[i], tx_sc_id[i], 1216 rx_sa_id[i], tx_sa_id[i]); 1217 } 1218 } 1219 1220 destroy_default_flow(port_id); 1221 1222 if (opts->rekey_en) 1223 rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC, 1224 test_macsec_event_callback, &err_vector); 1225 1226 /* Destroy session so that other cases can create the session again */ 1227 for (i = 0; i < opts->nb_td; i++) { 1228 if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP || 1229 op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) { 1230 rte_security_session_destroy(ctx, tx_sess[i]); 1231 tx_sess[i] = NULL; 1232 rte_security_macsec_sc_destroy(ctx, tx_sc_id[i], 1233 RTE_SECURITY_MACSEC_DIR_TX); 1234 rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][0], 1235 RTE_SECURITY_MACSEC_DIR_TX); 1236 if (opts->rekey_en) { 1237 rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][1], 1238 RTE_SECURITY_MACSEC_DIR_TX); 1239 } 1240 } 1241 if (op == MCS_DECAP || op == MCS_ENCAP_DECAP || 1242 op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) { 1243 rte_security_session_destroy(ctx, rx_sess[i]); 1244 rx_sess[i] = NULL; 1245 rte_security_macsec_sc_destroy(ctx, rx_sc_id[i], 1246 RTE_SECURITY_MACSEC_DIR_RX); 1247 for (j = 0; j < RTE_SECURITY_MACSEC_NUM_AN; j++) { 1248 rte_security_macsec_sa_destroy(ctx, rx_sa_id[i][j], 1249 RTE_SECURITY_MACSEC_DIR_RX); 1250 } 1251 } 1252 } 1253 1254 return ret; 1255 } 1256 1257 static int 1258 test_inline_macsec_encap_all(void) 1259 { 1260 const struct mcs_test_vector *cur_td; 1261 struct mcs_test_opts opts = {0}; 1262 int err, all_err = 0; 1263 int skipped = 0; 1264 int i, size; 1265 1266 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1267 opts.encrypt = true; 1268 opts.protect_frames = true; 1269 opts.sa_in_use = 1; 1270 opts.nb_td = 1; 1271 opts.sectag_insert_mode = 1; 1272 opts.mtu = RTE_ETHER_MTU; 1273 1274 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1275 for (i = 0; i < size; i++) { 1276 cur_td = &list_mcs_cipher_vectors[i]; 1277 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 1278 if (err == TEST_SKIPPED) { 1279 printf("Cipher Auth Encryption case %d skipped\n", cur_td->test_idx); 1280 skipped += 1; 1281 err = 0; 1282 } else if (err) { 1283 printf("\nCipher Auth Encryption case %d failed", cur_td->test_idx); 1284 err = -1; 1285 } else { 1286 printf("\nCipher Auth Encryption case %d Passed", cur_td->test_idx); 1287 err = 0; 1288 } 1289 all_err += err; 1290 } 1291 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1292 size + all_err - skipped, -all_err, skipped); 1293 1294 return skipped > 0 ? TEST_SKIPPED : all_err; 1295 } 1296 1297 static int 1298 test_inline_macsec_decap_all(void) 1299 { 1300 const struct mcs_test_vector *cur_td; 1301 struct mcs_test_opts opts = {0}; 1302 int err, all_err = 0; 1303 int skipped = 0; 1304 int i, size; 1305 1306 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1307 opts.sa_in_use = 1; 1308 opts.nb_td = 1; 1309 opts.sectag_insert_mode = 1; 1310 opts.mtu = RTE_ETHER_MTU; 1311 1312 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1313 for (i = 0; i < size; i++) { 1314 cur_td = &list_mcs_cipher_vectors[i]; 1315 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1316 if (err == TEST_SKIPPED) { 1317 printf("Cipher Auth Decryption case %d skipped\n", cur_td->test_idx); 1318 skipped += 1; 1319 err = 0; 1320 } else if (err) { 1321 printf("\nCipher Auth Decryption case %d failed", cur_td->test_idx); 1322 err = -1; 1323 } else { 1324 printf("\nCipher Auth Decryption case %d Passed", cur_td->test_idx); 1325 err = 0; 1326 } 1327 all_err += err; 1328 } 1329 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1330 size + all_err - skipped, -all_err, skipped); 1331 1332 return skipped > 0 ? TEST_SKIPPED : all_err; 1333 } 1334 1335 static int 1336 test_inline_macsec_auth_only_all(void) 1337 { 1338 const struct mcs_test_vector *cur_td; 1339 struct mcs_test_opts opts = {0}; 1340 int err, all_err = 0; 1341 int skipped = 0; 1342 int i, size; 1343 1344 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1345 opts.protect_frames = true; 1346 opts.sa_in_use = 1; 1347 opts.nb_td = 1; 1348 opts.sectag_insert_mode = 1; 1349 opts.mtu = RTE_ETHER_MTU; 1350 1351 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1352 1353 for (i = 0; i < size; i++) { 1354 cur_td = &list_mcs_integrity_vectors[i]; 1355 err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts); 1356 if (err == TEST_SKIPPED) { 1357 printf("Auth Generate case %d skipped\n", cur_td->test_idx); 1358 skipped += 1; 1359 err = 0; 1360 } else if (err) { 1361 printf("\nAuth Generate case %d failed", cur_td->test_idx); 1362 err = -1; 1363 } else { 1364 printf("\nAuth Generate case %d Passed", cur_td->test_idx); 1365 err = 0; 1366 } 1367 all_err += err; 1368 } 1369 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1370 size + all_err - skipped, -all_err, skipped); 1371 1372 return skipped > 0 ? TEST_SKIPPED : all_err; 1373 } 1374 1375 static int 1376 test_inline_macsec_verify_only_all(void) 1377 { 1378 const struct mcs_test_vector *cur_td; 1379 struct mcs_test_opts opts = {0}; 1380 int err, all_err = 0; 1381 int skipped = 0; 1382 int i, size; 1383 1384 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1385 opts.sa_in_use = 1; 1386 opts.nb_td = 1; 1387 opts.sectag_insert_mode = 1; 1388 opts.mtu = RTE_ETHER_MTU; 1389 1390 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1391 1392 for (i = 0; i < size; i++) { 1393 cur_td = &list_mcs_integrity_vectors[i]; 1394 err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts); 1395 if (err == TEST_SKIPPED) { 1396 printf("Auth Verify case %d skipped\n", cur_td->test_idx); 1397 skipped += 1; 1398 err = 0; 1399 } else if (err) { 1400 printf("\nAuth Verify case %d failed", cur_td->test_idx); 1401 err = -1; 1402 } else { 1403 printf("\nAuth Verify case %d Passed", cur_td->test_idx); 1404 err = 0; 1405 } 1406 all_err += err; 1407 } 1408 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1409 size + all_err - skipped, -all_err, skipped); 1410 1411 return skipped > 0 ? TEST_SKIPPED : all_err; 1412 } 1413 1414 static int 1415 test_inline_macsec_encap_decap_all(void) 1416 { 1417 const struct mcs_test_vector *cur_td; 1418 struct mcs_test_opts opts = {0}; 1419 int err, all_err = 0; 1420 int skipped = 0; 1421 int i, size; 1422 1423 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1424 opts.encrypt = true; 1425 opts.protect_frames = true; 1426 opts.sa_in_use = 1; 1427 opts.nb_td = 1; 1428 opts.sectag_insert_mode = 1; 1429 opts.mtu = RTE_ETHER_MTU; 1430 1431 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1432 1433 for (i = 0; i < size; i++) { 1434 cur_td = &list_mcs_cipher_vectors[i]; 1435 err = test_macsec(&cur_td, MCS_ENCAP_DECAP, &opts); 1436 if (err == TEST_SKIPPED) { 1437 printf("Cipher Auth Encap-decap case %d skipped\n", cur_td->test_idx); 1438 skipped += 1; 1439 err = 0; 1440 } else if (err) { 1441 printf("\nCipher Auth Encap-decap case %d failed", cur_td->test_idx); 1442 err = -1; 1443 } else { 1444 printf("\nCipher Auth Encap-decap case %d Passed", cur_td->test_idx); 1445 err = 0; 1446 } 1447 all_err += err; 1448 } 1449 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1450 size + all_err - skipped, -all_err, skipped); 1451 1452 return skipped > 0 ? TEST_SKIPPED : all_err; 1453 } 1454 1455 1456 static int 1457 test_inline_macsec_auth_verify_all(void) 1458 { 1459 const struct mcs_test_vector *cur_td; 1460 struct mcs_test_opts opts = {0}; 1461 int err, all_err = 0; 1462 int skipped = 0; 1463 int i, size; 1464 1465 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1466 opts.protect_frames = true; 1467 opts.sa_in_use = 1; 1468 opts.nb_td = 1; 1469 opts.sectag_insert_mode = 1; 1470 opts.mtu = RTE_ETHER_MTU; 1471 1472 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1473 1474 for (i = 0; i < size; i++) { 1475 cur_td = &list_mcs_integrity_vectors[i]; 1476 err = test_macsec(&cur_td, MCS_AUTH_VERIFY, &opts); 1477 if (err == TEST_SKIPPED) { 1478 printf("Auth Generate + Verify case %d skipped\n", cur_td->test_idx); 1479 skipped += 1; 1480 err = 0; 1481 } else if (err) { 1482 printf("\nAuth Generate + Verify case %d failed", cur_td->test_idx); 1483 err = -1; 1484 } else { 1485 printf("\nAuth Generate + Verify case %d Passed", cur_td->test_idx); 1486 err = 0; 1487 } 1488 all_err += err; 1489 } 1490 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1491 size + all_err - skipped, -all_err, skipped); 1492 1493 return skipped > 0 ? TEST_SKIPPED : all_err; 1494 } 1495 1496 static int 1497 test_inline_macsec_multi_flow(void) 1498 { 1499 const struct mcs_test_vector *tv[MCS_MAX_FLOWS]; 1500 struct mcs_test_vector iter[MCS_MAX_FLOWS]; 1501 struct mcs_test_opts opts = {0}; 1502 int i, err; 1503 1504 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1505 opts.encrypt = true; 1506 opts.protect_frames = true; 1507 opts.sa_in_use = 1; 1508 opts.nb_td = MCS_MAX_FLOWS; 1509 opts.sectag_insert_mode = 1; 1510 opts.mtu = RTE_ETHER_MTU; 1511 1512 for (i = 0; i < MCS_MAX_FLOWS; i++) { 1513 memcpy(&iter[i].sa_key.data, sa_key, MCS_MULTI_FLOW_TD_KEY_SZ); 1514 memcpy(&iter[i].plain_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN); 1515 memcpy(&iter[i].plain_pkt.data[2 * RTE_ETHER_ADDR_LEN], plain_user_data, 1516 MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ); 1517 memcpy(&iter[i].secure_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN); 1518 memcpy(&iter[i].secure_pkt.data[2 * RTE_ETHER_ADDR_LEN], secure_user_data, 1519 MCS_MULTI_FLOW_TD_SECURE_DATA_SZ); 1520 iter[i].sa_key.len = MCS_MULTI_FLOW_TD_KEY_SZ; 1521 iter[i].plain_pkt.len = MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ + 1522 (2 * RTE_ETHER_ADDR_LEN); 1523 iter[i].secure_pkt.len = MCS_MULTI_FLOW_TD_SECURE_DATA_SZ + 1524 (2 * RTE_ETHER_ADDR_LEN); 1525 iter[i].alg = RTE_SECURITY_MACSEC_ALG_GCM_128; 1526 iter[i].ssci = 0x0; 1527 iter[i].xpn = 0x0; 1528 tv[i] = (const struct mcs_test_vector *)&iter[i]; 1529 } 1530 err = test_macsec(tv, MCS_ENCAP_DECAP, &opts); 1531 if (err == TEST_SKIPPED) { 1532 printf("Cipher Auth Encryption multi flow skipped\n"); 1533 } else if (err) { 1534 printf("\nCipher Auth Encryption multi flow failed"); 1535 err = -1; 1536 } else { 1537 printf("\nCipher Auth Encryption multi flow Passed"); 1538 err = 0; 1539 } 1540 return err; 1541 } 1542 1543 static int 1544 test_inline_macsec_with_vlan(void) 1545 { 1546 const struct mcs_test_vector *cur_td; 1547 struct mcs_test_opts opts = {0}; 1548 int err, all_err = 0; 1549 int skipped = 0; 1550 int i, size; 1551 1552 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1553 opts.protect_frames = true; 1554 opts.sa_in_use = 1; 1555 opts.nb_td = 1; 1556 opts.mtu = RTE_ETHER_MTU; 1557 1558 size = (sizeof(list_mcs_vlan_vectors) / sizeof((list_mcs_vlan_vectors)[0])); 1559 1560 for (i = 0; i < size; i++) { 1561 cur_td = &list_mcs_vlan_vectors[i]; 1562 if (i == 0) { 1563 opts.sectag_insert_mode = 1; 1564 } else if (i == 1) { 1565 opts.sectag_insert_mode = 0; /* offset from special E-type */ 1566 opts.nb_vlan = 1; 1567 } else if (i == 2) { 1568 opts.sectag_insert_mode = 0; /* offset from special E-type */ 1569 opts.nb_vlan = 2; 1570 } 1571 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 1572 if (err == TEST_SKIPPED) { 1573 printf("VLAN Encap case %d skipped", cur_td->test_idx); 1574 skipped += 1; 1575 err = 0; 1576 } else if (err) { 1577 printf("\n VLAN Encap case %d failed", cur_td->test_idx); 1578 err = -1; 1579 } else { 1580 printf("\n VLAN Encap case %d passed", cur_td->test_idx); 1581 err = 0; 1582 } 1583 all_err += err; 1584 } 1585 for (i = 0; i < size; i++) { 1586 cur_td = &list_mcs_vlan_vectors[i]; 1587 if (i == 0) { 1588 opts.sectag_insert_mode = 1; 1589 } else if (i == 1) { 1590 opts.sectag_insert_mode = 0; /* offset from special E-type */ 1591 opts.nb_vlan = 1; 1592 } else if (i == 2) { 1593 opts.sectag_insert_mode = 0; /* offset from special E-type */ 1594 opts.nb_vlan = 2; 1595 } 1596 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1597 if (err == TEST_SKIPPED) { 1598 printf("VLAN Decap case %d skipped", cur_td->test_idx); 1599 skipped += 1; 1600 err = 0; 1601 } else if (err) { 1602 printf("\n VLAN Decap case %d failed", cur_td->test_idx); 1603 err = -1; 1604 } else { 1605 printf("\n VLAN Decap case %d passed", cur_td->test_idx); 1606 err = 0; 1607 } 1608 all_err += err; 1609 } 1610 1611 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1612 2 * size + all_err - skipped, -all_err, skipped); 1613 return skipped > 0 ? TEST_SKIPPED : all_err; 1614 } 1615 1616 static int 1617 test_inline_macsec_pkt_drop(void) 1618 { 1619 const struct mcs_test_vector *cur_td; 1620 struct mcs_test_opts opts = {0}; 1621 int err, all_err = 0; 1622 int skipped = 0; 1623 int i, size; 1624 1625 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1626 opts.encrypt = true; 1627 opts.protect_frames = true; 1628 opts.sa_in_use = 1; 1629 opts.nb_td = 1; 1630 opts.sectag_insert_mode = 1; 1631 opts.mtu = RTE_ETHER_MTU; 1632 1633 size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0])); 1634 1635 for (i = 0; i < size; i++) { 1636 cur_td = &list_mcs_err_cipher_vectors[i]; 1637 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1638 if (err == TEST_SKIPPED) { 1639 printf("Packet drop case %d skipped", cur_td->test_idx); 1640 skipped += 1; 1641 err = 0; 1642 } else if (err) { 1643 printf("\nPacket drop case %d passed", cur_td->test_idx); 1644 err = 0; 1645 } else { 1646 printf("\nPacket drop case %d failed", cur_td->test_idx); 1647 err = -1; 1648 } 1649 all_err += err; 1650 } 1651 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1652 size + all_err - skipped, -all_err, skipped); 1653 1654 return skipped > 0 ? TEST_SKIPPED : all_err; 1655 } 1656 1657 static int 1658 test_inline_macsec_untagged_rx(void) 1659 { 1660 const struct mcs_test_vector *cur_td; 1661 struct mcs_test_opts opts = {0}; 1662 int err, all_err = 0; 1663 int skipped = 0; 1664 int i, size; 1665 1666 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1667 opts.sa_in_use = 1; 1668 opts.nb_td = 1; 1669 opts.sectag_insert_mode = 1; 1670 opts.mtu = RTE_ETHER_MTU; 1671 opts.check_untagged_rx = 1; 1672 1673 size = (sizeof(list_mcs_untagged_cipher_vectors) / 1674 sizeof((list_mcs_untagged_cipher_vectors)[0])); 1675 1676 for (i = 0; i < size; i++) { 1677 cur_td = &list_mcs_untagged_cipher_vectors[i]; 1678 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1679 if (err == TEST_SKIPPED) { 1680 skipped += 1; 1681 err = 0; 1682 } else if (err) 1683 err = 0; 1684 else 1685 err = -1; 1686 1687 all_err += err; 1688 } 1689 1690 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD; 1691 for (i = 0; i < size; i++) { 1692 cur_td = &list_mcs_untagged_cipher_vectors[i]; 1693 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1694 if (err == TEST_SKIPPED) { 1695 skipped += 1; 1696 err = 0; 1697 } else if (err) 1698 err = 0; 1699 else 1700 err = -1; 1701 1702 all_err += err; 1703 } 1704 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1705 2 * size + all_err - skipped, -all_err, skipped); 1706 1707 return skipped > 0 ? TEST_SKIPPED : all_err; 1708 } 1709 1710 static int 1711 test_inline_macsec_bad_tag_rx(void) 1712 { 1713 const struct mcs_test_vector *cur_td; 1714 struct mcs_test_opts opts = {0}; 1715 int err, all_err = 0; 1716 int skipped = 0; 1717 int i, size; 1718 1719 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1720 opts.protect_frames = true; 1721 opts.sa_in_use = 1; 1722 opts.nb_td = 1; 1723 opts.sectag_insert_mode = 1; 1724 opts.mtu = RTE_ETHER_MTU; 1725 opts.check_bad_tag_cnt = 1; 1726 1727 size = (sizeof(list_mcs_bad_tag_vectors) / sizeof((list_mcs_bad_tag_vectors)[0])); 1728 1729 for (i = 0; i < size; i++) { 1730 cur_td = &list_mcs_bad_tag_vectors[i]; 1731 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1732 if (err == TEST_SKIPPED) { 1733 skipped += 1; 1734 err = 0; 1735 } else if (err) 1736 err = -1; 1737 else 1738 err = 0; 1739 1740 all_err += err; 1741 } 1742 1743 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1744 size + all_err - skipped, -all_err, skipped); 1745 1746 return skipped > 0 ? TEST_SKIPPED : all_err; 1747 } 1748 1749 static int 1750 test_inline_macsec_sa_not_in_use(void) 1751 { 1752 const struct mcs_test_vector *cur_td; 1753 struct mcs_test_opts opts = {0}; 1754 int err, all_err = 0; 1755 int skipped = 0; 1756 int i, size; 1757 1758 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1759 opts.protect_frames = true; 1760 opts.sa_in_use = 0; 1761 opts.nb_td = 1; 1762 opts.sectag_insert_mode = 1; 1763 opts.mtu = RTE_ETHER_MTU; 1764 opts.check_sa_not_in_use = 1; 1765 1766 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1767 1768 for (i = 0; i < size; i++) { 1769 cur_td = &list_mcs_cipher_vectors[i]; 1770 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1771 if (err == TEST_SKIPPED) { 1772 skipped += 1; 1773 err = 0; 1774 } else if (err) 1775 err = -1; 1776 else 1777 err = 0; 1778 1779 all_err += err; 1780 } 1781 1782 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1783 size + all_err - skipped, -all_err, skipped); 1784 1785 return skipped > 0 ? TEST_SKIPPED : all_err; 1786 } 1787 1788 static int 1789 test_inline_macsec_decap_stats(void) 1790 { 1791 const struct mcs_test_vector *cur_td; 1792 struct mcs_test_opts opts = {0}; 1793 int err, all_err = 0; 1794 int skipped = 0; 1795 int i, size; 1796 1797 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1798 opts.protect_frames = true; 1799 opts.sa_in_use = 1; 1800 opts.nb_td = 1; 1801 opts.sectag_insert_mode = 1; 1802 opts.mtu = RTE_ETHER_MTU; 1803 opts.check_decap_stats = 1; 1804 1805 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1806 1807 for (i = 0; i < size; i++) { 1808 cur_td = &list_mcs_cipher_vectors[i]; 1809 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1810 if (err == TEST_SKIPPED) { 1811 printf("Decap stats case %d skipped\n", cur_td->test_idx); 1812 skipped += 1; 1813 err = 0; 1814 } else if (err) { 1815 printf("\nDecap stats case %d failed", cur_td->test_idx); 1816 err = -1; 1817 } else { 1818 printf("\nDecap stats case %d passed", cur_td->test_idx); 1819 err = 0; 1820 } 1821 all_err += err; 1822 } 1823 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1824 size + all_err - skipped, -all_err, skipped); 1825 1826 return skipped > 0 ? TEST_SKIPPED : all_err; 1827 } 1828 1829 static int 1830 test_inline_macsec_verify_only_stats(void) 1831 { 1832 const struct mcs_test_vector *cur_td; 1833 struct mcs_test_opts opts = {0}; 1834 int err, all_err = 0; 1835 int skipped = 0; 1836 int i, size; 1837 1838 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1839 opts.protect_frames = true; 1840 opts.sa_in_use = 1; 1841 opts.nb_td = 1; 1842 opts.sectag_insert_mode = 1; 1843 opts.mtu = RTE_ETHER_MTU; 1844 opts.check_verify_only_stats = 1; 1845 1846 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1847 1848 for (i = 0; i < size; i++) { 1849 cur_td = &list_mcs_integrity_vectors[i]; 1850 err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts); 1851 if (err == TEST_SKIPPED) { 1852 printf("Verify only stats case %d skipped\n", cur_td->test_idx); 1853 skipped += 1; 1854 err = 0; 1855 } else if (err) { 1856 printf("\nVerify only stats case %d failed", cur_td->test_idx); 1857 err = -1; 1858 } else { 1859 printf("\nVerify only stats case %d Passed", cur_td->test_idx); 1860 err = 0; 1861 } 1862 all_err += err; 1863 } 1864 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1865 size + all_err - skipped, -all_err, skipped); 1866 1867 return skipped > 0 ? TEST_SKIPPED : all_err; 1868 } 1869 1870 static int 1871 test_inline_macsec_pkts_invalid_stats(void) 1872 { 1873 const struct mcs_test_vector *cur_td; 1874 struct mcs_test_opts opts = {0}; 1875 int err, all_err = 0; 1876 int skipped = 0; 1877 int i, size; 1878 1879 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1880 opts.protect_frames = true; 1881 opts.sa_in_use = 1; 1882 opts.nb_td = 1; 1883 opts.sectag_insert_mode = 1; 1884 opts.mtu = RTE_ETHER_MTU; 1885 1886 size = (sizeof(list_mcs_err_cipher_vectors) / sizeof((list_mcs_err_cipher_vectors)[0])); 1887 1888 for (i = 0; i < size; i++) { 1889 cur_td = &list_mcs_err_cipher_vectors[i]; 1890 err = test_macsec(&cur_td, MCS_DECAP, &opts); 1891 if (err == TEST_SKIPPED) { 1892 skipped += 1; 1893 err = 0; 1894 } else if (err) 1895 err = 0; 1896 else 1897 err = -1; 1898 1899 all_err += err; 1900 } 1901 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1902 size + all_err - skipped, -all_err, skipped); 1903 return skipped > 0 ? TEST_SKIPPED : all_err; 1904 } 1905 1906 static int 1907 test_inline_macsec_pkts_unchecked_stats(void) 1908 { 1909 const struct mcs_test_vector *cur_td; 1910 struct mcs_test_opts opts = {0}; 1911 int err, all_err = 0; 1912 int skipped = 0; 1913 int i, size; 1914 1915 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_DISABLE; 1916 opts.protect_frames = true; 1917 opts.sa_in_use = 1; 1918 opts.nb_td = 1; 1919 opts.sectag_insert_mode = 1; 1920 opts.mtu = RTE_ETHER_MTU; 1921 opts.check_pkts_unchecked_stats = 1; 1922 1923 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1924 1925 for (i = 0; i < size; i++) { 1926 cur_td = &list_mcs_integrity_vectors[i]; 1927 err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts); 1928 if (err == TEST_SKIPPED) { 1929 skipped += 1; 1930 err = 0; 1931 } else if (err) 1932 err = -1; 1933 else 1934 err = 0; 1935 1936 all_err += err; 1937 } 1938 1939 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1940 size + all_err - skipped, -all_err, skipped); 1941 return skipped > 0 ? TEST_SKIPPED : all_err; 1942 } 1943 1944 static int 1945 test_inline_macsec_out_pkts_untagged(void) 1946 { 1947 const struct mcs_test_vector *cur_td; 1948 struct mcs_test_opts opts = {0}; 1949 int err, all_err = 0; 1950 int skipped = 0; 1951 int i, size; 1952 1953 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1954 opts.encrypt = false; 1955 opts.protect_frames = false; 1956 opts.sa_in_use = 1; 1957 opts.nb_td = 1; 1958 opts.sectag_insert_mode = 1; 1959 opts.mtu = RTE_ETHER_MTU; 1960 opts.check_out_pkts_untagged = 1; 1961 1962 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1963 for (i = 0; i < size; i++) { 1964 cur_td = &list_mcs_cipher_vectors[i]; 1965 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 1966 if (err == TEST_SKIPPED) { 1967 skipped += 1; 1968 err = 0; 1969 } else if (err) 1970 err = -1; 1971 else 1972 err = 0; 1973 1974 all_err += err; 1975 } 1976 1977 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 1978 size + all_err - skipped, -all_err, skipped); 1979 return skipped > 0 ? TEST_SKIPPED : all_err; 1980 } 1981 1982 static int 1983 test_inline_macsec_out_pkts_toolong(void) 1984 { 1985 const struct mcs_test_vector *cur_td; 1986 struct mcs_test_opts opts = {0}; 1987 int err, all_err = 0; 1988 int skipped = 0; 1989 int i, size; 1990 1991 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_NO_DISCARD; 1992 opts.encrypt = true; 1993 opts.protect_frames = true; 1994 opts.sa_in_use = 1; 1995 opts.nb_td = 1; 1996 opts.sectag_insert_mode = 1; 1997 opts.mtu = 50; 1998 opts.check_out_pkts_toolong = 1; 1999 2000 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 2001 for (i = 0; i < size; i++) { 2002 cur_td = &list_mcs_cipher_vectors[i]; 2003 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 2004 if (err == TEST_SKIPPED) { 2005 skipped += 1; 2006 err = 0; 2007 } else if (err) 2008 err = -1; 2009 else 2010 err = 0; 2011 2012 all_err += err; 2013 } 2014 2015 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2016 size + all_err - skipped, -all_err, skipped); 2017 return skipped > 0 ? TEST_SKIPPED : all_err; 2018 } 2019 2020 static int 2021 test_inline_macsec_encap_stats(void) 2022 { 2023 const struct mcs_test_vector *cur_td; 2024 struct mcs_test_opts opts = {0}; 2025 int err, all_err = 0; 2026 int skipped = 0; 2027 int i, size; 2028 2029 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2030 opts.encrypt = true; 2031 opts.protect_frames = true; 2032 opts.sa_in_use = 1; 2033 opts.nb_td = 1; 2034 opts.sectag_insert_mode = 1; 2035 opts.mtu = RTE_ETHER_MTU; 2036 opts.check_encap_stats = 1; 2037 2038 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 2039 for (i = 0; i < size; i++) { 2040 cur_td = &list_mcs_cipher_vectors[i]; 2041 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 2042 if (err == TEST_SKIPPED) { 2043 skipped += 1; 2044 err = 0; 2045 } else if (err) 2046 err = -1; 2047 else 2048 err = 0; 2049 2050 all_err += err; 2051 } 2052 2053 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2054 size + all_err - skipped, -all_err, skipped); 2055 return skipped > 0 ? TEST_SKIPPED : all_err; 2056 } 2057 2058 static int 2059 test_inline_macsec_auth_only_stats(void) 2060 { 2061 const struct mcs_test_vector *cur_td; 2062 struct mcs_test_opts opts = {0}; 2063 int err, all_err = 0; 2064 int skipped = 0; 2065 int i, size; 2066 2067 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2068 opts.protect_frames = true; 2069 opts.sa_in_use = 1; 2070 opts.nb_td = 1; 2071 opts.sectag_insert_mode = 1; 2072 opts.mtu = RTE_ETHER_MTU; 2073 opts.check_auth_only_stats = 1; 2074 2075 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 2076 2077 for (i = 0; i < size; i++) { 2078 cur_td = &list_mcs_integrity_vectors[i]; 2079 err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts); 2080 if (err == TEST_SKIPPED) { 2081 skipped += 1; 2082 err = 0; 2083 } else if (err) 2084 err = -1; 2085 else 2086 err = 0; 2087 2088 all_err += err; 2089 } 2090 2091 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2092 size + all_err - skipped, -all_err, skipped); 2093 return skipped > 0 ? TEST_SKIPPED : all_err; 2094 } 2095 2096 static int 2097 test_inline_macsec_interrupts_all(void) 2098 { 2099 struct mcs_err_vector err_vector = {0}; 2100 const struct mcs_test_vector *cur_td; 2101 struct mcs_test_opts opts = {0}; 2102 int skipped = 0; 2103 int i, size; 2104 int err, all_err = 0; 2105 enum rte_eth_event_macsec_subtype subtype[] = { 2106 RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_V_EQ1, 2107 RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_E_EQ0_C_EQ1, 2108 RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SL_GTE48, 2109 RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_ES_EQ1_SC_EQ1, 2110 RTE_ETH_SUBEVENT_MACSEC_RX_SECTAG_SC_EQ1_SCB_EQ1, 2111 }; 2112 2113 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2114 opts.protect_frames = true; 2115 opts.sa_in_use = 1; 2116 opts.nb_td = 1; 2117 opts.sectag_insert_mode = 1; 2118 opts.mtu = RTE_ETHER_MTU; 2119 opts.check_sectag_interrupts = 1; 2120 2121 err_vector.event = RTE_ETH_EVENT_MACSEC_UNKNOWN; 2122 err_vector.event_subtype = RTE_ETH_SUBEVENT_MACSEC_UNKNOWN; 2123 rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_MACSEC, 2124 test_macsec_event_callback, &err_vector); 2125 2126 size = (sizeof(list_mcs_intr_test_vectors) / sizeof((list_mcs_intr_test_vectors)[0])); 2127 2128 for (i = 0; i < size; i++) { 2129 cur_td = &list_mcs_intr_test_vectors[i]; 2130 err = test_macsec(&cur_td, MCS_DECAP, &opts); 2131 if (err == TEST_SKIPPED) { 2132 printf("Sectag val err interrupt test case %d skipped", 2133 cur_td->test_idx); 2134 skipped += 1; 2135 err = 0; 2136 } else if ((err_vector.event == RTE_ETH_EVENT_MACSEC_SECTAG_VAL_ERR) && 2137 (err_vector.event_subtype == subtype[i])) { 2138 printf("\nSectag val err interrupt test case %d passed", 2139 cur_td->test_idx); 2140 err = 0; 2141 } else { 2142 printf("\nSectag val err interrupt test case %d failed", 2143 cur_td->test_idx); 2144 err = -1; 2145 } 2146 all_err += err; 2147 } 2148 rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_MACSEC, 2149 test_macsec_event_callback, &err_vector); 2150 2151 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2152 size + all_err - skipped, -all_err, skipped); 2153 return skipped > 0 ? TEST_SKIPPED : all_err; 2154 } 2155 2156 static int 2157 test_inline_macsec_rekey_tx(void) 2158 { 2159 const struct mcs_test_vector *cur_td; 2160 struct mcs_test_opts opts = {0}; 2161 int err, all_err = 0; 2162 int skipped = 0; 2163 int i, size; 2164 2165 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2166 opts.protect_frames = true; 2167 opts.encrypt = true; 2168 opts.sa_in_use = 1; 2169 opts.nb_td = 1; 2170 opts.sectag_insert_mode = 1; 2171 opts.mtu = RTE_ETHER_MTU; 2172 opts.rekey_en = 1; 2173 2174 size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0])); 2175 2176 for (i = 0; i < size; i++) { 2177 cur_td = &list_mcs_rekey_vectors[i]; 2178 opts.rekey_td = &list_mcs_rekey_vectors[++i]; 2179 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 2180 if (err == TEST_SKIPPED) { 2181 printf("Tx hw rekey test case %d skipped\n", i); 2182 skipped += 1; 2183 err = 0; 2184 } else if (err) { 2185 printf("Tx hw rekey test case %d failed\n", i); 2186 err = -1; 2187 } else { 2188 printf("Tx hw rekey test case %d passed\n", i); 2189 err = 0; 2190 } 2191 all_err += err; 2192 } 2193 2194 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2195 size / 2 + all_err - skipped, -all_err, skipped); 2196 return skipped > 0 ? TEST_SKIPPED : all_err; 2197 } 2198 2199 static int 2200 test_inline_macsec_rekey_rx(void) 2201 { 2202 const struct mcs_test_vector *cur_td; 2203 struct mcs_test_opts opts = {0}; 2204 int err, all_err = 0; 2205 int skipped = 0; 2206 int i, size; 2207 2208 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2209 opts.protect_frames = true; 2210 opts.sa_in_use = 1; 2211 opts.nb_td = 1; 2212 opts.sectag_insert_mode = 1; 2213 opts.mtu = RTE_ETHER_MTU; 2214 opts.rekey_en = 1; 2215 2216 size = (sizeof(list_mcs_rekey_vectors) / sizeof((list_mcs_rekey_vectors)[0])); 2217 for (i = 0; i < size; i++) { 2218 cur_td = &list_mcs_rekey_vectors[i]; 2219 opts.rekey_td = &list_mcs_rekey_vectors[++i]; 2220 err = test_macsec(&cur_td, MCS_DECAP, &opts); 2221 if (err == TEST_SKIPPED) { 2222 printf("Rx rekey test case %d skipped\n", i); 2223 skipped += 1; 2224 err = 0; 2225 } else if (err) { 2226 printf("Rx rekey test case %d failed\n", i); 2227 err = -1; 2228 } else { 2229 printf("Rx rekey test case %d passed\n", i); 2230 err = 0; 2231 } 2232 all_err += err; 2233 } 2234 2235 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2236 size / 2 + all_err - skipped, -all_err, skipped); 2237 return skipped > 0 ? TEST_SKIPPED : all_err; 2238 } 2239 2240 static int 2241 test_inline_macsec_anti_replay(void) 2242 { 2243 const struct mcs_test_vector *cur_td; 2244 struct mcs_test_opts opts = {0}; 2245 uint16_t replay_win_sz[2] = {32, 0}; 2246 int err, all_err = 0; 2247 int skipped = 0; 2248 int i, size; 2249 int j; 2250 2251 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 2252 opts.sa_in_use = 1; 2253 opts.nb_td = 1; 2254 opts.sectag_insert_mode = 1; 2255 opts.replay_protect = 1; 2256 2257 size = (sizeof(list_mcs_anti_replay_vectors) / sizeof((list_mcs_anti_replay_vectors)[0])); 2258 2259 for (j = 0; j < 2; j++) { 2260 opts.replay_win_sz = replay_win_sz[j]; 2261 2262 for (i = 0; i < size; i++) { 2263 cur_td = &list_mcs_anti_replay_vectors[i]; 2264 opts.ar_td[0] = &list_mcs_anti_replay_vectors[++i]; 2265 opts.ar_td[1] = &list_mcs_anti_replay_vectors[++i]; 2266 opts.ar_td[2] = &list_mcs_anti_replay_vectors[++i]; 2267 err = test_macsec(&cur_td, MCS_DECAP, &opts); 2268 if (err == TEST_SKIPPED) { 2269 printf("Replay window: %u, Anti replay test " 2270 "case %d skipped\n", opts.replay_win_sz, 2271 i); 2272 skipped += 1; 2273 err = 0; 2274 } else if (err) { 2275 printf("Replay window: %u, Anti replay test " 2276 "case %d failed\n", opts.replay_win_sz, 2277 i); 2278 err = -1; 2279 } else { 2280 printf("Replay window: %u, Anti replay test " 2281 "case %d passed\n", opts.replay_win_sz, 2282 i); 2283 err = 0; 2284 } 2285 all_err += err; 2286 } 2287 } 2288 2289 printf("\n%s: Success: %d, Failure: %d, Skipped: %d\n", __func__, 2290 size / 2 + all_err - skipped, -all_err, skipped); 2291 return skipped > 0 ? TEST_SKIPPED : all_err; 2292 } 2293 2294 static int 2295 ut_setup_inline_macsec(void) 2296 { 2297 int ret; 2298 2299 /* Start device */ 2300 ret = rte_eth_dev_start(port_id); 2301 if (ret < 0) { 2302 printf("rte_eth_dev_start: err=%d, port=%d\n", 2303 ret, port_id); 2304 return ret; 2305 } 2306 /* always enable promiscuous */ 2307 ret = rte_eth_promiscuous_enable(port_id); 2308 if (ret != 0) { 2309 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n", 2310 rte_strerror(-ret), port_id); 2311 return ret; 2312 } 2313 2314 check_all_ports_link_status(1, RTE_PORT_ALL); 2315 2316 return 0; 2317 } 2318 2319 static void 2320 ut_teardown_inline_macsec(void) 2321 { 2322 uint16_t portid; 2323 int ret; 2324 2325 /* port tear down */ 2326 RTE_ETH_FOREACH_DEV(portid) { 2327 ret = rte_eth_dev_stop(portid); 2328 if (ret != 0) 2329 printf("rte_eth_dev_stop: err=%s, port=%u\n", 2330 rte_strerror(-ret), portid); 2331 2332 } 2333 } 2334 2335 static int 2336 inline_macsec_testsuite_setup(void) 2337 { 2338 uint16_t nb_rxd; 2339 uint16_t nb_txd; 2340 uint16_t nb_ports; 2341 int ret; 2342 uint16_t nb_rx_queue = 1, nb_tx_queue = 1; 2343 2344 printf("Start inline MACsec test.\n"); 2345 2346 nb_ports = rte_eth_dev_count_avail(); 2347 if (nb_ports < NB_ETHPORTS_USED) { 2348 printf("At least %u port(s) used for test\n", 2349 NB_ETHPORTS_USED); 2350 return TEST_SKIPPED; 2351 } 2352 2353 ret = init_mempools(NB_MBUF); 2354 if (ret) 2355 return ret; 2356 2357 if (tx_pkts_burst == NULL) { 2358 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff", 2359 MAX_TRAFFIC_BURST, 2360 sizeof(void *), 2361 RTE_CACHE_LINE_SIZE); 2362 if (!tx_pkts_burst) 2363 return TEST_FAILED; 2364 2365 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff", 2366 MAX_TRAFFIC_BURST, 2367 sizeof(void *), 2368 RTE_CACHE_LINE_SIZE); 2369 if (!rx_pkts_burst) 2370 return TEST_FAILED; 2371 } 2372 2373 printf("Generate %d packets\n", MAX_TRAFFIC_BURST); 2374 2375 nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 2376 nb_txd = RTE_TEST_TX_DESC_DEFAULT; 2377 2378 /* configuring port 0 for the test is enough */ 2379 port_id = 0; 2380 /* port configure */ 2381 ret = rte_eth_dev_configure(port_id, nb_rx_queue, 2382 nb_tx_queue, &port_conf); 2383 if (ret < 0) { 2384 printf("Cannot configure device: err=%d, port=%d\n", 2385 ret, port_id); 2386 return ret; 2387 } 2388 ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]); 2389 if (ret < 0) { 2390 printf("Cannot get mac address: err=%d, port=%d\n", 2391 ret, port_id); 2392 return ret; 2393 } 2394 printf("Port %u ", port_id); 2395 print_ethaddr("Address:", &ports_eth_addr[port_id]); 2396 printf("\n"); 2397 2398 /* tx queue setup */ 2399 ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 2400 SOCKET_ID_ANY, &tx_conf); 2401 if (ret < 0) { 2402 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n", 2403 ret, port_id); 2404 return ret; 2405 } 2406 /* rx queue steup */ 2407 ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY, 2408 &rx_conf, mbufpool); 2409 if (ret < 0) { 2410 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n", 2411 ret, port_id); 2412 return ret; 2413 } 2414 2415 return 0; 2416 } 2417 2418 static void 2419 inline_macsec_testsuite_teardown(void) 2420 { 2421 uint16_t portid; 2422 int ret; 2423 2424 /* port tear down */ 2425 RTE_ETH_FOREACH_DEV(portid) { 2426 ret = rte_eth_dev_reset(portid); 2427 if (ret != 0) 2428 printf("rte_eth_dev_reset: err=%s, port=%u\n", 2429 rte_strerror(-ret), port_id); 2430 } 2431 rte_free(tx_pkts_burst); 2432 rte_free(rx_pkts_burst); 2433 } 2434 2435 2436 static struct unit_test_suite inline_macsec_testsuite = { 2437 .suite_name = "Inline MACsec Ethernet Device Unit Test Suite", 2438 .unit_test_cases = { 2439 TEST_CASE_NAMED_ST( 2440 "MACsec Encap + decap Multi flow", 2441 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2442 test_inline_macsec_multi_flow), 2443 TEST_CASE_NAMED_ST( 2444 "MACsec encap(Cipher+Auth) known vector", 2445 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2446 test_inline_macsec_encap_all), 2447 TEST_CASE_NAMED_ST( 2448 "MACsec decap(De-cipher+verify) known vector", 2449 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2450 test_inline_macsec_decap_all), 2451 TEST_CASE_NAMED_ST( 2452 "MACsec auth only known vector", 2453 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2454 test_inline_macsec_auth_only_all), 2455 TEST_CASE_NAMED_ST( 2456 "MACsec verify only known vector", 2457 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2458 test_inline_macsec_verify_only_all), 2459 TEST_CASE_NAMED_ST( 2460 "MACsec encap + decap known vector", 2461 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2462 test_inline_macsec_encap_decap_all), 2463 TEST_CASE_NAMED_ST( 2464 "MACsec auth + verify known vector", 2465 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2466 test_inline_macsec_auth_verify_all), 2467 TEST_CASE_NAMED_ST( 2468 "MACsec Encap and decap with VLAN", 2469 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2470 test_inline_macsec_with_vlan), 2471 TEST_CASE_NAMED_ST( 2472 "MACsec packet drop", 2473 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2474 test_inline_macsec_pkt_drop), 2475 TEST_CASE_NAMED_ST( 2476 "MACsec untagged Rx", 2477 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2478 test_inline_macsec_untagged_rx), 2479 TEST_CASE_NAMED_ST( 2480 "MACsec bad tag Rx", 2481 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2482 test_inline_macsec_bad_tag_rx), 2483 TEST_CASE_NAMED_ST( 2484 "MACsec SA not in use", 2485 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2486 test_inline_macsec_sa_not_in_use), 2487 TEST_CASE_NAMED_ST( 2488 "MACsec decap stats", 2489 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2490 test_inline_macsec_decap_stats), 2491 TEST_CASE_NAMED_ST( 2492 "MACsec verify only stats", 2493 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2494 test_inline_macsec_verify_only_stats), 2495 TEST_CASE_NAMED_ST( 2496 "MACsec pkts invalid stats", 2497 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2498 test_inline_macsec_pkts_invalid_stats), 2499 TEST_CASE_NAMED_ST( 2500 "MACsec pkts unchecked stats", 2501 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2502 test_inline_macsec_pkts_unchecked_stats), 2503 TEST_CASE_NAMED_ST( 2504 "MACsec out pkts untagged", 2505 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2506 test_inline_macsec_out_pkts_untagged), 2507 TEST_CASE_NAMED_ST( 2508 "MACsec out pkts too long", 2509 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2510 test_inline_macsec_out_pkts_toolong), 2511 TEST_CASE_NAMED_ST( 2512 "MACsec Encap stats", 2513 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2514 test_inline_macsec_encap_stats), 2515 TEST_CASE_NAMED_ST( 2516 "MACsec auth only stats", 2517 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2518 test_inline_macsec_auth_only_stats), 2519 TEST_CASE_NAMED_ST( 2520 "MACsec interrupts all", 2521 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2522 test_inline_macsec_interrupts_all), 2523 TEST_CASE_NAMED_ST( 2524 "MACsec re-key Tx", 2525 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2526 test_inline_macsec_rekey_tx), 2527 TEST_CASE_NAMED_ST( 2528 "MACsec re-key Rx", 2529 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2530 test_inline_macsec_rekey_rx), 2531 TEST_CASE_NAMED_ST( 2532 "MACsec anti-replay", 2533 ut_setup_inline_macsec, ut_teardown_inline_macsec, 2534 test_inline_macsec_anti_replay), 2535 2536 TEST_CASES_END() /**< NULL terminate unit test array */ 2537 }, 2538 }; 2539 2540 static int 2541 test_inline_macsec(void) 2542 { 2543 inline_macsec_testsuite.setup = inline_macsec_testsuite_setup; 2544 inline_macsec_testsuite.teardown = inline_macsec_testsuite_teardown; 2545 return unit_test_suite_runner(&inline_macsec_testsuite); 2546 } 2547 2548 #endif /* !RTE_EXEC_ENV_WINDOWS */ 2549 2550 REGISTER_TEST_COMMAND(inline_macsec_autotest, test_inline_macsec); 2551