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 test_macsec(const struct mcs_test_vector *td[], enum mcs_op op, const struct mcs_test_opts *opts) 664 { 665 uint16_t rx_sa_id[MCS_MAX_FLOWS][RTE_SECURITY_MACSEC_NUM_AN] = {{0}}; 666 uint16_t tx_sa_id[MCS_MAX_FLOWS][2] = {{0}}; 667 uint16_t rx_sc_id[MCS_MAX_FLOWS] = {0}; 668 uint16_t tx_sc_id[MCS_MAX_FLOWS] = {0}; 669 void *rx_sess[MCS_MAX_FLOWS] = {0}; 670 void *tx_sess[MCS_MAX_FLOWS] = {0}; 671 struct rte_security_session_conf sess_conf = {0}; 672 struct rte_security_macsec_sa sa_conf = {0}; 673 struct rte_security_macsec_sc sc_conf = {0}; 674 struct rte_security_ctx *ctx; 675 int nb_rx = 0, nb_sent; 676 int i, j = 0, ret, id, an = 0; 677 uint8_t tci_off; 678 679 memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * opts->nb_td); 680 681 ctx = (struct rte_security_ctx *)rte_eth_dev_get_sec_ctx(port_id); 682 if (ctx == NULL) { 683 printf("Ethernet device doesn't support security features.\n"); 684 return TEST_SKIPPED; 685 } 686 687 tci_off = (opts->sectag_insert_mode == 1) ? RTE_ETHER_HDR_LEN : 688 RTE_ETHER_HDR_LEN + (opts->nb_vlan * RTE_VLAN_HLEN); 689 690 for (i = 0, j = 0; i < opts->nb_td; i++) { 691 if (op == MCS_DECAP || op == MCS_VERIFY_ONLY) 692 tx_pkts_burst[j] = init_packet(mbufpool, td[i]->secure_pkt.data, 693 td[i]->secure_pkt.len); 694 else { 695 tx_pkts_burst[j] = init_packet(mbufpool, td[i]->plain_pkt.data, 696 td[i]->plain_pkt.len); 697 698 tx_pkts_burst[j]->ol_flags |= RTE_MBUF_F_TX_MACSEC; 699 } 700 if (tx_pkts_burst[j] == NULL) { 701 while (j--) 702 rte_pktmbuf_free(tx_pkts_burst[j]); 703 ret = TEST_FAILED; 704 goto out; 705 } 706 j++; 707 708 if (op == MCS_DECAP || op == MCS_ENCAP_DECAP || 709 op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) { 710 for (an = 0; an < RTE_SECURITY_MACSEC_NUM_AN; an++) { 711 /* For simplicity, using same SA conf for all AN */ 712 fill_macsec_sa_conf(td[i], &sa_conf, 713 RTE_SECURITY_MACSEC_DIR_RX, an, tci_off); 714 id = rte_security_macsec_sa_create(ctx, &sa_conf); 715 if (id < 0) { 716 printf("MACsec SA create failed : %d.\n", id); 717 return TEST_FAILED; 718 } 719 rx_sa_id[i][an] = (uint16_t)id; 720 } 721 fill_macsec_sc_conf(td[i], &sc_conf, opts, 722 RTE_SECURITY_MACSEC_DIR_RX, rx_sa_id[i], tci_off); 723 id = rte_security_macsec_sc_create(ctx, &sc_conf); 724 if (id < 0) { 725 printf("MACsec SC create failed : %d.\n", id); 726 goto out; 727 } 728 rx_sc_id[i] = (uint16_t)id; 729 730 /* Create Inline IPsec session. */ 731 ret = fill_session_conf(td[i], port_id, opts, &sess_conf, 732 RTE_SECURITY_MACSEC_DIR_RX, rx_sc_id[i], tci_off); 733 if (ret) 734 return TEST_FAILED; 735 736 rx_sess[i] = rte_security_session_create(ctx, &sess_conf, 737 sess_pool); 738 if (rx_sess[i] == NULL) { 739 printf("SEC Session init failed.\n"); 740 return TEST_FAILED; 741 } 742 ret = create_default_flow(td[i], port_id, 743 RTE_SECURITY_MACSEC_DIR_RX, rx_sess[i]); 744 if (ret) 745 goto out; 746 } 747 if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP || 748 op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) { 749 int id; 750 751 fill_macsec_sa_conf(td[i], &sa_conf, 752 RTE_SECURITY_MACSEC_DIR_TX, 753 td[i]->secure_pkt.data[tci_off] & RTE_MACSEC_AN_MASK, 754 tci_off); 755 id = rte_security_macsec_sa_create(ctx, &sa_conf); 756 if (id < 0) { 757 printf("MACsec SA create failed : %d.\n", id); 758 return TEST_FAILED; 759 } 760 tx_sa_id[i][0] = (uint16_t)id; 761 tx_sa_id[i][1] = MCS_INVALID_SA; 762 fill_macsec_sc_conf(td[i], &sc_conf, opts, 763 RTE_SECURITY_MACSEC_DIR_TX, tx_sa_id[i], tci_off); 764 id = rte_security_macsec_sc_create(ctx, &sc_conf); 765 if (id < 0) { 766 printf("MACsec SC create failed : %d.\n", id); 767 goto out; 768 } 769 tx_sc_id[i] = (uint16_t)id; 770 771 /* Create Inline IPsec session. */ 772 ret = fill_session_conf(td[i], port_id, opts, &sess_conf, 773 RTE_SECURITY_MACSEC_DIR_TX, tx_sc_id[i], tci_off); 774 if (ret) 775 return TEST_FAILED; 776 777 tx_sess[i] = rte_security_session_create(ctx, &sess_conf, 778 sess_pool); 779 if (tx_sess[i] == NULL) { 780 printf("SEC Session init failed.\n"); 781 return TEST_FAILED; 782 } 783 ret = create_default_flow(td[i], port_id, 784 RTE_SECURITY_MACSEC_DIR_TX, tx_sess[i]); 785 if (ret) 786 goto out; 787 } 788 } 789 790 /* Send packet to ethdev for inline MACsec processing. */ 791 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, j); 792 793 if (nb_sent != j) { 794 printf("\nUnable to TX %d packets, sent: %i", j, nb_sent); 795 for ( ; nb_sent < j; nb_sent++) 796 rte_pktmbuf_free(tx_pkts_burst[nb_sent]); 797 ret = TEST_FAILED; 798 goto out; 799 } 800 801 rte_pause(); 802 803 /* Receive back packet on loopback interface. */ 804 do { 805 nb_rx += rte_eth_rx_burst(port_id, 0, 806 &rx_pkts_burst[nb_rx], 807 nb_sent - nb_rx); 808 if (nb_rx >= nb_sent) 809 break; 810 rte_delay_ms(1); 811 } while (j++ < 5 && nb_rx == 0); 812 813 if (nb_rx != nb_sent) { 814 printf("\nUnable to RX all %d packets, received(%i)", 815 nb_sent, nb_rx); 816 while (--nb_rx >= 0) 817 rte_pktmbuf_free(rx_pkts_burst[nb_rx]); 818 ret = TEST_FAILED; 819 goto out; 820 } 821 822 for (i = 0; i < nb_rx; i++) { 823 ret = test_macsec_post_process(rx_pkts_burst[i], td[i], op, 824 opts->check_out_pkts_untagged); 825 if (ret != TEST_SUCCESS) { 826 for ( ; i < nb_rx; i++) 827 rte_pktmbuf_free(rx_pkts_burst[i]); 828 goto out; 829 } 830 831 rte_pktmbuf_free(rx_pkts_burst[i]); 832 rx_pkts_burst[i] = NULL; 833 } 834 out: 835 for (i = 0; i < opts->nb_td; i++) { 836 if (opts->dump_all_stats) { 837 mcs_stats_dump(ctx, op, 838 rx_sess[i], tx_sess[i], 839 rx_sc_id[i], tx_sc_id[i], 840 rx_sa_id[i], tx_sa_id[i]); 841 } 842 } 843 844 destroy_default_flow(port_id); 845 846 /* Destroy session so that other cases can create the session again */ 847 for (i = 0; i < opts->nb_td; i++) { 848 if (op == MCS_ENCAP || op == MCS_ENCAP_DECAP || 849 op == MCS_AUTH_ONLY || op == MCS_AUTH_VERIFY) { 850 rte_security_session_destroy(ctx, tx_sess[i]); 851 tx_sess[i] = NULL; 852 rte_security_macsec_sc_destroy(ctx, tx_sc_id[i], 853 RTE_SECURITY_MACSEC_DIR_TX); 854 rte_security_macsec_sa_destroy(ctx, tx_sa_id[i][0], 855 RTE_SECURITY_MACSEC_DIR_TX); 856 } 857 if (op == MCS_DECAP || op == MCS_ENCAP_DECAP || 858 op == MCS_VERIFY_ONLY || op == MCS_AUTH_VERIFY) { 859 rte_security_session_destroy(ctx, rx_sess[i]); 860 rx_sess[i] = NULL; 861 rte_security_macsec_sc_destroy(ctx, rx_sc_id[i], 862 RTE_SECURITY_MACSEC_DIR_RX); 863 for (j = 0; j < RTE_SECURITY_MACSEC_NUM_AN; j++) { 864 rte_security_macsec_sa_destroy(ctx, rx_sa_id[i][j], 865 RTE_SECURITY_MACSEC_DIR_RX); 866 } 867 } 868 } 869 870 return ret; 871 } 872 873 static int 874 test_inline_macsec_encap_all(const void *data __rte_unused) 875 { 876 const struct mcs_test_vector *cur_td; 877 struct mcs_test_opts opts = {0}; 878 int err, all_err = 0; 879 int i, size; 880 881 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 882 opts.encrypt = true; 883 opts.protect_frames = true; 884 opts.sa_in_use = 1; 885 opts.nb_td = 1; 886 opts.sectag_insert_mode = 1; 887 opts.mtu = RTE_ETHER_MTU; 888 889 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 890 for (i = 0; i < size; i++) { 891 cur_td = &list_mcs_cipher_vectors[i]; 892 err = test_macsec(&cur_td, MCS_ENCAP, &opts); 893 if (err) { 894 printf("\nCipher Auth Encryption case %d failed", cur_td->test_idx); 895 err = -1; 896 } else { 897 printf("\nCipher Auth Encryption case %d Passed", cur_td->test_idx); 898 err = 0; 899 } 900 all_err += err; 901 } 902 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 903 904 return all_err; 905 } 906 907 static int 908 test_inline_macsec_decap_all(const void *data __rte_unused) 909 { 910 const struct mcs_test_vector *cur_td; 911 struct mcs_test_opts opts = {0}; 912 int err, all_err = 0; 913 int i, size; 914 915 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 916 opts.sa_in_use = 1; 917 opts.nb_td = 1; 918 opts.sectag_insert_mode = 1; 919 opts.mtu = RTE_ETHER_MTU; 920 921 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 922 for (i = 0; i < size; i++) { 923 cur_td = &list_mcs_cipher_vectors[i]; 924 err = test_macsec(&cur_td, MCS_DECAP, &opts); 925 if (err) { 926 printf("\nCipher Auth Decryption case %d failed", cur_td->test_idx); 927 err = -1; 928 } else { 929 printf("\nCipher Auth Decryption case %d Passed", cur_td->test_idx); 930 err = 0; 931 } 932 all_err += err; 933 } 934 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 935 936 return all_err; 937 } 938 939 static int 940 test_inline_macsec_auth_only_all(const void *data __rte_unused) 941 { 942 const struct mcs_test_vector *cur_td; 943 struct mcs_test_opts opts = {0}; 944 int err, all_err = 0; 945 int i, size; 946 947 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 948 opts.protect_frames = true; 949 opts.sa_in_use = 1; 950 opts.nb_td = 1; 951 opts.sectag_insert_mode = 1; 952 opts.mtu = RTE_ETHER_MTU; 953 954 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 955 956 for (i = 0; i < size; i++) { 957 cur_td = &list_mcs_integrity_vectors[i]; 958 err = test_macsec(&cur_td, MCS_AUTH_ONLY, &opts); 959 if (err) { 960 printf("\nAuth Generate case %d failed", cur_td->test_idx); 961 err = -1; 962 } else { 963 printf("\nAuth Generate case %d Passed", cur_td->test_idx); 964 err = 0; 965 } 966 all_err += err; 967 } 968 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 969 970 return all_err; 971 } 972 973 static int 974 test_inline_macsec_verify_only_all(const void *data __rte_unused) 975 { 976 const struct mcs_test_vector *cur_td; 977 struct mcs_test_opts opts = {0}; 978 int err, all_err = 0; 979 int i, size; 980 981 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 982 opts.sa_in_use = 1; 983 opts.nb_td = 1; 984 opts.sectag_insert_mode = 1; 985 opts.mtu = RTE_ETHER_MTU; 986 987 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 988 989 for (i = 0; i < size; i++) { 990 cur_td = &list_mcs_integrity_vectors[i]; 991 err = test_macsec(&cur_td, MCS_VERIFY_ONLY, &opts); 992 if (err) { 993 printf("\nAuth Verify case %d failed", cur_td->test_idx); 994 err = -1; 995 } else { 996 printf("\nAuth Verify case %d Passed", cur_td->test_idx); 997 err = 0; 998 } 999 all_err += err; 1000 } 1001 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 1002 1003 return all_err; 1004 } 1005 1006 static int 1007 test_inline_macsec_encap_decap_all(const void *data __rte_unused) 1008 { 1009 const struct mcs_test_vector *cur_td; 1010 struct mcs_test_opts opts = {0}; 1011 int err, all_err = 0; 1012 int i, size; 1013 1014 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1015 opts.encrypt = true; 1016 opts.protect_frames = true; 1017 opts.sa_in_use = 1; 1018 opts.nb_td = 1; 1019 opts.sectag_insert_mode = 1; 1020 opts.mtu = RTE_ETHER_MTU; 1021 1022 size = (sizeof(list_mcs_cipher_vectors) / sizeof((list_mcs_cipher_vectors)[0])); 1023 1024 for (i = 0; i < size; i++) { 1025 cur_td = &list_mcs_cipher_vectors[i]; 1026 err = test_macsec(&cur_td, MCS_ENCAP_DECAP, &opts); 1027 if (err) { 1028 printf("\nCipher Auth Encap-decap case %d failed", cur_td->test_idx); 1029 err = -1; 1030 } else { 1031 printf("\nCipher Auth Encap-decap case %d Passed", cur_td->test_idx); 1032 err = 0; 1033 } 1034 all_err += err; 1035 } 1036 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 1037 1038 return all_err; 1039 } 1040 1041 1042 static int 1043 test_inline_macsec_auth_verify_all(const void *data __rte_unused) 1044 { 1045 const struct mcs_test_vector *cur_td; 1046 struct mcs_test_opts opts = {0}; 1047 int err, all_err = 0; 1048 int i, size; 1049 1050 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1051 opts.protect_frames = true; 1052 opts.sa_in_use = 1; 1053 opts.nb_td = 1; 1054 opts.sectag_insert_mode = 1; 1055 opts.mtu = RTE_ETHER_MTU; 1056 1057 size = (sizeof(list_mcs_integrity_vectors) / sizeof((list_mcs_integrity_vectors)[0])); 1058 1059 for (i = 0; i < size; i++) { 1060 cur_td = &list_mcs_integrity_vectors[i]; 1061 err = test_macsec(&cur_td, MCS_AUTH_VERIFY, &opts); 1062 if (err) { 1063 printf("\nAuth Generate + Verify case %d failed", cur_td->test_idx); 1064 err = -1; 1065 } else { 1066 printf("\nAuth Generate + Verify case %d Passed", cur_td->test_idx); 1067 err = 0; 1068 } 1069 all_err += err; 1070 } 1071 printf("\n%s: Success: %d, Failure: %d\n", __func__, size + all_err, -all_err); 1072 1073 return all_err; 1074 } 1075 1076 static int 1077 test_inline_macsec_multi_flow(const void *data __rte_unused) 1078 { 1079 const struct mcs_test_vector *tv[MCS_MAX_FLOWS]; 1080 struct mcs_test_vector iter[MCS_MAX_FLOWS]; 1081 struct mcs_test_opts opts = {0}; 1082 int i, err; 1083 1084 opts.val_frames = RTE_SECURITY_MACSEC_VALIDATE_STRICT; 1085 opts.encrypt = true; 1086 opts.protect_frames = true; 1087 opts.sa_in_use = 1; 1088 opts.nb_td = MCS_MAX_FLOWS; 1089 opts.sectag_insert_mode = 1; 1090 opts.mtu = RTE_ETHER_MTU; 1091 1092 for (i = 0; i < MCS_MAX_FLOWS; i++) { 1093 memcpy(&iter[i].sa_key.data, sa_key, MCS_MULTI_FLOW_TD_KEY_SZ); 1094 memcpy(&iter[i].plain_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN); 1095 memcpy(&iter[i].plain_pkt.data[2 * RTE_ETHER_ADDR_LEN], plain_user_data, 1096 MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ); 1097 memcpy(&iter[i].secure_pkt.data, eth_addrs[i], 2 * RTE_ETHER_ADDR_LEN); 1098 memcpy(&iter[i].secure_pkt.data[2 * RTE_ETHER_ADDR_LEN], secure_user_data, 1099 MCS_MULTI_FLOW_TD_SECURE_DATA_SZ); 1100 iter[i].sa_key.len = MCS_MULTI_FLOW_TD_KEY_SZ; 1101 iter[i].plain_pkt.len = MCS_MULTI_FLOW_TD_PLAIN_DATA_SZ + 1102 (2 * RTE_ETHER_ADDR_LEN); 1103 iter[i].secure_pkt.len = MCS_MULTI_FLOW_TD_SECURE_DATA_SZ + 1104 (2 * RTE_ETHER_ADDR_LEN); 1105 iter[i].alg = RTE_SECURITY_MACSEC_ALG_GCM_128; 1106 iter[i].ssci = 0x0; 1107 iter[i].xpn = 0x0; 1108 tv[i] = (const struct mcs_test_vector *)&iter[i]; 1109 } 1110 err = test_macsec(tv, MCS_ENCAP_DECAP, &opts); 1111 if (err) { 1112 printf("\nCipher Auth Encryption multi flow failed"); 1113 err = -1; 1114 } else { 1115 printf("\nCipher Auth Encryption multi flow Passed"); 1116 err = 0; 1117 } 1118 return err; 1119 } 1120 1121 static int 1122 ut_setup_inline_macsec(void) 1123 { 1124 int ret; 1125 1126 /* Start device */ 1127 ret = rte_eth_dev_start(port_id); 1128 if (ret < 0) { 1129 printf("rte_eth_dev_start: err=%d, port=%d\n", 1130 ret, port_id); 1131 return ret; 1132 } 1133 /* always enable promiscuous */ 1134 ret = rte_eth_promiscuous_enable(port_id); 1135 if (ret != 0) { 1136 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n", 1137 rte_strerror(-ret), port_id); 1138 return ret; 1139 } 1140 1141 check_all_ports_link_status(1, RTE_PORT_ALL); 1142 1143 return 0; 1144 } 1145 1146 static void 1147 ut_teardown_inline_macsec(void) 1148 { 1149 uint16_t portid; 1150 int ret; 1151 1152 /* port tear down */ 1153 RTE_ETH_FOREACH_DEV(portid) { 1154 ret = rte_eth_dev_stop(portid); 1155 if (ret != 0) 1156 printf("rte_eth_dev_stop: err=%s, port=%u\n", 1157 rte_strerror(-ret), portid); 1158 1159 } 1160 } 1161 1162 static int 1163 inline_macsec_testsuite_setup(void) 1164 { 1165 uint16_t nb_rxd; 1166 uint16_t nb_txd; 1167 uint16_t nb_ports; 1168 int ret; 1169 uint16_t nb_rx_queue = 1, nb_tx_queue = 1; 1170 1171 printf("Start inline MACsec test.\n"); 1172 1173 nb_ports = rte_eth_dev_count_avail(); 1174 if (nb_ports < NB_ETHPORTS_USED) { 1175 printf("At least %u port(s) used for test\n", 1176 NB_ETHPORTS_USED); 1177 return TEST_SKIPPED; 1178 } 1179 1180 ret = init_mempools(NB_MBUF); 1181 if (ret) 1182 return ret; 1183 1184 if (tx_pkts_burst == NULL) { 1185 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff", 1186 MAX_TRAFFIC_BURST, 1187 sizeof(void *), 1188 RTE_CACHE_LINE_SIZE); 1189 if (!tx_pkts_burst) 1190 return TEST_FAILED; 1191 1192 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff", 1193 MAX_TRAFFIC_BURST, 1194 sizeof(void *), 1195 RTE_CACHE_LINE_SIZE); 1196 if (!rx_pkts_burst) 1197 return TEST_FAILED; 1198 } 1199 1200 printf("Generate %d packets\n", MAX_TRAFFIC_BURST); 1201 1202 nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 1203 nb_txd = RTE_TEST_TX_DESC_DEFAULT; 1204 1205 /* configuring port 0 for the test is enough */ 1206 port_id = 0; 1207 /* port configure */ 1208 ret = rte_eth_dev_configure(port_id, nb_rx_queue, 1209 nb_tx_queue, &port_conf); 1210 if (ret < 0) { 1211 printf("Cannot configure device: err=%d, port=%d\n", 1212 ret, port_id); 1213 return ret; 1214 } 1215 ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]); 1216 if (ret < 0) { 1217 printf("Cannot get mac address: err=%d, port=%d\n", 1218 ret, port_id); 1219 return ret; 1220 } 1221 printf("Port %u ", port_id); 1222 print_ethaddr("Address:", &ports_eth_addr[port_id]); 1223 printf("\n"); 1224 1225 /* tx queue setup */ 1226 ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 1227 SOCKET_ID_ANY, &tx_conf); 1228 if (ret < 0) { 1229 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n", 1230 ret, port_id); 1231 return ret; 1232 } 1233 /* rx queue steup */ 1234 ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY, 1235 &rx_conf, mbufpool); 1236 if (ret < 0) { 1237 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n", 1238 ret, port_id); 1239 return ret; 1240 } 1241 1242 return 0; 1243 } 1244 1245 static void 1246 inline_macsec_testsuite_teardown(void) 1247 { 1248 uint16_t portid; 1249 int ret; 1250 1251 /* port tear down */ 1252 RTE_ETH_FOREACH_DEV(portid) { 1253 ret = rte_eth_dev_reset(portid); 1254 if (ret != 0) 1255 printf("rte_eth_dev_reset: err=%s, port=%u\n", 1256 rte_strerror(-ret), port_id); 1257 } 1258 rte_free(tx_pkts_burst); 1259 rte_free(rx_pkts_burst); 1260 } 1261 1262 1263 static struct unit_test_suite inline_macsec_testsuite = { 1264 .suite_name = "Inline MACsec Ethernet Device Unit Test Suite", 1265 .unit_test_cases = { 1266 TEST_CASE_NAMED_ST( 1267 "MACsec Encap + decap Multi flow", 1268 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1269 test_inline_macsec_multi_flow), 1270 TEST_CASE_NAMED_ST( 1271 "MACsec encap(Cipher+Auth) known vector", 1272 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1273 test_inline_macsec_encap_all), 1274 TEST_CASE_NAMED_ST( 1275 "MACsec decap(De-cipher+verify) known vector", 1276 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1277 test_inline_macsec_decap_all), 1278 TEST_CASE_NAMED_ST( 1279 "MACsec auth only known vector", 1280 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1281 test_inline_macsec_auth_only_all), 1282 TEST_CASE_NAMED_ST( 1283 "MACsec verify only known vector", 1284 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1285 test_inline_macsec_verify_only_all), 1286 TEST_CASE_NAMED_ST( 1287 "MACsec encap + decap known vector", 1288 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1289 test_inline_macsec_encap_decap_all), 1290 TEST_CASE_NAMED_ST( 1291 "MACsec auth + verify known vector", 1292 ut_setup_inline_macsec, ut_teardown_inline_macsec, 1293 test_inline_macsec_auth_verify_all), 1294 1295 TEST_CASES_END() /**< NULL terminate unit test array */ 1296 }, 1297 }; 1298 1299 static int 1300 test_inline_macsec(void) 1301 { 1302 inline_macsec_testsuite.setup = inline_macsec_testsuite_setup; 1303 inline_macsec_testsuite.teardown = inline_macsec_testsuite_teardown; 1304 return unit_test_suite_runner(&inline_macsec_testsuite); 1305 } 1306 1307 #endif /* !RTE_EXEC_ENV_WINDOWS */ 1308 1309 REGISTER_TEST_COMMAND(inline_macsec_autotest, test_inline_macsec); 1310