1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 Marvell. 3 */ 4 5 6 #include <stdio.h> 7 #include <inttypes.h> 8 9 #include <rte_ethdev.h> 10 #include <rte_malloc.h> 11 #include <rte_security.h> 12 13 #include "test.h" 14 #include "test_security_inline_proto_vectors.h" 15 #include "test_security_proto.h" 16 17 #ifdef RTE_EXEC_ENV_WINDOWS 18 static int 19 test_inline_ipsec(void) 20 { 21 printf("Inline ipsec not supported on Windows, skipping test\n"); 22 return TEST_SKIPPED; 23 } 24 25 static int 26 test_event_inline_ipsec(void) 27 { 28 printf("Event inline ipsec not supported on Windows, skipping test\n"); 29 return TEST_SKIPPED; 30 } 31 32 static int 33 test_inline_ipsec_sg(void) 34 { 35 printf("Inline ipsec SG not supported on Windows, skipping test\n"); 36 return TEST_SKIPPED; 37 } 38 39 #else 40 41 #include <rte_eventdev.h> 42 #include <rte_event_eth_rx_adapter.h> 43 #include <rte_event_eth_tx_adapter.h> 44 45 #define NB_ETHPORTS_USED 1 46 #define MEMPOOL_CACHE_SIZE 32 47 #define MAX_PKT_BURST 32 48 #define RX_DESC_DEFAULT 1024 49 #define TX_DESC_DEFAULT 1024 50 #define RTE_PORT_ALL (~(uint16_t)0x0) 51 52 #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ 53 #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ 54 #define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */ 55 56 #define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */ 57 #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ 58 #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ 59 60 #define MAX_TRAFFIC_BURST 2048 61 #define NB_MBUF 10240 62 63 #define ENCAP_DECAP_BURST_SZ 33 64 #define APP_REASS_TIMEOUT 10 65 66 extern struct ipsec_test_data pkt_aes_128_gcm; 67 extern struct ipsec_test_data pkt_aes_192_gcm; 68 extern struct ipsec_test_data pkt_aes_256_gcm; 69 extern struct ipsec_test_data pkt_aes_128_gcm_frag; 70 extern struct ipsec_test_data pkt_aes_128_cbc_null; 71 extern struct ipsec_test_data pkt_null_aes_xcbc; 72 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha384; 73 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha512; 74 extern struct ipsec_test_data pkt_3des_cbc_hmac_sha256; 75 extern struct ipsec_test_data pkt_3des_cbc_hmac_sha384; 76 extern struct ipsec_test_data pkt_3des_cbc_hmac_sha512; 77 extern struct ipsec_test_data pkt_3des_cbc_hmac_sha256_v6; 78 extern struct ipsec_test_data pkt_des_cbc_hmac_sha256; 79 extern struct ipsec_test_data pkt_des_cbc_hmac_sha384; 80 extern struct ipsec_test_data pkt_des_cbc_hmac_sha512; 81 extern struct ipsec_test_data pkt_des_cbc_hmac_sha256_v6; 82 extern struct ipsec_test_data pkt_aes_128_cbc_md5; 83 84 static struct rte_mempool *mbufpool; 85 static struct rte_mempool *sess_pool; 86 /* ethernet addresses of ports */ 87 static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 88 89 static struct rte_eth_conf port_conf = { 90 .rxmode = { 91 .mq_mode = RTE_ETH_MQ_RX_NONE, 92 .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM | 93 RTE_ETH_RX_OFFLOAD_SECURITY, 94 }, 95 .txmode = { 96 .mq_mode = RTE_ETH_MQ_TX_NONE, 97 .offloads = RTE_ETH_TX_OFFLOAD_SECURITY | 98 RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE, 99 }, 100 .lpbk_mode = 1, /* enable loopback */ 101 }; 102 103 static struct rte_eth_rxconf rx_conf = { 104 .rx_thresh = { 105 .pthresh = RX_PTHRESH, 106 .hthresh = RX_HTHRESH, 107 .wthresh = RX_WTHRESH, 108 }, 109 .rx_free_thresh = 32, 110 }; 111 112 static struct rte_eth_txconf tx_conf = { 113 .tx_thresh = { 114 .pthresh = TX_PTHRESH, 115 .hthresh = TX_HTHRESH, 116 .wthresh = TX_WTHRESH, 117 }, 118 .tx_free_thresh = 32, /* Use PMD default values */ 119 .tx_rs_thresh = 32, /* Use PMD default values */ 120 }; 121 122 static uint16_t port_id; 123 static uint8_t eventdev_id; 124 static uint8_t rx_adapter_id; 125 static uint8_t tx_adapter_id; 126 static uint16_t plaintext_len; 127 static bool sg_mode; 128 129 static bool event_mode_enabled; 130 131 static uint64_t link_mbps; 132 133 static int ip_reassembly_dynfield_offset = -1; 134 135 static struct rte_flow *default_flow[RTE_MAX_ETHPORTS]; 136 137 /* Create Inline IPsec session */ 138 static int 139 create_inline_ipsec_session(struct ipsec_test_data *sa, uint16_t portid, 140 void **sess, void **ctx, 141 uint32_t *ol_flags, const struct ipsec_test_flags *flags, 142 struct rte_security_session_conf *sess_conf) 143 { 144 uint16_t src_v6[8] = {0x2607, 0xf8b0, 0x400c, 0x0c03, 0x0000, 0x0000, 145 0x0000, 0x001a}; 146 uint16_t dst_v6[8] = {0x2001, 0x0470, 0xe5bf, 0xdead, 0x4957, 0x2174, 147 0xe82c, 0x4887}; 148 uint32_t src_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 2)); 149 uint32_t dst_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 1)); 150 struct rte_security_capability_idx sec_cap_idx; 151 const struct rte_security_capability *sec_cap; 152 enum rte_security_ipsec_sa_direction dir; 153 void *sec_ctx; 154 uint32_t verify; 155 156 sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL; 157 sess_conf->protocol = RTE_SECURITY_PROTOCOL_IPSEC; 158 sess_conf->ipsec = sa->ipsec_xform; 159 160 dir = sa->ipsec_xform.direction; 161 verify = flags->tunnel_hdr_verify; 162 163 if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && verify) { 164 if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR) 165 src_v4 += 1; 166 else if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR) 167 dst_v4 += 1; 168 } 169 170 if (sa->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 171 if (sa->ipsec_xform.tunnel.type == 172 RTE_SECURITY_IPSEC_TUNNEL_IPV4) { 173 memcpy(&sess_conf->ipsec.tunnel.ipv4.src_ip, &src_v4, 174 sizeof(src_v4)); 175 memcpy(&sess_conf->ipsec.tunnel.ipv4.dst_ip, &dst_v4, 176 sizeof(dst_v4)); 177 178 if (flags->df == TEST_IPSEC_SET_DF_0_INNER_1) 179 sess_conf->ipsec.tunnel.ipv4.df = 0; 180 181 if (flags->df == TEST_IPSEC_SET_DF_1_INNER_0) 182 sess_conf->ipsec.tunnel.ipv4.df = 1; 183 184 if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 185 sess_conf->ipsec.tunnel.ipv4.dscp = 0; 186 187 if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) 188 sess_conf->ipsec.tunnel.ipv4.dscp = 189 TEST_IPSEC_DSCP_VAL; 190 } else { 191 if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 192 sess_conf->ipsec.tunnel.ipv6.dscp = 0; 193 194 if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) 195 sess_conf->ipsec.tunnel.ipv6.dscp = 196 TEST_IPSEC_DSCP_VAL; 197 198 if (flags->flabel == TEST_IPSEC_SET_FLABEL_0_INNER_1) 199 sess_conf->ipsec.tunnel.ipv6.flabel = 0; 200 201 if (flags->flabel == TEST_IPSEC_SET_FLABEL_1_INNER_0) 202 sess_conf->ipsec.tunnel.ipv6.flabel = 203 TEST_IPSEC_FLABEL_VAL; 204 205 memcpy(&sess_conf->ipsec.tunnel.ipv6.src_addr, &src_v6, 206 sizeof(src_v6)); 207 memcpy(&sess_conf->ipsec.tunnel.ipv6.dst_addr, &dst_v6, 208 sizeof(dst_v6)); 209 } 210 } 211 212 /* Save SA as userdata for the security session. When 213 * the packet is received, this userdata will be 214 * retrieved using the metadata from the packet. 215 * 216 * The PMD is expected to set similar metadata for other 217 * operations, like rte_eth_event, which are tied to 218 * security session. In such cases, the userdata could 219 * be obtained to uniquely identify the security 220 * parameters denoted. 221 */ 222 223 sess_conf->userdata = (void *) sa; 224 225 sec_ctx = rte_eth_dev_get_sec_ctx(portid); 226 if (sec_ctx == NULL) { 227 printf("Ethernet device doesn't support security features.\n"); 228 return TEST_SKIPPED; 229 } 230 231 sec_cap_idx.action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL; 232 sec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_IPSEC; 233 sec_cap_idx.ipsec.proto = sess_conf->ipsec.proto; 234 sec_cap_idx.ipsec.mode = sess_conf->ipsec.mode; 235 sec_cap_idx.ipsec.direction = sess_conf->ipsec.direction; 236 sec_cap = rte_security_capability_get(sec_ctx, &sec_cap_idx); 237 if (sec_cap == NULL) { 238 printf("No capabilities registered\n"); 239 return TEST_SKIPPED; 240 } 241 242 if (sa->aead || sa->aes_gmac) 243 memcpy(&sess_conf->ipsec.salt, sa->salt.data, 244 RTE_MIN(sizeof(sess_conf->ipsec.salt), sa->salt.len)); 245 246 /* Copy cipher session parameters */ 247 if (sa->aead) { 248 rte_memcpy(sess_conf->crypto_xform, &sa->xform.aead, 249 sizeof(struct rte_crypto_sym_xform)); 250 sess_conf->crypto_xform->aead.key.data = sa->key.data; 251 /* Verify crypto capabilities */ 252 if (test_sec_crypto_caps_aead_verify(sec_cap, sess_conf->crypto_xform) != 0) { 253 RTE_LOG(INFO, USER1, 254 "Crypto capabilities not supported\n"); 255 return TEST_SKIPPED; 256 } 257 } else { 258 if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 259 rte_memcpy(&sess_conf->crypto_xform->cipher, 260 &sa->xform.chain.cipher.cipher, 261 sizeof(struct rte_crypto_cipher_xform)); 262 263 rte_memcpy(&sess_conf->crypto_xform->next->auth, 264 &sa->xform.chain.auth.auth, 265 sizeof(struct rte_crypto_auth_xform)); 266 sess_conf->crypto_xform->cipher.key.data = 267 sa->key.data; 268 sess_conf->crypto_xform->next->auth.key.data = 269 sa->auth_key.data; 270 /* Verify crypto capabilities */ 271 if (test_sec_crypto_caps_cipher_verify(sec_cap, 272 sess_conf->crypto_xform) != 0) { 273 RTE_LOG(INFO, USER1, 274 "Cipher crypto capabilities not supported\n"); 275 return TEST_SKIPPED; 276 } 277 278 if (test_sec_crypto_caps_auth_verify(sec_cap, 279 sess_conf->crypto_xform->next) != 0) { 280 RTE_LOG(INFO, USER1, 281 "Auth crypto capabilities not supported\n"); 282 return TEST_SKIPPED; 283 } 284 } else { 285 rte_memcpy(&sess_conf->crypto_xform->next->cipher, 286 &sa->xform.chain.cipher.cipher, 287 sizeof(struct rte_crypto_cipher_xform)); 288 rte_memcpy(&sess_conf->crypto_xform->auth, 289 &sa->xform.chain.auth.auth, 290 sizeof(struct rte_crypto_auth_xform)); 291 sess_conf->crypto_xform->auth.key.data = 292 sa->auth_key.data; 293 sess_conf->crypto_xform->next->cipher.key.data = 294 sa->key.data; 295 296 /* Verify crypto capabilities */ 297 if (test_sec_crypto_caps_cipher_verify(sec_cap, 298 sess_conf->crypto_xform->next) != 0) { 299 RTE_LOG(INFO, USER1, 300 "Cipher crypto capabilities not supported\n"); 301 return TEST_SKIPPED; 302 } 303 304 if (test_sec_crypto_caps_auth_verify(sec_cap, 305 sess_conf->crypto_xform) != 0) { 306 RTE_LOG(INFO, USER1, 307 "Auth crypto capabilities not supported\n"); 308 return TEST_SKIPPED; 309 } 310 } 311 } 312 313 if (test_ipsec_sec_caps_verify(&sess_conf->ipsec, sec_cap, false) != 0) 314 return TEST_SKIPPED; 315 316 if ((sa->ipsec_xform.direction == 317 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) && 318 (sa->ipsec_xform.options.iv_gen_disable == 1)) { 319 /* Set env variable when IV generation is disabled */ 320 char arr[128]; 321 int len = 0, j = 0; 322 int iv_len = (sa->aead || sa->aes_gmac) ? 8 : 16; 323 324 for (; j < iv_len; j++) 325 len += snprintf(arr+len, sizeof(arr) - len, 326 "0x%x, ", sa->iv.data[j]); 327 setenv("ETH_SEC_IV_OVR", arr, 1); 328 } 329 330 *sess = rte_security_session_create(sec_ctx, sess_conf, sess_pool); 331 if (*sess == NULL) { 332 printf("SEC Session init failed.\n"); 333 return TEST_FAILED; 334 } 335 336 *ol_flags = sec_cap->ol_flags; 337 *ctx = sec_ctx; 338 339 return 0; 340 } 341 342 /* Check the link status of all ports in up to 3s, and print them finally */ 343 static void 344 check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) 345 { 346 #define CHECK_INTERVAL 100 /* 100ms */ 347 #define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ 348 uint16_t portid; 349 uint8_t count, all_ports_up, print_flag = 0; 350 struct rte_eth_link link; 351 int ret; 352 char link_status[RTE_ETH_LINK_MAX_STR_LEN]; 353 354 printf("Checking link statuses...\n"); 355 fflush(stdout); 356 for (count = 0; count <= MAX_CHECK_TIME; count++) { 357 all_ports_up = 1; 358 for (portid = 0; portid < port_num; portid++) { 359 if ((port_mask & (1 << portid)) == 0) 360 continue; 361 memset(&link, 0, sizeof(link)); 362 ret = rte_eth_link_get_nowait(portid, &link); 363 if (ret < 0) { 364 all_ports_up = 0; 365 if (print_flag == 1) 366 printf("Port %u link get failed: %s\n", 367 portid, rte_strerror(-ret)); 368 continue; 369 } 370 371 /* print link status if flag set */ 372 if (print_flag == 1) { 373 if (link.link_status && link_mbps == 0) 374 link_mbps = link.link_speed; 375 376 rte_eth_link_to_str(link_status, 377 sizeof(link_status), &link); 378 printf("Port %d %s\n", portid, link_status); 379 continue; 380 } 381 /* clear all_ports_up flag if any link down */ 382 if (link.link_status == RTE_ETH_LINK_DOWN) { 383 all_ports_up = 0; 384 break; 385 } 386 } 387 /* after finally printing all link status, get out */ 388 if (print_flag == 1) 389 break; 390 391 if (all_ports_up == 0) { 392 fflush(stdout); 393 rte_delay_ms(CHECK_INTERVAL); 394 } 395 396 /* set the print_flag if all ports up or timeout */ 397 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) 398 print_flag = 1; 399 } 400 } 401 402 static void 403 print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr) 404 { 405 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 406 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); 407 printf("%s%s", name, buf); 408 } 409 410 static void 411 copy_buf_to_pkt_segs(const uint8_t *buf, unsigned int len, 412 struct rte_mbuf *pkt, unsigned int offset) 413 { 414 unsigned int copied = 0; 415 unsigned int copy_len; 416 struct rte_mbuf *seg; 417 void *seg_buf; 418 419 seg = pkt; 420 while (offset >= rte_pktmbuf_tailroom(seg)) { 421 offset -= rte_pktmbuf_tailroom(seg); 422 seg = seg->next; 423 } 424 copy_len = seg->buf_len - seg->data_off - offset; 425 seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset); 426 while (len > copy_len) { 427 rte_memcpy(seg_buf, buf + copied, (size_t) copy_len); 428 len -= copy_len; 429 copied += copy_len; 430 seg->data_len += copy_len; 431 432 seg = seg->next; 433 copy_len = seg->buf_len - seg->data_off; 434 seg_buf = rte_pktmbuf_mtod(seg, void *); 435 } 436 rte_memcpy(seg_buf, buf + copied, (size_t) len); 437 seg->data_len = len; 438 439 pkt->pkt_len += copied + len; 440 } 441 442 static bool 443 is_outer_ipv4(struct ipsec_test_data *td) 444 { 445 bool outer_ipv4; 446 447 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS || 448 td->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) 449 outer_ipv4 = (((td->input_text.data[0] & 0xF0) >> 4) == IPVERSION); 450 else 451 outer_ipv4 = (td->ipsec_xform.tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4); 452 return outer_ipv4; 453 } 454 455 static inline struct rte_mbuf * 456 init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len, bool outer_ipv4) 457 { 458 struct rte_mbuf *pkt, *tail; 459 uint16_t space; 460 461 pkt = rte_pktmbuf_alloc(mp); 462 if (pkt == NULL) 463 return NULL; 464 465 if (outer_ipv4) { 466 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN), 467 &dummy_ipv4_eth_hdr, RTE_ETHER_HDR_LEN); 468 pkt->l3_len = sizeof(struct rte_ipv4_hdr); 469 } else { 470 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN), 471 &dummy_ipv6_eth_hdr, RTE_ETHER_HDR_LEN); 472 pkt->l3_len = sizeof(struct rte_ipv6_hdr); 473 } 474 pkt->l2_len = RTE_ETHER_HDR_LEN; 475 476 space = rte_pktmbuf_tailroom(pkt); 477 tail = pkt; 478 /* Error if SG mode is not enabled */ 479 if (!sg_mode && space < len) { 480 rte_pktmbuf_free(pkt); 481 return NULL; 482 } 483 /* Extra room for expansion */ 484 while (space < len) { 485 tail->next = rte_pktmbuf_alloc(mp); 486 if (!tail->next) 487 goto error; 488 tail = tail->next; 489 space += rte_pktmbuf_tailroom(tail); 490 pkt->nb_segs++; 491 } 492 493 if (pkt->buf_len > len + RTE_ETHER_HDR_LEN) 494 rte_memcpy(rte_pktmbuf_append(pkt, len), data, len); 495 else 496 copy_buf_to_pkt_segs(data, len, pkt, RTE_ETHER_HDR_LEN); 497 return pkt; 498 error: 499 rte_pktmbuf_free(pkt); 500 return NULL; 501 } 502 503 static int 504 init_mempools(unsigned int nb_mbuf) 505 { 506 void *sec_ctx; 507 uint16_t nb_sess = 512; 508 uint32_t sess_sz; 509 char s[64]; 510 511 if (mbufpool == NULL) { 512 snprintf(s, sizeof(s), "mbuf_pool"); 513 mbufpool = rte_pktmbuf_pool_create(s, nb_mbuf, 514 MEMPOOL_CACHE_SIZE, RTE_CACHE_LINE_SIZE, 515 RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY); 516 if (mbufpool == NULL) { 517 printf("Cannot init mbuf pool\n"); 518 return TEST_FAILED; 519 } 520 printf("Allocated mbuf pool\n"); 521 } 522 523 sec_ctx = rte_eth_dev_get_sec_ctx(port_id); 524 if (sec_ctx == NULL) { 525 printf("Device does not support Security ctx\n"); 526 return TEST_SKIPPED; 527 } 528 sess_sz = rte_security_session_get_size(sec_ctx); 529 if (sess_pool == NULL) { 530 snprintf(s, sizeof(s), "sess_pool"); 531 sess_pool = rte_mempool_create(s, nb_sess, sess_sz, 532 MEMPOOL_CACHE_SIZE, 0, 533 NULL, NULL, NULL, NULL, 534 SOCKET_ID_ANY, 0); 535 if (sess_pool == NULL) { 536 printf("Cannot init sess pool\n"); 537 return TEST_FAILED; 538 } 539 printf("Allocated sess pool\n"); 540 } 541 542 return 0; 543 } 544 545 static int 546 create_default_flow(uint16_t portid) 547 { 548 struct rte_flow_action action[2]; 549 struct rte_flow_item pattern[2]; 550 struct rte_flow_attr attr = {0}; 551 struct rte_flow_error err; 552 struct rte_flow *flow; 553 int ret; 554 555 /* Add the default rte_flow to enable SECURITY for all ESP packets */ 556 557 pattern[0].type = RTE_FLOW_ITEM_TYPE_ESP; 558 pattern[0].spec = NULL; 559 pattern[0].mask = NULL; 560 pattern[0].last = NULL; 561 pattern[1].type = RTE_FLOW_ITEM_TYPE_END; 562 563 action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY; 564 action[0].conf = NULL; 565 action[1].type = RTE_FLOW_ACTION_TYPE_END; 566 action[1].conf = NULL; 567 568 attr.ingress = 1; 569 570 ret = rte_flow_validate(portid, &attr, pattern, action, &err); 571 if (ret) { 572 printf("\nValidate flow failed, ret = %d\n", ret); 573 return -1; 574 } 575 flow = rte_flow_create(portid, &attr, pattern, action, &err); 576 if (flow == NULL) { 577 printf("\nDefault flow rule create failed\n"); 578 return -1; 579 } 580 581 default_flow[portid] = flow; 582 583 return 0; 584 } 585 586 static void 587 destroy_default_flow(uint16_t portid) 588 { 589 struct rte_flow_error err; 590 int ret; 591 592 if (!default_flow[portid]) 593 return; 594 ret = rte_flow_destroy(portid, default_flow[portid], &err); 595 if (ret) { 596 printf("\nDefault flow rule destroy failed\n"); 597 return; 598 } 599 default_flow[portid] = NULL; 600 } 601 602 struct rte_mbuf **tx_pkts_burst; 603 struct rte_mbuf **rx_pkts_burst; 604 605 static int 606 compare_pkt_data(struct rte_mbuf *m, uint8_t *ref, unsigned int tot_len) 607 { 608 unsigned int len; 609 unsigned int nb_segs = m->nb_segs; 610 unsigned int matched = 0; 611 struct rte_mbuf *save = m; 612 613 while (m) { 614 len = tot_len; 615 if (len > m->data_len) 616 len = m->data_len; 617 if (len != 0) { 618 if (memcmp(rte_pktmbuf_mtod(m, char *), 619 ref + matched, len)) { 620 printf("\n====Reassembly case failed: Data Mismatch"); 621 rte_hexdump(stdout, "Reassembled", 622 rte_pktmbuf_mtod(m, char *), 623 len); 624 rte_hexdump(stdout, "reference", 625 ref + matched, 626 len); 627 return TEST_FAILED; 628 } 629 } 630 tot_len -= len; 631 matched += len; 632 m = m->next; 633 } 634 635 if (tot_len) { 636 printf("\n====Reassembly case failed: Data Missing %u", 637 tot_len); 638 printf("\n====nb_segs %u, tot_len %u", nb_segs, tot_len); 639 rte_pktmbuf_dump(stderr, save, -1); 640 return TEST_FAILED; 641 } 642 return TEST_SUCCESS; 643 } 644 645 static inline bool 646 is_ip_reassembly_incomplete(struct rte_mbuf *mbuf) 647 { 648 static uint64_t ip_reassembly_dynflag; 649 int ip_reassembly_dynflag_offset; 650 651 if (ip_reassembly_dynflag == 0) { 652 ip_reassembly_dynflag_offset = rte_mbuf_dynflag_lookup( 653 RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, NULL); 654 if (ip_reassembly_dynflag_offset < 0) 655 return false; 656 ip_reassembly_dynflag = RTE_BIT64(ip_reassembly_dynflag_offset); 657 } 658 659 return (mbuf->ol_flags & ip_reassembly_dynflag) != 0; 660 } 661 662 static void 663 free_mbuf(struct rte_mbuf *mbuf) 664 { 665 rte_eth_ip_reassembly_dynfield_t dynfield; 666 667 if (!mbuf) 668 return; 669 670 if (!is_ip_reassembly_incomplete(mbuf)) { 671 rte_pktmbuf_free(mbuf); 672 } else { 673 if (ip_reassembly_dynfield_offset < 0) 674 return; 675 676 while (mbuf) { 677 dynfield = *RTE_MBUF_DYNFIELD(mbuf, 678 ip_reassembly_dynfield_offset, 679 rte_eth_ip_reassembly_dynfield_t *); 680 rte_pktmbuf_free(mbuf); 681 if (dynfield.nb_frags == 0) 682 break; 683 mbuf = dynfield.next_frag; 684 } 685 } 686 } 687 688 689 static int 690 get_and_verify_incomplete_frags(struct rte_mbuf *mbuf, 691 struct reassembly_vector *vector) 692 { 693 rte_eth_ip_reassembly_dynfield_t *dynfield[MAX_PKT_BURST]; 694 int j = 0, ret; 695 /** 696 * IP reassembly offload is incomplete, and fragments are listed in 697 * dynfield which can be reassembled in SW. 698 */ 699 printf("\nHW IP Reassembly is not complete; attempt SW IP Reassembly," 700 "\nMatching with original frags."); 701 702 if (ip_reassembly_dynfield_offset < 0) 703 return -1; 704 705 printf("\ncomparing frag: %d", j); 706 /* Skip Ethernet header comparison */ 707 rte_pktmbuf_adj(mbuf, RTE_ETHER_HDR_LEN); 708 ret = compare_pkt_data(mbuf, vector->frags[j]->data, 709 vector->frags[j]->len); 710 if (ret) 711 return ret; 712 j++; 713 dynfield[j] = RTE_MBUF_DYNFIELD(mbuf, ip_reassembly_dynfield_offset, 714 rte_eth_ip_reassembly_dynfield_t *); 715 printf("\ncomparing frag: %d", j); 716 /* Skip Ethernet header comparison */ 717 rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN); 718 ret = compare_pkt_data(dynfield[j]->next_frag, vector->frags[j]->data, 719 vector->frags[j]->len); 720 if (ret) 721 return ret; 722 723 while ((dynfield[j]->nb_frags > 1) && 724 is_ip_reassembly_incomplete(dynfield[j]->next_frag)) { 725 j++; 726 dynfield[j] = RTE_MBUF_DYNFIELD(dynfield[j-1]->next_frag, 727 ip_reassembly_dynfield_offset, 728 rte_eth_ip_reassembly_dynfield_t *); 729 printf("\ncomparing frag: %d", j); 730 /* Skip Ethernet header comparison */ 731 rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN); 732 ret = compare_pkt_data(dynfield[j]->next_frag, 733 vector->frags[j]->data, vector->frags[j]->len); 734 if (ret) 735 return ret; 736 } 737 return ret; 738 } 739 740 static int 741 event_tx_burst(struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 742 { 743 struct rte_event ev; 744 int i, nb_sent = 0; 745 746 /* Convert packets to events */ 747 memset(&ev, 0, sizeof(ev)); 748 ev.sched_type = RTE_SCHED_TYPE_PARALLEL; 749 for (i = 0; i < nb_pkts; i++) { 750 ev.mbuf = tx_pkts[i]; 751 ev.mbuf->port = port_id; 752 nb_sent += rte_event_eth_tx_adapter_enqueue( 753 eventdev_id, port_id, &ev, 1, 0); 754 } 755 756 return nb_sent; 757 } 758 759 static int 760 event_rx_burst(struct rte_mbuf **rx_pkts, uint16_t nb_pkts_to_rx) 761 { 762 int nb_ev, nb_rx = 0, j = 0; 763 const int ms_per_pkt = 5; 764 struct rte_event ev; 765 766 do { 767 nb_ev = rte_event_dequeue_burst(eventdev_id, port_id, 768 &ev, 1, 0); 769 770 if (nb_ev == 0) { 771 rte_delay_ms(1); 772 continue; 773 } 774 775 /* Get packet from event */ 776 if (ev.event_type != RTE_EVENT_TYPE_ETHDEV) { 777 printf("Unsupported event type: %i\n", 778 ev.event_type); 779 continue; 780 } 781 rx_pkts[nb_rx++] = ev.mbuf; 782 } while (j++ < (nb_pkts_to_rx * ms_per_pkt) && nb_rx < nb_pkts_to_rx); 783 784 return nb_rx; 785 } 786 787 static int 788 verify_inbound_oop(struct ipsec_test_data *td, 789 bool silent, struct rte_mbuf *mbuf) 790 { 791 int ret = TEST_SUCCESS, rc; 792 struct rte_mbuf *orig; 793 uint32_t len; 794 void *data; 795 796 orig = *rte_security_oop_dynfield(mbuf); 797 if (!orig) { 798 if (!silent) 799 printf("\nUnable to get orig buffer OOP session"); 800 return TEST_FAILED; 801 } 802 803 /* Skip Ethernet header comparison */ 804 rte_pktmbuf_adj(orig, RTE_ETHER_HDR_LEN); 805 806 len = td->input_text.len; 807 if (orig->pkt_len != len) { 808 if (!silent) 809 printf("\nOriginal packet length mismatch, expected %u, got %u ", 810 len, orig->pkt_len); 811 ret = TEST_FAILED; 812 } 813 814 data = rte_pktmbuf_mtod(orig, void *); 815 rc = memcmp(data, td->input_text.data, len); 816 if (rc) { 817 ret = TEST_FAILED; 818 if (silent) 819 goto exit; 820 821 printf("TestCase %s line %d: %s\n", __func__, __LINE__, 822 "output text not as expected\n"); 823 824 rte_hexdump(stdout, "expected", td->input_text.data, len); 825 rte_hexdump(stdout, "actual", data, len); 826 } 827 exit: 828 rte_pktmbuf_free(orig); 829 return ret; 830 } 831 832 static int 833 test_ipsec_with_reassembly(struct reassembly_vector *vector, 834 const struct ipsec_test_flags *flags) 835 { 836 void *out_ses[ENCAP_DECAP_BURST_SZ] = {0}; 837 void *in_ses[ENCAP_DECAP_BURST_SZ] = {0}; 838 struct rte_eth_ip_reassembly_params reass_capa = {0}; 839 struct rte_security_session_conf sess_conf_out = {0}; 840 struct rte_security_session_conf sess_conf_in = {0}; 841 unsigned int nb_tx, burst_sz, nb_sent = 0; 842 struct rte_crypto_sym_xform cipher_out = {0}; 843 struct rte_crypto_sym_xform auth_out = {0}; 844 struct rte_crypto_sym_xform aead_out = {0}; 845 struct rte_crypto_sym_xform cipher_in = {0}; 846 struct rte_crypto_sym_xform auth_in = {0}; 847 struct rte_crypto_sym_xform aead_in = {0}; 848 struct ipsec_test_data sa_data; 849 void *ctx; 850 unsigned int i, nb_rx = 0, j; 851 uint32_t ol_flags; 852 bool outer_ipv4; 853 int ret = 0; 854 855 burst_sz = vector->burst ? ENCAP_DECAP_BURST_SZ : 1; 856 nb_tx = vector->nb_frags * burst_sz; 857 858 rte_eth_ip_reassembly_capability_get(port_id, &reass_capa); 859 if (reass_capa.max_frags < vector->nb_frags) 860 return TEST_SKIPPED; 861 862 memset(tx_pkts_burst, 0, sizeof(tx_pkts_burst[0]) * nb_tx); 863 memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_tx); 864 865 memcpy(&sa_data, vector->sa_data, sizeof(struct ipsec_test_data)); 866 sa_data.ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; 867 outer_ipv4 = is_outer_ipv4(&sa_data); 868 869 for (i = 0; i < nb_tx; i += vector->nb_frags) { 870 for (j = 0; j < vector->nb_frags; j++) { 871 tx_pkts_burst[i+j] = init_packet(mbufpool, 872 vector->frags[j]->data, 873 vector->frags[j]->len, outer_ipv4); 874 if (tx_pkts_burst[i+j] == NULL) { 875 ret = -1; 876 printf("\n packed init failed\n"); 877 goto out; 878 } 879 } 880 } 881 882 for (i = 0; i < burst_sz; i++) { 883 memcpy(&sa_data, vector->sa_data, 884 sizeof(struct ipsec_test_data)); 885 /* Update SPI for every new SA */ 886 sa_data.ipsec_xform.spi += i; 887 sa_data.ipsec_xform.direction = 888 RTE_SECURITY_IPSEC_SA_DIR_EGRESS; 889 if (sa_data.aead) { 890 sess_conf_out.crypto_xform = &aead_out; 891 } else { 892 sess_conf_out.crypto_xform = &cipher_out; 893 sess_conf_out.crypto_xform->next = &auth_out; 894 } 895 896 /* Create Inline IPsec outbound session. */ 897 ret = create_inline_ipsec_session(&sa_data, port_id, 898 &out_ses[i], &ctx, &ol_flags, flags, 899 &sess_conf_out); 900 if (ret) { 901 printf("\nInline outbound session create failed\n"); 902 goto out; 903 } 904 } 905 906 j = 0; 907 for (i = 0; i < nb_tx; i++) { 908 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 909 rte_security_set_pkt_metadata(ctx, 910 out_ses[j], tx_pkts_burst[i], NULL); 911 tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 912 913 /* Move to next SA after nb_frags */ 914 if ((i + 1) % vector->nb_frags == 0) 915 j++; 916 } 917 918 for (i = 0; i < burst_sz; i++) { 919 memcpy(&sa_data, vector->sa_data, 920 sizeof(struct ipsec_test_data)); 921 /* Update SPI for every new SA */ 922 sa_data.ipsec_xform.spi += i; 923 sa_data.ipsec_xform.direction = 924 RTE_SECURITY_IPSEC_SA_DIR_INGRESS; 925 926 if (sa_data.aead) { 927 sess_conf_in.crypto_xform = &aead_in; 928 } else { 929 sess_conf_in.crypto_xform = &auth_in; 930 sess_conf_in.crypto_xform->next = &cipher_in; 931 } 932 /* Create Inline IPsec inbound session. */ 933 ret = create_inline_ipsec_session(&sa_data, port_id, &in_ses[i], 934 &ctx, &ol_flags, flags, &sess_conf_in); 935 if (ret) { 936 printf("\nInline inbound session create failed\n"); 937 goto out; 938 } 939 } 940 941 /* Retrieve reassembly dynfield offset if available */ 942 if (ip_reassembly_dynfield_offset < 0 && vector->nb_frags > 1) 943 ip_reassembly_dynfield_offset = rte_mbuf_dynfield_lookup( 944 RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, NULL); 945 946 947 ret = create_default_flow(port_id); 948 if (ret) 949 goto out; 950 951 if (event_mode_enabled) 952 nb_sent = event_tx_burst(tx_pkts_burst, nb_tx); 953 else 954 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_tx); 955 if (nb_sent != nb_tx) { 956 ret = -1; 957 printf("\nFailed to tx %u pkts", nb_tx); 958 goto out; 959 } 960 961 rte_delay_ms(1); 962 963 /* Retry few times before giving up */ 964 nb_rx = 0; 965 j = 0; 966 if (event_mode_enabled) 967 nb_rx = event_rx_burst(rx_pkts_burst, nb_tx); 968 else 969 do { 970 nb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx], 971 nb_tx - nb_rx); 972 j++; 973 if (nb_rx >= nb_tx) 974 break; 975 rte_delay_ms(1); 976 } while (j < 5 || !nb_rx); 977 978 /* Check for minimum number of Rx packets expected */ 979 if ((vector->nb_frags == 1 && nb_rx != nb_tx) || 980 (vector->nb_frags > 1 && nb_rx < burst_sz)) { 981 printf("\nreceived less Rx pkts(%u) pkts\n", nb_rx); 982 ret = TEST_FAILED; 983 goto out; 984 } 985 986 for (i = 0; i < nb_rx; i++) { 987 if (vector->nb_frags > 1 && 988 is_ip_reassembly_incomplete(rx_pkts_burst[i])) { 989 ret = get_and_verify_incomplete_frags(rx_pkts_burst[i], 990 vector); 991 if (ret != TEST_SUCCESS) 992 break; 993 continue; 994 } 995 996 if (rx_pkts_burst[i]->ol_flags & 997 RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED || 998 !(rx_pkts_burst[i]->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD)) { 999 printf("\nsecurity offload failed\n"); 1000 ret = TEST_FAILED; 1001 break; 1002 } 1003 1004 if (vector->full_pkt->len + RTE_ETHER_HDR_LEN != 1005 rx_pkts_burst[i]->pkt_len) { 1006 printf("\nreassembled/decrypted packet length mismatch\n"); 1007 ret = TEST_FAILED; 1008 break; 1009 } 1010 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN); 1011 ret = compare_pkt_data(rx_pkts_burst[i], 1012 vector->full_pkt->data, 1013 vector->full_pkt->len); 1014 if (ret != TEST_SUCCESS) 1015 break; 1016 } 1017 1018 out: 1019 destroy_default_flow(port_id); 1020 1021 /* Clear session data. */ 1022 for (i = 0; i < burst_sz; i++) { 1023 if (out_ses[i]) 1024 rte_security_session_destroy(ctx, out_ses[i]); 1025 if (in_ses[i]) 1026 rte_security_session_destroy(ctx, in_ses[i]); 1027 } 1028 1029 for (i = nb_sent; i < nb_tx; i++) 1030 free_mbuf(tx_pkts_burst[i]); 1031 for (i = 0; i < nb_rx; i++) 1032 free_mbuf(rx_pkts_burst[i]); 1033 return ret; 1034 } 1035 1036 static int 1037 test_ipsec_inline_sa_exp_event_callback(uint16_t port_id, 1038 enum rte_eth_event_type type, void *param, void *ret_param) 1039 { 1040 struct sa_expiry_vector *vector = (struct sa_expiry_vector *)param; 1041 struct rte_eth_event_ipsec_desc *event_desc = NULL; 1042 1043 RTE_SET_USED(port_id); 1044 1045 if (type != RTE_ETH_EVENT_IPSEC) 1046 return -1; 1047 1048 event_desc = ret_param; 1049 if (event_desc == NULL) { 1050 printf("Event descriptor not set\n"); 1051 return -1; 1052 } 1053 vector->notify_event = true; 1054 if (event_desc->metadata != (uint64_t)vector->sa_data) { 1055 printf("Mismatch in event specific metadata\n"); 1056 return -1; 1057 } 1058 switch (event_desc->subtype) { 1059 case RTE_ETH_EVENT_IPSEC_SA_PKT_EXPIRY: 1060 vector->event = RTE_ETH_EVENT_IPSEC_SA_PKT_EXPIRY; 1061 break; 1062 case RTE_ETH_EVENT_IPSEC_SA_BYTE_EXPIRY: 1063 vector->event = RTE_ETH_EVENT_IPSEC_SA_BYTE_EXPIRY; 1064 break; 1065 case RTE_ETH_EVENT_IPSEC_SA_PKT_HARD_EXPIRY: 1066 vector->event = RTE_ETH_EVENT_IPSEC_SA_PKT_HARD_EXPIRY; 1067 break; 1068 case RTE_ETH_EVENT_IPSEC_SA_BYTE_HARD_EXPIRY: 1069 vector->event = RTE_ETH_EVENT_IPSEC_SA_BYTE_HARD_EXPIRY; 1070 break; 1071 default: 1072 printf("Invalid IPsec event reported\n"); 1073 return -1; 1074 } 1075 1076 return 0; 1077 } 1078 1079 static enum rte_eth_event_ipsec_subtype 1080 test_ipsec_inline_setup_expiry_vector(struct sa_expiry_vector *vector, 1081 const struct ipsec_test_flags *flags, 1082 struct ipsec_test_data *tdata) 1083 { 1084 enum rte_eth_event_ipsec_subtype event = RTE_ETH_EVENT_IPSEC_UNKNOWN; 1085 1086 vector->event = RTE_ETH_EVENT_IPSEC_UNKNOWN; 1087 vector->notify_event = false; 1088 vector->sa_data = (void *)tdata; 1089 if (flags->sa_expiry_pkts_soft) 1090 event = RTE_ETH_EVENT_IPSEC_SA_PKT_EXPIRY; 1091 else if (flags->sa_expiry_bytes_soft) 1092 event = RTE_ETH_EVENT_IPSEC_SA_BYTE_EXPIRY; 1093 else if (flags->sa_expiry_pkts_hard) 1094 event = RTE_ETH_EVENT_IPSEC_SA_PKT_HARD_EXPIRY; 1095 else 1096 event = RTE_ETH_EVENT_IPSEC_SA_BYTE_HARD_EXPIRY; 1097 rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_IPSEC, 1098 test_ipsec_inline_sa_exp_event_callback, vector); 1099 1100 return event; 1101 } 1102 1103 static int 1104 test_ipsec_inline_proto_process(struct ipsec_test_data *td, 1105 struct ipsec_test_data *res_d, 1106 int nb_pkts, 1107 bool silent, 1108 const struct ipsec_test_flags *flags) 1109 { 1110 enum rte_eth_event_ipsec_subtype event = RTE_ETH_EVENT_IPSEC_UNKNOWN; 1111 struct rte_security_session_conf sess_conf = {0}; 1112 struct rte_crypto_sym_xform cipher = {0}; 1113 struct rte_crypto_sym_xform auth = {0}; 1114 struct rte_crypto_sym_xform aead = {0}; 1115 struct sa_expiry_vector vector = {0}; 1116 void *ctx; 1117 int nb_rx = 0, nb_sent; 1118 uint32_t ol_flags; 1119 int i, j = 0, ret; 1120 bool outer_ipv4; 1121 void *ses; 1122 1123 memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_pkts); 1124 1125 if (flags->sa_expiry_pkts_soft || flags->sa_expiry_bytes_soft || 1126 flags->sa_expiry_pkts_hard || flags->sa_expiry_bytes_hard) { 1127 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) 1128 return TEST_SUCCESS; 1129 event = test_ipsec_inline_setup_expiry_vector(&vector, flags, td); 1130 } 1131 1132 if (td->aead) { 1133 sess_conf.crypto_xform = &aead; 1134 } else { 1135 if (td->ipsec_xform.direction == 1136 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1137 sess_conf.crypto_xform = &cipher; 1138 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1139 sess_conf.crypto_xform->next = &auth; 1140 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1141 } else { 1142 sess_conf.crypto_xform = &auth; 1143 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1144 sess_conf.crypto_xform->next = &cipher; 1145 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1146 } 1147 } 1148 1149 /* Create Inline IPsec session. */ 1150 ret = create_inline_ipsec_session(td, port_id, &ses, &ctx, 1151 &ol_flags, flags, &sess_conf); 1152 if (ret) 1153 return ret; 1154 1155 if (flags->inb_oop && rte_security_oop_dynfield_offset < 0) { 1156 printf("\nDynamic field not available for inline inbound OOP"); 1157 ret = TEST_FAILED; 1158 goto out; 1159 } 1160 1161 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 1162 ret = create_default_flow(port_id); 1163 if (ret) 1164 goto out; 1165 } 1166 outer_ipv4 = is_outer_ipv4(td); 1167 1168 for (i = 0; i < nb_pkts; i++) { 1169 tx_pkts_burst[i] = init_packet(mbufpool, td->input_text.data, 1170 td->input_text.len, outer_ipv4); 1171 if (tx_pkts_burst[i] == NULL) { 1172 while (i--) 1173 rte_pktmbuf_free(tx_pkts_burst[i]); 1174 ret = TEST_FAILED; 1175 goto out; 1176 } 1177 1178 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkts_burst[i], 1179 uint8_t *, RTE_ETHER_HDR_LEN), flags)) { 1180 while (i--) 1181 rte_pktmbuf_free(tx_pkts_burst[i]); 1182 ret = TEST_FAILED; 1183 goto out; 1184 } 1185 1186 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1187 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 1188 rte_security_set_pkt_metadata(ctx, ses, 1189 tx_pkts_burst[i], NULL); 1190 tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 1191 } 1192 } 1193 /* Send packet to ethdev for inline IPsec processing. */ 1194 if (event_mode_enabled) 1195 nb_sent = event_tx_burst(tx_pkts_burst, nb_pkts); 1196 else 1197 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_pkts); 1198 1199 if (nb_sent != nb_pkts) { 1200 printf("\nUnable to TX %d packets, sent: %i", nb_pkts, nb_sent); 1201 for ( ; nb_sent < nb_pkts; nb_sent++) 1202 rte_pktmbuf_free(tx_pkts_burst[nb_sent]); 1203 ret = TEST_FAILED; 1204 goto out; 1205 } 1206 1207 rte_pause(); 1208 1209 /* Receive back packet on loopback interface. */ 1210 if (event_mode_enabled) 1211 nb_rx = event_rx_burst(rx_pkts_burst, nb_sent); 1212 else 1213 do { 1214 rte_delay_ms(1); 1215 nb_rx += rte_eth_rx_burst(port_id, 0, 1216 &rx_pkts_burst[nb_rx], 1217 nb_sent - nb_rx); 1218 if (nb_rx >= nb_sent) 1219 break; 1220 } while (j++ < 5 || nb_rx == 0); 1221 1222 if (!flags->sa_expiry_pkts_hard && 1223 !flags->sa_expiry_bytes_hard && 1224 (nb_rx != nb_sent)) { 1225 printf("\nUnable to RX all %d packets, received(%i)", 1226 nb_sent, nb_rx); 1227 while (--nb_rx >= 0) 1228 rte_pktmbuf_free(rx_pkts_burst[nb_rx]); 1229 ret = TEST_FAILED; 1230 goto out; 1231 } 1232 1233 for (i = 0; i < nb_rx; i++) { 1234 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN); 1235 1236 ret = test_ipsec_post_process(rx_pkts_burst[i], td, 1237 res_d, silent, flags); 1238 if (ret != TEST_SUCCESS) { 1239 for ( ; i < nb_rx; i++) 1240 rte_pktmbuf_free(rx_pkts_burst[i]); 1241 goto out; 1242 } 1243 1244 ret = test_ipsec_stats_verify(ctx, ses, flags, 1245 td->ipsec_xform.direction); 1246 if (ret != TEST_SUCCESS) { 1247 for ( ; i < nb_rx; i++) 1248 rte_pktmbuf_free(rx_pkts_burst[i]); 1249 goto out; 1250 } 1251 1252 if (flags->inb_oop) { 1253 ret = verify_inbound_oop(td, silent, rx_pkts_burst[i]); 1254 if (ret != TEST_SUCCESS) { 1255 for ( ; i < nb_rx; i++) 1256 rte_pktmbuf_free(rx_pkts_burst[i]); 1257 goto out; 1258 } 1259 } 1260 1261 rte_pktmbuf_free(rx_pkts_burst[i]); 1262 rx_pkts_burst[i] = NULL; 1263 } 1264 1265 out: 1266 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) 1267 destroy_default_flow(port_id); 1268 if (flags->sa_expiry_pkts_soft || flags->sa_expiry_bytes_soft || 1269 flags->sa_expiry_pkts_hard || flags->sa_expiry_bytes_hard) { 1270 if (vector.notify_event && (vector.event == event)) 1271 ret = TEST_SUCCESS; 1272 else 1273 ret = TEST_FAILED; 1274 1275 rte_eth_dev_callback_unregister(port_id, RTE_ETH_EVENT_IPSEC, 1276 test_ipsec_inline_sa_exp_event_callback, &vector); 1277 } 1278 1279 /* Destroy session so that other cases can create the session again */ 1280 rte_security_session_destroy(ctx, ses); 1281 ses = NULL; 1282 1283 return ret; 1284 } 1285 1286 static int 1287 test_ipsec_inline_proto_all(const struct ipsec_test_flags *flags) 1288 { 1289 struct ipsec_test_data td_outb; 1290 struct ipsec_test_data td_inb; 1291 unsigned int i, nb_pkts = 1, pass_cnt = 0, fail_cnt = 0; 1292 int ret; 1293 1294 if (flags->iv_gen || flags->sa_expiry_pkts_soft || 1295 flags->sa_expiry_bytes_soft || 1296 flags->sa_expiry_bytes_hard || 1297 flags->sa_expiry_pkts_hard) 1298 nb_pkts = TEST_SEC_PKTS_MAX; 1299 1300 for (i = 0; i < RTE_DIM(sec_alg_list); i++) { 1301 test_ipsec_td_prepare(sec_alg_list[i].param1, 1302 sec_alg_list[i].param2, 1303 flags, &td_outb, 1); 1304 1305 if (!td_outb.aead) { 1306 enum rte_crypto_cipher_algorithm cipher_alg; 1307 enum rte_crypto_auth_algorithm auth_alg; 1308 1309 cipher_alg = td_outb.xform.chain.cipher.cipher.algo; 1310 auth_alg = td_outb.xform.chain.auth.auth.algo; 1311 1312 if (td_outb.aes_gmac && cipher_alg != RTE_CRYPTO_CIPHER_NULL) 1313 continue; 1314 1315 /* ICV is not applicable for NULL auth */ 1316 if (flags->icv_corrupt && 1317 auth_alg == RTE_CRYPTO_AUTH_NULL) 1318 continue; 1319 1320 /* IV is not applicable for NULL cipher */ 1321 if (flags->iv_gen && 1322 cipher_alg == RTE_CRYPTO_CIPHER_NULL) 1323 continue; 1324 } 1325 1326 if (flags->udp_encap) 1327 td_outb.ipsec_xform.options.udp_encap = 1; 1328 1329 if (flags->sa_expiry_bytes_soft) 1330 td_outb.ipsec_xform.life.bytes_soft_limit = 1331 (((td_outb.output_text.len + RTE_ETHER_HDR_LEN) 1332 * nb_pkts) >> 3) - 1; 1333 if (flags->sa_expiry_pkts_hard) 1334 td_outb.ipsec_xform.life.packets_hard_limit = TEST_SEC_PKTS_MAX - 1; 1335 if (flags->sa_expiry_bytes_hard) 1336 td_outb.ipsec_xform.life.bytes_hard_limit = 1337 (((td_outb.output_text.len + RTE_ETHER_HDR_LEN) 1338 * nb_pkts) >> 3) - 1; 1339 1340 ret = test_ipsec_inline_proto_process(&td_outb, &td_inb, nb_pkts, 1341 false, flags); 1342 if (ret == TEST_SKIPPED) 1343 continue; 1344 1345 if (ret == TEST_FAILED) { 1346 printf("\n TEST FAILED"); 1347 test_sec_alg_display(sec_alg_list[i].param1, sec_alg_list[i].param2); 1348 fail_cnt++; 1349 continue; 1350 } 1351 1352 test_ipsec_td_update(&td_inb, &td_outb, 1, flags); 1353 1354 ret = test_ipsec_inline_proto_process(&td_inb, NULL, nb_pkts, 1355 false, flags); 1356 if (ret == TEST_SKIPPED) 1357 continue; 1358 1359 if (ret == TEST_FAILED) { 1360 printf("\n TEST FAILED"); 1361 test_sec_alg_display(sec_alg_list[i].param1, sec_alg_list[i].param2); 1362 fail_cnt++; 1363 continue; 1364 } 1365 1366 if (flags->display_alg) 1367 test_sec_alg_display(sec_alg_list[i].param1, sec_alg_list[i].param2); 1368 1369 pass_cnt++; 1370 } 1371 1372 printf("Tests passed: %d, failed: %d", pass_cnt, fail_cnt); 1373 if (fail_cnt > 0) 1374 return TEST_FAILED; 1375 if (pass_cnt > 0) 1376 return TEST_SUCCESS; 1377 else 1378 return TEST_SKIPPED; 1379 } 1380 1381 static int 1382 test_ipsec_inline_proto_process_with_esn(struct ipsec_test_data td[], 1383 struct ipsec_test_data res_d[], 1384 int nb_pkts, 1385 bool silent, 1386 const struct ipsec_test_flags *flags) 1387 { 1388 struct rte_security_session_conf sess_conf = {0}; 1389 struct ipsec_test_data *res_d_tmp = NULL; 1390 struct rte_crypto_sym_xform cipher = {0}; 1391 struct rte_crypto_sym_xform auth = {0}; 1392 struct rte_crypto_sym_xform aead = {0}; 1393 struct rte_mbuf *rx_pkt = NULL; 1394 struct rte_mbuf *tx_pkt = NULL; 1395 int nb_rx, nb_sent; 1396 void *ses; 1397 void *ctx; 1398 uint32_t ol_flags; 1399 bool outer_ipv4; 1400 int i, ret; 1401 1402 if (td[0].aead) { 1403 sess_conf.crypto_xform = &aead; 1404 } else { 1405 if (td[0].ipsec_xform.direction == 1406 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1407 sess_conf.crypto_xform = &cipher; 1408 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1409 sess_conf.crypto_xform->next = &auth; 1410 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1411 } else { 1412 sess_conf.crypto_xform = &auth; 1413 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1414 sess_conf.crypto_xform->next = &cipher; 1415 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1416 } 1417 } 1418 1419 /* Create Inline IPsec session. */ 1420 ret = create_inline_ipsec_session(&td[0], port_id, &ses, &ctx, 1421 &ol_flags, flags, &sess_conf); 1422 if (ret) 1423 return ret; 1424 1425 if (td[0].ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 1426 ret = create_default_flow(port_id); 1427 if (ret) 1428 goto out; 1429 } 1430 outer_ipv4 = is_outer_ipv4(td); 1431 1432 for (i = 0; i < nb_pkts; i++) { 1433 tx_pkt = init_packet(mbufpool, td[i].input_text.data, 1434 td[i].input_text.len, outer_ipv4); 1435 if (tx_pkt == NULL) { 1436 ret = TEST_FAILED; 1437 goto out; 1438 } 1439 1440 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkt, 1441 uint8_t *, RTE_ETHER_HDR_LEN), flags)) { 1442 ret = TEST_FAILED; 1443 goto out; 1444 } 1445 1446 if (td[i].ipsec_xform.direction == 1447 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1448 if (flags->antireplay) { 1449 sess_conf.ipsec.esn.value = 1450 td[i].ipsec_xform.esn.value; 1451 ret = rte_security_session_update(ctx, ses, 1452 &sess_conf); 1453 if (ret) { 1454 printf("Could not update ESN in session\n"); 1455 rte_pktmbuf_free(tx_pkt); 1456 ret = TEST_SKIPPED; 1457 goto out; 1458 } 1459 } 1460 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 1461 rte_security_set_pkt_metadata(ctx, ses, 1462 tx_pkt, NULL); 1463 tx_pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 1464 } 1465 1466 /* Send packet to ethdev for inline IPsec processing. */ 1467 if (event_mode_enabled) 1468 nb_sent = event_tx_burst(&tx_pkt, 1); 1469 else 1470 nb_sent = rte_eth_tx_burst(port_id, 0, &tx_pkt, 1); 1471 1472 if (nb_sent != 1) { 1473 printf("\nUnable to TX packets"); 1474 rte_pktmbuf_free(tx_pkt); 1475 ret = TEST_FAILED; 1476 goto out; 1477 } 1478 1479 rte_pause(); 1480 1481 /* Receive back packet on loopback interface. */ 1482 if (event_mode_enabled) 1483 nb_rx = event_rx_burst(&rx_pkt, nb_sent); 1484 else { 1485 do { 1486 rte_delay_ms(1); 1487 nb_rx = rte_eth_rx_burst(port_id, 0, &rx_pkt, 1); 1488 } while (nb_rx == 0); 1489 } 1490 rte_pktmbuf_adj(rx_pkt, RTE_ETHER_HDR_LEN); 1491 1492 if (res_d != NULL) 1493 res_d_tmp = &res_d[i]; 1494 1495 ret = test_ipsec_post_process(rx_pkt, &td[i], 1496 res_d_tmp, silent, flags); 1497 if (ret != TEST_SUCCESS) { 1498 rte_pktmbuf_free(rx_pkt); 1499 goto out; 1500 } 1501 1502 ret = test_ipsec_stats_verify(ctx, ses, flags, 1503 td->ipsec_xform.direction); 1504 if (ret != TEST_SUCCESS) { 1505 rte_pktmbuf_free(rx_pkt); 1506 goto out; 1507 } 1508 1509 rte_pktmbuf_free(rx_pkt); 1510 rx_pkt = NULL; 1511 tx_pkt = NULL; 1512 } 1513 1514 out: 1515 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) 1516 destroy_default_flow(port_id); 1517 1518 /* Destroy session so that other cases can create the session again */ 1519 rte_security_session_destroy(ctx, ses); 1520 ses = NULL; 1521 1522 return ret; 1523 } 1524 1525 static int 1526 ut_setup_inline_ipsec_reassembly(void) 1527 { 1528 struct rte_eth_ip_reassembly_params reass_capa = {0}; 1529 int ret; 1530 1531 rte_eth_ip_reassembly_capability_get(port_id, &reass_capa); 1532 if (reass_capa.timeout_ms > APP_REASS_TIMEOUT) { 1533 reass_capa.timeout_ms = APP_REASS_TIMEOUT; 1534 rte_eth_ip_reassembly_conf_set(port_id, &reass_capa); 1535 } 1536 1537 /* Start event devices */ 1538 if (event_mode_enabled) { 1539 ret = rte_event_eth_rx_adapter_start(rx_adapter_id); 1540 if (ret < 0) { 1541 printf("Failed to start rx adapter %d\n", ret); 1542 return ret; 1543 } 1544 1545 ret = rte_event_dev_start(eventdev_id); 1546 if (ret < 0) { 1547 printf("Failed to start event device %d\n", ret); 1548 return ret; 1549 } 1550 } 1551 1552 /* Start device */ 1553 ret = rte_eth_dev_start(port_id); 1554 if (ret < 0) { 1555 printf("rte_eth_dev_start: err=%d, port=%d\n", 1556 ret, port_id); 1557 return ret; 1558 } 1559 /* always enable promiscuous */ 1560 ret = rte_eth_promiscuous_enable(port_id); 1561 if (ret != 0) { 1562 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n", 1563 rte_strerror(-ret), port_id); 1564 return ret; 1565 } 1566 1567 check_all_ports_link_status(1, RTE_PORT_ALL); 1568 1569 return 0; 1570 } 1571 1572 static void 1573 ut_teardown_inline_ipsec_reassembly(void) 1574 { 1575 struct rte_eth_ip_reassembly_params reass_conf = {0}; 1576 uint16_t portid; 1577 int ret; 1578 1579 /* Stop event devices */ 1580 if (event_mode_enabled) 1581 rte_event_dev_stop(eventdev_id); 1582 1583 /* port tear down */ 1584 RTE_ETH_FOREACH_DEV(portid) { 1585 ret = rte_eth_dev_stop(portid); 1586 if (ret != 0) 1587 printf("rte_eth_dev_stop: err=%s, port=%u\n", 1588 rte_strerror(-ret), portid); 1589 1590 /* Clear reassembly configuration */ 1591 rte_eth_ip_reassembly_conf_set(portid, &reass_conf); 1592 } 1593 } 1594 static int 1595 ut_setup_inline_ipsec(void) 1596 { 1597 int ret; 1598 1599 /* Start event devices */ 1600 if (event_mode_enabled) { 1601 ret = rte_event_dev_start(eventdev_id); 1602 if (ret < 0) { 1603 printf("Failed to start event device %d\n", ret); 1604 return ret; 1605 } 1606 } 1607 1608 /* Start device */ 1609 ret = rte_eth_dev_start(port_id); 1610 if (ret < 0) { 1611 printf("rte_eth_dev_start: err=%d, port=%d\n", 1612 ret, port_id); 1613 return ret; 1614 } 1615 /* always enable promiscuous */ 1616 ret = rte_eth_promiscuous_enable(port_id); 1617 if (ret != 0) { 1618 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n", 1619 rte_strerror(-ret), port_id); 1620 return ret; 1621 } 1622 1623 check_all_ports_link_status(1, RTE_PORT_ALL); 1624 1625 return 0; 1626 } 1627 1628 static void 1629 ut_teardown_inline_ipsec(void) 1630 { 1631 uint16_t portid; 1632 int ret; 1633 1634 /* Stop event devices */ 1635 if (event_mode_enabled) 1636 rte_event_dev_stop(eventdev_id); 1637 1638 /* port tear down */ 1639 RTE_ETH_FOREACH_DEV(portid) { 1640 ret = rte_eth_dev_stop(portid); 1641 if (ret != 0) 1642 printf("rte_eth_dev_stop: err=%s, port=%u\n", 1643 rte_strerror(-ret), portid); 1644 } 1645 } 1646 1647 static int 1648 inline_ipsec_testsuite_setup(void) 1649 { 1650 struct rte_eth_conf local_port_conf; 1651 struct rte_eth_dev_info dev_info; 1652 uint16_t nb_rxd; 1653 uint16_t nb_txd; 1654 uint16_t nb_ports; 1655 int ret; 1656 uint16_t nb_rx_queue = 1, nb_tx_queue = 1; 1657 1658 printf("Start inline IPsec test.\n"); 1659 1660 nb_ports = rte_eth_dev_count_avail(); 1661 if (nb_ports < NB_ETHPORTS_USED) { 1662 printf("At least %u port(s) used for test\n", 1663 NB_ETHPORTS_USED); 1664 return TEST_SKIPPED; 1665 } 1666 1667 ret = init_mempools(NB_MBUF); 1668 if (ret) 1669 return ret; 1670 1671 if (tx_pkts_burst == NULL) { 1672 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff", 1673 MAX_TRAFFIC_BURST, 1674 sizeof(void *), 1675 RTE_CACHE_LINE_SIZE); 1676 if (!tx_pkts_burst) 1677 return TEST_FAILED; 1678 1679 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff", 1680 MAX_TRAFFIC_BURST, 1681 sizeof(void *), 1682 RTE_CACHE_LINE_SIZE); 1683 if (!rx_pkts_burst) 1684 return TEST_FAILED; 1685 } 1686 1687 printf("Generate %d packets\n", MAX_TRAFFIC_BURST); 1688 1689 nb_rxd = RX_DESC_DEFAULT; 1690 nb_txd = TX_DESC_DEFAULT; 1691 1692 /* configuring port 0 for the test is enough */ 1693 port_id = 0; 1694 if (rte_eth_dev_info_get(0, &dev_info)) { 1695 printf("Failed to get devinfo"); 1696 return -1; 1697 } 1698 1699 memcpy(&local_port_conf, &port_conf, sizeof(port_conf)); 1700 /* Add Multi seg flags */ 1701 if (sg_mode) { 1702 uint16_t max_data_room = RTE_MBUF_DEFAULT_DATAROOM * 1703 dev_info.rx_desc_lim.nb_seg_max; 1704 1705 local_port_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_SCATTER; 1706 local_port_conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS; 1707 local_port_conf.rxmode.mtu = RTE_MIN(dev_info.max_mtu, max_data_room - 256); 1708 } 1709 1710 /* port configure */ 1711 ret = rte_eth_dev_configure(port_id, nb_rx_queue, 1712 nb_tx_queue, &local_port_conf); 1713 if (ret < 0) { 1714 printf("Cannot configure device: err=%d, port=%d\n", 1715 ret, port_id); 1716 return ret; 1717 } 1718 ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]); 1719 if (ret < 0) { 1720 printf("Cannot get mac address: err=%d, port=%d\n", 1721 ret, port_id); 1722 return ret; 1723 } 1724 printf("Port %u ", port_id); 1725 print_ethaddr("Address:", &ports_eth_addr[port_id]); 1726 printf("\n"); 1727 1728 /* tx queue setup */ 1729 ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 1730 SOCKET_ID_ANY, &tx_conf); 1731 if (ret < 0) { 1732 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n", 1733 ret, port_id); 1734 return ret; 1735 } 1736 /* rx queue steup */ 1737 ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY, 1738 &rx_conf, mbufpool); 1739 if (ret < 0) { 1740 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n", 1741 ret, port_id); 1742 return ret; 1743 } 1744 1745 test_sec_alg_list_populate(); 1746 1747 /* Change the plaintext size for tests without Known vectors */ 1748 if (sg_mode) { 1749 /* Leave space of 256B as ESP packet would be bigger and we 1750 * expect packets to be received back on same interface. 1751 * Without SG mode, default value is picked. 1752 */ 1753 plaintext_len = local_port_conf.rxmode.mtu - 256; 1754 } else { 1755 plaintext_len = 0; 1756 } 1757 1758 return 0; 1759 } 1760 1761 static void 1762 inline_ipsec_testsuite_teardown(void) 1763 { 1764 uint16_t portid; 1765 int ret; 1766 1767 /* port tear down */ 1768 RTE_ETH_FOREACH_DEV(portid) { 1769 ret = rte_eth_dev_reset(portid); 1770 if (ret != 0) 1771 printf("rte_eth_dev_reset: err=%s, port=%u\n", 1772 rte_strerror(-ret), port_id); 1773 } 1774 rte_free(tx_pkts_burst); 1775 rte_free(rx_pkts_burst); 1776 } 1777 1778 static int 1779 event_inline_ipsec_testsuite_setup(void) 1780 { 1781 struct rte_event_eth_rx_adapter_queue_conf queue_conf = {0}; 1782 struct rte_event_dev_info evdev_default_conf = {0}; 1783 struct rte_event_dev_config eventdev_conf = {0}; 1784 struct rte_event_queue_conf eventq_conf = {0}; 1785 struct rte_event_port_conf ev_port_conf = {0}; 1786 const uint16_t nb_txd = 1024, nb_rxd = 1024; 1787 uint16_t nb_rx_queue = 1, nb_tx_queue = 1; 1788 uint8_t ev_queue_id = 0, tx_queue_id = 0; 1789 int nb_eventqueue = 1, nb_eventport = 1; 1790 const int all_queues = -1; 1791 uint32_t caps = 0; 1792 uint16_t nb_ports; 1793 int ret; 1794 1795 printf("Start event inline IPsec test.\n"); 1796 1797 nb_ports = rte_eth_dev_count_avail(); 1798 if (nb_ports == 0) { 1799 printf("Test require: 1 port, available: 0\n"); 1800 return TEST_SKIPPED; 1801 } 1802 1803 init_mempools(NB_MBUF); 1804 1805 if (tx_pkts_burst == NULL) { 1806 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff", 1807 MAX_TRAFFIC_BURST, 1808 sizeof(void *), 1809 RTE_CACHE_LINE_SIZE); 1810 if (!tx_pkts_burst) 1811 return -1; 1812 1813 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff", 1814 MAX_TRAFFIC_BURST, 1815 sizeof(void *), 1816 RTE_CACHE_LINE_SIZE); 1817 if (!rx_pkts_burst) 1818 return -1; 1819 1820 } 1821 1822 printf("Generate %d packets\n", MAX_TRAFFIC_BURST); 1823 1824 /* configuring port 0 for the test is enough */ 1825 port_id = 0; 1826 /* port configure */ 1827 ret = rte_eth_dev_configure(port_id, nb_rx_queue, 1828 nb_tx_queue, &port_conf); 1829 if (ret < 0) { 1830 printf("Cannot configure device: err=%d, port=%d\n", 1831 ret, port_id); 1832 return ret; 1833 } 1834 1835 /* Tx queue setup */ 1836 ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 1837 SOCKET_ID_ANY, &tx_conf); 1838 if (ret < 0) { 1839 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n", 1840 ret, port_id); 1841 return ret; 1842 } 1843 1844 /* rx queue steup */ 1845 ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY, 1846 &rx_conf, mbufpool); 1847 if (ret < 0) { 1848 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n", 1849 ret, port_id); 1850 return ret; 1851 } 1852 1853 /* Setup eventdev */ 1854 eventdev_id = 0; 1855 rx_adapter_id = 0; 1856 tx_adapter_id = 0; 1857 1858 /* Get default conf of eventdev */ 1859 ret = rte_event_dev_info_get(eventdev_id, &evdev_default_conf); 1860 if (ret < 0) { 1861 printf("Error in getting event device info[devID:%d]\n", 1862 eventdev_id); 1863 return ret; 1864 } 1865 1866 /* Get Tx adapter capabilities */ 1867 ret = rte_event_eth_tx_adapter_caps_get(eventdev_id, tx_adapter_id, &caps); 1868 if (ret < 0) { 1869 printf("Failed to get event device %d eth tx adapter" 1870 " capabilities for port %d\n", 1871 eventdev_id, port_id); 1872 return ret; 1873 } 1874 if (!(caps & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)) 1875 tx_queue_id = nb_eventqueue++; 1876 1877 eventdev_conf.nb_events_limit = 1878 evdev_default_conf.max_num_events; 1879 eventdev_conf.nb_event_queue_flows = 1880 evdev_default_conf.max_event_queue_flows; 1881 eventdev_conf.nb_event_port_dequeue_depth = 1882 evdev_default_conf.max_event_port_dequeue_depth; 1883 eventdev_conf.nb_event_port_enqueue_depth = 1884 evdev_default_conf.max_event_port_enqueue_depth; 1885 1886 eventdev_conf.nb_event_queues = nb_eventqueue; 1887 eventdev_conf.nb_event_ports = nb_eventport; 1888 1889 /* Configure event device */ 1890 1891 ret = rte_event_dev_configure(eventdev_id, &eventdev_conf); 1892 if (ret < 0) { 1893 printf("Error in configuring event device\n"); 1894 return ret; 1895 } 1896 1897 /* Configure event queue */ 1898 eventq_conf.schedule_type = RTE_SCHED_TYPE_PARALLEL; 1899 eventq_conf.nb_atomic_flows = 1024; 1900 eventq_conf.nb_atomic_order_sequences = 1024; 1901 1902 /* Setup the queue */ 1903 ret = rte_event_queue_setup(eventdev_id, ev_queue_id, &eventq_conf); 1904 if (ret < 0) { 1905 printf("Failed to setup event queue %d\n", ret); 1906 return ret; 1907 } 1908 1909 /* Configure event port */ 1910 ret = rte_event_port_setup(eventdev_id, port_id, NULL); 1911 if (ret < 0) { 1912 printf("Failed to setup event port %d\n", ret); 1913 return ret; 1914 } 1915 1916 /* Make event queue - event port link */ 1917 ret = rte_event_port_link(eventdev_id, port_id, NULL, NULL, 1); 1918 if (ret < 0) { 1919 printf("Failed to link event port %d\n", ret); 1920 return ret; 1921 } 1922 1923 /* Setup port conf */ 1924 ev_port_conf.new_event_threshold = 1200; 1925 ev_port_conf.dequeue_depth = 1926 evdev_default_conf.max_event_port_dequeue_depth; 1927 ev_port_conf.enqueue_depth = 1928 evdev_default_conf.max_event_port_enqueue_depth; 1929 1930 /* Create Rx adapter */ 1931 ret = rte_event_eth_rx_adapter_create(rx_adapter_id, eventdev_id, 1932 &ev_port_conf); 1933 if (ret < 0) { 1934 printf("Failed to create rx adapter %d\n", ret); 1935 return ret; 1936 } 1937 1938 /* Setup queue conf */ 1939 queue_conf.ev.queue_id = ev_queue_id; 1940 queue_conf.ev.sched_type = RTE_SCHED_TYPE_PARALLEL; 1941 queue_conf.ev.event_type = RTE_EVENT_TYPE_ETHDEV; 1942 1943 /* Add queue to the adapter */ 1944 ret = rte_event_eth_rx_adapter_queue_add(rx_adapter_id, port_id, 1945 all_queues, &queue_conf); 1946 if (ret < 0) { 1947 printf("Failed to add eth queue to rx adapter %d\n", ret); 1948 return ret; 1949 } 1950 1951 /* Start rx adapter */ 1952 ret = rte_event_eth_rx_adapter_start(rx_adapter_id); 1953 if (ret < 0) { 1954 printf("Failed to start rx adapter %d\n", ret); 1955 return ret; 1956 } 1957 1958 /* Create tx adapter */ 1959 ret = rte_event_eth_tx_adapter_create(tx_adapter_id, eventdev_id, 1960 &ev_port_conf); 1961 if (ret < 0) { 1962 printf("Failed to create tx adapter %d\n", ret); 1963 return ret; 1964 } 1965 1966 /* Add queue to the adapter */ 1967 ret = rte_event_eth_tx_adapter_queue_add(tx_adapter_id, port_id, 1968 all_queues); 1969 if (ret < 0) { 1970 printf("Failed to add eth queue to tx adapter %d\n", ret); 1971 return ret; 1972 } 1973 /* Setup Tx queue & port */ 1974 if (tx_queue_id) { 1975 /* Setup the queue */ 1976 ret = rte_event_queue_setup(eventdev_id, tx_queue_id, 1977 &eventq_conf); 1978 if (ret < 0) { 1979 printf("Failed to setup tx event queue %d\n", ret); 1980 return ret; 1981 } 1982 /* Link Tx event queue to Tx port */ 1983 ret = rte_event_port_link(eventdev_id, port_id, 1984 &tx_queue_id, NULL, 1); 1985 if (ret != 1) { 1986 printf("Failed to link event queue to port\n"); 1987 return ret; 1988 } 1989 } 1990 1991 /* Start tx adapter */ 1992 ret = rte_event_eth_tx_adapter_start(tx_adapter_id); 1993 if (ret < 0) { 1994 printf("Failed to start tx adapter %d\n", ret); 1995 return ret; 1996 } 1997 1998 /* Start eventdev */ 1999 ret = rte_event_dev_start(eventdev_id); 2000 if (ret < 0) { 2001 printf("Failed to start event device %d\n", ret); 2002 return ret; 2003 } 2004 2005 event_mode_enabled = true; 2006 2007 test_sec_alg_list_populate(); 2008 2009 return 0; 2010 } 2011 2012 static void 2013 event_inline_ipsec_testsuite_teardown(void) 2014 { 2015 uint16_t portid; 2016 int ret; 2017 2018 event_mode_enabled = false; 2019 2020 /* Stop and release rx adapter */ 2021 ret = rte_event_eth_rx_adapter_stop(rx_adapter_id); 2022 if (ret < 0) 2023 printf("Failed to stop rx adapter %d\n", ret); 2024 ret = rte_event_eth_rx_adapter_queue_del(rx_adapter_id, port_id, -1); 2025 if (ret < 0) 2026 printf("Failed to remove rx adapter queues %d\n", ret); 2027 ret = rte_event_eth_rx_adapter_free(rx_adapter_id); 2028 if (ret < 0) 2029 printf("Failed to free rx adapter %d\n", ret); 2030 2031 /* Stop and release tx adapter */ 2032 ret = rte_event_eth_tx_adapter_stop(tx_adapter_id); 2033 if (ret < 0) 2034 printf("Failed to stop tx adapter %d\n", ret); 2035 ret = rte_event_eth_tx_adapter_queue_del(tx_adapter_id, port_id, -1); 2036 if (ret < 0) 2037 printf("Failed to remove tx adapter queues %d\n", ret); 2038 ret = rte_event_eth_tx_adapter_free(tx_adapter_id); 2039 if (ret < 0) 2040 printf("Failed to free tx adapter %d\n", ret); 2041 2042 /* Stop and release event devices */ 2043 rte_event_dev_stop(eventdev_id); 2044 ret = rte_event_dev_close(eventdev_id); 2045 if (ret < 0) 2046 printf("Failed to close event dev %d, %d\n", eventdev_id, ret); 2047 2048 /* port tear down */ 2049 RTE_ETH_FOREACH_DEV(portid) { 2050 ret = rte_eth_dev_reset(portid); 2051 if (ret != 0) 2052 printf("rte_eth_dev_reset: err=%s, port=%u\n", 2053 rte_strerror(-ret), port_id); 2054 } 2055 2056 rte_free(tx_pkts_burst); 2057 rte_free(rx_pkts_burst); 2058 } 2059 2060 static int 2061 test_inline_ip_reassembly(const void *testdata) 2062 { 2063 struct reassembly_vector reassembly_td = {0}; 2064 const struct reassembly_vector *td = testdata; 2065 struct ip_reassembly_test_packet full_pkt; 2066 struct ip_reassembly_test_packet frags[MAX_FRAGS]; 2067 uint16_t extra_data, extra_data_sum = 0; 2068 struct ipsec_test_flags flags = {0}; 2069 int i = 0; 2070 2071 reassembly_td.sa_data = td->sa_data; 2072 reassembly_td.nb_frags = td->nb_frags; 2073 reassembly_td.burst = td->burst; 2074 2075 memcpy(&full_pkt, td->full_pkt, 2076 sizeof(struct ip_reassembly_test_packet)); 2077 reassembly_td.full_pkt = &full_pkt; 2078 2079 for (; i < reassembly_td.nb_frags; i++) { 2080 memcpy(&frags[i], td->frags[i], 2081 sizeof(struct ip_reassembly_test_packet)); 2082 reassembly_td.frags[i] = &frags[i]; 2083 2084 /* Add extra data for multi-seg test on all fragments except last one */ 2085 extra_data = 0; 2086 if (plaintext_len && reassembly_td.frags[i]->len < plaintext_len && 2087 (i != reassembly_td.nb_frags - 1)) 2088 extra_data = ((plaintext_len - reassembly_td.frags[i]->len) & ~0x7ULL); 2089 2090 test_vector_payload_populate(reassembly_td.frags[i], 2091 (i == 0) ? true : false, extra_data, extra_data_sum); 2092 extra_data_sum += extra_data; 2093 } 2094 test_vector_payload_populate(reassembly_td.full_pkt, true, extra_data_sum, 0); 2095 2096 return test_ipsec_with_reassembly(&reassembly_td, &flags); 2097 } 2098 2099 static int 2100 test_ipsec_inline_proto_known_vec(const void *test_data) 2101 { 2102 struct ipsec_test_data td_outb; 2103 struct ipsec_test_flags flags; 2104 2105 memset(&flags, 0, sizeof(flags)); 2106 2107 memcpy(&td_outb, test_data, sizeof(td_outb)); 2108 2109 if (td_outb.aead || 2110 td_outb.xform.chain.cipher.cipher.algo != RTE_CRYPTO_CIPHER_NULL) { 2111 /* Disable IV gen to be able to test with known vectors */ 2112 td_outb.ipsec_xform.options.iv_gen_disable = 1; 2113 } 2114 2115 return test_ipsec_inline_proto_process(&td_outb, NULL, 1, 2116 false, &flags); 2117 } 2118 2119 static int 2120 test_ipsec_inline_proto_known_vec_inb(const void *test_data) 2121 { 2122 const struct ipsec_test_data *td = test_data; 2123 struct ipsec_test_flags flags; 2124 struct ipsec_test_data td_inb; 2125 2126 memset(&flags, 0, sizeof(flags)); 2127 2128 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) 2129 test_ipsec_td_in_from_out(td, &td_inb); 2130 else 2131 memcpy(&td_inb, td, sizeof(td_inb)); 2132 2133 return test_ipsec_inline_proto_process(&td_inb, NULL, 1, false, &flags); 2134 } 2135 2136 static int 2137 test_ipsec_inline_proto_oop_inb(const void *test_data) 2138 { 2139 const struct ipsec_test_data *td = test_data; 2140 struct ipsec_test_flags flags; 2141 struct ipsec_test_data td_inb; 2142 2143 memset(&flags, 0, sizeof(flags)); 2144 flags.inb_oop = true; 2145 2146 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) 2147 test_ipsec_td_in_from_out(td, &td_inb); 2148 else 2149 memcpy(&td_inb, td, sizeof(td_inb)); 2150 2151 td_inb.ipsec_xform.options.ingress_oop = true; 2152 2153 return test_ipsec_inline_proto_process(&td_inb, NULL, 1, false, &flags); 2154 } 2155 2156 static int 2157 test_ipsec_inline_proto_display_list(void) 2158 { 2159 struct ipsec_test_flags flags; 2160 2161 memset(&flags, 0, sizeof(flags)); 2162 2163 flags.display_alg = true; 2164 flags.plaintext_len = plaintext_len; 2165 2166 return test_ipsec_inline_proto_all(&flags); 2167 } 2168 2169 static int 2170 test_ipsec_inline_proto_udp_encap(void) 2171 { 2172 struct ipsec_test_flags flags; 2173 2174 memset(&flags, 0, sizeof(flags)); 2175 2176 flags.udp_encap = true; 2177 flags.plaintext_len = plaintext_len; 2178 2179 return test_ipsec_inline_proto_all(&flags); 2180 } 2181 2182 static int 2183 test_ipsec_inline_proto_udp_ports_verify(void) 2184 { 2185 struct ipsec_test_flags flags; 2186 2187 memset(&flags, 0, sizeof(flags)); 2188 2189 flags.udp_encap = true; 2190 flags.udp_ports_verify = true; 2191 flags.plaintext_len = plaintext_len; 2192 2193 return test_ipsec_inline_proto_all(&flags); 2194 } 2195 2196 static int 2197 test_ipsec_inline_proto_err_icv_corrupt(void) 2198 { 2199 struct ipsec_test_flags flags; 2200 2201 memset(&flags, 0, sizeof(flags)); 2202 2203 flags.icv_corrupt = true; 2204 flags.plaintext_len = plaintext_len; 2205 2206 return test_ipsec_inline_proto_all(&flags); 2207 } 2208 2209 static int 2210 test_ipsec_inline_proto_tunnel_dst_addr_verify(void) 2211 { 2212 struct ipsec_test_flags flags; 2213 2214 memset(&flags, 0, sizeof(flags)); 2215 2216 flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR; 2217 flags.plaintext_len = plaintext_len; 2218 2219 return test_ipsec_inline_proto_all(&flags); 2220 } 2221 2222 static int 2223 test_ipsec_inline_proto_tunnel_src_dst_addr_verify(void) 2224 { 2225 struct ipsec_test_flags flags; 2226 2227 memset(&flags, 0, sizeof(flags)); 2228 2229 flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR; 2230 flags.plaintext_len = plaintext_len; 2231 2232 return test_ipsec_inline_proto_all(&flags); 2233 } 2234 2235 static int 2236 test_ipsec_inline_proto_inner_ip_csum(void) 2237 { 2238 struct ipsec_test_flags flags; 2239 2240 memset(&flags, 0, sizeof(flags)); 2241 2242 flags.ip_csum = true; 2243 flags.plaintext_len = plaintext_len; 2244 2245 return test_ipsec_inline_proto_all(&flags); 2246 } 2247 2248 static int 2249 test_ipsec_inline_proto_inner_l4_csum(void) 2250 { 2251 struct ipsec_test_flags flags; 2252 2253 memset(&flags, 0, sizeof(flags)); 2254 2255 flags.l4_csum = true; 2256 flags.plaintext_len = plaintext_len; 2257 2258 return test_ipsec_inline_proto_all(&flags); 2259 } 2260 2261 static int 2262 test_ipsec_inline_proto_tunnel_v4_in_v4(void) 2263 { 2264 struct ipsec_test_flags flags; 2265 2266 memset(&flags, 0, sizeof(flags)); 2267 2268 flags.ipv6 = false; 2269 flags.tunnel_ipv6 = false; 2270 flags.plaintext_len = plaintext_len; 2271 2272 return test_ipsec_inline_proto_all(&flags); 2273 } 2274 2275 static int 2276 test_ipsec_inline_proto_tunnel_v6_in_v6(void) 2277 { 2278 struct ipsec_test_flags flags; 2279 2280 memset(&flags, 0, sizeof(flags)); 2281 2282 flags.ipv6 = true; 2283 flags.tunnel_ipv6 = true; 2284 flags.plaintext_len = plaintext_len; 2285 2286 return test_ipsec_inline_proto_all(&flags); 2287 } 2288 2289 static int 2290 test_ipsec_inline_proto_tunnel_v4_in_v6(void) 2291 { 2292 struct ipsec_test_flags flags; 2293 2294 memset(&flags, 0, sizeof(flags)); 2295 2296 flags.ipv6 = false; 2297 flags.tunnel_ipv6 = true; 2298 flags.plaintext_len = plaintext_len; 2299 2300 return test_ipsec_inline_proto_all(&flags); 2301 } 2302 2303 static int 2304 test_ipsec_inline_proto_tunnel_v6_in_v4(void) 2305 { 2306 struct ipsec_test_flags flags; 2307 2308 memset(&flags, 0, sizeof(flags)); 2309 2310 flags.ipv6 = true; 2311 flags.tunnel_ipv6 = false; 2312 flags.plaintext_len = plaintext_len; 2313 2314 return test_ipsec_inline_proto_all(&flags); 2315 } 2316 2317 static int 2318 test_ipsec_inline_proto_transport_v4(void) 2319 { 2320 struct ipsec_test_flags flags; 2321 2322 memset(&flags, 0, sizeof(flags)); 2323 2324 flags.ipv6 = false; 2325 flags.transport = true; 2326 flags.plaintext_len = plaintext_len; 2327 2328 return test_ipsec_inline_proto_all(&flags); 2329 } 2330 2331 static int 2332 test_ipsec_inline_proto_transport_l4_csum(void) 2333 { 2334 struct ipsec_test_flags flags = { 2335 .l4_csum = true, 2336 .transport = true, 2337 .plaintext_len = plaintext_len, 2338 }; 2339 2340 return test_ipsec_inline_proto_all(&flags); 2341 } 2342 2343 static int 2344 test_ipsec_inline_proto_stats(void) 2345 { 2346 struct ipsec_test_flags flags; 2347 2348 memset(&flags, 0, sizeof(flags)); 2349 2350 flags.stats_success = true; 2351 flags.plaintext_len = plaintext_len; 2352 2353 return test_ipsec_inline_proto_all(&flags); 2354 } 2355 2356 static int 2357 test_ipsec_inline_proto_pkt_fragment(void) 2358 { 2359 struct ipsec_test_flags flags; 2360 2361 memset(&flags, 0, sizeof(flags)); 2362 2363 flags.fragment = true; 2364 flags.plaintext_len = plaintext_len; 2365 2366 return test_ipsec_inline_proto_all(&flags); 2367 2368 } 2369 2370 static int 2371 test_ipsec_inline_proto_copy_df_inner_0(void) 2372 { 2373 struct ipsec_test_flags flags; 2374 2375 memset(&flags, 0, sizeof(flags)); 2376 2377 flags.df = TEST_IPSEC_COPY_DF_INNER_0; 2378 flags.plaintext_len = plaintext_len; 2379 2380 return test_ipsec_inline_proto_all(&flags); 2381 } 2382 2383 static int 2384 test_ipsec_inline_proto_copy_df_inner_1(void) 2385 { 2386 struct ipsec_test_flags flags; 2387 2388 memset(&flags, 0, sizeof(flags)); 2389 2390 flags.df = TEST_IPSEC_COPY_DF_INNER_1; 2391 flags.plaintext_len = plaintext_len; 2392 2393 return test_ipsec_inline_proto_all(&flags); 2394 } 2395 2396 static int 2397 test_ipsec_inline_proto_set_df_0_inner_1(void) 2398 { 2399 struct ipsec_test_flags flags; 2400 2401 memset(&flags, 0, sizeof(flags)); 2402 2403 flags.df = TEST_IPSEC_SET_DF_0_INNER_1; 2404 flags.plaintext_len = plaintext_len; 2405 2406 return test_ipsec_inline_proto_all(&flags); 2407 } 2408 2409 static int 2410 test_ipsec_inline_proto_set_df_1_inner_0(void) 2411 { 2412 struct ipsec_test_flags flags; 2413 2414 memset(&flags, 0, sizeof(flags)); 2415 2416 flags.df = TEST_IPSEC_SET_DF_1_INNER_0; 2417 flags.plaintext_len = plaintext_len; 2418 2419 return test_ipsec_inline_proto_all(&flags); 2420 } 2421 2422 static int 2423 test_ipsec_inline_proto_ipv4_copy_dscp_inner_0(void) 2424 { 2425 struct ipsec_test_flags flags; 2426 2427 memset(&flags, 0, sizeof(flags)); 2428 2429 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0; 2430 flags.plaintext_len = plaintext_len; 2431 2432 return test_ipsec_inline_proto_all(&flags); 2433 } 2434 2435 static int 2436 test_ipsec_inline_proto_ipv4_copy_dscp_inner_1(void) 2437 { 2438 struct ipsec_test_flags flags; 2439 2440 memset(&flags, 0, sizeof(flags)); 2441 2442 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1; 2443 flags.plaintext_len = plaintext_len; 2444 2445 return test_ipsec_inline_proto_all(&flags); 2446 } 2447 2448 static int 2449 test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1(void) 2450 { 2451 struct ipsec_test_flags flags; 2452 2453 memset(&flags, 0, sizeof(flags)); 2454 2455 flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1; 2456 flags.plaintext_len = plaintext_len; 2457 2458 return test_ipsec_inline_proto_all(&flags); 2459 } 2460 2461 static int 2462 test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0(void) 2463 { 2464 struct ipsec_test_flags flags; 2465 2466 memset(&flags, 0, sizeof(flags)); 2467 2468 flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0; 2469 flags.plaintext_len = plaintext_len; 2470 2471 return test_ipsec_inline_proto_all(&flags); 2472 } 2473 2474 static int 2475 test_ipsec_inline_proto_ipv6_copy_dscp_inner_0(void) 2476 { 2477 struct ipsec_test_flags flags; 2478 2479 memset(&flags, 0, sizeof(flags)); 2480 2481 flags.ipv6 = true; 2482 flags.tunnel_ipv6 = true; 2483 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0; 2484 flags.plaintext_len = plaintext_len; 2485 2486 return test_ipsec_inline_proto_all(&flags); 2487 } 2488 2489 static int 2490 test_ipsec_inline_proto_ipv6_copy_dscp_inner_1(void) 2491 { 2492 struct ipsec_test_flags flags; 2493 2494 memset(&flags, 0, sizeof(flags)); 2495 2496 flags.ipv6 = true; 2497 flags.tunnel_ipv6 = true; 2498 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1; 2499 flags.plaintext_len = plaintext_len; 2500 2501 return test_ipsec_inline_proto_all(&flags); 2502 } 2503 2504 static int 2505 test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1(void) 2506 { 2507 struct ipsec_test_flags flags; 2508 2509 memset(&flags, 0, sizeof(flags)); 2510 2511 flags.ipv6 = true; 2512 flags.tunnel_ipv6 = true; 2513 flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1; 2514 flags.plaintext_len = plaintext_len; 2515 2516 return test_ipsec_inline_proto_all(&flags); 2517 } 2518 2519 static int 2520 test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0(void) 2521 { 2522 struct ipsec_test_flags flags; 2523 2524 memset(&flags, 0, sizeof(flags)); 2525 2526 flags.ipv6 = true; 2527 flags.tunnel_ipv6 = true; 2528 flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0; 2529 flags.plaintext_len = plaintext_len; 2530 2531 return test_ipsec_inline_proto_all(&flags); 2532 } 2533 2534 static int 2535 test_ipsec_inline_proto_ipv6_copy_flabel_inner_0(void) 2536 { 2537 struct ipsec_test_flags flags; 2538 2539 memset(&flags, 0, sizeof(flags)); 2540 2541 flags.ipv6 = true; 2542 flags.tunnel_ipv6 = true; 2543 flags.flabel = TEST_IPSEC_COPY_FLABEL_INNER_0; 2544 2545 return test_ipsec_inline_proto_all(&flags); 2546 } 2547 2548 static int 2549 test_ipsec_inline_proto_ipv6_copy_flabel_inner_1(void) 2550 { 2551 struct ipsec_test_flags flags; 2552 2553 memset(&flags, 0, sizeof(flags)); 2554 2555 flags.ipv6 = true; 2556 flags.tunnel_ipv6 = true; 2557 flags.flabel = TEST_IPSEC_COPY_FLABEL_INNER_1; 2558 2559 return test_ipsec_inline_proto_all(&flags); 2560 } 2561 2562 static int 2563 test_ipsec_inline_proto_ipv6_set_flabel_0_inner_1(void) 2564 { 2565 struct ipsec_test_flags flags; 2566 2567 memset(&flags, 0, sizeof(flags)); 2568 2569 flags.ipv6 = true; 2570 flags.tunnel_ipv6 = true; 2571 flags.flabel = TEST_IPSEC_SET_FLABEL_0_INNER_1; 2572 2573 return test_ipsec_inline_proto_all(&flags); 2574 } 2575 2576 static int 2577 test_ipsec_inline_proto_ipv6_set_flabel_1_inner_0(void) 2578 { 2579 struct ipsec_test_flags flags; 2580 2581 memset(&flags, 0, sizeof(flags)); 2582 2583 flags.ipv6 = true; 2584 flags.tunnel_ipv6 = true; 2585 flags.flabel = TEST_IPSEC_SET_FLABEL_1_INNER_0; 2586 2587 return test_ipsec_inline_proto_all(&flags); 2588 } 2589 2590 static int 2591 test_ipsec_inline_proto_ipv4_ttl_decrement(void) 2592 { 2593 struct ipsec_test_flags flags = { 2594 .dec_ttl_or_hop_limit = true, 2595 .plaintext_len = plaintext_len, 2596 }; 2597 2598 return test_ipsec_inline_proto_all(&flags); 2599 } 2600 2601 static int 2602 test_ipsec_inline_proto_ipv6_hop_limit_decrement(void) 2603 { 2604 struct ipsec_test_flags flags = { 2605 .ipv6 = true, 2606 .dec_ttl_or_hop_limit = true, 2607 .plaintext_len = plaintext_len, 2608 }; 2609 2610 return test_ipsec_inline_proto_all(&flags); 2611 } 2612 2613 static int 2614 test_ipsec_inline_proto_iv_gen(void) 2615 { 2616 struct ipsec_test_flags flags; 2617 2618 memset(&flags, 0, sizeof(flags)); 2619 2620 flags.iv_gen = true; 2621 flags.plaintext_len = plaintext_len; 2622 2623 return test_ipsec_inline_proto_all(&flags); 2624 } 2625 2626 static int 2627 test_ipsec_inline_proto_sa_pkt_soft_expiry(void) 2628 { 2629 struct ipsec_test_flags flags = { 2630 .sa_expiry_pkts_soft = true, 2631 .plaintext_len = plaintext_len, 2632 }; 2633 return test_ipsec_inline_proto_all(&flags); 2634 } 2635 static int 2636 test_ipsec_inline_proto_sa_byte_soft_expiry(void) 2637 { 2638 struct ipsec_test_flags flags = { 2639 .sa_expiry_bytes_soft = true, 2640 .plaintext_len = plaintext_len, 2641 }; 2642 return test_ipsec_inline_proto_all(&flags); 2643 } 2644 2645 static int 2646 test_ipsec_inline_proto_sa_pkt_hard_expiry(void) 2647 { 2648 struct ipsec_test_flags flags = { 2649 .sa_expiry_pkts_hard = true 2650 }; 2651 2652 return test_ipsec_inline_proto_all(&flags); 2653 } 2654 2655 static int 2656 test_ipsec_inline_proto_sa_byte_hard_expiry(void) 2657 { 2658 struct ipsec_test_flags flags = { 2659 .sa_expiry_bytes_hard = true 2660 }; 2661 2662 return test_ipsec_inline_proto_all(&flags); 2663 } 2664 2665 static int 2666 test_ipsec_inline_proto_known_vec_fragmented(const void *test_data) 2667 { 2668 struct ipsec_test_data td_outb; 2669 struct ipsec_test_flags flags; 2670 2671 memset(&flags, 0, sizeof(flags)); 2672 flags.fragment = true; 2673 flags.plaintext_len = plaintext_len; 2674 2675 memcpy(&td_outb, test_data, sizeof(td_outb)); 2676 2677 /* Disable IV gen to be able to test with known vectors */ 2678 td_outb.ipsec_xform.options.iv_gen_disable = 1; 2679 2680 return test_ipsec_inline_proto_process(&td_outb, NULL, 1, false, 2681 &flags); 2682 } 2683 2684 static int 2685 test_ipsec_inline_pkt_replay(const void *test_data, const uint64_t esn[], 2686 bool replayed_pkt[], uint32_t nb_pkts, bool esn_en, 2687 uint64_t winsz) 2688 { 2689 struct ipsec_test_data td_outb[TEST_SEC_PKTS_MAX]; 2690 struct ipsec_test_data td_inb[TEST_SEC_PKTS_MAX]; 2691 struct ipsec_test_flags flags; 2692 uint32_t i, ret = 0; 2693 2694 memset(&flags, 0, sizeof(flags)); 2695 flags.antireplay = true; 2696 flags.plaintext_len = plaintext_len; 2697 2698 for (i = 0; i < nb_pkts; i++) { 2699 memcpy(&td_outb[i], test_data, sizeof(td_outb[0])); 2700 td_outb[i].ipsec_xform.options.iv_gen_disable = 1; 2701 td_outb[i].ipsec_xform.replay_win_sz = winsz; 2702 td_outb[i].ipsec_xform.options.esn = esn_en; 2703 } 2704 2705 for (i = 0; i < nb_pkts; i++) 2706 td_outb[i].ipsec_xform.esn.value = esn[i]; 2707 2708 ret = test_ipsec_inline_proto_process_with_esn(td_outb, td_inb, 2709 nb_pkts, true, &flags); 2710 if (ret != TEST_SUCCESS) 2711 return ret; 2712 2713 test_ipsec_td_update(td_inb, td_outb, nb_pkts, &flags); 2714 2715 for (i = 0; i < nb_pkts; i++) { 2716 td_inb[i].ipsec_xform.options.esn = esn_en; 2717 /* Set antireplay flag for packets to be dropped */ 2718 td_inb[i].ar_packet = replayed_pkt[i]; 2719 } 2720 2721 ret = test_ipsec_inline_proto_process_with_esn(td_inb, NULL, nb_pkts, 2722 true, &flags); 2723 2724 return ret; 2725 } 2726 2727 static int 2728 test_ipsec_inline_proto_pkt_antireplay(const void *test_data, uint64_t winsz) 2729 { 2730 2731 uint32_t nb_pkts = 5; 2732 bool replayed_pkt[5]; 2733 uint64_t esn[5]; 2734 2735 /* 1. Advance the TOP of the window to WS * 2 */ 2736 esn[0] = winsz * 2; 2737 /* 2. Test sequence number within the new window(WS + 1) */ 2738 esn[1] = winsz + 1; 2739 /* 3. Test sequence number less than the window BOTTOM */ 2740 esn[2] = winsz; 2741 /* 4. Test sequence number in the middle of the window */ 2742 esn[3] = winsz + (winsz / 2); 2743 /* 5. Test replay of the packet in the middle of the window */ 2744 esn[4] = winsz + (winsz / 2); 2745 2746 replayed_pkt[0] = false; 2747 replayed_pkt[1] = false; 2748 replayed_pkt[2] = true; 2749 replayed_pkt[3] = false; 2750 replayed_pkt[4] = true; 2751 2752 return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt, 2753 nb_pkts, false, winsz); 2754 } 2755 2756 static int 2757 test_ipsec_inline_proto_pkt_antireplay1024(const void *test_data) 2758 { 2759 return test_ipsec_inline_proto_pkt_antireplay(test_data, 1024); 2760 } 2761 2762 static int 2763 test_ipsec_inline_proto_pkt_antireplay2048(const void *test_data) 2764 { 2765 return test_ipsec_inline_proto_pkt_antireplay(test_data, 2048); 2766 } 2767 2768 static int 2769 test_ipsec_inline_proto_pkt_antireplay4096(const void *test_data) 2770 { 2771 return test_ipsec_inline_proto_pkt_antireplay(test_data, 4096); 2772 } 2773 2774 static int 2775 test_ipsec_inline_proto_pkt_esn_antireplay(const void *test_data, uint64_t winsz) 2776 { 2777 2778 uint32_t nb_pkts = 7; 2779 bool replayed_pkt[7]; 2780 uint64_t esn[7]; 2781 2782 /* Set the initial sequence number */ 2783 esn[0] = (uint64_t)(0xFFFFFFFF - winsz); 2784 /* 1. Advance the TOP of the window to (1<<32 + WS/2) */ 2785 esn[1] = (uint64_t)((1ULL << 32) + (winsz / 2)); 2786 /* 2. Test sequence number within new window (1<<32 + WS/2 + 1) */ 2787 esn[2] = (uint64_t)((1ULL << 32) - (winsz / 2) + 1); 2788 /* 3. Test with sequence number within window (1<<32 - 1) */ 2789 esn[3] = (uint64_t)((1ULL << 32) - 1); 2790 /* 4. Test with sequence number within window (1<<32 - 1) */ 2791 esn[4] = (uint64_t)(1ULL << 32); 2792 /* 5. Test with duplicate sequence number within 2793 * new window (1<<32 - 1) 2794 */ 2795 esn[5] = (uint64_t)((1ULL << 32) - 1); 2796 /* 6. Test with duplicate sequence number within new window (1<<32) */ 2797 esn[6] = (uint64_t)(1ULL << 32); 2798 2799 replayed_pkt[0] = false; 2800 replayed_pkt[1] = false; 2801 replayed_pkt[2] = false; 2802 replayed_pkt[3] = false; 2803 replayed_pkt[4] = false; 2804 replayed_pkt[5] = true; 2805 replayed_pkt[6] = true; 2806 2807 return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt, nb_pkts, 2808 true, winsz); 2809 } 2810 2811 static int 2812 test_ipsec_inline_proto_pkt_esn_antireplay1024(const void *test_data) 2813 { 2814 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 1024); 2815 } 2816 2817 static int 2818 test_ipsec_inline_proto_pkt_esn_antireplay2048(const void *test_data) 2819 { 2820 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 2048); 2821 } 2822 2823 static int 2824 test_ipsec_inline_proto_pkt_esn_antireplay4096(const void *test_data) 2825 { 2826 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 4096); 2827 } 2828 2829 static struct unit_test_suite inline_ipsec_testsuite = { 2830 .suite_name = "Inline IPsec Ethernet Device Unit Test Suite", 2831 .unit_test_cases = { 2832 TEST_CASE_NAMED_WITH_DATA( 2833 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 128)", 2834 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2835 test_ipsec_inline_proto_known_vec, &pkt_aes_128_gcm), 2836 TEST_CASE_NAMED_WITH_DATA( 2837 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 192)", 2838 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2839 test_ipsec_inline_proto_known_vec, &pkt_aes_192_gcm), 2840 TEST_CASE_NAMED_WITH_DATA( 2841 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 256)", 2842 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2843 test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm), 2844 TEST_CASE_NAMED_WITH_DATA( 2845 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC MD5 [12B ICV])", 2846 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2847 test_ipsec_inline_proto_known_vec, 2848 &pkt_aes_128_cbc_md5), 2849 TEST_CASE_NAMED_WITH_DATA( 2850 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2851 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2852 test_ipsec_inline_proto_known_vec, 2853 &pkt_aes_128_cbc_hmac_sha256), 2854 TEST_CASE_NAMED_WITH_DATA( 2855 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])", 2856 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2857 test_ipsec_inline_proto_known_vec, 2858 &pkt_aes_128_cbc_hmac_sha384), 2859 TEST_CASE_NAMED_WITH_DATA( 2860 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])", 2861 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2862 test_ipsec_inline_proto_known_vec, 2863 &pkt_aes_128_cbc_hmac_sha512), 2864 TEST_CASE_NAMED_WITH_DATA( 2865 "Outbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA256 [16B ICV])", 2866 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2867 test_ipsec_inline_proto_known_vec, 2868 &pkt_3des_cbc_hmac_sha256), 2869 TEST_CASE_NAMED_WITH_DATA( 2870 "Outbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA384 [24B ICV])", 2871 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2872 test_ipsec_inline_proto_known_vec, 2873 &pkt_3des_cbc_hmac_sha384), 2874 TEST_CASE_NAMED_WITH_DATA( 2875 "Outbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA512 [32B ICV])", 2876 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2877 test_ipsec_inline_proto_known_vec, 2878 &pkt_3des_cbc_hmac_sha512), 2879 TEST_CASE_NAMED_WITH_DATA( 2880 "Outbound known vector (ESP tunnel mode IPv6 AES-GCM 128)", 2881 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2882 test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm_v6), 2883 TEST_CASE_NAMED_WITH_DATA( 2884 "Outbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2885 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2886 test_ipsec_inline_proto_known_vec, 2887 &pkt_aes_128_cbc_hmac_sha256_v6), 2888 TEST_CASE_NAMED_WITH_DATA( 2889 "Outbound known vector (ESP tunnel mode IPv6 3DES-CBC HMAC-SHA256 [16B ICV])", 2890 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2891 test_ipsec_inline_proto_known_vec, 2892 &pkt_3des_cbc_hmac_sha256_v6), 2893 TEST_CASE_NAMED_WITH_DATA( 2894 "Outbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])", 2895 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2896 test_ipsec_inline_proto_known_vec, 2897 &pkt_null_aes_xcbc), 2898 TEST_CASE_NAMED_WITH_DATA( 2899 "Outbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA256 [16B ICV])", 2900 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2901 test_ipsec_inline_proto_known_vec, 2902 &pkt_des_cbc_hmac_sha256), 2903 TEST_CASE_NAMED_WITH_DATA( 2904 "Outbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA384 [24B ICV])", 2905 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2906 test_ipsec_inline_proto_known_vec, 2907 &pkt_des_cbc_hmac_sha384), 2908 TEST_CASE_NAMED_WITH_DATA( 2909 "Outbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA512 [32B ICV])", 2910 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2911 test_ipsec_inline_proto_known_vec, 2912 &pkt_des_cbc_hmac_sha512), 2913 TEST_CASE_NAMED_WITH_DATA( 2914 "Outbound known vector (ESP tunnel mode IPv6 DES-CBC HMAC-SHA256 [16B ICV])", 2915 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2916 test_ipsec_inline_proto_known_vec, 2917 &pkt_des_cbc_hmac_sha256_v6), 2918 2919 TEST_CASE_NAMED_WITH_DATA( 2920 "Outbound fragmented packet", 2921 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2922 test_ipsec_inline_proto_known_vec_fragmented, 2923 &pkt_aes_128_gcm_frag), 2924 2925 TEST_CASE_NAMED_WITH_DATA( 2926 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 128)", 2927 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2928 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_gcm), 2929 TEST_CASE_NAMED_WITH_DATA( 2930 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 192)", 2931 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2932 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_192_gcm), 2933 TEST_CASE_NAMED_WITH_DATA( 2934 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 256)", 2935 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2936 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm), 2937 TEST_CASE_NAMED_WITH_DATA( 2938 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128)", 2939 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2940 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_cbc_null), 2941 TEST_CASE_NAMED_WITH_DATA( 2942 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC MD5 [12B ICV])", 2943 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2944 test_ipsec_inline_proto_known_vec_inb, 2945 &pkt_aes_128_cbc_md5), 2946 TEST_CASE_NAMED_WITH_DATA( 2947 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2948 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2949 test_ipsec_inline_proto_known_vec_inb, 2950 &pkt_aes_128_cbc_hmac_sha256), 2951 TEST_CASE_NAMED_WITH_DATA( 2952 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])", 2953 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2954 test_ipsec_inline_proto_known_vec_inb, 2955 &pkt_aes_128_cbc_hmac_sha384), 2956 TEST_CASE_NAMED_WITH_DATA( 2957 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])", 2958 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2959 test_ipsec_inline_proto_known_vec_inb, 2960 &pkt_aes_128_cbc_hmac_sha512), 2961 TEST_CASE_NAMED_WITH_DATA( 2962 "Inbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA256 [16B ICV])", 2963 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2964 test_ipsec_inline_proto_known_vec_inb, 2965 &pkt_3des_cbc_hmac_sha256), 2966 TEST_CASE_NAMED_WITH_DATA( 2967 "Inbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA384 [24B ICV])", 2968 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2969 test_ipsec_inline_proto_known_vec_inb, 2970 &pkt_3des_cbc_hmac_sha384), 2971 TEST_CASE_NAMED_WITH_DATA( 2972 "Inbound known vector (ESP tunnel mode IPv4 3DES-CBC HMAC-SHA512 [32B ICV])", 2973 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2974 test_ipsec_inline_proto_known_vec_inb, 2975 &pkt_3des_cbc_hmac_sha512), 2976 TEST_CASE_NAMED_WITH_DATA( 2977 "Inbound known vector (ESP tunnel mode IPv6 AES-GCM 128)", 2978 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2979 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm_v6), 2980 TEST_CASE_NAMED_WITH_DATA( 2981 "Inbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2982 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2983 test_ipsec_inline_proto_known_vec_inb, 2984 &pkt_aes_128_cbc_hmac_sha256_v6), 2985 TEST_CASE_NAMED_WITH_DATA( 2986 "Inbound known vector (ESP tunnel mode IPv6 3DES-CBC HMAC-SHA256 [16B ICV])", 2987 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2988 test_ipsec_inline_proto_known_vec_inb, 2989 &pkt_3des_cbc_hmac_sha256_v6), 2990 TEST_CASE_NAMED_WITH_DATA( 2991 "Inbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])", 2992 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2993 test_ipsec_inline_proto_known_vec_inb, 2994 &pkt_null_aes_xcbc), 2995 TEST_CASE_NAMED_WITH_DATA( 2996 "Inbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA256 [16B ICV])", 2997 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2998 test_ipsec_inline_proto_known_vec_inb, 2999 &pkt_des_cbc_hmac_sha256), 3000 TEST_CASE_NAMED_WITH_DATA( 3001 "Inbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA384 [24B ICV])", 3002 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3003 test_ipsec_inline_proto_known_vec_inb, 3004 &pkt_des_cbc_hmac_sha384), 3005 TEST_CASE_NAMED_WITH_DATA( 3006 "Inbound known vector (ESP tunnel mode IPv4 DES-CBC HMAC-SHA512 [32B ICV])", 3007 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3008 test_ipsec_inline_proto_known_vec_inb, 3009 &pkt_des_cbc_hmac_sha512), 3010 TEST_CASE_NAMED_WITH_DATA( 3011 "Inbound known vector (ESP tunnel mode IPv6 DES-CBC HMAC-SHA256 [16B ICV])", 3012 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3013 test_ipsec_inline_proto_known_vec_inb, 3014 &pkt_des_cbc_hmac_sha256_v6), 3015 3016 3017 TEST_CASE_NAMED_ST( 3018 "Combined test alg list", 3019 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3020 test_ipsec_inline_proto_display_list), 3021 3022 TEST_CASE_NAMED_ST( 3023 "UDP encapsulation", 3024 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3025 test_ipsec_inline_proto_udp_encap), 3026 TEST_CASE_NAMED_ST( 3027 "UDP encapsulation ports verification test", 3028 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3029 test_ipsec_inline_proto_udp_ports_verify), 3030 TEST_CASE_NAMED_ST( 3031 "Negative test: ICV corruption", 3032 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3033 test_ipsec_inline_proto_err_icv_corrupt), 3034 TEST_CASE_NAMED_ST( 3035 "Tunnel dst addr verification", 3036 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3037 test_ipsec_inline_proto_tunnel_dst_addr_verify), 3038 TEST_CASE_NAMED_ST( 3039 "Tunnel src and dst addr verification", 3040 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3041 test_ipsec_inline_proto_tunnel_src_dst_addr_verify), 3042 TEST_CASE_NAMED_ST( 3043 "Inner IP checksum", 3044 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3045 test_ipsec_inline_proto_inner_ip_csum), 3046 TEST_CASE_NAMED_ST( 3047 "Inner L4 checksum", 3048 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3049 test_ipsec_inline_proto_inner_l4_csum), 3050 TEST_CASE_NAMED_ST( 3051 "Tunnel IPv4 in IPv4", 3052 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3053 test_ipsec_inline_proto_tunnel_v4_in_v4), 3054 TEST_CASE_NAMED_ST( 3055 "Tunnel IPv6 in IPv6", 3056 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3057 test_ipsec_inline_proto_tunnel_v6_in_v6), 3058 TEST_CASE_NAMED_ST( 3059 "Tunnel IPv4 in IPv6", 3060 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3061 test_ipsec_inline_proto_tunnel_v4_in_v6), 3062 TEST_CASE_NAMED_ST( 3063 "Tunnel IPv6 in IPv4", 3064 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3065 test_ipsec_inline_proto_tunnel_v6_in_v4), 3066 TEST_CASE_NAMED_ST( 3067 "Transport IPv4", 3068 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3069 test_ipsec_inline_proto_transport_v4), 3070 TEST_CASE_NAMED_ST( 3071 "Transport l4 checksum", 3072 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3073 test_ipsec_inline_proto_transport_l4_csum), 3074 TEST_CASE_NAMED_ST( 3075 "Statistics: success", 3076 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3077 test_ipsec_inline_proto_stats), 3078 TEST_CASE_NAMED_ST( 3079 "Fragmented packet", 3080 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3081 test_ipsec_inline_proto_pkt_fragment), 3082 TEST_CASE_NAMED_ST( 3083 "Tunnel header copy DF (inner 0)", 3084 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3085 test_ipsec_inline_proto_copy_df_inner_0), 3086 TEST_CASE_NAMED_ST( 3087 "Tunnel header copy DF (inner 1)", 3088 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3089 test_ipsec_inline_proto_copy_df_inner_1), 3090 TEST_CASE_NAMED_ST( 3091 "Tunnel header set DF 0 (inner 1)", 3092 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3093 test_ipsec_inline_proto_set_df_0_inner_1), 3094 TEST_CASE_NAMED_ST( 3095 "Tunnel header set DF 1 (inner 0)", 3096 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3097 test_ipsec_inline_proto_set_df_1_inner_0), 3098 TEST_CASE_NAMED_ST( 3099 "Tunnel header IPv4 copy DSCP (inner 0)", 3100 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3101 test_ipsec_inline_proto_ipv4_copy_dscp_inner_0), 3102 TEST_CASE_NAMED_ST( 3103 "Tunnel header IPv4 copy DSCP (inner 1)", 3104 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3105 test_ipsec_inline_proto_ipv4_copy_dscp_inner_1), 3106 TEST_CASE_NAMED_ST( 3107 "Tunnel header IPv4 set DSCP 0 (inner 1)", 3108 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3109 test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1), 3110 TEST_CASE_NAMED_ST( 3111 "Tunnel header IPv4 set DSCP 1 (inner 0)", 3112 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3113 test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0), 3114 TEST_CASE_NAMED_ST( 3115 "Tunnel header IPv6 copy DSCP (inner 0)", 3116 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3117 test_ipsec_inline_proto_ipv6_copy_dscp_inner_0), 3118 TEST_CASE_NAMED_ST( 3119 "Tunnel header IPv6 copy DSCP (inner 1)", 3120 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3121 test_ipsec_inline_proto_ipv6_copy_dscp_inner_1), 3122 TEST_CASE_NAMED_ST( 3123 "Tunnel header IPv6 set DSCP 0 (inner 1)", 3124 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3125 test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1), 3126 TEST_CASE_NAMED_ST( 3127 "Tunnel header IPv6 set DSCP 1 (inner 0)", 3128 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3129 test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0), 3130 TEST_CASE_NAMED_ST( 3131 "Tunnel header IPv6 copy FLABEL (inner 0)", 3132 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3133 test_ipsec_inline_proto_ipv6_copy_flabel_inner_0), 3134 TEST_CASE_NAMED_ST( 3135 "Tunnel header IPv6 copy FLABEL (inner 1)", 3136 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3137 test_ipsec_inline_proto_ipv6_copy_flabel_inner_1), 3138 TEST_CASE_NAMED_ST( 3139 "Tunnel header IPv6 set FLABEL 0 (inner 1)", 3140 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3141 test_ipsec_inline_proto_ipv6_set_flabel_0_inner_1), 3142 TEST_CASE_NAMED_ST( 3143 "Tunnel header IPv6 set FLABEL 1 (inner 0)", 3144 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3145 test_ipsec_inline_proto_ipv6_set_flabel_1_inner_0), 3146 TEST_CASE_NAMED_ST( 3147 "Tunnel header IPv4 decrement inner TTL", 3148 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3149 test_ipsec_inline_proto_ipv4_ttl_decrement), 3150 TEST_CASE_NAMED_ST( 3151 "Tunnel header IPv6 decrement inner hop limit", 3152 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3153 test_ipsec_inline_proto_ipv6_hop_limit_decrement), 3154 TEST_CASE_NAMED_ST( 3155 "IV generation", 3156 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3157 test_ipsec_inline_proto_iv_gen), 3158 TEST_CASE_NAMED_ST( 3159 "SA soft expiry with packet limit", 3160 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3161 test_ipsec_inline_proto_sa_pkt_soft_expiry), 3162 TEST_CASE_NAMED_ST( 3163 "SA soft expiry with byte limit", 3164 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3165 test_ipsec_inline_proto_sa_byte_soft_expiry), 3166 TEST_CASE_NAMED_ST( 3167 "SA hard expiry with packet limit", 3168 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3169 test_ipsec_inline_proto_sa_pkt_hard_expiry), 3170 TEST_CASE_NAMED_ST( 3171 "SA hard expiry with byte limit", 3172 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3173 test_ipsec_inline_proto_sa_byte_hard_expiry), 3174 3175 TEST_CASE_NAMED_WITH_DATA( 3176 "Antireplay with window size 1024", 3177 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3178 test_ipsec_inline_proto_pkt_antireplay1024, 3179 &pkt_aes_128_gcm), 3180 TEST_CASE_NAMED_WITH_DATA( 3181 "Antireplay with window size 2048", 3182 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3183 test_ipsec_inline_proto_pkt_antireplay2048, 3184 &pkt_aes_128_gcm), 3185 TEST_CASE_NAMED_WITH_DATA( 3186 "Antireplay with window size 4096", 3187 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3188 test_ipsec_inline_proto_pkt_antireplay4096, 3189 &pkt_aes_128_gcm), 3190 TEST_CASE_NAMED_WITH_DATA( 3191 "ESN and Antireplay with window size 1024", 3192 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3193 test_ipsec_inline_proto_pkt_esn_antireplay1024, 3194 &pkt_aes_128_gcm), 3195 TEST_CASE_NAMED_WITH_DATA( 3196 "ESN and Antireplay with window size 2048", 3197 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3198 test_ipsec_inline_proto_pkt_esn_antireplay2048, 3199 &pkt_aes_128_gcm), 3200 TEST_CASE_NAMED_WITH_DATA( 3201 "ESN and Antireplay with window size 4096", 3202 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3203 test_ipsec_inline_proto_pkt_esn_antireplay4096, 3204 &pkt_aes_128_gcm), 3205 3206 TEST_CASE_NAMED_WITH_DATA( 3207 "IPv4 Reassembly with 2 fragments", 3208 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3209 test_inline_ip_reassembly, &ipv4_2frag_vector), 3210 TEST_CASE_NAMED_WITH_DATA( 3211 "IPv6 Reassembly with 2 fragments", 3212 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3213 test_inline_ip_reassembly, &ipv6_2frag_vector), 3214 TEST_CASE_NAMED_WITH_DATA( 3215 "IPv4 Reassembly with 4 fragments", 3216 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3217 test_inline_ip_reassembly, &ipv4_4frag_vector), 3218 TEST_CASE_NAMED_WITH_DATA( 3219 "IPv6 Reassembly with 4 fragments", 3220 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3221 test_inline_ip_reassembly, &ipv6_4frag_vector), 3222 TEST_CASE_NAMED_WITH_DATA( 3223 "IPv4 Reassembly with 5 fragments", 3224 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3225 test_inline_ip_reassembly, &ipv4_5frag_vector), 3226 TEST_CASE_NAMED_WITH_DATA( 3227 "IPv6 Reassembly with 5 fragments", 3228 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3229 test_inline_ip_reassembly, &ipv6_5frag_vector), 3230 TEST_CASE_NAMED_WITH_DATA( 3231 "IPv4 Reassembly with incomplete fragments", 3232 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3233 test_inline_ip_reassembly, &ipv4_incomplete_vector), 3234 TEST_CASE_NAMED_WITH_DATA( 3235 "IPv4 Reassembly with overlapping fragments", 3236 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3237 test_inline_ip_reassembly, &ipv4_overlap_vector), 3238 TEST_CASE_NAMED_WITH_DATA( 3239 "IPv4 Reassembly with out of order fragments", 3240 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3241 test_inline_ip_reassembly, &ipv4_out_of_order_vector), 3242 TEST_CASE_NAMED_WITH_DATA( 3243 "IPv4 Reassembly with burst of 4 fragments", 3244 ut_setup_inline_ipsec_reassembly, ut_teardown_inline_ipsec_reassembly, 3245 test_inline_ip_reassembly, &ipv4_4frag_burst_vector), 3246 TEST_CASE_NAMED_WITH_DATA( 3247 "Inbound Out-Of-Place processing", 3248 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 3249 test_ipsec_inline_proto_oop_inb, 3250 &pkt_aes_128_gcm), 3251 3252 TEST_CASES_END() /**< NULL terminate unit test array */ 3253 }, 3254 }; 3255 3256 3257 static int 3258 test_inline_ipsec(void) 3259 { 3260 inline_ipsec_testsuite.setup = inline_ipsec_testsuite_setup; 3261 inline_ipsec_testsuite.teardown = inline_ipsec_testsuite_teardown; 3262 return unit_test_suite_runner(&inline_ipsec_testsuite); 3263 } 3264 3265 3266 static int 3267 test_inline_ipsec_sg(void) 3268 { 3269 int rc; 3270 3271 inline_ipsec_testsuite.setup = inline_ipsec_testsuite_setup; 3272 inline_ipsec_testsuite.teardown = inline_ipsec_testsuite_teardown; 3273 3274 sg_mode = true; 3275 /* Run the tests */ 3276 rc = unit_test_suite_runner(&inline_ipsec_testsuite); 3277 sg_mode = false; 3278 3279 port_conf.rxmode.offloads &= ~RTE_ETH_RX_OFFLOAD_SCATTER; 3280 port_conf.txmode.offloads &= ~RTE_ETH_TX_OFFLOAD_MULTI_SEGS; 3281 return rc; 3282 } 3283 3284 static int 3285 test_event_inline_ipsec(void) 3286 { 3287 inline_ipsec_testsuite.setup = event_inline_ipsec_testsuite_setup; 3288 inline_ipsec_testsuite.teardown = event_inline_ipsec_testsuite_teardown; 3289 return unit_test_suite_runner(&inline_ipsec_testsuite); 3290 } 3291 3292 #endif /* !RTE_EXEC_ENV_WINDOWS */ 3293 3294 REGISTER_TEST_COMMAND(inline_ipsec_autotest, test_inline_ipsec); 3295 REGISTER_TEST_COMMAND(inline_ipsec_sg_autotest, test_inline_ipsec_sg); 3296 REGISTER_TEST_COMMAND(event_inline_ipsec_autotest, test_event_inline_ipsec); 3297