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