dpdk/app/test/test_ipsec.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2018 Intel Corporation
   3 */
   4
   5#include "test.h"
   6
   7#include <time.h>
   8
   9#include <rte_common.h>
  10#include <rte_hexdump.h>
  11#include <rte_mbuf.h>
  12#include <rte_malloc.h>
  13#include <rte_memcpy.h>
  14#include <rte_cycles.h>
  15#include <rte_bus_vdev.h>
  16#include <rte_ip.h>
  17#include <rte_crypto.h>
  18#include <rte_cryptodev.h>
  19#include <rte_lcore.h>
  20
  21#ifdef RTE_EXEC_ENV_WINDOWS
  22static int
  23test_ipsec(void)
  24{
  25        printf("ipsec not supported on Windows, skipping test\n");
  26        return TEST_SKIPPED;
  27}
  28
  29#else
  30
  31#include <rte_ipsec.h>
  32#include <rte_random.h>
  33#include <rte_esp.h>
  34#include <rte_security_driver.h>
  35
  36#include "test_cryptodev.h"
  37
  38#define VDEV_ARGS_SIZE  100
  39#define MAX_NB_SESSIONS 200
  40#define MAX_NB_SAS              2
  41#define REPLAY_WIN_0    0
  42#define REPLAY_WIN_32   32
  43#define REPLAY_WIN_64   64
  44#define REPLAY_WIN_128  128
  45#define REPLAY_WIN_256  256
  46#define DATA_64_BYTES   64
  47#define DATA_80_BYTES   80
  48#define DATA_100_BYTES  100
  49#define ESN_ENABLED             1
  50#define ESN_DISABLED    0
  51#define INBOUND_SPI             7
  52#define OUTBOUND_SPI    17
  53#define BURST_SIZE              32
  54#define REORDER_PKTS    1
  55#define DEQUEUE_COUNT   1000
  56
  57struct user_params {
  58        enum rte_crypto_sym_xform_type auth;
  59        enum rte_crypto_sym_xform_type cipher;
  60        enum rte_crypto_sym_xform_type aead;
  61
  62        char auth_algo[128];
  63        char cipher_algo[128];
  64        char aead_algo[128];
  65};
  66
  67struct ipsec_testsuite_params {
  68        struct rte_mempool *mbuf_pool;
  69        struct rte_mempool *cop_mpool;
  70        struct rte_cryptodev_config conf;
  71        struct rte_cryptodev_qp_conf qp_conf;
  72
  73        uint8_t valid_dev;
  74        uint8_t valid_dev_found;
  75};
  76
  77struct ipsec_unitest_params {
  78        struct rte_crypto_sym_xform cipher_xform;
  79        struct rte_crypto_sym_xform auth_xform;
  80        struct rte_crypto_sym_xform aead_xform;
  81        struct rte_crypto_sym_xform *crypto_xforms;
  82
  83        struct rte_security_ipsec_xform ipsec_xform;
  84
  85        struct rte_ipsec_sa_prm sa_prm;
  86        struct rte_ipsec_session ss[MAX_NB_SAS];
  87
  88        struct rte_crypto_op *cop[BURST_SIZE];
  89
  90        struct rte_mbuf *obuf[BURST_SIZE], *ibuf[BURST_SIZE],
  91                *testbuf[BURST_SIZE];
  92
  93        uint16_t pkt_index;
  94};
  95
  96struct ipsec_test_cfg {
  97        uint32_t replay_win_sz;
  98        uint32_t esn;
  99        uint64_t flags;
 100        size_t pkt_sz;
 101        uint16_t num_pkts;
 102        uint32_t reorder_pkts;
 103};
 104
 105static const struct ipsec_test_cfg test_cfg[] = {
 106        {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, 1, 0},
 107        {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_64_BYTES, BURST_SIZE, 0},
 108        {REPLAY_WIN_0, ESN_DISABLED, 0, DATA_80_BYTES, BURST_SIZE,
 109                REORDER_PKTS},
 110        {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, 1, 0},
 111        {REPLAY_WIN_32, ESN_ENABLED, 0, DATA_100_BYTES, BURST_SIZE,
 112                REORDER_PKTS},
 113        {REPLAY_WIN_64, ESN_ENABLED, 0, DATA_64_BYTES, 1, 0},
 114        {REPLAY_WIN_128, ESN_ENABLED, RTE_IPSEC_SAFLAG_SQN_ATOM,
 115                DATA_80_BYTES, 1, 0},
 116        {REPLAY_WIN_256, ESN_DISABLED, 0, DATA_100_BYTES, 1, 0},
 117};
 118
 119static const int num_cfg = RTE_DIM(test_cfg);
 120static struct ipsec_testsuite_params testsuite_params = { NULL };
 121static struct ipsec_unitest_params unittest_params;
 122static struct user_params uparams;
 123
 124struct supported_cipher_algo {
 125        const char *keyword;
 126        enum rte_crypto_cipher_algorithm algo;
 127        uint16_t iv_len;
 128        uint16_t block_size;
 129        uint16_t key_len;
 130};
 131
 132struct supported_auth_algo {
 133        const char *keyword;
 134        enum rte_crypto_auth_algorithm algo;
 135        uint16_t digest_len;
 136        uint16_t key_len;
 137        uint8_t key_not_req;
 138};
 139
 140const struct supported_cipher_algo cipher_algos[] = {
 141        {
 142                .keyword = "null",
 143                .algo = RTE_CRYPTO_CIPHER_NULL,
 144                .iv_len = 0,
 145                .block_size = 4,
 146                .key_len = 0
 147        },
 148};
 149
 150const struct supported_auth_algo auth_algos[] = {
 151        {
 152                .keyword = "null",
 153                .algo = RTE_CRYPTO_AUTH_NULL,
 154                .digest_len = 0,
 155                .key_len = 0,
 156                .key_not_req = 1
 157        },
 158};
 159
 160static int
 161dummy_sec_create(void *device, struct rte_security_session_conf *conf,
 162        struct rte_security_session *sess, struct rte_mempool *mp)
 163{
 164        RTE_SET_USED(device);
 165        RTE_SET_USED(conf);
 166        RTE_SET_USED(mp);
 167
 168        sess->sess_private_data = NULL;
 169        return 0;
 170}
 171
 172static int
 173dummy_sec_destroy(void *device, struct rte_security_session *sess)
 174{
 175        RTE_SET_USED(device);
 176        RTE_SET_USED(sess);
 177        return 0;
 178}
 179
 180static const struct rte_security_ops dummy_sec_ops = {
 181        .session_create = dummy_sec_create,
 182        .session_destroy = dummy_sec_destroy,
 183};
 184
 185static struct rte_security_ctx dummy_sec_ctx = {
 186        .ops = &dummy_sec_ops,
 187};
 188
 189static const struct supported_cipher_algo *
 190find_match_cipher_algo(const char *cipher_keyword)
 191{
 192        size_t i;
 193
 194        for (i = 0; i < RTE_DIM(cipher_algos); i++) {
 195                const struct supported_cipher_algo *algo =
 196                        &cipher_algos[i];
 197
 198                if (strcmp(cipher_keyword, algo->keyword) == 0)
 199                        return algo;
 200        }
 201
 202        return NULL;
 203}
 204
 205static const struct supported_auth_algo *
 206find_match_auth_algo(const char *auth_keyword)
 207{
 208        size_t i;
 209
 210        for (i = 0; i < RTE_DIM(auth_algos); i++) {
 211                const struct supported_auth_algo *algo =
 212                        &auth_algos[i];
 213
 214                if (strcmp(auth_keyword, algo->keyword) == 0)
 215                        return algo;
 216        }
 217
 218        return NULL;
 219}
 220
 221static void
 222fill_crypto_xform(struct ipsec_unitest_params *ut_params,
 223        const struct supported_auth_algo *auth_algo,
 224        const struct supported_cipher_algo *cipher_algo)
 225{
 226        ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
 227        ut_params->cipher_xform.cipher.algo = cipher_algo->algo;
 228        ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
 229        ut_params->auth_xform.auth.algo = auth_algo->algo;
 230
 231        if (ut_params->ipsec_xform.direction ==
 232                        RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
 233                ut_params->cipher_xform.cipher.op =
 234                        RTE_CRYPTO_CIPHER_OP_DECRYPT;
 235                ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
 236                ut_params->cipher_xform.next = NULL;
 237                ut_params->auth_xform.next = &ut_params->cipher_xform;
 238                ut_params->crypto_xforms = &ut_params->auth_xform;
 239        } else {
 240                ut_params->cipher_xform.cipher.op =
 241                        RTE_CRYPTO_CIPHER_OP_ENCRYPT;
 242                ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
 243                ut_params->auth_xform.next = NULL;
 244                ut_params->cipher_xform.next = &ut_params->auth_xform;
 245                ut_params->crypto_xforms = &ut_params->cipher_xform;
 246        }
 247}
 248
 249static int
 250check_cryptodev_capability(const struct ipsec_unitest_params *ut,
 251                uint8_t dev_id)
 252{
 253        struct rte_cryptodev_sym_capability_idx cap_idx;
 254        const struct rte_cryptodev_symmetric_capability *cap;
 255        int rc = -1;
 256
 257        cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
 258        cap_idx.algo.auth = ut->auth_xform.auth.algo;
 259        cap = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
 260
 261        if (cap != NULL) {
 262                rc = rte_cryptodev_sym_capability_check_auth(cap,
 263                                ut->auth_xform.auth.key.length,
 264                                ut->auth_xform.auth.digest_length, 0);
 265                if (rc == 0) {
 266                        cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
 267                        cap_idx.algo.cipher = ut->cipher_xform.cipher.algo;
 268                        cap = rte_cryptodev_sym_capability_get(
 269                                        dev_id, &cap_idx);
 270                        if (cap != NULL)
 271                                rc = rte_cryptodev_sym_capability_check_cipher(
 272                                        cap,
 273                                        ut->cipher_xform.cipher.key.length,
 274                                        ut->cipher_xform.cipher.iv.length);
 275                }
 276        }
 277
 278        return rc;
 279}
 280
 281static int
 282testsuite_setup(void)
 283{
 284        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 285        struct ipsec_unitest_params *ut_params = &unittest_params;
 286        const struct supported_auth_algo *auth_algo;
 287        const struct supported_cipher_algo *cipher_algo;
 288        struct rte_cryptodev_info info;
 289        uint32_t i, nb_devs, dev_id;
 290        size_t sess_sz;
 291        int rc;
 292
 293        memset(ts_params, 0, sizeof(*ts_params));
 294        memset(ut_params, 0, sizeof(*ut_params));
 295        memset(&uparams, 0, sizeof(struct user_params));
 296
 297        uparams.auth = RTE_CRYPTO_SYM_XFORM_AUTH;
 298        uparams.cipher = RTE_CRYPTO_SYM_XFORM_CIPHER;
 299        uparams.aead = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED;
 300        strcpy(uparams.auth_algo, "null");
 301        strcpy(uparams.cipher_algo, "null");
 302
 303        auth_algo = find_match_auth_algo(uparams.auth_algo);
 304        cipher_algo = find_match_cipher_algo(uparams.cipher_algo);
 305        fill_crypto_xform(ut_params, auth_algo, cipher_algo);
 306
 307        nb_devs = rte_cryptodev_count();
 308        if (nb_devs < 1) {
 309                RTE_LOG(WARNING, USER1, "No crypto devices found?\n");
 310                return TEST_SKIPPED;
 311        }
 312
 313        /* Find first valid crypto device */
 314        for (i = 0; i < nb_devs; i++) {
 315                rc = check_cryptodev_capability(ut_params, i);
 316                if (rc == 0) {
 317                        ts_params->valid_dev = i;
 318                        ts_params->valid_dev_found = 1;
 319                        break;
 320                }
 321        }
 322
 323        if (ts_params->valid_dev_found == 0)
 324                return TEST_FAILED;
 325
 326        ts_params->mbuf_pool = rte_pktmbuf_pool_create(
 327                        "CRYPTO_MBUFPOOL",
 328                        NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
 329                        rte_socket_id());
 330        if (ts_params->mbuf_pool == NULL) {
 331                RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n");
 332                return TEST_FAILED;
 333        }
 334
 335        ts_params->cop_mpool = rte_crypto_op_pool_create(
 336                        "MBUF_CRYPTO_SYM_OP_POOL",
 337                        RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 338                        NUM_MBUFS, MBUF_CACHE_SIZE,
 339                        DEFAULT_NUM_XFORMS *
 340                        sizeof(struct rte_crypto_sym_xform) +
 341                        MAXIMUM_IV_LENGTH,
 342                        rte_socket_id());
 343        if (ts_params->cop_mpool == NULL) {
 344                RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
 345                return TEST_FAILED;
 346        }
 347
 348        /* Set up all the qps on the first of the valid devices found */
 349        dev_id = ts_params->valid_dev;
 350
 351        rte_cryptodev_info_get(dev_id, &info);
 352
 353        ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;
 354        ts_params->conf.socket_id = SOCKET_ID_ANY;
 355        ts_params->conf.ff_disable = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO;
 356
 357        sess_sz = rte_cryptodev_sym_get_private_session_size(dev_id);
 358        sess_sz = RTE_MAX(sess_sz, sizeof(struct rte_security_session));
 359
 360        /*
 361         * Create mempools for sessions
 362         */
 363        if (info.sym.max_nb_sessions != 0 &&
 364                        info.sym.max_nb_sessions < MAX_NB_SESSIONS) {
 365                RTE_LOG(ERR, USER1, "Device does not support "
 366                                "at least %u sessions\n",
 367                                MAX_NB_SESSIONS);
 368                return TEST_FAILED;
 369        }
 370
 371        ts_params->qp_conf.mp_session_private = rte_mempool_create(
 372                                "test_priv_sess_mp",
 373                                MAX_NB_SESSIONS,
 374                                sess_sz,
 375                                0, 0, NULL, NULL, NULL,
 376                                NULL, SOCKET_ID_ANY,
 377                                0);
 378
 379        TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session_private,
 380                        "private session mempool allocation failed");
 381
 382        ts_params->qp_conf.mp_session =
 383                rte_cryptodev_sym_session_pool_create("test_sess_mp",
 384                        MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY);
 385
 386        TEST_ASSERT_NOT_NULL(ts_params->qp_conf.mp_session,
 387                        "session mempool allocation failed");
 388
 389        TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id,
 390                        &ts_params->conf),
 391                        "Failed to configure cryptodev %u with %u qps",
 392                        dev_id, ts_params->conf.nb_queue_pairs);
 393
 394        ts_params->qp_conf.nb_descriptors = DEFAULT_NUM_OPS_INFLIGHT;
 395
 396        TEST_ASSERT_SUCCESS(rte_cryptodev_queue_pair_setup(
 397                dev_id, 0, &ts_params->qp_conf,
 398                rte_cryptodev_socket_id(dev_id)),
 399                "Failed to setup queue pair %u on cryptodev %u",
 400                0, dev_id);
 401
 402        return TEST_SUCCESS;
 403}
 404
 405static void
 406testsuite_teardown(void)
 407{
 408        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 409
 410        if (ts_params->mbuf_pool != NULL) {
 411                RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
 412                rte_mempool_avail_count(ts_params->mbuf_pool));
 413                rte_mempool_free(ts_params->mbuf_pool);
 414                ts_params->mbuf_pool = NULL;
 415        }
 416
 417        if (ts_params->cop_mpool != NULL) {
 418                RTE_LOG(DEBUG, USER1, "CRYPTO_OP_POOL count %u\n",
 419                rte_mempool_avail_count(ts_params->cop_mpool));
 420                rte_mempool_free(ts_params->cop_mpool);
 421                ts_params->cop_mpool = NULL;
 422        }
 423
 424        /* Free session mempools */
 425        if (ts_params->qp_conf.mp_session != NULL) {
 426                rte_mempool_free(ts_params->qp_conf.mp_session);
 427                ts_params->qp_conf.mp_session = NULL;
 428        }
 429
 430        if (ts_params->qp_conf.mp_session_private != NULL) {
 431                rte_mempool_free(ts_params->qp_conf.mp_session_private);
 432                ts_params->qp_conf.mp_session_private = NULL;
 433        }
 434}
 435
 436static int
 437ut_setup_ipsec(void)
 438{
 439        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 440        struct ipsec_unitest_params *ut_params = &unittest_params;
 441
 442        /* Clear unit test parameters before running test */
 443        memset(ut_params, 0, sizeof(*ut_params));
 444
 445        /* Reconfigure device to default parameters */
 446        ts_params->conf.socket_id = SOCKET_ID_ANY;
 447
 448        /* Start the device */
 449        TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_dev),
 450                        "Failed to start cryptodev %u",
 451                        ts_params->valid_dev);
 452
 453        return TEST_SUCCESS;
 454}
 455
 456static void
 457ut_teardown_ipsec(void)
 458{
 459        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 460        struct ipsec_unitest_params *ut_params = &unittest_params;
 461        int i;
 462
 463        for (i = 0; i < BURST_SIZE; i++) {
 464                /* free crypto operation structure */
 465                if (ut_params->cop[i]) {
 466                        rte_crypto_op_free(ut_params->cop[i]);
 467                        ut_params->cop[i] = NULL;
 468                }
 469
 470                /*
 471                 * free mbuf - both obuf and ibuf are usually the same,
 472                 * so check if they point at the same address is necessary,
 473                 * to avoid freeing the mbuf twice.
 474                 */
 475                if (ut_params->obuf[i]) {
 476                        rte_pktmbuf_free(ut_params->obuf[i]);
 477                        if (ut_params->ibuf[i] == ut_params->obuf[i])
 478                                ut_params->ibuf[i] = NULL;
 479                        ut_params->obuf[i] = NULL;
 480                }
 481                if (ut_params->ibuf[i]) {
 482                        rte_pktmbuf_free(ut_params->ibuf[i]);
 483                        ut_params->ibuf[i] = NULL;
 484                }
 485
 486                if (ut_params->testbuf[i]) {
 487                        rte_pktmbuf_free(ut_params->testbuf[i]);
 488                        ut_params->testbuf[i] = NULL;
 489                }
 490        }
 491
 492        if (ts_params->mbuf_pool != NULL)
 493                RTE_LOG(DEBUG, USER1, "CRYPTO_MBUFPOOL count %u\n",
 494                        rte_mempool_avail_count(ts_params->mbuf_pool));
 495
 496        /* Stop the device */
 497        rte_cryptodev_stop(ts_params->valid_dev);
 498}
 499
 500#define IPSEC_MAX_PAD_SIZE      UINT8_MAX
 501
 502static const uint8_t esp_pad_bytes[IPSEC_MAX_PAD_SIZE] = {
 503        1, 2, 3, 4, 5, 6, 7, 8,
 504        9, 10, 11, 12, 13, 14, 15, 16,
 505        17, 18, 19, 20, 21, 22, 23, 24,
 506        25, 26, 27, 28, 29, 30, 31, 32,
 507        33, 34, 35, 36, 37, 38, 39, 40,
 508        41, 42, 43, 44, 45, 46, 47, 48,
 509        49, 50, 51, 52, 53, 54, 55, 56,
 510        57, 58, 59, 60, 61, 62, 63, 64,
 511        65, 66, 67, 68, 69, 70, 71, 72,
 512        73, 74, 75, 76, 77, 78, 79, 80,
 513        81, 82, 83, 84, 85, 86, 87, 88,
 514        89, 90, 91, 92, 93, 94, 95, 96,
 515        97, 98, 99, 100, 101, 102, 103, 104,
 516        105, 106, 107, 108, 109, 110, 111, 112,
 517        113, 114, 115, 116, 117, 118, 119, 120,
 518        121, 122, 123, 124, 125, 126, 127, 128,
 519        129, 130, 131, 132, 133, 134, 135, 136,
 520        137, 138, 139, 140, 141, 142, 143, 144,
 521        145, 146, 147, 148, 149, 150, 151, 152,
 522        153, 154, 155, 156, 157, 158, 159, 160,
 523        161, 162, 163, 164, 165, 166, 167, 168,
 524        169, 170, 171, 172, 173, 174, 175, 176,
 525        177, 178, 179, 180, 181, 182, 183, 184,
 526        185, 186, 187, 188, 189, 190, 191, 192,
 527        193, 194, 195, 196, 197, 198, 199, 200,
 528        201, 202, 203, 204, 205, 206, 207, 208,
 529        209, 210, 211, 212, 213, 214, 215, 216,
 530        217, 218, 219, 220, 221, 222, 223, 224,
 531        225, 226, 227, 228, 229, 230, 231, 232,
 532        233, 234, 235, 236, 237, 238, 239, 240,
 533        241, 242, 243, 244, 245, 246, 247, 248,
 534        249, 250, 251, 252, 253, 254, 255,
 535};
 536
 537/* ***** data for tests ***** */
 538
 539const char null_plain_data[] =
 540        "Network Security People Have A Strange Sense Of Humor unlike Other "
 541        "People who have a normal sense of humour";
 542
 543const char null_encrypted_data[] =
 544        "Network Security People Have A Strange Sense Of Humor unlike Other "
 545        "People who have a normal sense of humour";
 546
 547struct rte_ipv4_hdr ipv4_outer  = {
 548        .version_ihl = IPVERSION << 4 |
 549                sizeof(ipv4_outer) / RTE_IPV4_IHL_MULTIPLIER,
 550        .time_to_live = IPDEFTTL,
 551        .next_proto_id = IPPROTO_ESP,
 552        .src_addr = RTE_IPV4(192, 168, 1, 100),
 553        .dst_addr = RTE_IPV4(192, 168, 2, 100),
 554};
 555
 556static struct rte_mbuf *
 557setup_test_string(struct rte_mempool *mpool, const char *string,
 558        size_t string_len, size_t len, uint8_t blocksize)
 559{
 560        struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
 561        size_t t_len = len - (blocksize ? (len % blocksize) : 0);
 562
 563        RTE_VERIFY(len <= string_len);
 564
 565        if (m) {
 566                memset(m->buf_addr, 0, m->buf_len);
 567                char *dst = rte_pktmbuf_append(m, t_len);
 568
 569                if (!dst) {
 570                        rte_pktmbuf_free(m);
 571                        return NULL;
 572                }
 573                if (string != NULL)
 574                        rte_memcpy(dst, string, t_len);
 575                else
 576                        memset(dst, 0, t_len);
 577        }
 578
 579        return m;
 580}
 581
 582static struct rte_mbuf *
 583setup_test_string_tunneled(struct rte_mempool *mpool, const char *string,
 584        size_t len, uint32_t spi, uint32_t seq)
 585{
 586        struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
 587        uint32_t hdrlen = sizeof(struct rte_ipv4_hdr) +
 588                sizeof(struct rte_esp_hdr);
 589        uint32_t taillen = sizeof(struct rte_esp_tail);
 590        uint32_t t_len = len + hdrlen + taillen;
 591        uint32_t padlen;
 592
 593        struct rte_esp_hdr esph  = {
 594                .spi = rte_cpu_to_be_32(spi),
 595                .seq = rte_cpu_to_be_32(seq)
 596        };
 597
 598        padlen = RTE_ALIGN(t_len, 4) - t_len;
 599        t_len += padlen;
 600
 601        struct rte_esp_tail espt = {
 602                .pad_len = padlen,
 603                .next_proto = IPPROTO_IPIP,
 604        };
 605
 606        if (m == NULL)
 607                return NULL;
 608
 609        memset(m->buf_addr, 0, m->buf_len);
 610        char *dst = rte_pktmbuf_append(m, t_len);
 611
 612        if (!dst) {
 613                rte_pktmbuf_free(m);
 614                return NULL;
 615        }
 616        /* copy outer IP and ESP header */
 617        ipv4_outer.total_length = rte_cpu_to_be_16(t_len);
 618        ipv4_outer.packet_id = rte_cpu_to_be_16(seq);
 619        rte_memcpy(dst, &ipv4_outer, sizeof(ipv4_outer));
 620        dst += sizeof(ipv4_outer);
 621        m->l3_len = sizeof(ipv4_outer);
 622        rte_memcpy(dst, &esph, sizeof(esph));
 623        dst += sizeof(esph);
 624
 625        if (string != NULL) {
 626                /* copy payload */
 627                rte_memcpy(dst, string, len);
 628                dst += len;
 629                /* copy pad bytes */
 630                rte_memcpy(dst, esp_pad_bytes, padlen);
 631                dst += padlen;
 632                /* copy ESP tail header */
 633                rte_memcpy(dst, &espt, sizeof(espt));
 634        } else
 635                memset(dst, 0, t_len);
 636
 637        return m;
 638}
 639
 640static int
 641create_dummy_sec_session(struct ipsec_unitest_params *ut,
 642        struct rte_cryptodev_qp_conf *qp, uint32_t j)
 643{
 644        static struct rte_security_session_conf conf;
 645
 646        ut->ss[j].security.ses = rte_security_session_create(&dummy_sec_ctx,
 647                                        &conf, qp->mp_session,
 648                                        qp->mp_session_private);
 649
 650        if (ut->ss[j].security.ses == NULL)
 651                return -ENOMEM;
 652
 653        ut->ss[j].security.ctx = &dummy_sec_ctx;
 654        ut->ss[j].security.ol_flags = 0;
 655        return 0;
 656}
 657
 658static int
 659create_crypto_session(struct ipsec_unitest_params *ut,
 660        struct rte_cryptodev_qp_conf *qp, uint8_t dev_id, uint32_t j)
 661{
 662        int32_t rc;
 663        struct rte_cryptodev_sym_session *s;
 664
 665        s = rte_cryptodev_sym_session_create(qp->mp_session);
 666        if (s == NULL)
 667                return -ENOMEM;
 668
 669        /* initialize SA crypto session for device */
 670        rc = rte_cryptodev_sym_session_init(dev_id, s,
 671                        ut->crypto_xforms, qp->mp_session_private);
 672        if (rc == 0) {
 673                ut->ss[j].crypto.ses = s;
 674                return 0;
 675        } else {
 676                /* failure, do cleanup */
 677                rte_cryptodev_sym_session_clear(dev_id, s);
 678                rte_cryptodev_sym_session_free(s);
 679                return rc;
 680        }
 681}
 682
 683static int
 684create_session(struct ipsec_unitest_params *ut,
 685        struct rte_cryptodev_qp_conf *qp, uint8_t crypto_dev, uint32_t j)
 686{
 687        if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE)
 688                return create_crypto_session(ut, qp, crypto_dev, j);
 689        else
 690                return create_dummy_sec_session(ut, qp, j);
 691}
 692
 693static int
 694fill_ipsec_param(uint32_t replay_win_sz, uint64_t flags)
 695{
 696        struct ipsec_unitest_params *ut_params = &unittest_params;
 697        struct rte_ipsec_sa_prm *prm = &ut_params->sa_prm;
 698        const struct supported_auth_algo *auth_algo;
 699        const struct supported_cipher_algo *cipher_algo;
 700
 701        memset(prm, 0, sizeof(*prm));
 702
 703        prm->userdata = 1;
 704        prm->flags = flags;
 705
 706        /* setup ipsec xform */
 707        prm->ipsec_xform = ut_params->ipsec_xform;
 708        prm->ipsec_xform.salt = (uint32_t)rte_rand();
 709        prm->ipsec_xform.replay_win_sz = replay_win_sz;
 710
 711        /* setup tunnel related fields */
 712        prm->tun.hdr_len = sizeof(ipv4_outer);
 713        prm->tun.next_proto = IPPROTO_IPIP;
 714        prm->tun.hdr = &ipv4_outer;
 715
 716        /* setup crypto section */
 717        if (uparams.aead != 0) {
 718                /* TODO: will need to fill out with other test cases */
 719        } else {
 720                if (uparams.auth == 0 && uparams.cipher == 0)
 721                        return TEST_FAILED;
 722
 723                auth_algo = find_match_auth_algo(uparams.auth_algo);
 724                cipher_algo = find_match_cipher_algo(uparams.cipher_algo);
 725
 726                fill_crypto_xform(ut_params, auth_algo, cipher_algo);
 727        }
 728
 729        prm->crypto_xform = ut_params->crypto_xforms;
 730        return TEST_SUCCESS;
 731}
 732
 733static int
 734create_sa(enum rte_security_session_action_type action_type,
 735                uint32_t replay_win_sz, uint64_t flags, uint32_t j)
 736{
 737        struct ipsec_testsuite_params *ts = &testsuite_params;
 738        struct ipsec_unitest_params *ut = &unittest_params;
 739        size_t sz;
 740        int rc;
 741
 742        memset(&ut->ss[j], 0, sizeof(ut->ss[j]));
 743
 744        rc = fill_ipsec_param(replay_win_sz, flags);
 745        if (rc != 0)
 746                return TEST_FAILED;
 747
 748        /* create rte_ipsec_sa*/
 749        sz = rte_ipsec_sa_size(&ut->sa_prm);
 750        TEST_ASSERT(sz > 0, "rte_ipsec_sa_size() failed\n");
 751
 752        ut->ss[j].sa = rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
 753        TEST_ASSERT_NOT_NULL(ut->ss[j].sa,
 754                "failed to allocate memory for rte_ipsec_sa\n");
 755
 756        ut->ss[j].type = action_type;
 757        rc = create_session(ut, &ts->qp_conf, ts->valid_dev, j);
 758        if (rc != 0)
 759                return rc;
 760
 761        rc = rte_ipsec_sa_init(ut->ss[j].sa, &ut->sa_prm, sz);
 762        rc = (rc > 0 && (uint32_t)rc <= sz) ? 0 : -EINVAL;
 763        if (rc == 0)
 764                rc = rte_ipsec_session_prepare(&ut->ss[j]);
 765
 766        return rc;
 767}
 768
 769static int
 770crypto_dequeue_burst(uint16_t num_pkts)
 771{
 772        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 773        struct ipsec_unitest_params *ut_params = &unittest_params;
 774        uint32_t pkt_cnt, k;
 775        int i;
 776
 777        for (i = 0, pkt_cnt = 0;
 778                i < DEQUEUE_COUNT && pkt_cnt != num_pkts; i++) {
 779                k = rte_cryptodev_dequeue_burst(ts_params->valid_dev, 0,
 780                        &ut_params->cop[pkt_cnt], num_pkts - pkt_cnt);
 781                pkt_cnt += k;
 782                rte_delay_us(1);
 783        }
 784
 785        if (pkt_cnt != num_pkts) {
 786                RTE_LOG(ERR, USER1, "rte_cryptodev_dequeue_burst fail\n");
 787                return TEST_FAILED;
 788        }
 789        return TEST_SUCCESS;
 790}
 791
 792static int
 793crypto_ipsec(uint16_t num_pkts)
 794{
 795        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 796        struct ipsec_unitest_params *ut_params = &unittest_params;
 797        uint32_t k, ng;
 798        struct rte_ipsec_group grp[1];
 799
 800        /* call crypto prepare */
 801        k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf,
 802                ut_params->cop, num_pkts);
 803        if (k != num_pkts) {
 804                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
 805                return TEST_FAILED;
 806        }
 807
 808        k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
 809                ut_params->cop, num_pkts);
 810        if (k != num_pkts) {
 811                RTE_LOG(ERR, USER1, "rte_cryptodev_enqueue_burst fail\n");
 812                return TEST_FAILED;
 813        }
 814
 815        if (crypto_dequeue_burst(num_pkts) == TEST_FAILED)
 816                return TEST_FAILED;
 817
 818        ng = rte_ipsec_pkt_crypto_group(
 819                (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
 820                ut_params->obuf, grp, num_pkts);
 821        if (ng != 1 ||
 822                grp[0].m[0] != ut_params->obuf[0] ||
 823                grp[0].cnt != num_pkts ||
 824                grp[0].id.ptr != &ut_params->ss[0]) {
 825                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n");
 826                return TEST_FAILED;
 827        }
 828
 829        /* call crypto process */
 830        k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt);
 831        if (k != num_pkts) {
 832                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
 833                return TEST_FAILED;
 834        }
 835
 836        return TEST_SUCCESS;
 837}
 838
 839static int
 840lksd_proto_ipsec(uint16_t num_pkts)
 841{
 842        struct ipsec_unitest_params *ut_params = &unittest_params;
 843        uint32_t i, k, ng;
 844        struct rte_ipsec_group grp[1];
 845
 846        /* call crypto prepare */
 847        k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[0], ut_params->ibuf,
 848                ut_params->cop, num_pkts);
 849        if (k != num_pkts) {
 850                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_prepare fail\n");
 851                return TEST_FAILED;
 852        }
 853
 854        /* check crypto ops */
 855        for (i = 0; i != num_pkts; i++) {
 856                TEST_ASSERT_EQUAL(ut_params->cop[i]->type,
 857                        RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 858                        "%s: invalid crypto op type for %u-th packet\n",
 859                        __func__, i);
 860                TEST_ASSERT_EQUAL(ut_params->cop[i]->status,
 861                        RTE_CRYPTO_OP_STATUS_NOT_PROCESSED,
 862                        "%s: invalid crypto op status for %u-th packet\n",
 863                        __func__, i);
 864                TEST_ASSERT_EQUAL(ut_params->cop[i]->sess_type,
 865                        RTE_CRYPTO_OP_SECURITY_SESSION,
 866                        "%s: invalid crypto op sess_type for %u-th packet\n",
 867                        __func__, i);
 868                TEST_ASSERT_EQUAL(ut_params->cop[i]->sym->m_src,
 869                        ut_params->ibuf[i],
 870                        "%s: invalid crypto op m_src for %u-th packet\n",
 871                        __func__, i);
 872        }
 873
 874        /* update crypto ops, pretend all finished ok */
 875        for (i = 0; i != num_pkts; i++)
 876                ut_params->cop[i]->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
 877
 878        ng = rte_ipsec_pkt_crypto_group(
 879                (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
 880                ut_params->obuf, grp, num_pkts);
 881        if (ng != 1 ||
 882                grp[0].m[0] != ut_params->obuf[0] ||
 883                grp[0].cnt != num_pkts ||
 884                grp[0].id.ptr != &ut_params->ss[0]) {
 885                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail\n");
 886                return TEST_FAILED;
 887        }
 888
 889        /* call crypto process */
 890        k = rte_ipsec_pkt_process(grp[0].id.ptr, grp[0].m, grp[0].cnt);
 891        if (k != num_pkts) {
 892                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_process fail\n");
 893                return TEST_FAILED;
 894        }
 895
 896        return TEST_SUCCESS;
 897}
 898
 899static void
 900dump_grp_pkt(uint32_t i, struct rte_ipsec_group *grp, uint32_t k)
 901{
 902        RTE_LOG(ERR, USER1,
 903                "After rte_ipsec_pkt_process grp[%d].cnt=%d k=%d fail\n",
 904                i, grp[i].cnt, k);
 905        RTE_LOG(ERR, USER1,
 906                "After rte_ipsec_pkt_process grp[%d].m=%p grp[%d].m[%d]=%p\n",
 907                i, grp[i].m, i, k, grp[i].m[k]);
 908
 909        rte_pktmbuf_dump(stdout, grp[i].m[k], grp[i].m[k]->data_len);
 910}
 911
 912static int
 913crypto_ipsec_2sa(void)
 914{
 915        struct ipsec_testsuite_params *ts_params = &testsuite_params;
 916        struct ipsec_unitest_params *ut_params = &unittest_params;
 917        struct rte_ipsec_group grp[BURST_SIZE];
 918        uint32_t k, ng, i, r;
 919
 920        for (i = 0; i < BURST_SIZE; i++) {
 921                r = i % 2;
 922                /* call crypto prepare */
 923                k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[r],
 924                                ut_params->ibuf + i, ut_params->cop + i, 1);
 925                if (k != 1) {
 926                        RTE_LOG(ERR, USER1,
 927                                "rte_ipsec_pkt_crypto_prepare fail\n");
 928                        return TEST_FAILED;
 929                }
 930                k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
 931                                ut_params->cop + i, 1);
 932                if (k != 1) {
 933                        RTE_LOG(ERR, USER1,
 934                                "rte_cryptodev_enqueue_burst fail\n");
 935                        return TEST_FAILED;
 936                }
 937        }
 938
 939        if (crypto_dequeue_burst(BURST_SIZE) == TEST_FAILED)
 940                return TEST_FAILED;
 941
 942        ng = rte_ipsec_pkt_crypto_group(
 943                (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
 944                ut_params->obuf, grp, BURST_SIZE);
 945        if (ng != BURST_SIZE) {
 946                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n",
 947                        ng);
 948                return TEST_FAILED;
 949        }
 950
 951        /* call crypto process */
 952        for (i = 0; i < ng; i++) {
 953                k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt);
 954                if (k != grp[i].cnt) {
 955                        dump_grp_pkt(i, grp, k);
 956                        return TEST_FAILED;
 957                }
 958        }
 959        return TEST_SUCCESS;
 960}
 961
 962#define PKT_4   4
 963#define PKT_12  12
 964#define PKT_21  21
 965
 966static uint32_t
 967crypto_ipsec_4grp(uint32_t pkt_num)
 968{
 969        uint32_t sa_ind;
 970
 971        /* group packets in 4 different size groups groups, 2 per SA */
 972        if (pkt_num < PKT_4)
 973                sa_ind = 0;
 974        else if (pkt_num < PKT_12)
 975                sa_ind = 1;
 976        else if (pkt_num < PKT_21)
 977                sa_ind = 0;
 978        else
 979                sa_ind = 1;
 980
 981        return sa_ind;
 982}
 983
 984static uint32_t
 985crypto_ipsec_4grp_check_mbufs(uint32_t grp_ind, struct rte_ipsec_group *grp)
 986{
 987        struct ipsec_unitest_params *ut_params = &unittest_params;
 988        uint32_t i, j;
 989        uint32_t rc = 0;
 990
 991        if (grp_ind == 0) {
 992                for (i = 0, j = 0; i < PKT_4; i++, j++)
 993                        if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
 994                                rc = TEST_FAILED;
 995                                break;
 996                        }
 997        } else if (grp_ind == 1) {
 998                for (i = 0, j = PKT_4; i < (PKT_12 - PKT_4); i++, j++) {
 999                        if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
1000                                rc = TEST_FAILED;
1001                                break;
1002                        }
1003                }
1004        } else if (grp_ind == 2) {
1005                for (i = 0, j =  PKT_12; i < (PKT_21 - PKT_12); i++, j++)
1006                        if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
1007                                rc = TEST_FAILED;
1008                                break;
1009                        }
1010        } else if (grp_ind == 3) {
1011                for (i = 0, j = PKT_21; i < (BURST_SIZE - PKT_21); i++, j++)
1012                        if (grp[grp_ind].m[i] != ut_params->obuf[j]) {
1013                                rc = TEST_FAILED;
1014                                break;
1015                        }
1016        } else
1017                rc = TEST_FAILED;
1018
1019        return rc;
1020}
1021
1022static uint32_t
1023crypto_ipsec_4grp_check_cnt(uint32_t grp_ind, struct rte_ipsec_group *grp)
1024{
1025        uint32_t rc = 0;
1026
1027        if (grp_ind == 0) {
1028                if (grp[grp_ind].cnt != PKT_4)
1029                        rc = TEST_FAILED;
1030        } else if (grp_ind == 1) {
1031                if (grp[grp_ind].cnt != PKT_12 - PKT_4)
1032                        rc = TEST_FAILED;
1033        } else if (grp_ind == 2) {
1034                if (grp[grp_ind].cnt != PKT_21 - PKT_12)
1035                        rc = TEST_FAILED;
1036        } else if (grp_ind == 3) {
1037                if (grp[grp_ind].cnt != BURST_SIZE - PKT_21)
1038                        rc = TEST_FAILED;
1039        } else
1040                rc = TEST_FAILED;
1041
1042        return rc;
1043}
1044
1045static int
1046crypto_ipsec_2sa_4grp(void)
1047{
1048        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1049        struct ipsec_unitest_params *ut_params = &unittest_params;
1050        struct rte_ipsec_group grp[BURST_SIZE];
1051        uint32_t k, ng, i, j;
1052        uint32_t rc = 0;
1053
1054        for (i = 0; i < BURST_SIZE; i++) {
1055                j = crypto_ipsec_4grp(i);
1056
1057                /* call crypto prepare */
1058                k = rte_ipsec_pkt_crypto_prepare(&ut_params->ss[j],
1059                                ut_params->ibuf + i, ut_params->cop + i, 1);
1060                if (k != 1) {
1061                        RTE_LOG(ERR, USER1,
1062                                "rte_ipsec_pkt_crypto_prepare fail\n");
1063                        return TEST_FAILED;
1064                }
1065                k = rte_cryptodev_enqueue_burst(ts_params->valid_dev, 0,
1066                                ut_params->cop + i, 1);
1067                if (k != 1) {
1068                        RTE_LOG(ERR, USER1,
1069                                "rte_cryptodev_enqueue_burst fail\n");
1070                        return TEST_FAILED;
1071                }
1072        }
1073
1074        if (crypto_dequeue_burst(BURST_SIZE) == TEST_FAILED)
1075                return TEST_FAILED;
1076
1077        ng = rte_ipsec_pkt_crypto_group(
1078                (const struct rte_crypto_op **)(uintptr_t)ut_params->cop,
1079                ut_params->obuf, grp, BURST_SIZE);
1080        if (ng != 4) {
1081                RTE_LOG(ERR, USER1, "rte_ipsec_pkt_crypto_group fail ng=%d\n",
1082                        ng);
1083                return TEST_FAILED;
1084        }
1085
1086        /* call crypto process */
1087        for (i = 0; i < ng; i++) {
1088                k = rte_ipsec_pkt_process(grp[i].id.ptr, grp[i].m, grp[i].cnt);
1089                if (k != grp[i].cnt) {
1090                        dump_grp_pkt(i, grp, k);
1091                        return TEST_FAILED;
1092                }
1093                rc = crypto_ipsec_4grp_check_cnt(i, grp);
1094                if (rc != 0) {
1095                        RTE_LOG(ERR, USER1,
1096                                "crypto_ipsec_4grp_check_cnt fail\n");
1097                        return TEST_FAILED;
1098                }
1099                rc = crypto_ipsec_4grp_check_mbufs(i, grp);
1100                if (rc != 0) {
1101                        RTE_LOG(ERR, USER1,
1102                                "crypto_ipsec_4grp_check_mbufs fail\n");
1103                        return TEST_FAILED;
1104                }
1105        }
1106        return TEST_SUCCESS;
1107}
1108
1109static void
1110test_ipsec_reorder_inb_pkt_burst(uint16_t num_pkts)
1111{
1112        struct ipsec_unitest_params *ut_params = &unittest_params;
1113        struct rte_mbuf *ibuf_tmp[BURST_SIZE];
1114        uint16_t j;
1115
1116        /* reorder packets and create gaps in sequence numbers */
1117        static const uint32_t reorder[BURST_SIZE] = {
1118                        24, 25, 26, 27, 28, 29, 30, 31,
1119                        16, 17, 18, 19, 20, 21, 22, 23,
1120                        8, 9, 10, 11, 12, 13, 14, 15,
1121                        0, 1, 2, 3, 4, 5, 6, 7,
1122        };
1123
1124        if (num_pkts != BURST_SIZE)
1125                return;
1126
1127        for (j = 0; j != BURST_SIZE; j++)
1128                ibuf_tmp[j] = ut_params->ibuf[reorder[j]];
1129
1130        memcpy(ut_params->ibuf, ibuf_tmp, sizeof(ut_params->ibuf));
1131}
1132
1133static int
1134test_ipsec_crypto_op_alloc(uint16_t num_pkts)
1135{
1136        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1137        struct ipsec_unitest_params *ut_params = &unittest_params;
1138        int rc = 0;
1139        uint16_t j;
1140
1141        for (j = 0; j < num_pkts && rc == 0; j++) {
1142                ut_params->cop[j] = rte_crypto_op_alloc(ts_params->cop_mpool,
1143                                RTE_CRYPTO_OP_TYPE_SYMMETRIC);
1144                if (ut_params->cop[j] == NULL) {
1145                        RTE_LOG(ERR, USER1,
1146                                "Failed to allocate symmetric crypto op\n");
1147                        rc = TEST_FAILED;
1148                }
1149        }
1150
1151        return rc;
1152}
1153
1154static void
1155test_ipsec_dump_buffers(struct ipsec_unitest_params *ut_params, int i)
1156{
1157        uint16_t j = ut_params->pkt_index;
1158
1159        printf("\ntest config: num %d\n", i);
1160        printf("        replay_win_sz %u\n", test_cfg[i].replay_win_sz);
1161        printf("        esn %u\n", test_cfg[i].esn);
1162        printf("        flags 0x%" PRIx64 "\n", test_cfg[i].flags);
1163        printf("        pkt_sz %zu\n", test_cfg[i].pkt_sz);
1164        printf("        num_pkts %u\n\n", test_cfg[i].num_pkts);
1165
1166        if (ut_params->ibuf[j]) {
1167                printf("ibuf[%u] data:\n", j);
1168                rte_pktmbuf_dump(stdout, ut_params->ibuf[j],
1169                        ut_params->ibuf[j]->data_len);
1170        }
1171        if (ut_params->obuf[j]) {
1172                printf("obuf[%u] data:\n", j);
1173                rte_pktmbuf_dump(stdout, ut_params->obuf[j],
1174                        ut_params->obuf[j]->data_len);
1175        }
1176        if (ut_params->testbuf[j]) {
1177                printf("testbuf[%u] data:\n", j);
1178                rte_pktmbuf_dump(stdout, ut_params->testbuf[j],
1179                        ut_params->testbuf[j]->data_len);
1180        }
1181}
1182
1183static void
1184destroy_dummy_sec_session(struct ipsec_unitest_params *ut,
1185        uint32_t j)
1186{
1187        rte_security_session_destroy(&dummy_sec_ctx,
1188                                        ut->ss[j].security.ses);
1189        ut->ss[j].security.ctx = NULL;
1190}
1191
1192static void
1193destroy_crypto_session(struct ipsec_unitest_params *ut,
1194        uint8_t crypto_dev, uint32_t j)
1195{
1196        rte_cryptodev_sym_session_clear(crypto_dev, ut->ss[j].crypto.ses);
1197        rte_cryptodev_sym_session_free(ut->ss[j].crypto.ses);
1198        memset(&ut->ss[j], 0, sizeof(ut->ss[j]));
1199}
1200
1201static void
1202destroy_session(struct ipsec_unitest_params *ut,
1203        uint8_t crypto_dev, uint32_t j)
1204{
1205        if (ut->ss[j].type == RTE_SECURITY_ACTION_TYPE_NONE)
1206                return destroy_crypto_session(ut, crypto_dev, j);
1207        else
1208                return destroy_dummy_sec_session(ut, j);
1209}
1210
1211static void
1212destroy_sa(uint32_t j)
1213{
1214        struct ipsec_unitest_params *ut = &unittest_params;
1215        struct ipsec_testsuite_params *ts = &testsuite_params;
1216
1217        rte_ipsec_sa_fini(ut->ss[j].sa);
1218        rte_free(ut->ss[j].sa);
1219
1220        destroy_session(ut, ts->valid_dev, j);
1221}
1222
1223static int
1224crypto_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1225                uint16_t num_pkts)
1226{
1227        uint16_t j;
1228
1229        for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1230                ut_params->pkt_index = j;
1231
1232                /* compare the data buffers */
1233                TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
1234                        rte_pktmbuf_mtod(ut_params->obuf[j], void *),
1235                        test_cfg[i].pkt_sz,
1236                        "input and output data does not match\n");
1237                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1238                        ut_params->obuf[j]->pkt_len,
1239                        "data_len is not equal to pkt_len");
1240                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1241                        test_cfg[i].pkt_sz,
1242                        "data_len is not equal to input data");
1243        }
1244
1245        return 0;
1246}
1247
1248static int
1249test_ipsec_crypto_inb_burst_null_null(int i)
1250{
1251        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1252        struct ipsec_unitest_params *ut_params = &unittest_params;
1253        uint16_t num_pkts = test_cfg[i].num_pkts;
1254        uint16_t j;
1255        int rc;
1256
1257        /* create rte_ipsec_sa */
1258        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1259                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1260        if (rc != 0) {
1261                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1262                return rc;
1263        }
1264
1265        /* Generate test mbuf data */
1266        for (j = 0; j < num_pkts && rc == 0; j++) {
1267                /* packet with sequence number 0 is invalid */
1268                ut_params->ibuf[j] = setup_test_string_tunneled(
1269                        ts_params->mbuf_pool, null_encrypted_data,
1270                        test_cfg[i].pkt_sz, INBOUND_SPI, j + 1);
1271                if (ut_params->ibuf[j] == NULL)
1272                        rc = TEST_FAILED;
1273        }
1274
1275        if (rc == 0) {
1276                if (test_cfg[i].reorder_pkts)
1277                        test_ipsec_reorder_inb_pkt_burst(num_pkts);
1278                rc = test_ipsec_crypto_op_alloc(num_pkts);
1279        }
1280
1281        if (rc == 0) {
1282                /* call ipsec library api */
1283                rc = crypto_ipsec(num_pkts);
1284                if (rc == 0)
1285                        rc = crypto_inb_burst_null_null_check(
1286                                        ut_params, i, num_pkts);
1287                else {
1288                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1289                                i);
1290                        rc = TEST_FAILED;
1291                }
1292        }
1293
1294        if (rc == TEST_FAILED)
1295                test_ipsec_dump_buffers(ut_params, i);
1296
1297        destroy_sa(0);
1298        return rc;
1299}
1300
1301static int
1302test_ipsec_crypto_inb_burst_null_null_wrapper(void)
1303{
1304        int i;
1305        int rc = 0;
1306        struct ipsec_unitest_params *ut_params = &unittest_params;
1307
1308        ut_params->ipsec_xform.spi = INBOUND_SPI;
1309        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1310        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1311        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1312        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1313
1314        for (i = 0; i < num_cfg && rc == 0; i++) {
1315                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1316                rc = test_ipsec_crypto_inb_burst_null_null(i);
1317        }
1318
1319        return rc;
1320}
1321
1322static int
1323crypto_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params,
1324        uint16_t num_pkts)
1325{
1326        void *obuf_data;
1327        void *testbuf_data;
1328        uint16_t j;
1329
1330        for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1331                ut_params->pkt_index = j;
1332
1333                testbuf_data = rte_pktmbuf_mtod(ut_params->testbuf[j], void *);
1334                obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1335                /* compare the buffer data */
1336                TEST_ASSERT_BUFFERS_ARE_EQUAL(testbuf_data, obuf_data,
1337                        ut_params->obuf[j]->pkt_len,
1338                        "test and output data does not match\n");
1339                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1340                        ut_params->testbuf[j]->data_len,
1341                        "obuf data_len is not equal to testbuf data_len");
1342                TEST_ASSERT_EQUAL(ut_params->obuf[j]->pkt_len,
1343                        ut_params->testbuf[j]->pkt_len,
1344                        "obuf pkt_len is not equal to testbuf pkt_len");
1345        }
1346
1347        return 0;
1348}
1349
1350static int
1351test_ipsec_crypto_outb_burst_null_null(int i)
1352{
1353        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1354        struct ipsec_unitest_params *ut_params = &unittest_params;
1355        uint16_t num_pkts = test_cfg[i].num_pkts;
1356        uint16_t j;
1357        int32_t rc;
1358
1359        /* create rte_ipsec_sa*/
1360        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1361                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1362        if (rc != 0) {
1363                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1364                return rc;
1365        }
1366
1367        /* Generate input mbuf data */
1368        for (j = 0; j < num_pkts && rc == 0; j++) {
1369                ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1370                        null_plain_data, sizeof(null_plain_data),
1371                        test_cfg[i].pkt_sz, 0);
1372                if (ut_params->ibuf[j] == NULL)
1373                        rc = TEST_FAILED;
1374                else {
1375                        /* Generate test mbuf data */
1376                        /* packet with sequence number 0 is invalid */
1377                        ut_params->testbuf[j] = setup_test_string_tunneled(
1378                                        ts_params->mbuf_pool,
1379                                        null_plain_data, test_cfg[i].pkt_sz,
1380                                        OUTBOUND_SPI, j + 1);
1381                        if (ut_params->testbuf[j] == NULL)
1382                                rc = TEST_FAILED;
1383                }
1384        }
1385
1386        if (rc == 0)
1387                rc = test_ipsec_crypto_op_alloc(num_pkts);
1388
1389        if (rc == 0) {
1390                /* call ipsec library api */
1391                rc = crypto_ipsec(num_pkts);
1392                if (rc == 0)
1393                        rc = crypto_outb_burst_null_null_check(ut_params,
1394                                        num_pkts);
1395                else
1396                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1397                                i);
1398        }
1399
1400        if (rc == TEST_FAILED)
1401                test_ipsec_dump_buffers(ut_params, i);
1402
1403        destroy_sa(0);
1404        return rc;
1405}
1406
1407static int
1408test_ipsec_crypto_outb_burst_null_null_wrapper(void)
1409{
1410        int i;
1411        int rc = 0;
1412        struct ipsec_unitest_params *ut_params = &unittest_params;
1413
1414        ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1415        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1416        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1417        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1418        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1419
1420        for (i = 0; i < num_cfg && rc == 0; i++) {
1421                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1422                rc = test_ipsec_crypto_outb_burst_null_null(i);
1423        }
1424
1425        return rc;
1426}
1427
1428static int
1429inline_inb_burst_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1430        uint16_t num_pkts)
1431{
1432        void *ibuf_data;
1433        void *obuf_data;
1434        uint16_t j;
1435
1436        for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1437                ut_params->pkt_index = j;
1438
1439                /* compare the buffer data */
1440                ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *);
1441                obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1442
1443                TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
1444                        ut_params->ibuf[j]->data_len,
1445                        "input and output data does not match\n");
1446                TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1447                        ut_params->obuf[j]->data_len,
1448                        "ibuf data_len is not equal to obuf data_len");
1449                TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len,
1450                        ut_params->obuf[j]->pkt_len,
1451                        "ibuf pkt_len is not equal to obuf pkt_len");
1452                TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1453                        test_cfg[i].pkt_sz,
1454                        "data_len is not equal input data");
1455        }
1456        return 0;
1457}
1458
1459static int
1460test_ipsec_inline_crypto_inb_burst_null_null(int i)
1461{
1462        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1463        struct ipsec_unitest_params *ut_params = &unittest_params;
1464        uint16_t num_pkts = test_cfg[i].num_pkts;
1465        uint16_t j;
1466        int32_t rc;
1467        uint32_t n;
1468
1469        /* create rte_ipsec_sa*/
1470        rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
1471                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1472        if (rc != 0) {
1473                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1474                return rc;
1475        }
1476
1477        /* Generate inbound mbuf data */
1478        for (j = 0; j < num_pkts && rc == 0; j++) {
1479                ut_params->ibuf[j] = setup_test_string_tunneled(
1480                        ts_params->mbuf_pool,
1481                        null_plain_data, test_cfg[i].pkt_sz,
1482                        INBOUND_SPI, j + 1);
1483                if (ut_params->ibuf[j] == NULL)
1484                        rc = TEST_FAILED;
1485                else {
1486                        /* Generate test mbuf data */
1487                        ut_params->obuf[j] = setup_test_string(
1488                                ts_params->mbuf_pool,
1489                                null_plain_data, sizeof(null_plain_data),
1490                                test_cfg[i].pkt_sz, 0);
1491                        if (ut_params->obuf[j] == NULL)
1492                                rc = TEST_FAILED;
1493                }
1494        }
1495
1496        if (rc == 0) {
1497                n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1498                                num_pkts);
1499                if (n == num_pkts)
1500                        rc = inline_inb_burst_null_null_check(ut_params, i,
1501                                        num_pkts);
1502                else {
1503                        RTE_LOG(ERR, USER1,
1504                                "rte_ipsec_pkt_process failed, cfg %d\n",
1505                                i);
1506                        rc = TEST_FAILED;
1507                }
1508        }
1509
1510        if (rc == TEST_FAILED)
1511                test_ipsec_dump_buffers(ut_params, i);
1512
1513        destroy_sa(0);
1514        return rc;
1515}
1516
1517static int
1518test_ipsec_inline_crypto_inb_burst_null_null_wrapper(void)
1519{
1520        int i;
1521        int rc = 0;
1522        struct ipsec_unitest_params *ut_params = &unittest_params;
1523
1524        ut_params->ipsec_xform.spi = INBOUND_SPI;
1525        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1526        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1527        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1528        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1529
1530        for (i = 0; i < num_cfg && rc == 0; i++) {
1531                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1532                rc = test_ipsec_inline_crypto_inb_burst_null_null(i);
1533        }
1534
1535        return rc;
1536}
1537
1538static int
1539test_ipsec_inline_proto_inb_burst_null_null(int i)
1540{
1541        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1542        struct ipsec_unitest_params *ut_params = &unittest_params;
1543        uint16_t num_pkts = test_cfg[i].num_pkts;
1544        uint16_t j;
1545        int32_t rc;
1546        uint32_t n;
1547
1548        /* create rte_ipsec_sa*/
1549        rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
1550                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1551        if (rc != 0) {
1552                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1553                return rc;
1554        }
1555
1556        /* Generate inbound mbuf data */
1557        for (j = 0; j < num_pkts && rc == 0; j++) {
1558                ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1559                        null_plain_data, sizeof(null_plain_data),
1560                        test_cfg[i].pkt_sz, 0);
1561                if (ut_params->ibuf[j] == NULL)
1562                        rc = TEST_FAILED;
1563                else {
1564                        /* Generate test mbuf data */
1565                        ut_params->obuf[j] = setup_test_string(
1566                                ts_params->mbuf_pool,
1567                                null_plain_data, sizeof(null_plain_data),
1568                                test_cfg[i].pkt_sz, 0);
1569                        if (ut_params->obuf[j] == NULL)
1570                                rc = TEST_FAILED;
1571                }
1572        }
1573
1574        if (rc == 0) {
1575                n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1576                                num_pkts);
1577                if (n == num_pkts)
1578                        rc = inline_inb_burst_null_null_check(ut_params, i,
1579                                        num_pkts);
1580                else {
1581                        RTE_LOG(ERR, USER1,
1582                                "rte_ipsec_pkt_process failed, cfg %d\n",
1583                                i);
1584                        rc = TEST_FAILED;
1585                }
1586        }
1587
1588        if (rc == TEST_FAILED)
1589                test_ipsec_dump_buffers(ut_params, i);
1590
1591        destroy_sa(0);
1592        return rc;
1593}
1594
1595static int
1596test_ipsec_inline_proto_inb_burst_null_null_wrapper(void)
1597{
1598        int i;
1599        int rc = 0;
1600        struct ipsec_unitest_params *ut_params = &unittest_params;
1601
1602        ut_params->ipsec_xform.spi = INBOUND_SPI;
1603        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1604        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1605        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1606        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1607
1608        for (i = 0; i < num_cfg && rc == 0; i++) {
1609                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1610                rc = test_ipsec_inline_proto_inb_burst_null_null(i);
1611        }
1612
1613        return rc;
1614}
1615
1616static int
1617inline_outb_burst_null_null_check(struct ipsec_unitest_params *ut_params,
1618        uint16_t num_pkts)
1619{
1620        void *obuf_data;
1621        void *ibuf_data;
1622        uint16_t j;
1623
1624        for (j = 0; j < num_pkts && num_pkts <= BURST_SIZE; j++) {
1625                ut_params->pkt_index = j;
1626
1627                /* compare the buffer data */
1628                ibuf_data = rte_pktmbuf_mtod(ut_params->ibuf[j], void *);
1629                obuf_data = rte_pktmbuf_mtod(ut_params->obuf[j], void *);
1630                TEST_ASSERT_BUFFERS_ARE_EQUAL(ibuf_data, obuf_data,
1631                        ut_params->ibuf[j]->data_len,
1632                        "input and output data does not match\n");
1633                TEST_ASSERT_EQUAL(ut_params->ibuf[j]->data_len,
1634                        ut_params->obuf[j]->data_len,
1635                        "ibuf data_len is not equal to obuf data_len");
1636                TEST_ASSERT_EQUAL(ut_params->ibuf[j]->pkt_len,
1637                        ut_params->obuf[j]->pkt_len,
1638                        "ibuf pkt_len is not equal to obuf pkt_len");
1639
1640                /* check mbuf ol_flags */
1641                TEST_ASSERT(ut_params->ibuf[j]->ol_flags & RTE_MBUF_F_TX_SEC_OFFLOAD,
1642                            "ibuf RTE_MBUF_F_TX_SEC_OFFLOAD is not set");
1643        }
1644        return 0;
1645}
1646
1647static int
1648test_ipsec_inline_crypto_outb_burst_null_null(int i)
1649{
1650        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1651        struct ipsec_unitest_params *ut_params = &unittest_params;
1652        uint16_t num_pkts = test_cfg[i].num_pkts;
1653        uint16_t j;
1654        int32_t rc;
1655        uint32_t n;
1656
1657        /* create rte_ipsec_sa */
1658        rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
1659                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1660        if (rc != 0) {
1661                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1662                return rc;
1663        }
1664
1665        /* Generate test mbuf data */
1666        for (j = 0; j < num_pkts && rc == 0; j++) {
1667                ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1668                        null_plain_data, sizeof(null_plain_data),
1669                        test_cfg[i].pkt_sz, 0);
1670                if (ut_params->ibuf[0] == NULL)
1671                        rc = TEST_FAILED;
1672
1673                if (rc == 0) {
1674                        /* Generate test tunneled mbuf data for comparison */
1675                        ut_params->obuf[j] = setup_test_string_tunneled(
1676                                        ts_params->mbuf_pool,
1677                                        null_plain_data, test_cfg[i].pkt_sz,
1678                                        OUTBOUND_SPI, j + 1);
1679                        if (ut_params->obuf[j] == NULL)
1680                                rc = TEST_FAILED;
1681                }
1682        }
1683
1684        if (rc == 0) {
1685                n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1686                                num_pkts);
1687                if (n == num_pkts)
1688                        rc = inline_outb_burst_null_null_check(ut_params,
1689                                        num_pkts);
1690                else {
1691                        RTE_LOG(ERR, USER1,
1692                                "rte_ipsec_pkt_process failed, cfg %d\n",
1693                                i);
1694                        rc = TEST_FAILED;
1695                }
1696        }
1697
1698        if (rc == TEST_FAILED)
1699                test_ipsec_dump_buffers(ut_params, i);
1700
1701        destroy_sa(0);
1702        return rc;
1703}
1704
1705static int
1706test_ipsec_inline_crypto_outb_burst_null_null_wrapper(void)
1707{
1708        int i;
1709        int rc = 0;
1710        struct ipsec_unitest_params *ut_params = &unittest_params;
1711
1712        ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1713        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1714        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1715        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1716        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1717
1718        for (i = 0; i < num_cfg && rc == 0; i++) {
1719                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1720                rc = test_ipsec_inline_crypto_outb_burst_null_null(i);
1721        }
1722
1723        return rc;
1724}
1725
1726static int
1727test_ipsec_inline_proto_outb_burst_null_null(int i)
1728{
1729        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1730        struct ipsec_unitest_params *ut_params = &unittest_params;
1731        uint16_t num_pkts = test_cfg[i].num_pkts;
1732        uint16_t j;
1733        int32_t rc;
1734        uint32_t n;
1735
1736        /* create rte_ipsec_sa */
1737        rc = create_sa(RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
1738                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1739        if (rc != 0) {
1740                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1741                return rc;
1742        }
1743
1744        /* Generate test mbuf data */
1745        for (j = 0; j < num_pkts && rc == 0; j++) {
1746                ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1747                        null_plain_data, sizeof(null_plain_data),
1748                        test_cfg[i].pkt_sz, 0);
1749                if (ut_params->ibuf[0] == NULL)
1750                        rc = TEST_FAILED;
1751
1752                if (rc == 0) {
1753                        /* Generate test tunneled mbuf data for comparison */
1754                        ut_params->obuf[j] = setup_test_string(
1755                                ts_params->mbuf_pool, null_plain_data,
1756                                sizeof(null_plain_data), test_cfg[i].pkt_sz,
1757                                0);
1758                        if (ut_params->obuf[j] == NULL)
1759                                rc = TEST_FAILED;
1760                }
1761        }
1762
1763        if (rc == 0) {
1764                n = rte_ipsec_pkt_process(&ut_params->ss[0], ut_params->ibuf,
1765                                num_pkts);
1766                if (n == num_pkts)
1767                        rc = inline_outb_burst_null_null_check(ut_params,
1768                                        num_pkts);
1769                else {
1770                        RTE_LOG(ERR, USER1,
1771                                "rte_ipsec_pkt_process failed, cfg %d\n",
1772                                i);
1773                        rc = TEST_FAILED;
1774                }
1775        }
1776
1777        if (rc == TEST_FAILED)
1778                test_ipsec_dump_buffers(ut_params, i);
1779
1780        destroy_sa(0);
1781        return rc;
1782}
1783
1784static int
1785test_ipsec_inline_proto_outb_burst_null_null_wrapper(void)
1786{
1787        int i;
1788        int rc = 0;
1789        struct ipsec_unitest_params *ut_params = &unittest_params;
1790
1791        ut_params->ipsec_xform.spi = OUTBOUND_SPI;
1792        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1793        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1794        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1795        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1796
1797        for (i = 0; i < num_cfg && rc == 0; i++) {
1798                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1799                rc = test_ipsec_inline_proto_outb_burst_null_null(i);
1800        }
1801
1802        return rc;
1803}
1804
1805static int
1806test_ipsec_lksd_proto_inb_burst_null_null(int i)
1807{
1808        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1809        struct ipsec_unitest_params *ut_params = &unittest_params;
1810        uint16_t num_pkts = test_cfg[i].num_pkts;
1811        uint16_t j;
1812        int rc;
1813
1814        /* create rte_ipsec_sa */
1815        rc = create_sa(RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
1816                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1817        if (rc != 0) {
1818                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1819                return rc;
1820        }
1821
1822        /* Generate test mbuf data */
1823        for (j = 0; j < num_pkts && rc == 0; j++) {
1824                /* packet with sequence number 0 is invalid */
1825                ut_params->ibuf[j] = setup_test_string(ts_params->mbuf_pool,
1826                        null_encrypted_data, sizeof(null_encrypted_data),
1827                        test_cfg[i].pkt_sz, 0);
1828                if (ut_params->ibuf[j] == NULL)
1829                        rc = TEST_FAILED;
1830        }
1831
1832        if (rc == 0) {
1833                if (test_cfg[i].reorder_pkts)
1834                        test_ipsec_reorder_inb_pkt_burst(num_pkts);
1835                rc = test_ipsec_crypto_op_alloc(num_pkts);
1836        }
1837
1838        if (rc == 0) {
1839                /* call ipsec library api */
1840                rc = lksd_proto_ipsec(num_pkts);
1841                if (rc == 0)
1842                        rc = crypto_inb_burst_null_null_check(ut_params, i,
1843                                        num_pkts);
1844                else {
1845                        RTE_LOG(ERR, USER1, "%s failed, cfg %d\n",
1846                                __func__, i);
1847                        rc = TEST_FAILED;
1848                }
1849        }
1850
1851        if (rc == TEST_FAILED)
1852                test_ipsec_dump_buffers(ut_params, i);
1853
1854        destroy_sa(0);
1855        return rc;
1856}
1857
1858static int
1859test_ipsec_lksd_proto_inb_burst_null_null_wrapper(void)
1860{
1861        int i;
1862        int rc = 0;
1863        struct ipsec_unitest_params *ut_params = &unittest_params;
1864
1865        ut_params->ipsec_xform.spi = INBOUND_SPI;
1866        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
1867        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1868        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1869        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1870
1871        for (i = 0; i < num_cfg && rc == 0; i++) {
1872                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1873                rc = test_ipsec_lksd_proto_inb_burst_null_null(i);
1874        }
1875
1876        return rc;
1877}
1878
1879static int
1880test_ipsec_lksd_proto_outb_burst_null_null_wrapper(void)
1881{
1882        int i;
1883        int rc = 0;
1884        struct ipsec_unitest_params *ut_params = &unittest_params;
1885
1886        ut_params->ipsec_xform.spi = INBOUND_SPI;
1887        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS;
1888        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1889        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1890        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
1891
1892        for (i = 0; i < num_cfg && rc == 0; i++) {
1893                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
1894                rc = test_ipsec_lksd_proto_inb_burst_null_null(i);
1895        }
1896
1897        return rc;
1898}
1899
1900static int
1901replay_inb_null_null_check(struct ipsec_unitest_params *ut_params, int i,
1902        int num_pkts)
1903{
1904        uint16_t j;
1905
1906        for (j = 0; j < num_pkts; j++) {
1907                /* compare the buffer data */
1908                TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
1909                        rte_pktmbuf_mtod(ut_params->obuf[j], void *),
1910                        test_cfg[i].pkt_sz,
1911                        "input and output data does not match\n");
1912
1913                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
1914                        ut_params->obuf[j]->pkt_len,
1915                        "data_len is not equal to pkt_len");
1916        }
1917
1918        return 0;
1919}
1920
1921static int
1922test_ipsec_replay_inb_inside_null_null(int i)
1923{
1924        struct ipsec_testsuite_params *ts_params = &testsuite_params;
1925        struct ipsec_unitest_params *ut_params = &unittest_params;
1926        int rc;
1927
1928        /* create rte_ipsec_sa*/
1929        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
1930                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
1931        if (rc != 0) {
1932                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
1933                return rc;
1934        }
1935
1936        /* Generate inbound mbuf data */
1937        ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
1938                null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
1939        if (ut_params->ibuf[0] == NULL)
1940                rc = TEST_FAILED;
1941        else
1942                rc = test_ipsec_crypto_op_alloc(1);
1943
1944        if (rc == 0) {
1945                /* call ipsec library api */
1946                rc = crypto_ipsec(1);
1947                if (rc == 0)
1948                        rc = replay_inb_null_null_check(ut_params, i, 1);
1949                else {
1950                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
1951                                        i);
1952                        rc = TEST_FAILED;
1953                }
1954        }
1955
1956        if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
1957                /* generate packet with seq number inside the replay window */
1958                if (ut_params->ibuf[0]) {
1959                        rte_pktmbuf_free(ut_params->ibuf[0]);
1960                        ut_params->ibuf[0] = 0;
1961                }
1962
1963                ut_params->ibuf[0] = setup_test_string_tunneled(
1964                        ts_params->mbuf_pool, null_encrypted_data,
1965                        test_cfg[i].pkt_sz, INBOUND_SPI,
1966                        test_cfg[i].replay_win_sz);
1967                if (ut_params->ibuf[0] == NULL)
1968                        rc = TEST_FAILED;
1969                else
1970                        rc = test_ipsec_crypto_op_alloc(1);
1971
1972                if (rc == 0) {
1973                        /* call ipsec library api */
1974                        rc = crypto_ipsec(1);
1975                        if (rc == 0)
1976                                rc = replay_inb_null_null_check(
1977                                                ut_params, i, 1);
1978                        else {
1979                                RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
1980                                rc = TEST_FAILED;
1981                        }
1982                }
1983        }
1984
1985        if (rc == TEST_FAILED)
1986                test_ipsec_dump_buffers(ut_params, i);
1987
1988        destroy_sa(0);
1989
1990        return rc;
1991}
1992
1993static int
1994test_ipsec_replay_inb_inside_null_null_wrapper(void)
1995{
1996        int i;
1997        int rc = 0;
1998        struct ipsec_unitest_params *ut_params = &unittest_params;
1999
2000        ut_params->ipsec_xform.spi = INBOUND_SPI;
2001        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2002        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2003        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2004        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2005
2006        for (i = 0; i < num_cfg && rc == 0; i++) {
2007                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2008                rc = test_ipsec_replay_inb_inside_null_null(i);
2009        }
2010
2011        return rc;
2012}
2013
2014static int
2015test_ipsec_replay_inb_outside_null_null(int i)
2016{
2017        struct ipsec_testsuite_params *ts_params = &testsuite_params;
2018        struct ipsec_unitest_params *ut_params = &unittest_params;
2019        int rc;
2020
2021        /* create rte_ipsec_sa */
2022        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2023                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2024        if (rc != 0) {
2025                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2026                return rc;
2027        }
2028
2029        /* Generate test mbuf data */
2030        ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2031                null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI,
2032                test_cfg[i].replay_win_sz + 2);
2033        if (ut_params->ibuf[0] == NULL)
2034                rc = TEST_FAILED;
2035        else
2036                rc = test_ipsec_crypto_op_alloc(1);
2037
2038        if (rc == 0) {
2039                /* call ipsec library api */
2040                rc = crypto_ipsec(1);
2041                if (rc == 0)
2042                        rc = replay_inb_null_null_check(ut_params, i, 1);
2043                else {
2044                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2045                                        i);
2046                        rc = TEST_FAILED;
2047                }
2048        }
2049
2050        if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2051                /* generate packet with seq number outside the replay window */
2052                if (ut_params->ibuf[0]) {
2053                        rte_pktmbuf_free(ut_params->ibuf[0]);
2054                        ut_params->ibuf[0] = 0;
2055                }
2056                ut_params->ibuf[0] = setup_test_string_tunneled(
2057                        ts_params->mbuf_pool, null_encrypted_data,
2058                        test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2059                if (ut_params->ibuf[0] == NULL)
2060                        rc = TEST_FAILED;
2061                else
2062                        rc = test_ipsec_crypto_op_alloc(1);
2063
2064                if (rc == 0) {
2065                        /* call ipsec library api */
2066                        rc = crypto_ipsec(1);
2067                        if (rc == 0) {
2068                                if (test_cfg[i].esn == 0) {
2069                                        RTE_LOG(ERR, USER1,
2070                                                "packet is not outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n",
2071                                                i,
2072                                                test_cfg[i].replay_win_sz + 2,
2073                                                1);
2074                                        rc = TEST_FAILED;
2075                                }
2076                        } else {
2077                                RTE_LOG(ERR, USER1,
2078                                        "packet is outside the replay window, cfg %d pkt0_seq %u pkt1_seq %u\n",
2079                                        i, test_cfg[i].replay_win_sz + 2, 1);
2080                                rc = 0;
2081                        }
2082                }
2083        }
2084
2085        if (rc == TEST_FAILED)
2086                test_ipsec_dump_buffers(ut_params, i);
2087
2088        destroy_sa(0);
2089
2090        return rc;
2091}
2092
2093static int
2094test_ipsec_replay_inb_outside_null_null_wrapper(void)
2095{
2096        int i;
2097        int rc = 0;
2098        struct ipsec_unitest_params *ut_params = &unittest_params;
2099
2100        ut_params->ipsec_xform.spi = INBOUND_SPI;
2101        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2102        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2103        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2104        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2105
2106        for (i = 0; i < num_cfg && rc == 0; i++) {
2107                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2108                rc = test_ipsec_replay_inb_outside_null_null(i);
2109        }
2110
2111        return rc;
2112}
2113
2114static int
2115test_ipsec_replay_inb_repeat_null_null(int i)
2116{
2117        struct ipsec_testsuite_params *ts_params = &testsuite_params;
2118        struct ipsec_unitest_params *ut_params = &unittest_params;
2119        int rc;
2120
2121        /* create rte_ipsec_sa */
2122        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2123                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2124        if (rc != 0) {
2125                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2126                return rc;
2127        }
2128
2129        /* Generate test mbuf data */
2130        ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2131                null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2132        if (ut_params->ibuf[0] == NULL)
2133                rc = TEST_FAILED;
2134        else
2135                rc = test_ipsec_crypto_op_alloc(1);
2136
2137        if (rc == 0) {
2138                /* call ipsec library api */
2139                rc = crypto_ipsec(1);
2140                if (rc == 0)
2141                        rc = replay_inb_null_null_check(ut_params, i, 1);
2142                else {
2143                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2144                                        i);
2145                        rc = TEST_FAILED;
2146                }
2147        }
2148
2149        if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2150                /*
2151                 * generate packet with repeat seq number in the replay
2152                 * window
2153                 */
2154                if (ut_params->ibuf[0]) {
2155                        rte_pktmbuf_free(ut_params->ibuf[0]);
2156                        ut_params->ibuf[0] = 0;
2157                }
2158
2159                ut_params->ibuf[0] = setup_test_string_tunneled(
2160                        ts_params->mbuf_pool, null_encrypted_data,
2161                        test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2162                if (ut_params->ibuf[0] == NULL)
2163                        rc = TEST_FAILED;
2164                else
2165                        rc = test_ipsec_crypto_op_alloc(1);
2166
2167                if (rc == 0) {
2168                        /* call ipsec library api */
2169                        rc = crypto_ipsec(1);
2170                        if (rc == 0) {
2171                                RTE_LOG(ERR, USER1,
2172                                        "packet is not repeated in the replay window, cfg %d seq %u\n",
2173                                        i, 1);
2174                                rc = TEST_FAILED;
2175                        } else {
2176                                RTE_LOG(ERR, USER1,
2177                                        "packet is repeated in the replay window, cfg %d seq %u\n",
2178                                        i, 1);
2179                                rc = 0;
2180                        }
2181                }
2182        }
2183
2184        if (rc == TEST_FAILED)
2185                test_ipsec_dump_buffers(ut_params, i);
2186
2187        destroy_sa(0);
2188
2189        return rc;
2190}
2191
2192static int
2193test_ipsec_replay_inb_repeat_null_null_wrapper(void)
2194{
2195        int i;
2196        int rc = 0;
2197        struct ipsec_unitest_params *ut_params = &unittest_params;
2198
2199        ut_params->ipsec_xform.spi = INBOUND_SPI;
2200        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2201        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2202        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2203        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2204
2205        for (i = 0; i < num_cfg && rc == 0; i++) {
2206                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2207                rc = test_ipsec_replay_inb_repeat_null_null(i);
2208        }
2209
2210        return rc;
2211}
2212
2213static int
2214test_ipsec_replay_inb_inside_burst_null_null(int i)
2215{
2216        struct ipsec_testsuite_params *ts_params = &testsuite_params;
2217        struct ipsec_unitest_params *ut_params = &unittest_params;
2218        uint16_t num_pkts = test_cfg[i].num_pkts;
2219        int rc;
2220        int j;
2221
2222        /* create rte_ipsec_sa*/
2223        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2224                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2225        if (rc != 0) {
2226                RTE_LOG(ERR, USER1, "create_sa failed, cfg %d\n", i);
2227                return rc;
2228        }
2229
2230        /* Generate inbound mbuf data */
2231        ut_params->ibuf[0] = setup_test_string_tunneled(ts_params->mbuf_pool,
2232                null_encrypted_data, test_cfg[i].pkt_sz, INBOUND_SPI, 1);
2233        if (ut_params->ibuf[0] == NULL)
2234                rc = TEST_FAILED;
2235        else
2236                rc = test_ipsec_crypto_op_alloc(1);
2237
2238        if (rc == 0) {
2239                /* call ipsec library api */
2240                rc = crypto_ipsec(1);
2241                if (rc == 0)
2242                        rc = replay_inb_null_null_check(ut_params, i, 1);
2243                else {
2244                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2245                                        i);
2246                        rc = TEST_FAILED;
2247                }
2248        }
2249
2250        if ((rc == 0) && (test_cfg[i].replay_win_sz != 0)) {
2251                /*
2252                 *  generate packet(s) with seq number(s) inside the
2253                 *  replay window
2254                 */
2255                if (ut_params->ibuf[0]) {
2256                        rte_pktmbuf_free(ut_params->ibuf[0]);
2257                        ut_params->ibuf[0] = 0;
2258                }
2259
2260                for (j = 0; j < num_pkts && rc == 0; j++) {
2261                        /* packet with sequence number 1 already processed */
2262                        ut_params->ibuf[j] = setup_test_string_tunneled(
2263                                ts_params->mbuf_pool, null_encrypted_data,
2264                                test_cfg[i].pkt_sz, INBOUND_SPI, j + 2);
2265                        if (ut_params->ibuf[j] == NULL)
2266                                rc = TEST_FAILED;
2267                }
2268
2269                if (rc == 0) {
2270                        if (test_cfg[i].reorder_pkts)
2271                                test_ipsec_reorder_inb_pkt_burst(num_pkts);
2272                        rc = test_ipsec_crypto_op_alloc(num_pkts);
2273                }
2274
2275                if (rc == 0) {
2276                        /* call ipsec library api */
2277                        rc = crypto_ipsec(num_pkts);
2278                        if (rc == 0)
2279                                rc = replay_inb_null_null_check(
2280                                                ut_params, i, num_pkts);
2281                        else {
2282                                RTE_LOG(ERR, USER1, "crypto_ipsec failed\n");
2283                                rc = TEST_FAILED;
2284                        }
2285                }
2286        }
2287
2288        if (rc == TEST_FAILED)
2289                test_ipsec_dump_buffers(ut_params, i);
2290
2291        destroy_sa(0);
2292
2293        return rc;
2294}
2295
2296static int
2297test_ipsec_replay_inb_inside_burst_null_null_wrapper(void)
2298{
2299        int i;
2300        int rc = 0;
2301        struct ipsec_unitest_params *ut_params = &unittest_params;
2302
2303        ut_params->ipsec_xform.spi = INBOUND_SPI;
2304        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2305        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2306        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2307        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2308
2309        for (i = 0; i < num_cfg && rc == 0; i++) {
2310                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2311                rc = test_ipsec_replay_inb_inside_burst_null_null(i);
2312        }
2313
2314        return rc;
2315}
2316
2317
2318static int
2319crypto_inb_burst_2sa_null_null_check(struct ipsec_unitest_params *ut_params,
2320                int i)
2321{
2322        uint16_t j;
2323
2324        for (j = 0; j < BURST_SIZE; j++) {
2325                ut_params->pkt_index = j;
2326
2327                /* compare the data buffers */
2328                TEST_ASSERT_BUFFERS_ARE_EQUAL(null_plain_data,
2329                        rte_pktmbuf_mtod(ut_params->obuf[j], void *),
2330                        test_cfg[i].pkt_sz,
2331                        "input and output data does not match\n");
2332                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
2333                        ut_params->obuf[j]->pkt_len,
2334                        "data_len is not equal to pkt_len");
2335                TEST_ASSERT_EQUAL(ut_params->obuf[j]->data_len,
2336                        test_cfg[i].pkt_sz,
2337                        "data_len is not equal to input data");
2338        }
2339
2340        return 0;
2341}
2342
2343static int
2344test_ipsec_crypto_inb_burst_2sa_null_null(int i)
2345{
2346        struct ipsec_testsuite_params *ts_params = &testsuite_params;
2347        struct ipsec_unitest_params *ut_params = &unittest_params;
2348        uint16_t num_pkts = test_cfg[i].num_pkts;
2349        uint16_t j, r;
2350        int rc = 0;
2351
2352        if (num_pkts != BURST_SIZE)
2353                return rc;
2354
2355        /* create rte_ipsec_sa */
2356        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2357                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2358        if (rc != 0) {
2359                RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i);
2360                return rc;
2361        }
2362
2363        /* create second rte_ipsec_sa */
2364        ut_params->ipsec_xform.spi = INBOUND_SPI + 1;
2365        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2366                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 1);
2367        if (rc != 0) {
2368                RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i);
2369                destroy_sa(0);
2370                return rc;
2371        }
2372
2373        /* Generate test mbuf data */
2374        for (j = 0; j < num_pkts && rc == 0; j++) {
2375                r = j % 2;
2376                /* packet with sequence number 0 is invalid */
2377                ut_params->ibuf[j] = setup_test_string_tunneled(
2378                        ts_params->mbuf_pool, null_encrypted_data,
2379                        test_cfg[i].pkt_sz, INBOUND_SPI + r, j + 1);
2380                if (ut_params->ibuf[j] == NULL)
2381                        rc = TEST_FAILED;
2382        }
2383
2384        if (rc == 0)
2385                rc = test_ipsec_crypto_op_alloc(num_pkts);
2386
2387        if (rc == 0) {
2388                /* call ipsec library api */
2389                rc = crypto_ipsec_2sa();
2390                if (rc == 0)
2391                        rc = crypto_inb_burst_2sa_null_null_check(
2392                                        ut_params, i);
2393                else {
2394                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2395                                i);
2396                        rc = TEST_FAILED;
2397                }
2398        }
2399
2400        if (rc == TEST_FAILED)
2401                test_ipsec_dump_buffers(ut_params, i);
2402
2403        destroy_sa(0);
2404        destroy_sa(1);
2405        return rc;
2406}
2407
2408static int
2409test_ipsec_crypto_inb_burst_2sa_null_null_wrapper(void)
2410{
2411        int i;
2412        int rc = 0;
2413        struct ipsec_unitest_params *ut_params = &unittest_params;
2414
2415        ut_params->ipsec_xform.spi = INBOUND_SPI;
2416        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2417        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2418        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2419        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2420
2421        for (i = 0; i < num_cfg && rc == 0; i++) {
2422                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2423                rc = test_ipsec_crypto_inb_burst_2sa_null_null(i);
2424        }
2425
2426        return rc;
2427}
2428
2429static int
2430test_ipsec_crypto_inb_burst_2sa_4grp_null_null(int i)
2431{
2432        struct ipsec_testsuite_params *ts_params = &testsuite_params;
2433        struct ipsec_unitest_params *ut_params = &unittest_params;
2434        uint16_t num_pkts = test_cfg[i].num_pkts;
2435        uint16_t j, k;
2436        int rc = 0;
2437
2438        if (num_pkts != BURST_SIZE)
2439                return rc;
2440
2441        /* create rte_ipsec_sa */
2442        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2443                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 0);
2444        if (rc != 0) {
2445                RTE_LOG(ERR, USER1, "create_sa 0 failed, cfg %d\n", i);
2446                return rc;
2447        }
2448
2449        /* create second rte_ipsec_sa */
2450        ut_params->ipsec_xform.spi = INBOUND_SPI + 1;
2451        rc = create_sa(RTE_SECURITY_ACTION_TYPE_NONE,
2452                        test_cfg[i].replay_win_sz, test_cfg[i].flags, 1);
2453        if (rc != 0) {
2454                RTE_LOG(ERR, USER1, "create_sa 1 failed, cfg %d\n", i);
2455                destroy_sa(0);
2456                return rc;
2457        }
2458
2459        /* Generate test mbuf data */
2460        for (j = 0; j < num_pkts && rc == 0; j++) {
2461                k = crypto_ipsec_4grp(j);
2462
2463                /* packet with sequence number 0 is invalid */
2464                ut_params->ibuf[j] = setup_test_string_tunneled(
2465                        ts_params->mbuf_pool, null_encrypted_data,
2466                        test_cfg[i].pkt_sz, INBOUND_SPI + k, j + 1);
2467                if (ut_params->ibuf[j] == NULL)
2468                        rc = TEST_FAILED;
2469        }
2470
2471        if (rc == 0)
2472                rc = test_ipsec_crypto_op_alloc(num_pkts);
2473
2474        if (rc == 0) {
2475                /* call ipsec library api */
2476                rc = crypto_ipsec_2sa_4grp();
2477                if (rc == 0)
2478                        rc = crypto_inb_burst_2sa_null_null_check(
2479                                        ut_params, i);
2480                else {
2481                        RTE_LOG(ERR, USER1, "crypto_ipsec failed, cfg %d\n",
2482                                i);
2483                        rc = TEST_FAILED;
2484                }
2485        }
2486
2487        if (rc == TEST_FAILED)
2488                test_ipsec_dump_buffers(ut_params, i);
2489
2490        destroy_sa(0);
2491        destroy_sa(1);
2492        return rc;
2493}
2494
2495static int
2496test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper(void)
2497{
2498        int i;
2499        int rc = 0;
2500        struct ipsec_unitest_params *ut_params = &unittest_params;
2501
2502        ut_params->ipsec_xform.spi = INBOUND_SPI;
2503        ut_params->ipsec_xform.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS;
2504        ut_params->ipsec_xform.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
2505        ut_params->ipsec_xform.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
2506        ut_params->ipsec_xform.tunnel.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4;
2507
2508        for (i = 0; i < num_cfg && rc == 0; i++) {
2509                ut_params->ipsec_xform.options.esn = test_cfg[i].esn;
2510                rc = test_ipsec_crypto_inb_burst_2sa_4grp_null_null(i);
2511        }
2512
2513        return rc;
2514}
2515
2516static struct unit_test_suite ipsec_testsuite  = {
2517        .suite_name = "IPsec NULL Unit Test Suite",
2518        .setup = testsuite_setup,
2519        .teardown = testsuite_teardown,
2520        .unit_test_cases = {
2521                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2522                        test_ipsec_crypto_inb_burst_null_null_wrapper),
2523                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2524                        test_ipsec_crypto_outb_burst_null_null_wrapper),
2525                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2526                        test_ipsec_inline_crypto_inb_burst_null_null_wrapper),
2527                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2528                        test_ipsec_inline_crypto_outb_burst_null_null_wrapper),
2529                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2530                        test_ipsec_inline_proto_inb_burst_null_null_wrapper),
2531                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2532                        test_ipsec_inline_proto_outb_burst_null_null_wrapper),
2533                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2534                        test_ipsec_lksd_proto_inb_burst_null_null_wrapper),
2535                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2536                        test_ipsec_lksd_proto_outb_burst_null_null_wrapper),
2537                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2538                        test_ipsec_replay_inb_inside_null_null_wrapper),
2539                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2540                        test_ipsec_replay_inb_outside_null_null_wrapper),
2541                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2542                        test_ipsec_replay_inb_repeat_null_null_wrapper),
2543                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2544                        test_ipsec_replay_inb_inside_burst_null_null_wrapper),
2545                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2546                        test_ipsec_crypto_inb_burst_2sa_null_null_wrapper),
2547                TEST_CASE_ST(ut_setup_ipsec, ut_teardown_ipsec,
2548                        test_ipsec_crypto_inb_burst_2sa_4grp_null_null_wrapper),
2549                TEST_CASES_END() /**< NULL terminate unit test array */
2550        }
2551};
2552
2553static int
2554test_ipsec(void)
2555{
2556        return unit_test_suite_runner(&ipsec_testsuite);
2557}
2558
2559#endif /* !RTE_EXEC_ENV_WINDOWS */
2560
2561REGISTER_TEST_COMMAND(ipsec_autotest, test_ipsec);
2562