get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/111701/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 111701,
    "url": "http://patches.dpdk.org/api/patches/111701/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220524072216.1283647-2-gakhil@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220524072216.1283647-2-gakhil@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220524072216.1283647-2-gakhil@marvell.com",
    "date": "2022-05-24T07:22:10",
    "name": "[v7,1/7] app/test: add unit cases for inline IPsec offload",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "c3a784ac23c20907bb68b1c367f97b049116cee5",
    "submitter": {
        "id": 2094,
        "url": "http://patches.dpdk.org/api/people/2094/?format=api",
        "name": "Akhil Goyal",
        "email": "gakhil@marvell.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220524072216.1283647-2-gakhil@marvell.com/mbox/",
    "series": [
        {
            "id": 23112,
            "url": "http://patches.dpdk.org/api/series/23112/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=23112",
            "date": "2022-05-24T07:22:11",
            "name": "app/test: add inline IPsec and reassembly cases",
            "version": 7,
            "mbox": "http://patches.dpdk.org/series/23112/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/111701/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/111701/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id A9F11A04FF;\n\tTue, 24 May 2022 09:56:19 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 78ED442670;\n\tTue, 24 May 2022 09:56:19 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174])\n by mails.dpdk.org (Postfix) with ESMTP id DB8FA410E8\n for <dev@dpdk.org>; Tue, 24 May 2022 09:56:17 +0200 (CEST)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id\n 24NNBBBE022471;\n Tue, 24 May 2022 00:56:17 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3g8kqjhjs5-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT);\n Tue, 24 May 2022 00:56:16 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Tue, 24 May 2022 00:56:14 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend\n Transport; Tue, 24 May 2022 00:56:15 -0700",
            "from localhost.localdomain (unknown [10.28.48.55])\n by maili.marvell.com (Postfix) with ESMTP id 60C0767429;\n Tue, 24 May 2022 00:22:22 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=D87xs1+FAgdOkLeEHfz5NkKN0CWCsxG9dzE+D+GE3dc=;\n b=aJfSZYaKM6bTueRFkfWD5GtICdjyoBIKUc2Hcfpav6Kd9TfAxalFTkZy7/CgnWsR5fyV\n XfNhcIBILdt/stcg5ZIt9d70FQqlfCigOobJYd13wgYjJ7mhJN2UV5awj7EtKE2tt6Vi\n qHX7YJI1YtvUn1lZb/guXzyF8JIqsJK/g2jNw6dLdxw2oYAMBLwkLVtbXXHwHQewVGLf\n uMyFmSRrby9/IKyypoUumCz9iVYHhtwXYXUgQROX+HMDHrd8gszWqsqpOCvVdRtRUdDj\n Tzt7YhUbMnpfPGHhG0RUyCn/dNFGjVMT+5yyezEf9u5MBPbhNnynOltZy3ZilQnnnmsZ Jg==",
        "From": "Akhil Goyal <gakhil@marvell.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<thomas@monjalon.net>, <david.marchand@redhat.com>,\n <hemant.agrawal@nxp.com>, <anoobj@marvell.com>,\n <konstantin.ananyev@intel.com>, <ciara.power@intel.com>,\n <ferruh.yigit@intel.com>, <andrew.rybchenko@oktetlabs.ru>,\n <ndabilpuram@marvell.com>, <vattunuru@marvell.com>, Akhil Goyal\n <gakhil@marvell.com>, Fan Zhang <roy.fan.zhang@intel.com>",
        "Subject": "[PATCH v7 1/7] app/test: add unit cases for inline IPsec offload",
        "Date": "Tue, 24 May 2022 12:52:10 +0530",
        "Message-ID": "<20220524072216.1283647-2-gakhil@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20220524072216.1283647-1-gakhil@marvell.com>",
        "References": "<20220513073201.2320812-1-gakhil@marvell.com>\n <20220524072216.1283647-1-gakhil@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "VcZVaGcZVbOA9PmzLLVsm0sMVPW3wxFz",
        "X-Proofpoint-GUID": "VcZVaGcZVbOA9PmzLLVsm0sMVPW3wxFz",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.205,Aquarius:18.0.874,Hydra:6.0.486,FMLib:17.11.64.514\n definitions=2022-05-24_05,2022-05-23_01,2022-02-23_01",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "A new test suite is added in test app to test inline IPsec protocol\noffload. In this patch, predefined vectors from Lookaside IPsec test\nare used to verify the IPsec functionality without the need of\nexternal traffic generators. The sent packet is loopbacked onto the same\ninterface which is received and matched with the expected output.\nThe test suite can be updated further with other functional test cases.\nIn this patch encap only cases are added.\nThe testsuite can be run using:\nRTE> inline_ipsec_autotest\n\nSigned-off-by: Akhil Goyal <gakhil@marvell.com>\nSigned-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>\nAcked-by: Fan Zhang <roy.fan.zhang@intel.com>\n---\n MAINTAINERS                                   |   2 +-\n app/test/meson.build                          |   1 +\n app/test/test_security_inline_proto.c         | 887 ++++++++++++++++++\n app/test/test_security_inline_proto_vectors.h |  20 +\n doc/guides/rel_notes/release_22_07.rst        |   5 +\n 5 files changed, 914 insertions(+), 1 deletion(-)\n create mode 100644 app/test/test_security_inline_proto.c\n create mode 100644 app/test/test_security_inline_proto_vectors.h",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 17a0559ee7..841279814b 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -441,7 +441,7 @@ M: Akhil Goyal <gakhil@marvell.com>\n T: git://dpdk.org/next/dpdk-next-crypto\n F: lib/security/\n F: doc/guides/prog_guide/rte_security.rst\n-F: app/test/test_security.c\n+F: app/test/test_security*\n \n Compression API - EXPERIMENTAL\n M: Fan Zhang <roy.fan.zhang@intel.com>\ndiff --git a/app/test/meson.build b/app/test/meson.build\nindex 15591ce5cf..0f712680de 100644\n--- a/app/test/meson.build\n+++ b/app/test/meson.build\n@@ -125,6 +125,7 @@ test_sources = files(\n         'test_rwlock.c',\n         'test_sched.c',\n         'test_security.c',\n+        'test_security_inline_proto.c',\n         'test_service_cores.c',\n         'test_spinlock.c',\n         'test_stack.c',\ndiff --git a/app/test/test_security_inline_proto.c b/app/test/test_security_inline_proto.c\nnew file mode 100644\nindex 0000000000..4b960ddfe0\n--- /dev/null\n+++ b/app/test/test_security_inline_proto.c\n@@ -0,0 +1,887 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2022 Marvell.\n+ */\n+\n+\n+#include <stdio.h>\n+#include <inttypes.h>\n+\n+#include <rte_ethdev.h>\n+#include <rte_malloc.h>\n+#include <rte_security.h>\n+\n+#include \"test.h\"\n+#include \"test_security_inline_proto_vectors.h\"\n+\n+#ifdef RTE_EXEC_ENV_WINDOWS\n+static int\n+test_inline_ipsec(void)\n+{\n+\tprintf(\"Inline ipsec not supported on Windows, skipping test\\n\");\n+\treturn TEST_SKIPPED;\n+}\n+\n+#else\n+\n+#define NB_ETHPORTS_USED\t\t1\n+#define MEMPOOL_CACHE_SIZE\t\t32\n+#define MAX_PKT_BURST\t\t\t32\n+#define RTE_TEST_RX_DESC_DEFAULT\t1024\n+#define RTE_TEST_TX_DESC_DEFAULT\t1024\n+#define RTE_PORT_ALL\t\t(~(uint16_t)0x0)\n+\n+#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */\n+#define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */\n+#define RX_WTHRESH 0 /**< Default values of RX write-back threshold reg. */\n+\n+#define TX_PTHRESH 32 /**< Default values of TX prefetch threshold reg. */\n+#define TX_HTHRESH 0  /**< Default values of TX host threshold reg. */\n+#define TX_WTHRESH 0  /**< Default values of TX write-back threshold reg. */\n+\n+#define MAX_TRAFFIC_BURST\t\t2048\n+#define NB_MBUF\t\t\t\t10240\n+\n+extern struct ipsec_test_data pkt_aes_128_gcm;\n+extern struct ipsec_test_data pkt_aes_192_gcm;\n+extern struct ipsec_test_data pkt_aes_256_gcm;\n+extern struct ipsec_test_data pkt_aes_128_gcm_frag;\n+extern struct ipsec_test_data pkt_aes_128_cbc_null;\n+extern struct ipsec_test_data pkt_null_aes_xcbc;\n+extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha384;\n+extern struct ipsec_test_data pkt_aes_128_cbc_hmac_sha512;\n+\n+static struct rte_mempool *mbufpool;\n+static struct rte_mempool *sess_pool;\n+static struct rte_mempool *sess_priv_pool;\n+/* ethernet addresses of ports */\n+static struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];\n+\n+static struct rte_eth_conf port_conf = {\n+\t.rxmode = {\n+\t\t.mq_mode = RTE_ETH_MQ_RX_NONE,\n+\t\t.split_hdr_size = 0,\n+\t\t.offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM |\n+\t\t\t    RTE_ETH_RX_OFFLOAD_SECURITY,\n+\t},\n+\t.txmode = {\n+\t\t.mq_mode = RTE_ETH_MQ_TX_NONE,\n+\t\t.offloads = RTE_ETH_TX_OFFLOAD_SECURITY |\n+\t\t\t    RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE,\n+\t},\n+\t.lpbk_mode = 1,  /* enable loopback */\n+};\n+\n+static struct rte_eth_rxconf rx_conf = {\n+\t.rx_thresh = {\n+\t\t.pthresh = RX_PTHRESH,\n+\t\t.hthresh = RX_HTHRESH,\n+\t\t.wthresh = RX_WTHRESH,\n+\t},\n+\t.rx_free_thresh = 32,\n+};\n+\n+static struct rte_eth_txconf tx_conf = {\n+\t.tx_thresh = {\n+\t\t.pthresh = TX_PTHRESH,\n+\t\t.hthresh = TX_HTHRESH,\n+\t\t.wthresh = TX_WTHRESH,\n+\t},\n+\t.tx_free_thresh = 32, /* Use PMD default values */\n+\t.tx_rs_thresh = 32, /* Use PMD default values */\n+};\n+\n+uint16_t port_id;\n+\n+static uint64_t link_mbps;\n+\n+static struct rte_flow *default_flow[RTE_MAX_ETHPORTS];\n+\n+/* Create Inline IPsec session */\n+static int\n+create_inline_ipsec_session(struct ipsec_test_data *sa, uint16_t portid,\n+\t\tstruct rte_security_session **sess, struct rte_security_ctx **ctx,\n+\t\tuint32_t *ol_flags, const struct ipsec_test_flags *flags,\n+\t\tstruct rte_security_session_conf *sess_conf)\n+{\n+\tuint16_t src_v6[8] = {0x2607, 0xf8b0, 0x400c, 0x0c03, 0x0000, 0x0000,\n+\t\t\t\t0x0000, 0x001a};\n+\tuint16_t dst_v6[8] = {0x2001, 0x0470, 0xe5bf, 0xdead, 0x4957, 0x2174,\n+\t\t\t\t0xe82c, 0x4887};\n+\tuint32_t src_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 2));\n+\tuint32_t dst_v4 = rte_cpu_to_be_32(RTE_IPV4(192, 168, 1, 1));\n+\tstruct rte_security_capability_idx sec_cap_idx;\n+\tconst struct rte_security_capability *sec_cap;\n+\tenum rte_security_ipsec_sa_direction dir;\n+\tstruct rte_security_ctx *sec_ctx;\n+\tuint32_t verify;\n+\n+\tsess_conf->action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;\n+\tsess_conf->protocol = RTE_SECURITY_PROTOCOL_IPSEC;\n+\tsess_conf->ipsec = sa->ipsec_xform;\n+\n+\tdir = sa->ipsec_xform.direction;\n+\tverify = flags->tunnel_hdr_verify;\n+\n+\tif ((dir == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) && verify) {\n+\t\tif (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR)\n+\t\t\tsrc_v4 += 1;\n+\t\telse if (verify == RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR)\n+\t\t\tdst_v4 += 1;\n+\t}\n+\n+\tif (sa->ipsec_xform.mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {\n+\t\tif (sa->ipsec_xform.tunnel.type ==\n+\t\t\t\tRTE_SECURITY_IPSEC_TUNNEL_IPV4) {\n+\t\t\tmemcpy(&sess_conf->ipsec.tunnel.ipv4.src_ip, &src_v4,\n+\t\t\t\t\tsizeof(src_v4));\n+\t\t\tmemcpy(&sess_conf->ipsec.tunnel.ipv4.dst_ip, &dst_v4,\n+\t\t\t\t\tsizeof(dst_v4));\n+\n+\t\t\tif (flags->df == TEST_IPSEC_SET_DF_0_INNER_1)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv4.df = 0;\n+\n+\t\t\tif (flags->df == TEST_IPSEC_SET_DF_1_INNER_0)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv4.df = 1;\n+\n+\t\t\tif (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv4.dscp = 0;\n+\n+\t\t\tif (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv4.dscp =\n+\t\t\t\t\t\tTEST_IPSEC_DSCP_VAL;\n+\t\t} else {\n+\t\t\tif (flags->dscp == TEST_IPSEC_SET_DSCP_0_INNER_1)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv6.dscp = 0;\n+\n+\t\t\tif (flags->dscp == TEST_IPSEC_SET_DSCP_1_INNER_0)\n+\t\t\t\tsess_conf->ipsec.tunnel.ipv6.dscp =\n+\t\t\t\t\t\tTEST_IPSEC_DSCP_VAL;\n+\n+\t\t\tmemcpy(&sess_conf->ipsec.tunnel.ipv6.src_addr, &src_v6,\n+\t\t\t\t\tsizeof(src_v6));\n+\t\t\tmemcpy(&sess_conf->ipsec.tunnel.ipv6.dst_addr, &dst_v6,\n+\t\t\t\t\tsizeof(dst_v6));\n+\t\t}\n+\t}\n+\n+\t/* Save SA as userdata for the security session. When\n+\t * the packet is received, this userdata will be\n+\t * retrieved using the metadata from the packet.\n+\t *\n+\t * The PMD is expected to set similar metadata for other\n+\t * operations, like rte_eth_event, which are tied to\n+\t * security session. In such cases, the userdata could\n+\t * be obtained to uniquely identify the security\n+\t * parameters denoted.\n+\t */\n+\n+\tsess_conf->userdata = (void *) sa;\n+\n+\tsec_ctx = (struct rte_security_ctx *)rte_eth_dev_get_sec_ctx(portid);\n+\tif (sec_ctx == NULL) {\n+\t\tprintf(\"Ethernet device doesn't support security features.\\n\");\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\tsec_cap_idx.action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;\n+\tsec_cap_idx.protocol = RTE_SECURITY_PROTOCOL_IPSEC;\n+\tsec_cap_idx.ipsec.proto = sess_conf->ipsec.proto;\n+\tsec_cap_idx.ipsec.mode = sess_conf->ipsec.mode;\n+\tsec_cap_idx.ipsec.direction = sess_conf->ipsec.direction;\n+\tsec_cap = rte_security_capability_get(sec_ctx, &sec_cap_idx);\n+\tif (sec_cap == NULL) {\n+\t\tprintf(\"No capabilities registered\\n\");\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\tif (sa->aead || sa->aes_gmac)\n+\t\tmemcpy(&sess_conf->ipsec.salt, sa->salt.data,\n+\t\t\tRTE_MIN(sizeof(sess_conf->ipsec.salt), sa->salt.len));\n+\n+\t/* Copy cipher session parameters */\n+\tif (sa->aead) {\n+\t\trte_memcpy(sess_conf->crypto_xform, &sa->xform.aead,\n+\t\t\t\tsizeof(struct rte_crypto_sym_xform));\n+\t\tsess_conf->crypto_xform->aead.key.data = sa->key.data;\n+\t\t/* Verify crypto capabilities */\n+\t\tif (test_ipsec_crypto_caps_aead_verify(sec_cap,\n+\t\t\t\t\tsess_conf->crypto_xform) != 0) {\n+\t\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\t\"Crypto capabilities not supported\\n\");\n+\t\t\treturn TEST_SKIPPED;\n+\t\t}\n+\t} else {\n+\t\tif (dir == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {\n+\t\t\trte_memcpy(&sess_conf->crypto_xform->cipher,\n+\t\t\t\t\t&sa->xform.chain.cipher.cipher,\n+\t\t\t\t\tsizeof(struct rte_crypto_cipher_xform));\n+\n+\t\t\trte_memcpy(&sess_conf->crypto_xform->next->auth,\n+\t\t\t\t\t&sa->xform.chain.auth.auth,\n+\t\t\t\t\tsizeof(struct rte_crypto_auth_xform));\n+\t\t\tsess_conf->crypto_xform->cipher.key.data =\n+\t\t\t\t\t\t\tsa->key.data;\n+\t\t\tsess_conf->crypto_xform->next->auth.key.data =\n+\t\t\t\t\t\t\tsa->auth_key.data;\n+\t\t\t/* Verify crypto capabilities */\n+\t\t\tif (test_ipsec_crypto_caps_cipher_verify(sec_cap,\n+\t\t\t\t\tsess_conf->crypto_xform) != 0) {\n+\t\t\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\t\t\"Cipher crypto capabilities not supported\\n\");\n+\t\t\t\treturn TEST_SKIPPED;\n+\t\t\t}\n+\n+\t\t\tif (test_ipsec_crypto_caps_auth_verify(sec_cap,\n+\t\t\t\t\tsess_conf->crypto_xform->next) != 0) {\n+\t\t\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\t\t\"Auth crypto capabilities not supported\\n\");\n+\t\t\t\treturn TEST_SKIPPED;\n+\t\t\t}\n+\t\t} else {\n+\t\t\trte_memcpy(&sess_conf->crypto_xform->next->cipher,\n+\t\t\t\t\t&sa->xform.chain.cipher.cipher,\n+\t\t\t\t\tsizeof(struct rte_crypto_cipher_xform));\n+\t\t\trte_memcpy(&sess_conf->crypto_xform->auth,\n+\t\t\t\t\t&sa->xform.chain.auth.auth,\n+\t\t\t\t\tsizeof(struct rte_crypto_auth_xform));\n+\t\t\tsess_conf->crypto_xform->auth.key.data =\n+\t\t\t\t\t\t\tsa->auth_key.data;\n+\t\t\tsess_conf->crypto_xform->next->cipher.key.data =\n+\t\t\t\t\t\t\tsa->key.data;\n+\n+\t\t\t/* Verify crypto capabilities */\n+\t\t\tif (test_ipsec_crypto_caps_cipher_verify(sec_cap,\n+\t\t\t\t\tsess_conf->crypto_xform->next) != 0) {\n+\t\t\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\t\t\"Cipher crypto capabilities not supported\\n\");\n+\t\t\t\treturn TEST_SKIPPED;\n+\t\t\t}\n+\n+\t\t\tif (test_ipsec_crypto_caps_auth_verify(sec_cap,\n+\t\t\t\t\tsess_conf->crypto_xform) != 0) {\n+\t\t\t\tRTE_LOG(INFO, USER1,\n+\t\t\t\t\t\"Auth crypto capabilities not supported\\n\");\n+\t\t\t\treturn TEST_SKIPPED;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (test_ipsec_sec_caps_verify(&sess_conf->ipsec, sec_cap, false) != 0)\n+\t\treturn TEST_SKIPPED;\n+\n+\tif ((sa->ipsec_xform.direction ==\n+\t\t\tRTE_SECURITY_IPSEC_SA_DIR_EGRESS) &&\n+\t\t\t(sa->ipsec_xform.options.iv_gen_disable == 1)) {\n+\t\t/* Set env variable when IV generation is disabled */\n+\t\tchar arr[128];\n+\t\tint len = 0, j = 0;\n+\t\tint iv_len = (sa->aead || sa->aes_gmac) ? 8 : 16;\n+\n+\t\tfor (; j < iv_len; j++)\n+\t\t\tlen += snprintf(arr+len, sizeof(arr) - len,\n+\t\t\t\t\t\"0x%x, \", sa->iv.data[j]);\n+\t\tsetenv(\"ETH_SEC_IV_OVR\", arr, 1);\n+\t}\n+\n+\t*sess = rte_security_session_create(sec_ctx,\n+\t\t\t\tsess_conf, sess_pool, sess_priv_pool);\n+\tif (*sess == NULL) {\n+\t\tprintf(\"SEC Session init failed.\\n\");\n+\t\treturn TEST_FAILED;\n+\t}\n+\n+\t*ol_flags = sec_cap->ol_flags;\n+\t*ctx = sec_ctx;\n+\n+\treturn 0;\n+}\n+\n+/* Check the link status of all ports in up to 3s, and print them finally */\n+static void\n+check_all_ports_link_status(uint16_t port_num, uint32_t port_mask)\n+{\n+#define CHECK_INTERVAL 100 /* 100ms */\n+#define MAX_CHECK_TIME 30 /* 3s (30 * 100ms) in total */\n+\tuint16_t portid;\n+\tuint8_t count, all_ports_up, print_flag = 0;\n+\tstruct rte_eth_link link;\n+\tint ret;\n+\tchar link_status[RTE_ETH_LINK_MAX_STR_LEN];\n+\n+\tprintf(\"Checking link statuses...\\n\");\n+\tfflush(stdout);\n+\tfor (count = 0; count <= MAX_CHECK_TIME; count++) {\n+\t\tall_ports_up = 1;\n+\t\tfor (portid = 0; portid < port_num; portid++) {\n+\t\t\tif ((port_mask & (1 << portid)) == 0)\n+\t\t\t\tcontinue;\n+\t\t\tmemset(&link, 0, sizeof(link));\n+\t\t\tret = rte_eth_link_get_nowait(portid, &link);\n+\t\t\tif (ret < 0) {\n+\t\t\t\tall_ports_up = 0;\n+\t\t\t\tif (print_flag == 1)\n+\t\t\t\t\tprintf(\"Port %u link get failed: %s\\n\",\n+\t\t\t\t\t\tportid, rte_strerror(-ret));\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\t/* print link status if flag set */\n+\t\t\tif (print_flag == 1) {\n+\t\t\t\tif (link.link_status && link_mbps == 0)\n+\t\t\t\t\tlink_mbps = link.link_speed;\n+\n+\t\t\t\trte_eth_link_to_str(link_status,\n+\t\t\t\t\tsizeof(link_status), &link);\n+\t\t\t\tprintf(\"Port %d %s\\n\", portid, link_status);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\t/* clear all_ports_up flag if any link down */\n+\t\t\tif (link.link_status == RTE_ETH_LINK_DOWN) {\n+\t\t\t\tall_ports_up = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* after finally printing all link status, get out */\n+\t\tif (print_flag == 1)\n+\t\t\tbreak;\n+\n+\t\tif (all_ports_up == 0) {\n+\t\t\tfflush(stdout);\n+\t\t\trte_delay_ms(CHECK_INTERVAL);\n+\t\t}\n+\n+\t\t/* set the print_flag if all ports up or timeout */\n+\t\tif (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1))\n+\t\t\tprint_flag = 1;\n+\t}\n+}\n+\n+static void\n+print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)\n+{\n+\tchar buf[RTE_ETHER_ADDR_FMT_SIZE];\n+\trte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);\n+\tprintf(\"%s%s\", name, buf);\n+}\n+\n+static void\n+copy_buf_to_pkt_segs(const uint8_t *buf, unsigned int len,\n+\t\t     struct rte_mbuf *pkt, unsigned int offset)\n+{\n+\tunsigned int copied = 0;\n+\tunsigned int copy_len;\n+\tstruct rte_mbuf *seg;\n+\tvoid *seg_buf;\n+\n+\tseg = pkt;\n+\twhile (offset >= seg->data_len) {\n+\t\toffset -= seg->data_len;\n+\t\tseg = seg->next;\n+\t}\n+\tcopy_len = seg->data_len - offset;\n+\tseg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);\n+\twhile (len > copy_len) {\n+\t\trte_memcpy(seg_buf, buf + copied, (size_t) copy_len);\n+\t\tlen -= copy_len;\n+\t\tcopied += copy_len;\n+\t\tseg = seg->next;\n+\t\tseg_buf = rte_pktmbuf_mtod(seg, void *);\n+\t}\n+\trte_memcpy(seg_buf, buf + copied, (size_t) len);\n+}\n+\n+static inline struct rte_mbuf *\n+init_packet(struct rte_mempool *mp, const uint8_t *data, unsigned int len)\n+{\n+\tstruct rte_mbuf *pkt;\n+\n+\tpkt = rte_pktmbuf_alloc(mp);\n+\tif (pkt == NULL)\n+\t\treturn NULL;\n+\tif (((data[0] & 0xF0) >> 4) == IPVERSION) {\n+\t\trte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN),\n+\t\t\t\t&dummy_ipv4_eth_hdr, RTE_ETHER_HDR_LEN);\n+\t\tpkt->l3_len = sizeof(struct rte_ipv4_hdr);\n+\t} else {\n+\t\trte_memcpy(rte_pktmbuf_append(pkt, RTE_ETHER_HDR_LEN),\n+\t\t\t\t&dummy_ipv6_eth_hdr, RTE_ETHER_HDR_LEN);\n+\t\tpkt->l3_len = sizeof(struct rte_ipv6_hdr);\n+\t}\n+\tpkt->l2_len = RTE_ETHER_HDR_LEN;\n+\n+\tif (pkt->buf_len > (len + RTE_ETHER_HDR_LEN))\n+\t\trte_memcpy(rte_pktmbuf_append(pkt, len), data, len);\n+\telse\n+\t\tcopy_buf_to_pkt_segs(data, len, pkt, RTE_ETHER_HDR_LEN);\n+\treturn pkt;\n+}\n+\n+static int\n+init_mempools(unsigned int nb_mbuf)\n+{\n+\tstruct rte_security_ctx *sec_ctx;\n+\tuint16_t nb_sess = 512;\n+\tuint32_t sess_sz;\n+\tchar s[64];\n+\n+\tif (mbufpool == NULL) {\n+\t\tsnprintf(s, sizeof(s), \"mbuf_pool\");\n+\t\tmbufpool = rte_pktmbuf_pool_create(s, nb_mbuf,\n+\t\t\t\tMEMPOOL_CACHE_SIZE, 0,\n+\t\t\t\tRTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY);\n+\t\tif (mbufpool == NULL) {\n+\t\t\tprintf(\"Cannot init mbuf pool\\n\");\n+\t\t\treturn TEST_FAILED;\n+\t\t}\n+\t\tprintf(\"Allocated mbuf pool\\n\");\n+\t}\n+\n+\tsec_ctx = rte_eth_dev_get_sec_ctx(port_id);\n+\tif (sec_ctx == NULL) {\n+\t\tprintf(\"Device does not support Security ctx\\n\");\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\tsess_sz = rte_security_session_get_size(sec_ctx);\n+\tif (sess_pool == NULL) {\n+\t\tsnprintf(s, sizeof(s), \"sess_pool\");\n+\t\tsess_pool = rte_mempool_create(s, nb_sess, sess_sz,\n+\t\t\t\tMEMPOOL_CACHE_SIZE, 0,\n+\t\t\t\tNULL, NULL, NULL, NULL,\n+\t\t\t\tSOCKET_ID_ANY, 0);\n+\t\tif (sess_pool == NULL) {\n+\t\t\tprintf(\"Cannot init sess pool\\n\");\n+\t\t\treturn TEST_FAILED;\n+\t\t}\n+\t\tprintf(\"Allocated sess pool\\n\");\n+\t}\n+\tif (sess_priv_pool == NULL) {\n+\t\tsnprintf(s, sizeof(s), \"sess_priv_pool\");\n+\t\tsess_priv_pool = rte_mempool_create(s, nb_sess, sess_sz,\n+\t\t\t\tMEMPOOL_CACHE_SIZE, 0,\n+\t\t\t\tNULL, NULL, NULL, NULL,\n+\t\t\t\tSOCKET_ID_ANY, 0);\n+\t\tif (sess_priv_pool == NULL) {\n+\t\t\tprintf(\"Cannot init sess_priv pool\\n\");\n+\t\t\treturn TEST_FAILED;\n+\t\t}\n+\t\tprintf(\"Allocated sess_priv pool\\n\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+create_default_flow(uint16_t portid)\n+{\n+\tstruct rte_flow_action action[2];\n+\tstruct rte_flow_item pattern[2];\n+\tstruct rte_flow_attr attr = {0};\n+\tstruct rte_flow_error err;\n+\tstruct rte_flow *flow;\n+\tint ret;\n+\n+\t/* Add the default rte_flow to enable SECURITY for all ESP packets */\n+\n+\tpattern[0].type = RTE_FLOW_ITEM_TYPE_ESP;\n+\tpattern[0].spec = NULL;\n+\tpattern[0].mask = NULL;\n+\tpattern[0].last = NULL;\n+\tpattern[1].type = RTE_FLOW_ITEM_TYPE_END;\n+\n+\taction[0].type = RTE_FLOW_ACTION_TYPE_SECURITY;\n+\taction[0].conf = NULL;\n+\taction[1].type = RTE_FLOW_ACTION_TYPE_END;\n+\taction[1].conf = NULL;\n+\n+\tattr.ingress = 1;\n+\n+\tret = rte_flow_validate(portid, &attr, pattern, action, &err);\n+\tif (ret) {\n+\t\tprintf(\"\\nValidate flow failed, ret = %d\\n\", ret);\n+\t\treturn -1;\n+\t}\n+\tflow = rte_flow_create(portid, &attr, pattern, action, &err);\n+\tif (flow == NULL) {\n+\t\tprintf(\"\\nDefault flow rule create failed\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tdefault_flow[portid] = flow;\n+\n+\treturn 0;\n+}\n+\n+static void\n+destroy_default_flow(uint16_t portid)\n+{\n+\tstruct rte_flow_error err;\n+\tint ret;\n+\n+\tif (!default_flow[portid])\n+\t\treturn;\n+\tret = rte_flow_destroy(portid, default_flow[portid], &err);\n+\tif (ret) {\n+\t\tprintf(\"\\nDefault flow rule destroy failed\\n\");\n+\t\treturn;\n+\t}\n+\tdefault_flow[portid] = NULL;\n+}\n+\n+struct rte_mbuf **tx_pkts_burst;\n+struct rte_mbuf **rx_pkts_burst;\n+\n+static int\n+test_ipsec_inline_proto_process(struct ipsec_test_data *td,\n+\t\tstruct ipsec_test_data *res_d,\n+\t\tint nb_pkts,\n+\t\tbool silent,\n+\t\tconst struct ipsec_test_flags *flags)\n+{\n+\tstruct rte_security_session_conf sess_conf = {0};\n+\tstruct rte_crypto_sym_xform cipher = {0};\n+\tstruct rte_crypto_sym_xform auth = {0};\n+\tstruct rte_crypto_sym_xform aead = {0};\n+\tstruct rte_security_session *ses;\n+\tstruct rte_security_ctx *ctx;\n+\tint nb_rx = 0, nb_sent;\n+\tuint32_t ol_flags;\n+\tint i, j = 0, ret;\n+\n+\tmemset(rx_pkts_burst, 0, sizeof(rx_pkts_burst[0]) * nb_pkts);\n+\n+\tif (td->aead) {\n+\t\tsess_conf.crypto_xform = &aead;\n+\t} else {\n+\t\tif (td->ipsec_xform.direction ==\n+\t\t\t\tRTE_SECURITY_IPSEC_SA_DIR_EGRESS) {\n+\t\t\tsess_conf.crypto_xform = &cipher;\n+\t\t\tsess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\t\t\tsess_conf.crypto_xform->next = &auth;\n+\t\t\tsess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;\n+\t\t} else {\n+\t\t\tsess_conf.crypto_xform = &auth;\n+\t\t\tsess_conf.crypto_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;\n+\t\t\tsess_conf.crypto_xform->next = &cipher;\n+\t\t\tsess_conf.crypto_xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER;\n+\t\t}\n+\t}\n+\n+\t/* Create Inline IPsec session. */\n+\tret = create_inline_ipsec_session(td, port_id, &ses, &ctx,\n+\t\t\t\t\t  &ol_flags, flags, &sess_conf);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {\n+\t\tret = create_default_flow(port_id);\n+\t\tif (ret)\n+\t\t\tgoto out;\n+\t}\n+\tfor (i = 0; i < nb_pkts; i++) {\n+\t\ttx_pkts_burst[i] = init_packet(mbufpool, td->input_text.data,\n+\t\t\t\t\t\ttd->input_text.len);\n+\t\tif (tx_pkts_burst[i] == NULL) {\n+\t\t\twhile (i--)\n+\t\t\t\trte_pktmbuf_free(tx_pkts_burst[i]);\n+\t\t\tret = TEST_FAILED;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tif (test_ipsec_pkt_update(rte_pktmbuf_mtod_offset(tx_pkts_burst[i],\n+\t\t\t\t\tuint8_t *, RTE_ETHER_HDR_LEN), flags)) {\n+\t\t\twhile (i--)\n+\t\t\t\trte_pktmbuf_free(tx_pkts_burst[i]);\n+\t\t\tret = TEST_FAILED;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tif (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {\n+\t\t\tif (ol_flags & RTE_SECURITY_TX_OLOAD_NEED_MDATA)\n+\t\t\t\trte_security_set_pkt_metadata(ctx, ses,\n+\t\t\t\t\t\ttx_pkts_burst[i], NULL);\n+\t\t\ttx_pkts_burst[i]->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;\n+\t\t}\n+\t}\n+\t/* Send packet to ethdev for inline IPsec processing. */\n+\tnb_sent = rte_eth_tx_burst(port_id, 0, tx_pkts_burst, nb_pkts);\n+\tif (nb_sent != nb_pkts) {\n+\t\tprintf(\"\\nUnable to TX %d packets\", nb_pkts);\n+\t\tfor ( ; nb_sent < nb_pkts; nb_sent++)\n+\t\t\trte_pktmbuf_free(tx_pkts_burst[nb_sent]);\n+\t\tret = TEST_FAILED;\n+\t\tgoto out;\n+\t}\n+\n+\trte_pause();\n+\n+\t/* Receive back packet on loopback interface. */\n+\tdo {\n+\t\trte_delay_ms(1);\n+\t\tnb_rx += rte_eth_rx_burst(port_id, 0, &rx_pkts_burst[nb_rx],\n+\t\t\t\tnb_sent - nb_rx);\n+\t\tif (nb_rx >= nb_sent)\n+\t\t\tbreak;\n+\t} while (j++ < 5 || nb_rx == 0);\n+\n+\tif (nb_rx != nb_sent) {\n+\t\tprintf(\"\\nUnable to RX all %d packets\", nb_sent);\n+\t\twhile (--nb_rx)\n+\t\t\trte_pktmbuf_free(rx_pkts_burst[nb_rx]);\n+\t\tret = TEST_FAILED;\n+\t\tgoto out;\n+\t}\n+\n+\tfor (i = 0; i < nb_rx; i++) {\n+\t\trte_pktmbuf_adj(rx_pkts_burst[i], RTE_ETHER_HDR_LEN);\n+\n+\t\tret = test_ipsec_post_process(rx_pkts_burst[i], td,\n+\t\t\t\t\t      res_d, silent, flags);\n+\t\tif (ret != TEST_SUCCESS) {\n+\t\t\tfor ( ; i < nb_rx; i++)\n+\t\t\t\trte_pktmbuf_free(rx_pkts_burst[i]);\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\tret = test_ipsec_stats_verify(ctx, ses, flags,\n+\t\t\t\t\ttd->ipsec_xform.direction);\n+\t\tif (ret != TEST_SUCCESS) {\n+\t\t\tfor ( ; i < nb_rx; i++)\n+\t\t\t\trte_pktmbuf_free(rx_pkts_burst[i]);\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\trte_pktmbuf_free(rx_pkts_burst[i]);\n+\t\trx_pkts_burst[i] = NULL;\n+\t}\n+\n+out:\n+\tif (td->ipsec_xform.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS)\n+\t\tdestroy_default_flow(port_id);\n+\n+\t/* Destroy session so that other cases can create the session again */\n+\trte_security_session_destroy(ctx, ses);\n+\tses = NULL;\n+\n+\treturn ret;\n+}\n+\n+static int\n+ut_setup_inline_ipsec(void)\n+{\n+\tint ret;\n+\n+\t/* Start device */\n+\tret = rte_eth_dev_start(port_id);\n+\tif (ret < 0) {\n+\t\tprintf(\"rte_eth_dev_start: err=%d, port=%d\\n\",\n+\t\t\tret, port_id);\n+\t\treturn ret;\n+\t}\n+\t/* always enable promiscuous */\n+\tret = rte_eth_promiscuous_enable(port_id);\n+\tif (ret != 0) {\n+\t\tprintf(\"rte_eth_promiscuous_enable: err=%s, port=%d\\n\",\n+\t\t\trte_strerror(-ret), port_id);\n+\t\treturn ret;\n+\t}\n+\n+\tcheck_all_ports_link_status(1, RTE_PORT_ALL);\n+\n+\treturn 0;\n+}\n+\n+static void\n+ut_teardown_inline_ipsec(void)\n+{\n+\tuint16_t portid;\n+\tint ret;\n+\n+\t/* port tear down */\n+\tRTE_ETH_FOREACH_DEV(portid) {\n+\t\tret = rte_eth_dev_stop(portid);\n+\t\tif (ret != 0)\n+\t\t\tprintf(\"rte_eth_dev_stop: err=%s, port=%u\\n\",\n+\t\t\t       rte_strerror(-ret), portid);\n+\t}\n+}\n+\n+static int\n+inline_ipsec_testsuite_setup(void)\n+{\n+\tuint16_t nb_rxd;\n+\tuint16_t nb_txd;\n+\tuint16_t nb_ports;\n+\tint ret;\n+\tuint16_t nb_rx_queue = 1, nb_tx_queue = 1;\n+\n+\tprintf(\"Start inline IPsec test.\\n\");\n+\n+\tnb_ports = rte_eth_dev_count_avail();\n+\tif (nb_ports < NB_ETHPORTS_USED) {\n+\t\tprintf(\"At least %u port(s) used for test\\n\",\n+\t\t       NB_ETHPORTS_USED);\n+\t\treturn TEST_SKIPPED;\n+\t}\n+\n+\tret = init_mempools(NB_MBUF);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (tx_pkts_burst == NULL) {\n+\t\ttx_pkts_burst = (struct rte_mbuf **)rte_calloc(\"tx_buff\",\n+\t\t\t\t\t  MAX_TRAFFIC_BURST,\n+\t\t\t\t\t  sizeof(void *),\n+\t\t\t\t\t  RTE_CACHE_LINE_SIZE);\n+\t\tif (!tx_pkts_burst)\n+\t\t\treturn TEST_FAILED;\n+\n+\t\trx_pkts_burst = (struct rte_mbuf **)rte_calloc(\"rx_buff\",\n+\t\t\t\t\t  MAX_TRAFFIC_BURST,\n+\t\t\t\t\t  sizeof(void *),\n+\t\t\t\t\t  RTE_CACHE_LINE_SIZE);\n+\t\tif (!rx_pkts_burst)\n+\t\t\treturn TEST_FAILED;\n+\t}\n+\n+\tprintf(\"Generate %d packets\\n\", MAX_TRAFFIC_BURST);\n+\n+\tnb_rxd = RTE_TEST_RX_DESC_DEFAULT;\n+\tnb_txd = RTE_TEST_TX_DESC_DEFAULT;\n+\n+\t/* configuring port 0 for the test is enough */\n+\tport_id = 0;\n+\t/* port configure */\n+\tret = rte_eth_dev_configure(port_id, nb_rx_queue,\n+\t\t\t\t    nb_tx_queue, &port_conf);\n+\tif (ret < 0) {\n+\t\tprintf(\"Cannot configure device: err=%d, port=%d\\n\",\n+\t\t\t ret, port_id);\n+\t\treturn ret;\n+\t}\n+\tret = rte_eth_macaddr_get(port_id, &ports_eth_addr[port_id]);\n+\tif (ret < 0) {\n+\t\tprintf(\"Cannot get mac address: err=%d, port=%d\\n\",\n+\t\t\t ret, port_id);\n+\t\treturn ret;\n+\t}\n+\tprintf(\"Port %u \", port_id);\n+\tprint_ethaddr(\"Address:\", &ports_eth_addr[port_id]);\n+\tprintf(\"\\n\");\n+\n+\t/* tx queue setup */\n+\tret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,\n+\t\t\t\t     SOCKET_ID_ANY, &tx_conf);\n+\tif (ret < 0) {\n+\t\tprintf(\"rte_eth_tx_queue_setup: err=%d, port=%d\\n\",\n+\t\t\t\tret, port_id);\n+\t\treturn ret;\n+\t}\n+\t/* rx queue steup */\n+\tret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd, SOCKET_ID_ANY,\n+\t\t\t\t     &rx_conf, mbufpool);\n+\tif (ret < 0) {\n+\t\tprintf(\"rte_eth_rx_queue_setup: err=%d, port=%d\\n\",\n+\t\t\t\tret, port_id);\n+\t\treturn ret;\n+\t}\n+\ttest_ipsec_alg_list_populate();\n+\n+\treturn 0;\n+}\n+\n+static void\n+inline_ipsec_testsuite_teardown(void)\n+{\n+\tuint16_t portid;\n+\tint ret;\n+\n+\t/* port tear down */\n+\tRTE_ETH_FOREACH_DEV(portid) {\n+\t\tret = rte_eth_dev_reset(portid);\n+\t\tif (ret != 0)\n+\t\t\tprintf(\"rte_eth_dev_reset: err=%s, port=%u\\n\",\n+\t\t\t       rte_strerror(-ret), port_id);\n+\t}\n+}\n+\n+static int\n+test_ipsec_inline_proto_known_vec(const void *test_data)\n+{\n+\tstruct ipsec_test_data td_outb;\n+\tstruct ipsec_test_flags flags;\n+\n+\tmemset(&flags, 0, sizeof(flags));\n+\n+\tmemcpy(&td_outb, test_data, sizeof(td_outb));\n+\n+\tif (td_outb.aead ||\n+\t    td_outb.xform.chain.cipher.cipher.algo != RTE_CRYPTO_CIPHER_NULL) {\n+\t\t/* Disable IV gen to be able to test with known vectors */\n+\t\ttd_outb.ipsec_xform.options.iv_gen_disable = 1;\n+\t}\n+\n+\treturn test_ipsec_inline_proto_process(&td_outb, NULL, 1,\n+\t\t\t\tfalse, &flags);\n+}\n+\n+static struct unit_test_suite inline_ipsec_testsuite  = {\n+\t.suite_name = \"Inline IPsec Ethernet Device Unit Test Suite\",\n+\t.setup = inline_ipsec_testsuite_setup,\n+\t.teardown = inline_ipsec_testsuite_teardown,\n+\t.unit_test_cases = {\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-GCM 128)\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec, &pkt_aes_128_gcm),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-GCM 192)\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec, &pkt_aes_192_gcm),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-GCM 256)\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA256 [16B ICV])\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec,\n+\t\t\t&pkt_aes_128_cbc_hmac_sha256),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA384 [24B ICV])\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec,\n+\t\t\t&pkt_aes_128_cbc_hmac_sha384),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 AES-CBC 128 HMAC-SHA512 [32B ICV])\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec,\n+\t\t\t&pkt_aes_128_cbc_hmac_sha512),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv6 AES-GCM 128)\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec, &pkt_aes_256_gcm_v6),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv6 AES-CBC 128 HMAC-SHA256 [16B ICV])\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec,\n+\t\t\t&pkt_aes_128_cbc_hmac_sha256_v6),\n+\t\tTEST_CASE_NAMED_WITH_DATA(\n+\t\t\t\"Outbound known vector (ESP tunnel mode IPv4 NULL AES-XCBC-MAC [12B ICV])\",\n+\t\t\tut_setup_inline_ipsec, ut_teardown_inline_ipsec,\n+\t\t\ttest_ipsec_inline_proto_known_vec,\n+\t\t\t&pkt_null_aes_xcbc),\n+\n+\t\tTEST_CASES_END() /**< NULL terminate unit test array */\n+\t},\n+};\n+\n+\n+static int\n+test_inline_ipsec(void)\n+{\n+\treturn unit_test_suite_runner(&inline_ipsec_testsuite);\n+}\n+\n+#endif /* !RTE_EXEC_ENV_WINDOWS */\n+\n+REGISTER_TEST_COMMAND(inline_ipsec_autotest, test_inline_ipsec);\ndiff --git a/app/test/test_security_inline_proto_vectors.h b/app/test/test_security_inline_proto_vectors.h\nnew file mode 100644\nindex 0000000000..d1074da36a\n--- /dev/null\n+++ b/app/test/test_security_inline_proto_vectors.h\n@@ -0,0 +1,20 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2022 Marvell.\n+ */\n+#ifndef _TEST_INLINE_IPSEC_REASSEMBLY_VECTORS_H_\n+#define _TEST_INLINE_IPSEC_REASSEMBLY_VECTORS_H_\n+\n+#include \"test_cryptodev_security_ipsec.h\"\n+\n+uint8_t dummy_ipv4_eth_hdr[] = {\n+\t\t/* ETH */\n+\t\t0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,\n+\t\t0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00,\n+};\n+uint8_t dummy_ipv6_eth_hdr[] = {\n+\t\t/* ETH */\n+\t\t0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1,\n+\t\t0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd,\n+};\n+\n+#endif\ndiff --git a/doc/guides/rel_notes/release_22_07.rst b/doc/guides/rel_notes/release_22_07.rst\nindex e49cacecef..46d60f7369 100644\n--- a/doc/guides/rel_notes/release_22_07.rst\n+++ b/doc/guides/rel_notes/release_22_07.rst\n@@ -104,6 +104,11 @@ New Features\n   * ``RTE_EVENT_QUEUE_ATTR_WEIGHT``\n   * ``RTE_EVENT_QUEUE_ATTR_AFFINITY``\n \n+* **Added security inline protocol (IPsec) tests in dpdk-test.**\n+\n+  Added various functional test cases in dpdk-test to verify\n+  inline IPsec protocol offload using loopback interface.\n+\n \n Removed Items\n -------------\n",
    "prefixes": [
        "v7",
        "1/7"
    ]
}