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 16 #ifdef RTE_EXEC_ENV_WINDOWS 17 static int 18 test_inline_ipsec(void) 19 { 20 printf("Inline ipsec not supported on Windows, skipping test\n"); 21 return TEST_SKIPPED; 22 } 23 24 #else 25 26 #define NB_ETHPORTS_USED 1 27 #define MEMPOOL_CACHE_SIZE 32 28 #define MAX_PKT_BURST 32 29 #define RTE_TEST_RX_DESC_DEFAULT 1024 30 #define RTE_TEST_TX_DESC_DEFAULT 1024 31 #define RTE_PORT_ALL (~(uint16_t)0x0) 32 33 #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ 34 #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ 35 #define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */ 36 37 #define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */ 38 #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ 39 #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ 40 41 #define MAX_TRAFFIC_BURST 2048 42 #define NB_MBUF 10240 43 44 #define ENCAP_DECAP_BURST_SZ 33 45 #define APP_REASS_TIMEOUT 10 46 47 extern struct ipsec_test_data pkt_aes_128_gcm; 48 extern struct ipsec_test_data pkt_aes_192_gcm; 49 extern struct ipsec_test_data pkt_aes_256_gcm; 50 extern struct ipsec_test_data pkt_aes_128_gcm_frag; 51 extern struct ipsec_test_data pkt_aes_128_cbc_null; 52 extern struct ipsec_test_data pkt_null_aes_xcbc; 53 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha384; 54 extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha512; 55 56 static struct rte_mempool *mbufpool; 57 static struct rte_mempool *sess_pool; 58 static struct rte_mempool *sess_priv_pool; 59 /* ethernet addresses of ports */ 60 static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 61 62 static struct rte_eth_conf port_conf = { 63 .rxmode = { 64 .mq_mode = RTE_ETH_MQ_RX_NONE, 65 .split_hdr_size = 0, 66 .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM | 67 RTE_ETH_RX_OFFLOAD_SECURITY, 68 }, 69 .txmode = { 70 .mq_mode = RTE_ETH_MQ_TX_NONE, 71 .offloads = RTE_ETH_TX_OFFLOAD_SECURITY | 72 RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE, 73 }, 74 .lpbk_mode = 1, /* enable loopback */ 75 }; 76 77 static struct rte_eth_rxconf rx_conf = { 78 .rx_thresh = { 79 .pthresh = RX_PTHRESH, 80 .hthresh = RX_HTHRESH, 81 .wthresh = RX_WTHRESH, 82 }, 83 .rx_free_thresh = 32, 84 }; 85 86 static struct rte_eth_txconf tx_conf = { 87 .tx_thresh = { 88 .pthresh = TX_PTHRESH, 89 .hthresh = TX_HTHRESH, 90 .wthresh = TX_WTHRESH, 91 }, 92 .tx_free_thresh = 32, /* Use PMD default values */ 93 .tx_rs_thresh = 32, /* Use PMD default values */ 94 }; 95 96 uint16_t port_id; 97 98 static uint64_t link_mbps; 99 100 static int ip_reassembly_dynfield_offset = -1; 101 102 static struct rte_flow *default_flow[RTE_MAX_ETHPORTS]; 103 104 /* Create Inline IPsec session */ 105 static int 106 create_inline_ipsec_session(struct ipsec_test_data *sa, uint16_t portid, 107 struct rte_security_session **sess, struct rte_security_ctx **ctx, 108 uint32_t *ol_flags, const struct ipsec_test_flags *flags, 109 struct rte_security_session_conf *sess_conf) 110 { 111 uint16_t src_v6[8] = {0x2607, 0xf8b0, 0x400c, 0x0c03, 0x0000, 0x0000, 112 0x0000, 0x001a}; 113 uint16_t dst_v6[8] = {0x2001, 0x0470, 0xe5bf, 0xdead, 0x4957, 0x2174, 114 0xe82c, 0x4887}; 115 uint32_t src_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 2)); 116 uint32_t dst_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 1)); 117 struct rte_security_capability_idx sec_cap_idx; 118 const struct rte_security_capability *sec_cap; 119 enum rte_security_ipsec_sa_direction dir; 120 struct rte_security_ctx *sec_ctx; 121 uint32_t verify; 122 123 sess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL; 124 sess_conf->protocol = RTE_SECURITY_PROTOCOL_IPSEC; 125 sess_conf->ipsec = sa->ipsec_xform; 126 127 dir = sa->ipsec_xform.direction; 128 verify = flags->tunnel_hdr_verify; 129 130 if ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && verify) { 131 if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR) 132 src_v4 += 1; 133 else if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR) 134 dst_v4 += 1; 135 } 136 137 if (sa->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { 138 if (sa->ipsec_xform.tunnel.type == 139 RTE_SECURITY_IPSEC_TUNNEL_IPV4) { 140 memcpy(&sess_conf->ipsec.tunnel.ipv4.src_ip, &src_v4, 141 sizeof(src_v4)); 142 memcpy(&sess_conf->ipsec.tunnel.ipv4.dst_ip, &dst_v4, 143 sizeof(dst_v4)); 144 145 if (flags->df == TEST_IPSEC_SET_DF_0_INNER_1) 146 sess_conf->ipsec.tunnel.ipv4.df = 0; 147 148 if (flags->df == TEST_IPSEC_SET_DF_1_INNER_0) 149 sess_conf->ipsec.tunnel.ipv4.df = 1; 150 151 if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 152 sess_conf->ipsec.tunnel.ipv4.dscp = 0; 153 154 if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) 155 sess_conf->ipsec.tunnel.ipv4.dscp = 156 TEST_IPSEC_DSCP_VAL; 157 } else { 158 if (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1) 159 sess_conf->ipsec.tunnel.ipv6.dscp = 0; 160 161 if (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0) 162 sess_conf->ipsec.tunnel.ipv6.dscp = 163 TEST_IPSEC_DSCP_VAL; 164 165 if (flags->flabel == TEST_IPSEC_SET_FLABEL_0_INNER_1) 166 sess_conf->ipsec.tunnel.ipv6.flabel = 0; 167 168 if (flags->flabel == TEST_IPSEC_SET_FLABEL_1_INNER_0) 169 sess_conf->ipsec.tunnel.ipv6.flabel = 170 TEST_IPSEC_FLABEL_VAL; 171 172 memcpy(&sess_conf->ipsec.tunnel.ipv6.src_addr, &src_v6, 173 sizeof(src_v6)); 174 memcpy(&sess_conf->ipsec.tunnel.ipv6.dst_addr, &dst_v6, 175 sizeof(dst_v6)); 176 } 177 } 178 179 /* Save SA as userdata for the security session. When 180 * the packet is received, this userdata will be 181 * retrieved using the metadata from the packet. 182 * 183 * The PMD is expected to set similar metadata for other 184 * operations, like rte_eth_event, which are tied to 185 * security session. In such cases, the userdata could 186 * be obtained to uniquely identify the security 187 * parameters denoted. 188 */ 189 190 sess_conf->userdata = (void *) sa; 191 192 sec_ctx = (struct rte_security_ctx *)rte_eth_dev_get_sec_ctx(portid); 193 if (sec_ctx == NULL) { 194 printf("Ethernet device doesn't support security features.\n"); 195 return TEST_SKIPPED; 196 } 197 198 sec_cap_idx.action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL; 199 sec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_IPSEC; 200 sec_cap_idx.ipsec.proto = sess_conf->ipsec.proto; 201 sec_cap_idx.ipsec.mode = sess_conf->ipsec.mode; 202 sec_cap_idx.ipsec.direction = sess_conf->ipsec.direction; 203 sec_cap = rte_security_capability_get(sec_ctx, &sec_cap_idx); 204 if (sec_cap == NULL) { 205 printf("No capabilities registered\n"); 206 return TEST_SKIPPED; 207 } 208 209 if (sa->aead || sa->aes_gmac) 210 memcpy(&sess_conf->ipsec.salt, sa->salt.data, 211 RTE_MIN(sizeof(sess_conf->ipsec.salt), sa->salt.len)); 212 213 /* Copy cipher session parameters */ 214 if (sa->aead) { 215 rte_memcpy(sess_conf->crypto_xform, &sa->xform.aead, 216 sizeof(struct rte_crypto_sym_xform)); 217 sess_conf->crypto_xform->aead.key.data = sa->key.data; 218 /* Verify crypto capabilities */ 219 if (test_ipsec_crypto_caps_aead_verify(sec_cap, 220 sess_conf->crypto_xform) != 0) { 221 RTE_LOG(INFO, USER1, 222 "Crypto capabilities not supported\n"); 223 return TEST_SKIPPED; 224 } 225 } else { 226 if (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 227 rte_memcpy(&sess_conf->crypto_xform->cipher, 228 &sa->xform.chain.cipher.cipher, 229 sizeof(struct rte_crypto_cipher_xform)); 230 231 rte_memcpy(&sess_conf->crypto_xform->next->auth, 232 &sa->xform.chain.auth.auth, 233 sizeof(struct rte_crypto_auth_xform)); 234 sess_conf->crypto_xform->cipher.key.data = 235 sa->key.data; 236 sess_conf->crypto_xform->next->auth.key.data = 237 sa->auth_key.data; 238 /* Verify crypto capabilities */ 239 if (test_ipsec_crypto_caps_cipher_verify(sec_cap, 240 sess_conf->crypto_xform) != 0) { 241 RTE_LOG(INFO, USER1, 242 "Cipher crypto capabilities not supported\n"); 243 return TEST_SKIPPED; 244 } 245 246 if (test_ipsec_crypto_caps_auth_verify(sec_cap, 247 sess_conf->crypto_xform->next) != 0) { 248 RTE_LOG(INFO, USER1, 249 "Auth crypto capabilities not supported\n"); 250 return TEST_SKIPPED; 251 } 252 } else { 253 rte_memcpy(&sess_conf->crypto_xform->next->cipher, 254 &sa->xform.chain.cipher.cipher, 255 sizeof(struct rte_crypto_cipher_xform)); 256 rte_memcpy(&sess_conf->crypto_xform->auth, 257 &sa->xform.chain.auth.auth, 258 sizeof(struct rte_crypto_auth_xform)); 259 sess_conf->crypto_xform->auth.key.data = 260 sa->auth_key.data; 261 sess_conf->crypto_xform->next->cipher.key.data = 262 sa->key.data; 263 264 /* Verify crypto capabilities */ 265 if (test_ipsec_crypto_caps_cipher_verify(sec_cap, 266 sess_conf->crypto_xform->next) != 0) { 267 RTE_LOG(INFO, USER1, 268 "Cipher crypto capabilities not supported\n"); 269 return TEST_SKIPPED; 270 } 271 272 if (test_ipsec_crypto_caps_auth_verify(sec_cap, 273 sess_conf->crypto_xform) != 0) { 274 RTE_LOG(INFO, USER1, 275 "Auth crypto capabilities not supported\n"); 276 return TEST_SKIPPED; 277 } 278 } 279 } 280 281 if (test_ipsec_sec_caps_verify(&sess_conf->ipsec, sec_cap, false) != 0) 282 return TEST_SKIPPED; 283 284 if ((sa->ipsec_xform.direction == 285 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) && 286 (sa->ipsec_xform.options.iv_gen_disable == 1)) { 287 /* Set env variable when IV generation is disabled */ 288 char arr[128]; 289 int len = 0, j = 0; 290 int iv_len = (sa->aead || sa->aes_gmac) ? 8 : 16; 291 292 for (; j < iv_len; j++) 293 len += snprintf(arr+len, sizeof(arr) - len, 294 "0x%x, ", sa->iv.data[j]); 295 setenv("ETH_SEC_IV_OVR", arr, 1); 296 } 297 298 *sess = rte_security_session_create(sec_ctx, 299 sess_conf, sess_pool, sess_priv_pool); 300 if (*sess == NULL) { 301 printf("SEC Session init failed.\n"); 302 return TEST_FAILED; 303 } 304 305 *ol_flags = sec_cap->ol_flags; 306 *ctx = sec_ctx; 307 308 return 0; 309 } 310 311 /* Check the link status of all ports in up to 3s, and print them finally */ 312 static void 313 check_all_ports_link_status(uint16_t port_num, uint32_t port_mask) 314 { 315 #define CHECK_INTERVAL 100 /* 100ms */ 316 #define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */ 317 uint16_t portid; 318 uint8_t count, all_ports_up, print_flag = 0; 319 struct rte_eth_link link; 320 int ret; 321 char link_status[RTE_ETH_LINK_MAX_STR_LEN]; 322 323 printf("Checking link statuses...\n"); 324 fflush(stdout); 325 for (count = 0; count <= MAX_CHECK_TIME; count++) { 326 all_ports_up = 1; 327 for (portid = 0; portid < port_num; portid++) { 328 if ((port_mask & (1 << portid)) == 0) 329 continue; 330 memset(&link, 0, sizeof(link)); 331 ret = rte_eth_link_get_nowait(portid, &link); 332 if (ret < 0) { 333 all_ports_up = 0; 334 if (print_flag == 1) 335 printf("Port %u link get failed: %s\n", 336 portid, rte_strerror(-ret)); 337 continue; 338 } 339 340 /* print link status if flag set */ 341 if (print_flag == 1) { 342 if (link.link_status && link_mbps == 0) 343 link_mbps = link.link_speed; 344 345 rte_eth_link_to_str(link_status, 346 sizeof(link_status), &link); 347 printf("Port %d %s\n", portid, link_status); 348 continue; 349 } 350 /* clear all_ports_up flag if any link down */ 351 if (link.link_status == RTE_ETH_LINK_DOWN) { 352 all_ports_up = 0; 353 break; 354 } 355 } 356 /* after finally printing all link status, get out */ 357 if (print_flag == 1) 358 break; 359 360 if (all_ports_up == 0) { 361 fflush(stdout); 362 rte_delay_ms(CHECK_INTERVAL); 363 } 364 365 /* set the print_flag if all ports up or timeout */ 366 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) 367 print_flag = 1; 368 } 369 } 370 371 static void 372 print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr) 373 { 374 char buf[RTE_ETHER_ADDR_FMT_SIZE]; 375 rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); 376 printf("%s%s", name, buf); 377 } 378 379 static void 380 copy_buf_to_pkt_segs(const uint8_t *buf, unsigned int len, 381 struct rte_mbuf *pkt, unsigned int offset) 382 { 383 unsigned int copied = 0; 384 unsigned int copy_len; 385 struct rte_mbuf *seg; 386 void *seg_buf; 387 388 seg = pkt; 389 while (offset >= seg->data_len) { 390 offset -= seg->data_len; 391 seg = seg->next; 392 } 393 copy_len = seg->data_len - offset; 394 seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset); 395 while (len > copy_len) { 396 rte_memcpy(seg_buf, buf + copied, (size_t) copy_len); 397 len -= copy_len; 398 copied += copy_len; 399 seg = seg->next; 400 seg_buf = rte_pktmbuf_mtod(seg, void *); 401 } 402 rte_memcpy(seg_buf, buf + copied, (size_t) len); 403 } 404 405 static inline struct rte_mbuf * 406 init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len) 407 { 408 struct rte_mbuf *pkt; 409 410 pkt = rte_pktmbuf_alloc(mp); 411 if (pkt == NULL) 412 return NULL; 413 if (((data[0] & 0xF0) >> 4) == IPVERSION) { 414 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN), 415 &dummy_ipv4_eth_hdr, RTE_ETHER_HDR_LEN); 416 pkt->l3_len = sizeof(struct rte_ipv4_hdr); 417 } else { 418 rte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN), 419 &dummy_ipv6_eth_hdr, RTE_ETHER_HDR_LEN); 420 pkt->l3_len = sizeof(struct rte_ipv6_hdr); 421 } 422 pkt->l2_len = RTE_ETHER_HDR_LEN; 423 424 if (pkt->buf_len > (len + RTE_ETHER_HDR_LEN)) 425 rte_memcpy(rte_pktmbuf_append(pkt, len), data, len); 426 else 427 copy_buf_to_pkt_segs(data, len, pkt, RTE_ETHER_HDR_LEN); 428 return pkt; 429 } 430 431 static int 432 init_mempools(unsigned int nb_mbuf) 433 { 434 struct rte_security_ctx *sec_ctx; 435 uint16_t nb_sess = 512; 436 uint32_t sess_sz; 437 char s[64]; 438 439 if (mbufpool == NULL) { 440 snprintf(s, sizeof(s), "mbuf_pool"); 441 mbufpool = rte_pktmbuf_pool_create(s, nb_mbuf, 442 MEMPOOL_CACHE_SIZE, 0, 443 RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY); 444 if (mbufpool == NULL) { 445 printf("Cannot init mbuf pool\n"); 446 return TEST_FAILED; 447 } 448 printf("Allocated mbuf pool\n"); 449 } 450 451 sec_ctx = rte_eth_dev_get_sec_ctx(port_id); 452 if (sec_ctx == NULL) { 453 printf("Device does not support Security ctx\n"); 454 return TEST_SKIPPED; 455 } 456 sess_sz = rte_security_session_get_size(sec_ctx); 457 if (sess_pool == NULL) { 458 snprintf(s, sizeof(s), "sess_pool"); 459 sess_pool = rte_mempool_create(s, nb_sess, sess_sz, 460 MEMPOOL_CACHE_SIZE, 0, 461 NULL, NULL, NULL, NULL, 462 SOCKET_ID_ANY, 0); 463 if (sess_pool == NULL) { 464 printf("Cannot init sess pool\n"); 465 return TEST_FAILED; 466 } 467 printf("Allocated sess pool\n"); 468 } 469 if (sess_priv_pool == NULL) { 470 snprintf(s, sizeof(s), "sess_priv_pool"); 471 sess_priv_pool = rte_mempool_create(s, nb_sess, sess_sz, 472 MEMPOOL_CACHE_SIZE, 0, 473 NULL, NULL, NULL, NULL, 474 SOCKET_ID_ANY, 0); 475 if (sess_priv_pool == NULL) { 476 printf("Cannot init sess_priv pool\n"); 477 return TEST_FAILED; 478 } 479 printf("Allocated sess_priv pool\n"); 480 } 481 482 return 0; 483 } 484 485 static int 486 create_default_flow(uint16_t portid) 487 { 488 struct rte_flow_action action[2]; 489 struct rte_flow_item pattern[2]; 490 struct rte_flow_attr attr = {0}; 491 struct rte_flow_error err; 492 struct rte_flow *flow; 493 int ret; 494 495 /* Add the default rte_flow to enable SECURITY for all ESP packets */ 496 497 pattern[0].type = RTE_FLOW_ITEM_TYPE_ESP; 498 pattern[0].spec = NULL; 499 pattern[0].mask = NULL; 500 pattern[0].last = NULL; 501 pattern[1].type = RTE_FLOW_ITEM_TYPE_END; 502 503 action[0].type = RTE_FLOW_ACTION_TYPE_SECURITY; 504 action[0].conf = NULL; 505 action[1].type = RTE_FLOW_ACTION_TYPE_END; 506 action[1].conf = NULL; 507 508 attr.ingress = 1; 509 510 ret = rte_flow_validate(portid, &attr, pattern, action, &err); 511 if (ret) { 512 printf("\nValidate flow failed, ret = %d\n", ret); 513 return -1; 514 } 515 flow = rte_flow_create(portid, &attr, pattern, action, &err); 516 if (flow == NULL) { 517 printf("\nDefault flow rule create failed\n"); 518 return -1; 519 } 520 521 default_flow[portid] = flow; 522 523 return 0; 524 } 525 526 static void 527 destroy_default_flow(uint16_t portid) 528 { 529 struct rte_flow_error err; 530 int ret; 531 532 if (!default_flow[portid]) 533 return; 534 ret = rte_flow_destroy(portid, default_flow[portid], &err); 535 if (ret) { 536 printf("\nDefault flow rule destroy failed\n"); 537 return; 538 } 539 default_flow[portid] = NULL; 540 } 541 542 struct rte_mbuf **tx_pkts_burst; 543 struct rte_mbuf **rx_pkts_burst; 544 545 static int 546 compare_pkt_data(struct rte_mbuf *m, uint8_t *ref, unsigned int tot_len) 547 { 548 unsigned int len; 549 unsigned int nb_segs = m->nb_segs; 550 unsigned int matched = 0; 551 struct rte_mbuf *save = m; 552 553 while (m) { 554 len = tot_len; 555 if (len > m->data_len) 556 len = m->data_len; 557 if (len != 0) { 558 if (memcmp(rte_pktmbuf_mtod(m, char *), 559 ref + matched, len)) { 560 printf("\n====Reassembly case failed: Data Mismatch"); 561 rte_hexdump(stdout, "Reassembled", 562 rte_pktmbuf_mtod(m, char *), 563 len); 564 rte_hexdump(stdout, "reference", 565 ref + matched, 566 len); 567 return TEST_FAILED; 568 } 569 } 570 tot_len -= len; 571 matched += len; 572 m = m->next; 573 } 574 575 if (tot_len) { 576 printf("\n====Reassembly case failed: Data Missing %u", 577 tot_len); 578 printf("\n====nb_segs %u, tot_len %u", nb_segs, tot_len); 579 rte_pktmbuf_dump(stderr, save, -1); 580 return TEST_FAILED; 581 } 582 return TEST_SUCCESS; 583 } 584 585 static inline bool 586 is_ip_reassembly_incomplete(struct rte_mbuf *mbuf) 587 { 588 static uint64_t ip_reassembly_dynflag; 589 int ip_reassembly_dynflag_offset; 590 591 if (ip_reassembly_dynflag == 0) { 592 ip_reassembly_dynflag_offset = rte_mbuf_dynflag_lookup( 593 RTE_MBUF_DYNFLAG_IP_REASSEMBLY_INCOMPLETE_NAME, NULL); 594 if (ip_reassembly_dynflag_offset < 0) 595 return false; 596 ip_reassembly_dynflag = RTE_BIT64(ip_reassembly_dynflag_offset); 597 } 598 599 return (mbuf->ol_flags & ip_reassembly_dynflag) != 0; 600 } 601 602 static void 603 free_mbuf(struct rte_mbuf *mbuf) 604 { 605 rte_eth_ip_reassembly_dynfield_t dynfield; 606 607 if (!mbuf) 608 return; 609 610 if (!is_ip_reassembly_incomplete(mbuf)) { 611 rte_pktmbuf_free(mbuf); 612 } else { 613 if (ip_reassembly_dynfield_offset < 0) 614 return; 615 616 while (mbuf) { 617 dynfield = *RTE_MBUF_DYNFIELD(mbuf, 618 ip_reassembly_dynfield_offset, 619 rte_eth_ip_reassembly_dynfield_t *); 620 rte_pktmbuf_free(mbuf); 621 mbuf = dynfield.next_frag; 622 } 623 } 624 } 625 626 627 static int 628 get_and_verify_incomplete_frags(struct rte_mbuf *mbuf, 629 struct reassembly_vector *vector) 630 { 631 rte_eth_ip_reassembly_dynfield_t *dynfield[MAX_PKT_BURST]; 632 int j = 0, ret; 633 /** 634 * IP reassembly offload is incomplete, and fragments are listed in 635 * dynfield which can be reassembled in SW. 636 */ 637 printf("\nHW IP Reassembly is not complete; attempt SW IP Reassembly," 638 "\nMatching with original frags."); 639 640 if (ip_reassembly_dynfield_offset < 0) 641 return -1; 642 643 printf("\ncomparing frag: %d", j); 644 /* Skip Ethernet header comparison */ 645 rte_pktmbuf_adj(mbuf, RTE_ETHER_HDR_LEN); 646 ret = compare_pkt_data(mbuf, vector->frags[j]->data, 647 vector->frags[j]->len); 648 if (ret) 649 return ret; 650 j++; 651 dynfield[j] = RTE_MBUF_DYNFIELD(mbuf, ip_reassembly_dynfield_offset, 652 rte_eth_ip_reassembly_dynfield_t *); 653 printf("\ncomparing frag: %d", j); 654 /* Skip Ethernet header comparison */ 655 rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN); 656 ret = compare_pkt_data(dynfield[j]->next_frag, vector->frags[j]->data, 657 vector->frags[j]->len); 658 if (ret) 659 return ret; 660 661 while ((dynfield[j]->nb_frags > 1) && 662 is_ip_reassembly_incomplete(dynfield[j]->next_frag)) { 663 j++; 664 dynfield[j] = RTE_MBUF_DYNFIELD(dynfield[j-1]->next_frag, 665 ip_reassembly_dynfield_offset, 666 rte_eth_ip_reassembly_dynfield_t *); 667 printf("\ncomparing frag: %d", j); 668 /* Skip Ethernet header comparison */ 669 rte_pktmbuf_adj(dynfield[j]->next_frag, RTE_ETHER_HDR_LEN); 670 ret = compare_pkt_data(dynfield[j]->next_frag, 671 vector->frags[j]->data, vector->frags[j]->len); 672 if (ret) 673 return ret; 674 } 675 return ret; 676 } 677 678 static int 679 test_ipsec_with_reassembly(struct reassembly_vector *vector, 680 const struct ipsec_test_flags *flags) 681 { 682 struct rte_security_session *out_ses[ENCAP_DECAP_BURST_SZ] = {0}; 683 struct rte_security_session *in_ses[ENCAP_DECAP_BURST_SZ] = {0}; 684 struct rte_eth_ip_reassembly_params reass_capa = {0}; 685 struct rte_security_session_conf sess_conf_out = {0}; 686 struct rte_security_session_conf sess_conf_in = {0}; 687 unsigned int nb_tx, burst_sz, nb_sent = 0; 688 struct rte_crypto_sym_xform cipher_out = {0}; 689 struct rte_crypto_sym_xform auth_out = {0}; 690 struct rte_crypto_sym_xform aead_out = {0}; 691 struct rte_crypto_sym_xform cipher_in = {0}; 692 struct rte_crypto_sym_xform auth_in = {0}; 693 struct rte_crypto_sym_xform aead_in = {0}; 694 struct ipsec_test_data sa_data; 695 struct rte_security_ctx *ctx; 696 unsigned int i, nb_rx = 0, j; 697 uint32_t ol_flags; 698 int ret = 0; 699 700 burst_sz = vector->burst ? ENCAP_DECAP_BURST_SZ : 1; 701 nb_tx = vector->nb_frags * burst_sz; 702 703 rte_eth_dev_stop(port_id); 704 if (ret != 0) { 705 printf("rte_eth_dev_stop: err=%s, port=%u\n", 706 rte_strerror(-ret), port_id); 707 return ret; 708 } 709 rte_eth_ip_reassembly_capability_get(port_id, &reass_capa); 710 if (reass_capa.max_frags < vector->nb_frags) 711 return TEST_SKIPPED; 712 if (reass_capa.timeout_ms > APP_REASS_TIMEOUT) { 713 reass_capa.timeout_ms = APP_REASS_TIMEOUT; 714 rte_eth_ip_reassembly_conf_set(port_id, &reass_capa); 715 } 716 717 ret = rte_eth_dev_start(port_id); 718 if (ret < 0) { 719 printf("rte_eth_dev_start: err=%d, port=%d\n", 720 ret, port_id); 721 return ret; 722 } 723 724 memset(tx_pkts_burst, 0, sizeof(tx_pkts_burst[0]) * nb_tx); 725 memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_tx); 726 727 for (i = 0; i < nb_tx; i += vector->nb_frags) { 728 for (j = 0; j < vector->nb_frags; j++) { 729 tx_pkts_burst[i+j] = init_packet(mbufpool, 730 vector->frags[j]->data, 731 vector->frags[j]->len); 732 if (tx_pkts_burst[i+j] == NULL) { 733 ret = -1; 734 printf("\n packed init failed\n"); 735 goto out; 736 } 737 } 738 } 739 740 for (i = 0; i < burst_sz; i++) { 741 memcpy(&sa_data, vector->sa_data, 742 sizeof(struct ipsec_test_data)); 743 /* Update SPI for every new SA */ 744 sa_data.ipsec_xform.spi += i; 745 sa_data.ipsec_xform.direction = 746 RTE_SECURITY_IPSEC_SA_DIR_EGRESS; 747 if (sa_data.aead) { 748 sess_conf_out.crypto_xform = &aead_out; 749 } else { 750 sess_conf_out.crypto_xform = &cipher_out; 751 sess_conf_out.crypto_xform->next = &auth_out; 752 } 753 754 /* Create Inline IPsec outbound session. */ 755 ret = create_inline_ipsec_session(&sa_data, port_id, 756 &out_ses[i], &ctx, &ol_flags, flags, 757 &sess_conf_out); 758 if (ret) { 759 printf("\nInline outbound session create failed\n"); 760 goto out; 761 } 762 } 763 764 j = 0; 765 for (i = 0; i < nb_tx; i++) { 766 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 767 rte_security_set_pkt_metadata(ctx, 768 out_ses[j], tx_pkts_burst[i], NULL); 769 tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 770 771 /* Move to next SA after nb_frags */ 772 if ((i + 1) % vector->nb_frags == 0) 773 j++; 774 } 775 776 for (i = 0; i < burst_sz; i++) { 777 memcpy(&sa_data, vector->sa_data, 778 sizeof(struct ipsec_test_data)); 779 /* Update SPI for every new SA */ 780 sa_data.ipsec_xform.spi += i; 781 sa_data.ipsec_xform.direction = 782 RTE_SECURITY_IPSEC_SA_DIR_INGRESS; 783 784 if (sa_data.aead) { 785 sess_conf_in.crypto_xform = &aead_in; 786 } else { 787 sess_conf_in.crypto_xform = &auth_in; 788 sess_conf_in.crypto_xform->next = &cipher_in; 789 } 790 /* Create Inline IPsec inbound session. */ 791 ret = create_inline_ipsec_session(&sa_data, port_id, &in_ses[i], 792 &ctx, &ol_flags, flags, &sess_conf_in); 793 if (ret) { 794 printf("\nInline inbound session create failed\n"); 795 goto out; 796 } 797 } 798 799 /* Retrieve reassembly dynfield offset if available */ 800 if (ip_reassembly_dynfield_offset < 0 && vector->nb_frags > 1) 801 ip_reassembly_dynfield_offset = rte_mbuf_dynfield_lookup( 802 RTE_MBUF_DYNFIELD_IP_REASSEMBLY_NAME, NULL); 803 804 805 ret = create_default_flow(port_id); 806 if (ret) 807 goto out; 808 809 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_tx); 810 if (nb_sent != nb_tx) { 811 ret = -1; 812 printf("\nFailed to tx %u pkts", nb_tx); 813 goto out; 814 } 815 816 rte_delay_ms(1); 817 818 /* Retry few times before giving up */ 819 nb_rx = 0; 820 j = 0; 821 do { 822 nb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx], 823 nb_tx - nb_rx); 824 j++; 825 if (nb_rx >= nb_tx) 826 break; 827 rte_delay_ms(1); 828 } while (j < 5 || !nb_rx); 829 830 /* Check for minimum number of Rx packets expected */ 831 if ((vector->nb_frags == 1 && nb_rx != nb_tx) || 832 (vector->nb_frags > 1 && nb_rx < burst_sz)) { 833 printf("\nreceived less Rx pkts(%u) pkts\n", nb_rx); 834 ret = TEST_FAILED; 835 goto out; 836 } 837 838 for (i = 0; i < nb_rx; i++) { 839 if (vector->nb_frags > 1 && 840 is_ip_reassembly_incomplete(rx_pkts_burst[i])) { 841 ret = get_and_verify_incomplete_frags(rx_pkts_burst[i], 842 vector); 843 if (ret != TEST_SUCCESS) 844 break; 845 continue; 846 } 847 848 if (rx_pkts_burst[i]->ol_flags & 849 RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED || 850 !(rx_pkts_burst[i]->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD)) { 851 printf("\nsecurity offload failed\n"); 852 ret = TEST_FAILED; 853 break; 854 } 855 856 if (vector->full_pkt->len + RTE_ETHER_HDR_LEN != 857 rx_pkts_burst[i]->pkt_len) { 858 printf("\nreassembled/decrypted packet length mismatch\n"); 859 ret = TEST_FAILED; 860 break; 861 } 862 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN); 863 ret = compare_pkt_data(rx_pkts_burst[i], 864 vector->full_pkt->data, 865 vector->full_pkt->len); 866 if (ret != TEST_SUCCESS) 867 break; 868 } 869 870 out: 871 destroy_default_flow(port_id); 872 873 /* Clear session data. */ 874 for (i = 0; i < burst_sz; i++) { 875 if (out_ses[i]) 876 rte_security_session_destroy(ctx, out_ses[i]); 877 if (in_ses[i]) 878 rte_security_session_destroy(ctx, in_ses[i]); 879 } 880 881 for (i = nb_sent; i < nb_tx; i++) 882 free_mbuf(tx_pkts_burst[i]); 883 for (i = 0; i < nb_rx; i++) 884 free_mbuf(rx_pkts_burst[i]); 885 return ret; 886 } 887 888 static int 889 test_ipsec_inline_proto_process(struct ipsec_test_data *td, 890 struct ipsec_test_data *res_d, 891 int nb_pkts, 892 bool silent, 893 const struct ipsec_test_flags *flags) 894 { 895 struct rte_security_session_conf sess_conf = {0}; 896 struct rte_crypto_sym_xform cipher = {0}; 897 struct rte_crypto_sym_xform auth = {0}; 898 struct rte_crypto_sym_xform aead = {0}; 899 struct rte_security_session *ses; 900 struct rte_security_ctx *ctx; 901 int nb_rx = 0, nb_sent; 902 uint32_t ol_flags; 903 int i, j = 0, ret; 904 905 memset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_pkts); 906 907 if (td->aead) { 908 sess_conf.crypto_xform = &aead; 909 } else { 910 if (td->ipsec_xform.direction == 911 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 912 sess_conf.crypto_xform = &cipher; 913 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 914 sess_conf.crypto_xform->next = &auth; 915 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; 916 } else { 917 sess_conf.crypto_xform = &auth; 918 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 919 sess_conf.crypto_xform->next = &cipher; 920 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 921 } 922 } 923 924 /* Create Inline IPsec session. */ 925 ret = create_inline_ipsec_session(td, port_id, &ses, &ctx, 926 &ol_flags, flags, &sess_conf); 927 if (ret) 928 return ret; 929 930 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 931 ret = create_default_flow(port_id); 932 if (ret) 933 goto out; 934 } 935 for (i = 0; i < nb_pkts; i++) { 936 tx_pkts_burst[i] = init_packet(mbufpool, td->input_text.data, 937 td->input_text.len); 938 if (tx_pkts_burst[i] == NULL) { 939 while (i--) 940 rte_pktmbuf_free(tx_pkts_burst[i]); 941 ret = TEST_FAILED; 942 goto out; 943 } 944 945 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkts_burst[i], 946 uint8_t *, RTE_ETHER_HDR_LEN), flags)) { 947 while (i--) 948 rte_pktmbuf_free(tx_pkts_burst[i]); 949 ret = TEST_FAILED; 950 goto out; 951 } 952 953 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 954 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 955 rte_security_set_pkt_metadata(ctx, ses, 956 tx_pkts_burst[i], NULL); 957 tx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 958 } 959 } 960 /* Send packet to ethdev for inline IPsec processing. */ 961 nb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_pkts); 962 if (nb_sent != nb_pkts) { 963 printf("\nUnable to TX %d packets", nb_pkts); 964 for ( ; nb_sent < nb_pkts; nb_sent++) 965 rte_pktmbuf_free(tx_pkts_burst[nb_sent]); 966 ret = TEST_FAILED; 967 goto out; 968 } 969 970 rte_pause(); 971 972 /* Receive back packet on loopback interface. */ 973 do { 974 rte_delay_ms(1); 975 nb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx], 976 nb_sent - nb_rx); 977 if (nb_rx >= nb_sent) 978 break; 979 } while (j++ < 5 || nb_rx == 0); 980 981 if (nb_rx != nb_sent) { 982 printf("\nUnable to RX all %d packets", nb_sent); 983 while (--nb_rx) 984 rte_pktmbuf_free(rx_pkts_burst[nb_rx]); 985 ret = TEST_FAILED; 986 goto out; 987 } 988 989 for (i = 0; i < nb_rx; i++) { 990 rte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN); 991 992 ret = test_ipsec_post_process(rx_pkts_burst[i], td, 993 res_d, silent, flags); 994 if (ret != TEST_SUCCESS) { 995 for ( ; i < nb_rx; i++) 996 rte_pktmbuf_free(rx_pkts_burst[i]); 997 goto out; 998 } 999 1000 ret = test_ipsec_stats_verify(ctx, ses, flags, 1001 td->ipsec_xform.direction); 1002 if (ret != TEST_SUCCESS) { 1003 for ( ; i < nb_rx; i++) 1004 rte_pktmbuf_free(rx_pkts_burst[i]); 1005 goto out; 1006 } 1007 1008 rte_pktmbuf_free(rx_pkts_burst[i]); 1009 rx_pkts_burst[i] = NULL; 1010 } 1011 1012 out: 1013 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) 1014 destroy_default_flow(port_id); 1015 1016 /* Destroy session so that other cases can create the session again */ 1017 rte_security_session_destroy(ctx, ses); 1018 ses = NULL; 1019 1020 return ret; 1021 } 1022 1023 static int 1024 test_ipsec_inline_proto_all(const struct ipsec_test_flags *flags) 1025 { 1026 struct ipsec_test_data td_outb; 1027 struct ipsec_test_data td_inb; 1028 unsigned int i, nb_pkts = 1, pass_cnt = 0, fail_cnt = 0; 1029 int ret; 1030 1031 if (flags->iv_gen || flags->sa_expiry_pkts_soft || 1032 flags->sa_expiry_pkts_hard) 1033 nb_pkts = IPSEC_TEST_PACKETS_MAX; 1034 1035 for (i = 0; i < RTE_DIM(alg_list); i++) { 1036 test_ipsec_td_prepare(alg_list[i].param1, 1037 alg_list[i].param2, 1038 flags, &td_outb, 1); 1039 1040 if (!td_outb.aead) { 1041 enum rte_crypto_cipher_algorithm cipher_alg; 1042 enum rte_crypto_auth_algorithm auth_alg; 1043 1044 cipher_alg = td_outb.xform.chain.cipher.cipher.algo; 1045 auth_alg = td_outb.xform.chain.auth.auth.algo; 1046 1047 if (td_outb.aes_gmac && cipher_alg != RTE_CRYPTO_CIPHER_NULL) 1048 continue; 1049 1050 /* ICV is not applicable for NULL auth */ 1051 if (flags->icv_corrupt && 1052 auth_alg == RTE_CRYPTO_AUTH_NULL) 1053 continue; 1054 1055 /* IV is not applicable for NULL cipher */ 1056 if (flags->iv_gen && 1057 cipher_alg == RTE_CRYPTO_CIPHER_NULL) 1058 continue; 1059 } 1060 1061 if (flags->udp_encap) 1062 td_outb.ipsec_xform.options.udp_encap = 1; 1063 1064 ret = test_ipsec_inline_proto_process(&td_outb, &td_inb, nb_pkts, 1065 false, flags); 1066 if (ret == TEST_SKIPPED) 1067 continue; 1068 1069 if (ret == TEST_FAILED) { 1070 printf("\n TEST FAILED"); 1071 test_ipsec_display_alg(alg_list[i].param1, 1072 alg_list[i].param2); 1073 fail_cnt++; 1074 continue; 1075 } 1076 1077 test_ipsec_td_update(&td_inb, &td_outb, 1, flags); 1078 1079 ret = test_ipsec_inline_proto_process(&td_inb, NULL, nb_pkts, 1080 false, flags); 1081 if (ret == TEST_SKIPPED) 1082 continue; 1083 1084 if (ret == TEST_FAILED) { 1085 printf("\n TEST FAILED"); 1086 test_ipsec_display_alg(alg_list[i].param1, 1087 alg_list[i].param2); 1088 fail_cnt++; 1089 continue; 1090 } 1091 1092 if (flags->display_alg) 1093 test_ipsec_display_alg(alg_list[i].param1, 1094 alg_list[i].param2); 1095 1096 pass_cnt++; 1097 } 1098 1099 printf("Tests passed: %d, failed: %d", pass_cnt, fail_cnt); 1100 if (fail_cnt > 0) 1101 return TEST_FAILED; 1102 if (pass_cnt > 0) 1103 return TEST_SUCCESS; 1104 else 1105 return TEST_SKIPPED; 1106 } 1107 1108 static int 1109 test_ipsec_inline_proto_process_with_esn(struct ipsec_test_data td[], 1110 struct ipsec_test_data res_d[], 1111 int nb_pkts, 1112 bool silent, 1113 const struct ipsec_test_flags *flags) 1114 { 1115 struct rte_security_session_conf sess_conf = {0}; 1116 struct ipsec_test_data *res_d_tmp = NULL; 1117 struct rte_crypto_sym_xform cipher = {0}; 1118 struct rte_crypto_sym_xform auth = {0}; 1119 struct rte_crypto_sym_xform aead = {0}; 1120 struct rte_mbuf *rx_pkt = NULL; 1121 struct rte_mbuf *tx_pkt = NULL; 1122 int nb_rx, nb_sent; 1123 struct rte_security_session *ses; 1124 struct rte_security_ctx *ctx; 1125 uint32_t ol_flags; 1126 int i, ret; 1127 1128 if (td[0].aead) { 1129 sess_conf.crypto_xform = &aead; 1130 } else { 1131 if (td[0].ipsec_xform.direction == 1132 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1133 sess_conf.crypto_xform = &cipher; 1134 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1135 sess_conf.crypto_xform->next = &auth; 1136 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1137 } else { 1138 sess_conf.crypto_xform = &auth; 1139 sess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; 1140 sess_conf.crypto_xform->next = &cipher; 1141 sess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER; 1142 } 1143 } 1144 1145 /* Create Inline IPsec session. */ 1146 ret = create_inline_ipsec_session(&td[0], port_id, &ses, &ctx, 1147 &ol_flags, flags, &sess_conf); 1148 if (ret) 1149 return ret; 1150 1151 if (td[0].ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { 1152 ret = create_default_flow(port_id); 1153 if (ret) 1154 goto out; 1155 } 1156 1157 for (i = 0; i < nb_pkts; i++) { 1158 tx_pkt = init_packet(mbufpool, td[i].input_text.data, 1159 td[i].input_text.len); 1160 if (tx_pkt == NULL) { 1161 ret = TEST_FAILED; 1162 goto out; 1163 } 1164 1165 if (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkt, 1166 uint8_t *, RTE_ETHER_HDR_LEN), flags)) { 1167 ret = TEST_FAILED; 1168 goto out; 1169 } 1170 1171 if (td[i].ipsec_xform.direction == 1172 RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { 1173 if (flags->antireplay) { 1174 sess_conf.ipsec.esn.value = 1175 td[i].ipsec_xform.esn.value; 1176 ret = rte_security_session_update(ctx, ses, 1177 &sess_conf); 1178 if (ret) { 1179 printf("Could not update ESN in session\n"); 1180 rte_pktmbuf_free(tx_pkt); 1181 ret = TEST_SKIPPED; 1182 goto out; 1183 } 1184 } 1185 if (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA) 1186 rte_security_set_pkt_metadata(ctx, ses, 1187 tx_pkt, NULL); 1188 tx_pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD; 1189 } 1190 /* Send packet to ethdev for inline IPsec processing. */ 1191 nb_sent = rte_eth_tx_burst(port_id, 0, &tx_pkt, 1); 1192 if (nb_sent != 1) { 1193 printf("\nUnable to TX packets"); 1194 rte_pktmbuf_free(tx_pkt); 1195 ret = TEST_FAILED; 1196 goto out; 1197 } 1198 1199 rte_pause(); 1200 1201 /* Receive back packet on loopback interface. */ 1202 do { 1203 rte_delay_ms(1); 1204 nb_rx = rte_eth_rx_burst(port_id, 0, &rx_pkt, 1); 1205 } while (nb_rx == 0); 1206 1207 rte_pktmbuf_adj(rx_pkt, RTE_ETHER_HDR_LEN); 1208 1209 if (res_d != NULL) 1210 res_d_tmp = &res_d[i]; 1211 1212 ret = test_ipsec_post_process(rx_pkt, &td[i], 1213 res_d_tmp, silent, flags); 1214 if (ret != TEST_SUCCESS) { 1215 rte_pktmbuf_free(rx_pkt); 1216 goto out; 1217 } 1218 1219 ret = test_ipsec_stats_verify(ctx, ses, flags, 1220 td->ipsec_xform.direction); 1221 if (ret != TEST_SUCCESS) { 1222 rte_pktmbuf_free(rx_pkt); 1223 goto out; 1224 } 1225 1226 rte_pktmbuf_free(rx_pkt); 1227 rx_pkt = NULL; 1228 tx_pkt = NULL; 1229 } 1230 1231 out: 1232 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) 1233 destroy_default_flow(port_id); 1234 1235 /* Destroy session so that other cases can create the session again */ 1236 rte_security_session_destroy(ctx, ses); 1237 ses = NULL; 1238 1239 return ret; 1240 } 1241 1242 static int 1243 ut_setup_inline_ipsec(void) 1244 { 1245 int ret; 1246 1247 /* Start device */ 1248 ret = rte_eth_dev_start(port_id); 1249 if (ret < 0) { 1250 printf("rte_eth_dev_start: err=%d, port=%d\n", 1251 ret, port_id); 1252 return ret; 1253 } 1254 /* always enable promiscuous */ 1255 ret = rte_eth_promiscuous_enable(port_id); 1256 if (ret != 0) { 1257 printf("rte_eth_promiscuous_enable: err=%s, port=%d\n", 1258 rte_strerror(-ret), port_id); 1259 return ret; 1260 } 1261 1262 check_all_ports_link_status(1, RTE_PORT_ALL); 1263 1264 return 0; 1265 } 1266 1267 static void 1268 ut_teardown_inline_ipsec(void) 1269 { 1270 struct rte_eth_ip_reassembly_params reass_conf = {0}; 1271 uint16_t portid; 1272 int ret; 1273 1274 /* port tear down */ 1275 RTE_ETH_FOREACH_DEV(portid) { 1276 ret = rte_eth_dev_stop(portid); 1277 if (ret != 0) 1278 printf("rte_eth_dev_stop: err=%s, port=%u\n", 1279 rte_strerror(-ret), portid); 1280 1281 /* Clear reassembly configuration */ 1282 rte_eth_ip_reassembly_conf_set(portid, &reass_conf); 1283 } 1284 } 1285 1286 static int 1287 inline_ipsec_testsuite_setup(void) 1288 { 1289 uint16_t nb_rxd; 1290 uint16_t nb_txd; 1291 uint16_t nb_ports; 1292 int ret; 1293 uint16_t nb_rx_queue = 1, nb_tx_queue = 1; 1294 1295 printf("Start inline IPsec test.\n"); 1296 1297 nb_ports = rte_eth_dev_count_avail(); 1298 if (nb_ports < NB_ETHPORTS_USED) { 1299 printf("At least %u port(s) used for test\n", 1300 NB_ETHPORTS_USED); 1301 return TEST_SKIPPED; 1302 } 1303 1304 ret = init_mempools(NB_MBUF); 1305 if (ret) 1306 return ret; 1307 1308 if (tx_pkts_burst == NULL) { 1309 tx_pkts_burst = (struct rte_mbuf **)rte_calloc("tx_buff", 1310 MAX_TRAFFIC_BURST, 1311 sizeof(void *), 1312 RTE_CACHE_LINE_SIZE); 1313 if (!tx_pkts_burst) 1314 return TEST_FAILED; 1315 1316 rx_pkts_burst = (struct rte_mbuf **)rte_calloc("rx_buff", 1317 MAX_TRAFFIC_BURST, 1318 sizeof(void *), 1319 RTE_CACHE_LINE_SIZE); 1320 if (!rx_pkts_burst) 1321 return TEST_FAILED; 1322 } 1323 1324 printf("Generate %d packets\n", MAX_TRAFFIC_BURST); 1325 1326 nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 1327 nb_txd = RTE_TEST_TX_DESC_DEFAULT; 1328 1329 /* configuring port 0 for the test is enough */ 1330 port_id = 0; 1331 /* port configure */ 1332 ret = rte_eth_dev_configure(port_id, nb_rx_queue, 1333 nb_tx_queue, &port_conf); 1334 if (ret < 0) { 1335 printf("Cannot configure device: err=%d, port=%d\n", 1336 ret, port_id); 1337 return ret; 1338 } 1339 ret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]); 1340 if (ret < 0) { 1341 printf("Cannot get mac address: err=%d, port=%d\n", 1342 ret, port_id); 1343 return ret; 1344 } 1345 printf("Port %u ", port_id); 1346 print_ethaddr("Address:", &ports_eth_addr[port_id]); 1347 printf("\n"); 1348 1349 /* tx queue setup */ 1350 ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd, 1351 SOCKET_ID_ANY, &tx_conf); 1352 if (ret < 0) { 1353 printf("rte_eth_tx_queue_setup: err=%d, port=%d\n", 1354 ret, port_id); 1355 return ret; 1356 } 1357 /* rx queue steup */ 1358 ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY, 1359 &rx_conf, mbufpool); 1360 if (ret < 0) { 1361 printf("rte_eth_rx_queue_setup: err=%d, port=%d\n", 1362 ret, port_id); 1363 return ret; 1364 } 1365 test_ipsec_alg_list_populate(); 1366 1367 return 0; 1368 } 1369 1370 static void 1371 inline_ipsec_testsuite_teardown(void) 1372 { 1373 uint16_t portid; 1374 int ret; 1375 1376 /* port tear down */ 1377 RTE_ETH_FOREACH_DEV(portid) { 1378 ret = rte_eth_dev_reset(portid); 1379 if (ret != 0) 1380 printf("rte_eth_dev_reset: err=%s, port=%u\n", 1381 rte_strerror(-ret), port_id); 1382 } 1383 } 1384 1385 static int 1386 test_inline_ip_reassembly(const void *testdata) 1387 { 1388 struct reassembly_vector reassembly_td = {0}; 1389 const struct reassembly_vector *td = testdata; 1390 struct ip_reassembly_test_packet full_pkt; 1391 struct ip_reassembly_test_packet frags[MAX_FRAGS]; 1392 struct ipsec_test_flags flags = {0}; 1393 int i = 0; 1394 1395 reassembly_td.sa_data = td->sa_data; 1396 reassembly_td.nb_frags = td->nb_frags; 1397 reassembly_td.burst = td->burst; 1398 1399 memcpy(&full_pkt, td->full_pkt, 1400 sizeof(struct ip_reassembly_test_packet)); 1401 reassembly_td.full_pkt = &full_pkt; 1402 1403 test_vector_payload_populate(reassembly_td.full_pkt, true); 1404 for (; i < reassembly_td.nb_frags; i++) { 1405 memcpy(&frags[i], td->frags[i], 1406 sizeof(struct ip_reassembly_test_packet)); 1407 reassembly_td.frags[i] = &frags[i]; 1408 test_vector_payload_populate(reassembly_td.frags[i], 1409 (i == 0) ? true : false); 1410 } 1411 1412 return test_ipsec_with_reassembly(&reassembly_td, &flags); 1413 } 1414 1415 static int 1416 test_ipsec_inline_proto_known_vec(const void *test_data) 1417 { 1418 struct ipsec_test_data td_outb; 1419 struct ipsec_test_flags flags; 1420 1421 memset(&flags, 0, sizeof(flags)); 1422 1423 memcpy(&td_outb, test_data, sizeof(td_outb)); 1424 1425 if (td_outb.aead || 1426 td_outb.xform.chain.cipher.cipher.algo != RTE_CRYPTO_CIPHER_NULL) { 1427 /* Disable IV gen to be able to test with known vectors */ 1428 td_outb.ipsec_xform.options.iv_gen_disable = 1; 1429 } 1430 1431 return test_ipsec_inline_proto_process(&td_outb, NULL, 1, 1432 false, &flags); 1433 } 1434 1435 static int 1436 test_ipsec_inline_proto_known_vec_inb(const void *test_data) 1437 { 1438 const struct ipsec_test_data *td = test_data; 1439 struct ipsec_test_flags flags; 1440 struct ipsec_test_data td_inb; 1441 1442 memset(&flags, 0, sizeof(flags)); 1443 1444 if (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) 1445 test_ipsec_td_in_from_out(td, &td_inb); 1446 else 1447 memcpy(&td_inb, td, sizeof(td_inb)); 1448 1449 return test_ipsec_inline_proto_process(&td_inb, NULL, 1, false, &flags); 1450 } 1451 1452 static int 1453 test_ipsec_inline_proto_display_list(const void *data __rte_unused) 1454 { 1455 struct ipsec_test_flags flags; 1456 1457 memset(&flags, 0, sizeof(flags)); 1458 1459 flags.display_alg = true; 1460 1461 return test_ipsec_inline_proto_all(&flags); 1462 } 1463 1464 static int 1465 test_ipsec_inline_proto_udp_encap(const void *data __rte_unused) 1466 { 1467 struct ipsec_test_flags flags; 1468 1469 memset(&flags, 0, sizeof(flags)); 1470 1471 flags.udp_encap = true; 1472 1473 return test_ipsec_inline_proto_all(&flags); 1474 } 1475 1476 static int 1477 test_ipsec_inline_proto_udp_ports_verify(const void *data __rte_unused) 1478 { 1479 struct ipsec_test_flags flags; 1480 1481 memset(&flags, 0, sizeof(flags)); 1482 1483 flags.udp_encap = true; 1484 flags.udp_ports_verify = true; 1485 1486 return test_ipsec_inline_proto_all(&flags); 1487 } 1488 1489 static int 1490 test_ipsec_inline_proto_err_icv_corrupt(const void *data __rte_unused) 1491 { 1492 struct ipsec_test_flags flags; 1493 1494 memset(&flags, 0, sizeof(flags)); 1495 1496 flags.icv_corrupt = true; 1497 1498 return test_ipsec_inline_proto_all(&flags); 1499 } 1500 1501 static int 1502 test_ipsec_inline_proto_tunnel_dst_addr_verify(const void *data __rte_unused) 1503 { 1504 struct ipsec_test_flags flags; 1505 1506 memset(&flags, 0, sizeof(flags)); 1507 1508 flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR; 1509 1510 return test_ipsec_inline_proto_all(&flags); 1511 } 1512 1513 static int 1514 test_ipsec_inline_proto_tunnel_src_dst_addr_verify(const void *data __rte_unused) 1515 { 1516 struct ipsec_test_flags flags; 1517 1518 memset(&flags, 0, sizeof(flags)); 1519 1520 flags.tunnel_hdr_verify = RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR; 1521 1522 return test_ipsec_inline_proto_all(&flags); 1523 } 1524 1525 static int 1526 test_ipsec_inline_proto_inner_ip_csum(const void *data __rte_unused) 1527 { 1528 struct ipsec_test_flags flags; 1529 1530 memset(&flags, 0, sizeof(flags)); 1531 1532 flags.ip_csum = true; 1533 1534 return test_ipsec_inline_proto_all(&flags); 1535 } 1536 1537 static int 1538 test_ipsec_inline_proto_inner_l4_csum(const void *data __rte_unused) 1539 { 1540 struct ipsec_test_flags flags; 1541 1542 memset(&flags, 0, sizeof(flags)); 1543 1544 flags.l4_csum = true; 1545 1546 return test_ipsec_inline_proto_all(&flags); 1547 } 1548 1549 static int 1550 test_ipsec_inline_proto_tunnel_v4_in_v4(const void *data __rte_unused) 1551 { 1552 struct ipsec_test_flags flags; 1553 1554 memset(&flags, 0, sizeof(flags)); 1555 1556 flags.ipv6 = false; 1557 flags.tunnel_ipv6 = false; 1558 1559 return test_ipsec_inline_proto_all(&flags); 1560 } 1561 1562 static int 1563 test_ipsec_inline_proto_tunnel_v6_in_v6(const void *data __rte_unused) 1564 { 1565 struct ipsec_test_flags flags; 1566 1567 memset(&flags, 0, sizeof(flags)); 1568 1569 flags.ipv6 = true; 1570 flags.tunnel_ipv6 = true; 1571 1572 return test_ipsec_inline_proto_all(&flags); 1573 } 1574 1575 static int 1576 test_ipsec_inline_proto_tunnel_v4_in_v6(const void *data __rte_unused) 1577 { 1578 struct ipsec_test_flags flags; 1579 1580 memset(&flags, 0, sizeof(flags)); 1581 1582 flags.ipv6 = false; 1583 flags.tunnel_ipv6 = true; 1584 1585 return test_ipsec_inline_proto_all(&flags); 1586 } 1587 1588 static int 1589 test_ipsec_inline_proto_tunnel_v6_in_v4(const void *data __rte_unused) 1590 { 1591 struct ipsec_test_flags flags; 1592 1593 memset(&flags, 0, sizeof(flags)); 1594 1595 flags.ipv6 = true; 1596 flags.tunnel_ipv6 = false; 1597 1598 return test_ipsec_inline_proto_all(&flags); 1599 } 1600 1601 static int 1602 test_ipsec_inline_proto_transport_v4(const void *data __rte_unused) 1603 { 1604 struct ipsec_test_flags flags; 1605 1606 memset(&flags, 0, sizeof(flags)); 1607 1608 flags.ipv6 = false; 1609 flags.transport = true; 1610 1611 return test_ipsec_inline_proto_all(&flags); 1612 } 1613 1614 static int 1615 test_ipsec_inline_proto_transport_l4_csum(const void *data __rte_unused) 1616 { 1617 struct ipsec_test_flags flags = { 1618 .l4_csum = true, 1619 .transport = true, 1620 }; 1621 1622 return test_ipsec_inline_proto_all(&flags); 1623 } 1624 1625 static int 1626 test_ipsec_inline_proto_stats(const void *data __rte_unused) 1627 { 1628 struct ipsec_test_flags flags; 1629 1630 memset(&flags, 0, sizeof(flags)); 1631 1632 flags.stats_success = true; 1633 1634 return test_ipsec_inline_proto_all(&flags); 1635 } 1636 1637 static int 1638 test_ipsec_inline_proto_pkt_fragment(const void *data __rte_unused) 1639 { 1640 struct ipsec_test_flags flags; 1641 1642 memset(&flags, 0, sizeof(flags)); 1643 1644 flags.fragment = true; 1645 1646 return test_ipsec_inline_proto_all(&flags); 1647 1648 } 1649 1650 static int 1651 test_ipsec_inline_proto_copy_df_inner_0(const void *data __rte_unused) 1652 { 1653 struct ipsec_test_flags flags; 1654 1655 memset(&flags, 0, sizeof(flags)); 1656 1657 flags.df = TEST_IPSEC_COPY_DF_INNER_0; 1658 1659 return test_ipsec_inline_proto_all(&flags); 1660 } 1661 1662 static int 1663 test_ipsec_inline_proto_copy_df_inner_1(const void *data __rte_unused) 1664 { 1665 struct ipsec_test_flags flags; 1666 1667 memset(&flags, 0, sizeof(flags)); 1668 1669 flags.df = TEST_IPSEC_COPY_DF_INNER_1; 1670 1671 return test_ipsec_inline_proto_all(&flags); 1672 } 1673 1674 static int 1675 test_ipsec_inline_proto_set_df_0_inner_1(const void *data __rte_unused) 1676 { 1677 struct ipsec_test_flags flags; 1678 1679 memset(&flags, 0, sizeof(flags)); 1680 1681 flags.df = TEST_IPSEC_SET_DF_0_INNER_1; 1682 1683 return test_ipsec_inline_proto_all(&flags); 1684 } 1685 1686 static int 1687 test_ipsec_inline_proto_set_df_1_inner_0(const void *data __rte_unused) 1688 { 1689 struct ipsec_test_flags flags; 1690 1691 memset(&flags, 0, sizeof(flags)); 1692 1693 flags.df = TEST_IPSEC_SET_DF_1_INNER_0; 1694 1695 return test_ipsec_inline_proto_all(&flags); 1696 } 1697 1698 static int 1699 test_ipsec_inline_proto_ipv4_copy_dscp_inner_0(const void *data __rte_unused) 1700 { 1701 struct ipsec_test_flags flags; 1702 1703 memset(&flags, 0, sizeof(flags)); 1704 1705 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0; 1706 1707 return test_ipsec_inline_proto_all(&flags); 1708 } 1709 1710 static int 1711 test_ipsec_inline_proto_ipv4_copy_dscp_inner_1(const void *data __rte_unused) 1712 { 1713 struct ipsec_test_flags flags; 1714 1715 memset(&flags, 0, sizeof(flags)); 1716 1717 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1; 1718 1719 return test_ipsec_inline_proto_all(&flags); 1720 } 1721 1722 static int 1723 test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1(const void *data __rte_unused) 1724 { 1725 struct ipsec_test_flags flags; 1726 1727 memset(&flags, 0, sizeof(flags)); 1728 1729 flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1; 1730 1731 return test_ipsec_inline_proto_all(&flags); 1732 } 1733 1734 static int 1735 test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0(const void *data __rte_unused) 1736 { 1737 struct ipsec_test_flags flags; 1738 1739 memset(&flags, 0, sizeof(flags)); 1740 1741 flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0; 1742 1743 return test_ipsec_inline_proto_all(&flags); 1744 } 1745 1746 static int 1747 test_ipsec_inline_proto_ipv6_copy_dscp_inner_0(const void *data __rte_unused) 1748 { 1749 struct ipsec_test_flags flags; 1750 1751 memset(&flags, 0, sizeof(flags)); 1752 1753 flags.ipv6 = true; 1754 flags.tunnel_ipv6 = true; 1755 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_0; 1756 1757 return test_ipsec_inline_proto_all(&flags); 1758 } 1759 1760 static int 1761 test_ipsec_inline_proto_ipv6_copy_dscp_inner_1(const void *data __rte_unused) 1762 { 1763 struct ipsec_test_flags flags; 1764 1765 memset(&flags, 0, sizeof(flags)); 1766 1767 flags.ipv6 = true; 1768 flags.tunnel_ipv6 = true; 1769 flags.dscp = TEST_IPSEC_COPY_DSCP_INNER_1; 1770 1771 return test_ipsec_inline_proto_all(&flags); 1772 } 1773 1774 static int 1775 test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1(const void *data __rte_unused) 1776 { 1777 struct ipsec_test_flags flags; 1778 1779 memset(&flags, 0, sizeof(flags)); 1780 1781 flags.ipv6 = true; 1782 flags.tunnel_ipv6 = true; 1783 flags.dscp = TEST_IPSEC_SET_DSCP_0_INNER_1; 1784 1785 return test_ipsec_inline_proto_all(&flags); 1786 } 1787 1788 static int 1789 test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0(const void *data __rte_unused) 1790 { 1791 struct ipsec_test_flags flags; 1792 1793 memset(&flags, 0, sizeof(flags)); 1794 1795 flags.ipv6 = true; 1796 flags.tunnel_ipv6 = true; 1797 flags.dscp = TEST_IPSEC_SET_DSCP_1_INNER_0; 1798 1799 return test_ipsec_inline_proto_all(&flags); 1800 } 1801 1802 static int 1803 test_ipsec_inline_proto_ipv6_copy_flabel_inner_0(const void *data __rte_unused) 1804 { 1805 struct ipsec_test_flags flags; 1806 1807 memset(&flags, 0, sizeof(flags)); 1808 1809 flags.ipv6 = true; 1810 flags.tunnel_ipv6 = true; 1811 flags.flabel = TEST_IPSEC_COPY_FLABEL_INNER_0; 1812 1813 return test_ipsec_inline_proto_all(&flags); 1814 } 1815 1816 static int 1817 test_ipsec_inline_proto_ipv6_copy_flabel_inner_1(const void *data __rte_unused) 1818 { 1819 struct ipsec_test_flags flags; 1820 1821 memset(&flags, 0, sizeof(flags)); 1822 1823 flags.ipv6 = true; 1824 flags.tunnel_ipv6 = true; 1825 flags.flabel = TEST_IPSEC_COPY_FLABEL_INNER_1; 1826 1827 return test_ipsec_inline_proto_all(&flags); 1828 } 1829 1830 static int 1831 test_ipsec_inline_proto_ipv6_set_flabel_0_inner_1(const void *data __rte_unused) 1832 { 1833 struct ipsec_test_flags flags; 1834 1835 memset(&flags, 0, sizeof(flags)); 1836 1837 flags.ipv6 = true; 1838 flags.tunnel_ipv6 = true; 1839 flags.flabel = TEST_IPSEC_SET_FLABEL_0_INNER_1; 1840 1841 return test_ipsec_inline_proto_all(&flags); 1842 } 1843 1844 static int 1845 test_ipsec_inline_proto_ipv6_set_flabel_1_inner_0(const void *data __rte_unused) 1846 { 1847 struct ipsec_test_flags flags; 1848 1849 memset(&flags, 0, sizeof(flags)); 1850 1851 flags.ipv6 = true; 1852 flags.tunnel_ipv6 = true; 1853 flags.flabel = TEST_IPSEC_SET_FLABEL_1_INNER_0; 1854 1855 return test_ipsec_inline_proto_all(&flags); 1856 } 1857 1858 static int 1859 test_ipsec_inline_proto_ipv4_ttl_decrement(const void *data __rte_unused) 1860 { 1861 struct ipsec_test_flags flags = { 1862 .dec_ttl_or_hop_limit = true 1863 }; 1864 1865 return test_ipsec_inline_proto_all(&flags); 1866 } 1867 1868 static int 1869 test_ipsec_inline_proto_ipv6_hop_limit_decrement(const void *data __rte_unused) 1870 { 1871 struct ipsec_test_flags flags = { 1872 .ipv6 = true, 1873 .dec_ttl_or_hop_limit = true 1874 }; 1875 1876 return test_ipsec_inline_proto_all(&flags); 1877 } 1878 1879 static int 1880 test_ipsec_inline_proto_iv_gen(const void *data __rte_unused) 1881 { 1882 struct ipsec_test_flags flags; 1883 1884 memset(&flags, 0, sizeof(flags)); 1885 1886 flags.iv_gen = true; 1887 1888 return test_ipsec_inline_proto_all(&flags); 1889 } 1890 1891 static int 1892 test_ipsec_inline_proto_known_vec_fragmented(const void *test_data) 1893 { 1894 struct ipsec_test_data td_outb; 1895 struct ipsec_test_flags flags; 1896 1897 memset(&flags, 0, sizeof(flags)); 1898 flags.fragment = true; 1899 1900 memcpy(&td_outb, test_data, sizeof(td_outb)); 1901 1902 /* Disable IV gen to be able to test with known vectors */ 1903 td_outb.ipsec_xform.options.iv_gen_disable = 1; 1904 1905 return test_ipsec_inline_proto_process(&td_outb, NULL, 1, false, 1906 &flags); 1907 } 1908 1909 static int 1910 test_ipsec_inline_pkt_replay(const void *test_data, const uint64_t esn[], 1911 bool replayed_pkt[], uint32_t nb_pkts, bool esn_en, 1912 uint64_t winsz) 1913 { 1914 struct ipsec_test_data td_outb[IPSEC_TEST_PACKETS_MAX]; 1915 struct ipsec_test_data td_inb[IPSEC_TEST_PACKETS_MAX]; 1916 struct ipsec_test_flags flags; 1917 uint32_t i, ret = 0; 1918 1919 memset(&flags, 0, sizeof(flags)); 1920 flags.antireplay = true; 1921 1922 for (i = 0; i < nb_pkts; i++) { 1923 memcpy(&td_outb[i], test_data, sizeof(td_outb)); 1924 td_outb[i].ipsec_xform.options.iv_gen_disable = 1; 1925 td_outb[i].ipsec_xform.replay_win_sz = winsz; 1926 td_outb[i].ipsec_xform.options.esn = esn_en; 1927 } 1928 1929 for (i = 0; i < nb_pkts; i++) 1930 td_outb[i].ipsec_xform.esn.value = esn[i]; 1931 1932 ret = test_ipsec_inline_proto_process_with_esn(td_outb, td_inb, 1933 nb_pkts, true, &flags); 1934 if (ret != TEST_SUCCESS) 1935 return ret; 1936 1937 test_ipsec_td_update(td_inb, td_outb, nb_pkts, &flags); 1938 1939 for (i = 0; i < nb_pkts; i++) { 1940 td_inb[i].ipsec_xform.options.esn = esn_en; 1941 /* Set antireplay flag for packets to be dropped */ 1942 td_inb[i].ar_packet = replayed_pkt[i]; 1943 } 1944 1945 ret = test_ipsec_inline_proto_process_with_esn(td_inb, NULL, nb_pkts, 1946 true, &flags); 1947 1948 return ret; 1949 } 1950 1951 static int 1952 test_ipsec_inline_proto_pkt_antireplay(const void *test_data, uint64_t winsz) 1953 { 1954 1955 uint32_t nb_pkts = 5; 1956 bool replayed_pkt[5]; 1957 uint64_t esn[5]; 1958 1959 /* 1. Advance the TOP of the window to WS * 2 */ 1960 esn[0] = winsz * 2; 1961 /* 2. Test sequence number within the new window(WS + 1) */ 1962 esn[1] = winsz + 1; 1963 /* 3. Test sequence number less than the window BOTTOM */ 1964 esn[2] = winsz; 1965 /* 4. Test sequence number in the middle of the window */ 1966 esn[3] = winsz + (winsz / 2); 1967 /* 5. Test replay of the packet in the middle of the window */ 1968 esn[4] = winsz + (winsz / 2); 1969 1970 replayed_pkt[0] = false; 1971 replayed_pkt[1] = false; 1972 replayed_pkt[2] = true; 1973 replayed_pkt[3] = false; 1974 replayed_pkt[4] = true; 1975 1976 return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt, 1977 nb_pkts, false, winsz); 1978 } 1979 1980 static int 1981 test_ipsec_inline_proto_pkt_antireplay1024(const void *test_data) 1982 { 1983 return test_ipsec_inline_proto_pkt_antireplay(test_data, 1024); 1984 } 1985 1986 static int 1987 test_ipsec_inline_proto_pkt_antireplay2048(const void *test_data) 1988 { 1989 return test_ipsec_inline_proto_pkt_antireplay(test_data, 2048); 1990 } 1991 1992 static int 1993 test_ipsec_inline_proto_pkt_antireplay4096(const void *test_data) 1994 { 1995 return test_ipsec_inline_proto_pkt_antireplay(test_data, 4096); 1996 } 1997 1998 static int 1999 test_ipsec_inline_proto_pkt_esn_antireplay(const void *test_data, uint64_t winsz) 2000 { 2001 2002 uint32_t nb_pkts = 7; 2003 bool replayed_pkt[7]; 2004 uint64_t esn[7]; 2005 2006 /* Set the initial sequence number */ 2007 esn[0] = (uint64_t)(0xFFFFFFFF - winsz); 2008 /* 1. Advance the TOP of the window to (1<<32 + WS/2) */ 2009 esn[1] = (uint64_t)((1ULL << 32) + (winsz / 2)); 2010 /* 2. Test sequence number within new window (1<<32 + WS/2 + 1) */ 2011 esn[2] = (uint64_t)((1ULL << 32) - (winsz / 2) + 1); 2012 /* 3. Test with sequence number within window (1<<32 - 1) */ 2013 esn[3] = (uint64_t)((1ULL << 32) - 1); 2014 /* 4. Test with sequence number within window (1<<32 - 1) */ 2015 esn[4] = (uint64_t)(1ULL << 32); 2016 /* 5. Test with duplicate sequence number within 2017 * new window (1<<32 - 1) 2018 */ 2019 esn[5] = (uint64_t)((1ULL << 32) - 1); 2020 /* 6. Test with duplicate sequence number within new window (1<<32) */ 2021 esn[6] = (uint64_t)(1ULL << 32); 2022 2023 replayed_pkt[0] = false; 2024 replayed_pkt[1] = false; 2025 replayed_pkt[2] = false; 2026 replayed_pkt[3] = false; 2027 replayed_pkt[4] = false; 2028 replayed_pkt[5] = true; 2029 replayed_pkt[6] = true; 2030 2031 return test_ipsec_inline_pkt_replay(test_data, esn, replayed_pkt, nb_pkts, 2032 true, winsz); 2033 } 2034 2035 static int 2036 test_ipsec_inline_proto_pkt_esn_antireplay1024(const void *test_data) 2037 { 2038 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 1024); 2039 } 2040 2041 static int 2042 test_ipsec_inline_proto_pkt_esn_antireplay2048(const void *test_data) 2043 { 2044 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 2048); 2045 } 2046 2047 static int 2048 test_ipsec_inline_proto_pkt_esn_antireplay4096(const void *test_data) 2049 { 2050 return test_ipsec_inline_proto_pkt_esn_antireplay(test_data, 4096); 2051 } 2052 2053 2054 2055 static struct unit_test_suite inline_ipsec_testsuite = { 2056 .suite_name = "Inline IPsec Ethernet Device Unit Test Suite", 2057 .setup = inline_ipsec_testsuite_setup, 2058 .teardown = inline_ipsec_testsuite_teardown, 2059 .unit_test_cases = { 2060 TEST_CASE_NAMED_WITH_DATA( 2061 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 128)", 2062 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2063 test_ipsec_inline_proto_known_vec, &pkt_aes_128_gcm), 2064 TEST_CASE_NAMED_WITH_DATA( 2065 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 192)", 2066 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2067 test_ipsec_inline_proto_known_vec, &pkt_aes_192_gcm), 2068 TEST_CASE_NAMED_WITH_DATA( 2069 "Outbound known vector (ESP tunnel mode IPv4 AES-GCM 256)", 2070 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2071 test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm), 2072 TEST_CASE_NAMED_WITH_DATA( 2073 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2074 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2075 test_ipsec_inline_proto_known_vec, 2076 &pkt_aes_128_cbc_hmac_sha256), 2077 TEST_CASE_NAMED_WITH_DATA( 2078 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])", 2079 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2080 test_ipsec_inline_proto_known_vec, 2081 &pkt_aes_128_cbc_hmac_sha384), 2082 TEST_CASE_NAMED_WITH_DATA( 2083 "Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])", 2084 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2085 test_ipsec_inline_proto_known_vec, 2086 &pkt_aes_128_cbc_hmac_sha512), 2087 TEST_CASE_NAMED_WITH_DATA( 2088 "Outbound known vector (ESP tunnel mode IPv6 AES-GCM 128)", 2089 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2090 test_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm_v6), 2091 TEST_CASE_NAMED_WITH_DATA( 2092 "Outbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2093 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2094 test_ipsec_inline_proto_known_vec, 2095 &pkt_aes_128_cbc_hmac_sha256_v6), 2096 TEST_CASE_NAMED_WITH_DATA( 2097 "Outbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])", 2098 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2099 test_ipsec_inline_proto_known_vec, 2100 &pkt_null_aes_xcbc), 2101 2102 TEST_CASE_NAMED_WITH_DATA( 2103 "Outbound fragmented packet", 2104 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2105 test_ipsec_inline_proto_known_vec_fragmented, 2106 &pkt_aes_128_gcm_frag), 2107 2108 TEST_CASE_NAMED_WITH_DATA( 2109 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 128)", 2110 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2111 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_gcm), 2112 TEST_CASE_NAMED_WITH_DATA( 2113 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 192)", 2114 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2115 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_192_gcm), 2116 TEST_CASE_NAMED_WITH_DATA( 2117 "Inbound known vector (ESP tunnel mode IPv4 AES-GCM 256)", 2118 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2119 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm), 2120 TEST_CASE_NAMED_WITH_DATA( 2121 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128)", 2122 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2123 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_128_cbc_null), 2124 TEST_CASE_NAMED_WITH_DATA( 2125 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2126 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2127 test_ipsec_inline_proto_known_vec_inb, 2128 &pkt_aes_128_cbc_hmac_sha256), 2129 TEST_CASE_NAMED_WITH_DATA( 2130 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])", 2131 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2132 test_ipsec_inline_proto_known_vec_inb, 2133 &pkt_aes_128_cbc_hmac_sha384), 2134 TEST_CASE_NAMED_WITH_DATA( 2135 "Inbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])", 2136 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2137 test_ipsec_inline_proto_known_vec_inb, 2138 &pkt_aes_128_cbc_hmac_sha512), 2139 TEST_CASE_NAMED_WITH_DATA( 2140 "Inbound known vector (ESP tunnel mode IPv6 AES-GCM 128)", 2141 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2142 test_ipsec_inline_proto_known_vec_inb, &pkt_aes_256_gcm_v6), 2143 TEST_CASE_NAMED_WITH_DATA( 2144 "Inbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])", 2145 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2146 test_ipsec_inline_proto_known_vec_inb, 2147 &pkt_aes_128_cbc_hmac_sha256_v6), 2148 TEST_CASE_NAMED_WITH_DATA( 2149 "Inbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])", 2150 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2151 test_ipsec_inline_proto_known_vec_inb, 2152 &pkt_null_aes_xcbc), 2153 2154 TEST_CASE_NAMED_ST( 2155 "Combined test alg list", 2156 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2157 test_ipsec_inline_proto_display_list), 2158 2159 TEST_CASE_NAMED_ST( 2160 "UDP encapsulation", 2161 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2162 test_ipsec_inline_proto_udp_encap), 2163 TEST_CASE_NAMED_ST( 2164 "UDP encapsulation ports verification test", 2165 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2166 test_ipsec_inline_proto_udp_ports_verify), 2167 TEST_CASE_NAMED_ST( 2168 "Negative test: ICV corruption", 2169 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2170 test_ipsec_inline_proto_err_icv_corrupt), 2171 TEST_CASE_NAMED_ST( 2172 "Tunnel dst addr verification", 2173 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2174 test_ipsec_inline_proto_tunnel_dst_addr_verify), 2175 TEST_CASE_NAMED_ST( 2176 "Tunnel src and dst addr verification", 2177 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2178 test_ipsec_inline_proto_tunnel_src_dst_addr_verify), 2179 TEST_CASE_NAMED_ST( 2180 "Inner IP checksum", 2181 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2182 test_ipsec_inline_proto_inner_ip_csum), 2183 TEST_CASE_NAMED_ST( 2184 "Inner L4 checksum", 2185 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2186 test_ipsec_inline_proto_inner_l4_csum), 2187 TEST_CASE_NAMED_ST( 2188 "Tunnel IPv4 in IPv4", 2189 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2190 test_ipsec_inline_proto_tunnel_v4_in_v4), 2191 TEST_CASE_NAMED_ST( 2192 "Tunnel IPv6 in IPv6", 2193 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2194 test_ipsec_inline_proto_tunnel_v6_in_v6), 2195 TEST_CASE_NAMED_ST( 2196 "Tunnel IPv4 in IPv6", 2197 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2198 test_ipsec_inline_proto_tunnel_v4_in_v6), 2199 TEST_CASE_NAMED_ST( 2200 "Tunnel IPv6 in IPv4", 2201 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2202 test_ipsec_inline_proto_tunnel_v6_in_v4), 2203 TEST_CASE_NAMED_ST( 2204 "Transport IPv4", 2205 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2206 test_ipsec_inline_proto_transport_v4), 2207 TEST_CASE_NAMED_ST( 2208 "Transport l4 checksum", 2209 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2210 test_ipsec_inline_proto_transport_l4_csum), 2211 TEST_CASE_NAMED_ST( 2212 "Statistics: success", 2213 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2214 test_ipsec_inline_proto_stats), 2215 TEST_CASE_NAMED_ST( 2216 "Fragmented packet", 2217 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2218 test_ipsec_inline_proto_pkt_fragment), 2219 TEST_CASE_NAMED_ST( 2220 "Tunnel header copy DF (inner 0)", 2221 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2222 test_ipsec_inline_proto_copy_df_inner_0), 2223 TEST_CASE_NAMED_ST( 2224 "Tunnel header copy DF (inner 1)", 2225 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2226 test_ipsec_inline_proto_copy_df_inner_1), 2227 TEST_CASE_NAMED_ST( 2228 "Tunnel header set DF 0 (inner 1)", 2229 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2230 test_ipsec_inline_proto_set_df_0_inner_1), 2231 TEST_CASE_NAMED_ST( 2232 "Tunnel header set DF 1 (inner 0)", 2233 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2234 test_ipsec_inline_proto_set_df_1_inner_0), 2235 TEST_CASE_NAMED_ST( 2236 "Tunnel header IPv4 copy DSCP (inner 0)", 2237 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2238 test_ipsec_inline_proto_ipv4_copy_dscp_inner_0), 2239 TEST_CASE_NAMED_ST( 2240 "Tunnel header IPv4 copy DSCP (inner 1)", 2241 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2242 test_ipsec_inline_proto_ipv4_copy_dscp_inner_1), 2243 TEST_CASE_NAMED_ST( 2244 "Tunnel header IPv4 set DSCP 0 (inner 1)", 2245 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2246 test_ipsec_inline_proto_ipv4_set_dscp_0_inner_1), 2247 TEST_CASE_NAMED_ST( 2248 "Tunnel header IPv4 set DSCP 1 (inner 0)", 2249 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2250 test_ipsec_inline_proto_ipv4_set_dscp_1_inner_0), 2251 TEST_CASE_NAMED_ST( 2252 "Tunnel header IPv6 copy DSCP (inner 0)", 2253 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2254 test_ipsec_inline_proto_ipv6_copy_dscp_inner_0), 2255 TEST_CASE_NAMED_ST( 2256 "Tunnel header IPv6 copy DSCP (inner 1)", 2257 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2258 test_ipsec_inline_proto_ipv6_copy_dscp_inner_1), 2259 TEST_CASE_NAMED_ST( 2260 "Tunnel header IPv6 set DSCP 0 (inner 1)", 2261 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2262 test_ipsec_inline_proto_ipv6_set_dscp_0_inner_1), 2263 TEST_CASE_NAMED_ST( 2264 "Tunnel header IPv6 set DSCP 1 (inner 0)", 2265 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2266 test_ipsec_inline_proto_ipv6_set_dscp_1_inner_0), 2267 TEST_CASE_NAMED_ST( 2268 "Tunnel header IPv6 copy FLABEL (inner 0)", 2269 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2270 test_ipsec_inline_proto_ipv6_copy_flabel_inner_0), 2271 TEST_CASE_NAMED_ST( 2272 "Tunnel header IPv6 copy FLABEL (inner 1)", 2273 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2274 test_ipsec_inline_proto_ipv6_copy_flabel_inner_1), 2275 TEST_CASE_NAMED_ST( 2276 "Tunnel header IPv6 set FLABEL 0 (inner 1)", 2277 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2278 test_ipsec_inline_proto_ipv6_set_flabel_0_inner_1), 2279 TEST_CASE_NAMED_ST( 2280 "Tunnel header IPv6 set FLABEL 1 (inner 0)", 2281 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2282 test_ipsec_inline_proto_ipv6_set_flabel_1_inner_0), 2283 TEST_CASE_NAMED_ST( 2284 "Tunnel header IPv4 decrement inner TTL", 2285 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2286 test_ipsec_inline_proto_ipv4_ttl_decrement), 2287 TEST_CASE_NAMED_ST( 2288 "Tunnel header IPv6 decrement inner hop limit", 2289 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2290 test_ipsec_inline_proto_ipv6_hop_limit_decrement), 2291 TEST_CASE_NAMED_ST( 2292 "IV generation", 2293 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2294 test_ipsec_inline_proto_iv_gen), 2295 2296 2297 TEST_CASE_NAMED_WITH_DATA( 2298 "Antireplay with window size 1024", 2299 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2300 test_ipsec_inline_proto_pkt_antireplay1024, 2301 &pkt_aes_128_gcm), 2302 TEST_CASE_NAMED_WITH_DATA( 2303 "Antireplay with window size 2048", 2304 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2305 test_ipsec_inline_proto_pkt_antireplay2048, 2306 &pkt_aes_128_gcm), 2307 TEST_CASE_NAMED_WITH_DATA( 2308 "Antireplay with window size 4096", 2309 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2310 test_ipsec_inline_proto_pkt_antireplay4096, 2311 &pkt_aes_128_gcm), 2312 TEST_CASE_NAMED_WITH_DATA( 2313 "ESN and Antireplay with window size 1024", 2314 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2315 test_ipsec_inline_proto_pkt_esn_antireplay1024, 2316 &pkt_aes_128_gcm), 2317 TEST_CASE_NAMED_WITH_DATA( 2318 "ESN and Antireplay with window size 2048", 2319 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2320 test_ipsec_inline_proto_pkt_esn_antireplay2048, 2321 &pkt_aes_128_gcm), 2322 TEST_CASE_NAMED_WITH_DATA( 2323 "ESN and Antireplay with window size 4096", 2324 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2325 test_ipsec_inline_proto_pkt_esn_antireplay4096, 2326 &pkt_aes_128_gcm), 2327 2328 TEST_CASE_NAMED_WITH_DATA( 2329 "IPv4 Reassembly with 2 fragments", 2330 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2331 test_inline_ip_reassembly, &ipv4_2frag_vector), 2332 TEST_CASE_NAMED_WITH_DATA( 2333 "IPv6 Reassembly with 2 fragments", 2334 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2335 test_inline_ip_reassembly, &ipv6_2frag_vector), 2336 TEST_CASE_NAMED_WITH_DATA( 2337 "IPv4 Reassembly with 4 fragments", 2338 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2339 test_inline_ip_reassembly, &ipv4_4frag_vector), 2340 TEST_CASE_NAMED_WITH_DATA( 2341 "IPv6 Reassembly with 4 fragments", 2342 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2343 test_inline_ip_reassembly, &ipv6_4frag_vector), 2344 TEST_CASE_NAMED_WITH_DATA( 2345 "IPv4 Reassembly with 5 fragments", 2346 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2347 test_inline_ip_reassembly, &ipv4_5frag_vector), 2348 TEST_CASE_NAMED_WITH_DATA( 2349 "IPv6 Reassembly with 5 fragments", 2350 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2351 test_inline_ip_reassembly, &ipv6_5frag_vector), 2352 TEST_CASE_NAMED_WITH_DATA( 2353 "IPv4 Reassembly with incomplete fragments", 2354 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2355 test_inline_ip_reassembly, &ipv4_incomplete_vector), 2356 TEST_CASE_NAMED_WITH_DATA( 2357 "IPv4 Reassembly with overlapping fragments", 2358 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2359 test_inline_ip_reassembly, &ipv4_overlap_vector), 2360 TEST_CASE_NAMED_WITH_DATA( 2361 "IPv4 Reassembly with out of order fragments", 2362 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2363 test_inline_ip_reassembly, &ipv4_out_of_order_vector), 2364 TEST_CASE_NAMED_WITH_DATA( 2365 "IPv4 Reassembly with burst of 4 fragments", 2366 ut_setup_inline_ipsec, ut_teardown_inline_ipsec, 2367 test_inline_ip_reassembly, &ipv4_4frag_burst_vector), 2368 2369 TEST_CASES_END() /**< NULL terminate unit test array */ 2370 }, 2371 }; 2372 2373 2374 static int 2375 test_inline_ipsec(void) 2376 { 2377 return unit_test_suite_runner(&inline_ipsec_testsuite); 2378 } 2379 2380 #endif /* !RTE_EXEC_ENV_WINDOWS */ 2381 2382 REGISTER_TEST_COMMAND(inline_ipsec_autotest, test_inline_ipsec); 2383