get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 48919,
    "url": "http://patches.dpdk.org/api/patches/48919/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1544805623-18150-8-git-send-email-konstantin.ananyev@intel.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": "<1544805623-18150-8-git-send-email-konstantin.ananyev@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1544805623-18150-8-git-send-email-konstantin.ananyev@intel.com",
    "date": "2018-12-14T16:40:21",
    "name": "[v4,7/9] examples/ipsec-secgw: make data-path to use ipsec library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "019a5508a9851263163bcc0f1c26150daf5f3cf8",
    "submitter": {
        "id": 33,
        "url": "http://patches.dpdk.org/api/people/33/?format=api",
        "name": "Ananyev, Konstantin",
        "email": "konstantin.ananyev@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1544805623-18150-8-git-send-email-konstantin.ananyev@intel.com/mbox/",
    "series": [
        {
            "id": 2799,
            "url": "http://patches.dpdk.org/api/series/2799/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=2799",
            "date": "2018-12-14T16:40:21",
            "name": null,
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/2799/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/48919/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/48919/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5FFF81BB83;\n\tFri, 14 Dec 2018 17:40:48 +0100 (CET)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id 3EDE11B92C\n\tfor <dev@dpdk.org>; Fri, 14 Dec 2018 17:40:40 +0100 (CET)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t14 Dec 2018 08:40:39 -0800",
            "from sivswdev08.ir.intel.com (HELO localhost.localdomain)\n\t([10.237.217.47])\n\tby orsmga008.jf.intel.com with ESMTP; 14 Dec 2018 08:40:37 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.56,353,1539673200\"; d=\"scan'208\";a=\"101573835\"",
        "From": "Konstantin Ananyev <konstantin.ananyev@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "akhil.goyal@nxp.com, radu.nicolau@intel.com,\n\tKonstantin Ananyev <konstantin.ananyev@intel.com>,\n\tMohammad Abdul Awal <mohammad.abdul.awal@intel.com>,\n\tBernard Iremonger <bernard.iremonger@intel.com>",
        "Date": "Fri, 14 Dec 2018 16:40:21 +0000",
        "Message-Id": "<1544805623-18150-8-git-send-email-konstantin.ananyev@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": "<1544111691-7481-1-git-send-email-konstantin.ananyev@intel.com>",
        "References": "<1544111691-7481-1-git-send-email-konstantin.ananyev@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v4 7/9] examples/ipsec-secgw: make data-path to\n\tuse ipsec library",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Changes to make ipsec-secgw data-path code to utilize librte_ipsec library.\nNote that right now by default current (non-librte_ipsec) code-path will\nbe used. User has to run application with new command-line option ('-l')\nto enable new codepath.\n\nSigned-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>\nSigned-off-by: Bernard Iremonger <bernard.iremonger@intel.com>\nSigned-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>\nAcked-by: Radu Nicolau <radu.nicolau@intel.com>\n---\n examples/ipsec-secgw/Makefile        |   1 +\n examples/ipsec-secgw/ipsec-secgw.c   | 178 ++++++++------\n examples/ipsec-secgw/ipsec.c         |   2 +-\n examples/ipsec-secgw/ipsec.h         |  23 ++\n examples/ipsec-secgw/ipsec_process.c | 341 +++++++++++++++++++++++++++\n examples/ipsec-secgw/meson.build     |   4 +-\n examples/ipsec-secgw/sa.c            |   7 +-\n 7 files changed, 477 insertions(+), 79 deletions(-)\n create mode 100644 examples/ipsec-secgw/ipsec_process.c",
    "diff": "diff --git a/examples/ipsec-secgw/Makefile b/examples/ipsec-secgw/Makefile\nindex 02d41e39a..4d6b4cfa4 100644\n--- a/examples/ipsec-secgw/Makefile\n+++ b/examples/ipsec-secgw/Makefile\n@@ -13,6 +13,7 @@ SRCS-y += sp4.c\n SRCS-y += sp6.c\n SRCS-y += sa.c\n SRCS-y += rt.c\n+SRCS-y += ipsec_process.c\n SRCS-y += ipsec-secgw.c\n \n CFLAGS += -gdwarf-2\ndiff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c\nindex 48baa5001..53cfe585d 100644\n--- a/examples/ipsec-secgw/ipsec-secgw.c\n+++ b/examples/ipsec-secgw/ipsec-secgw.c\n@@ -216,19 +216,6 @@ static struct rte_eth_conf port_conf = {\n \n static struct socket_ctx socket_ctx[NB_SOCKETS];\n \n-struct traffic_type {\n-\tconst uint8_t *data[MAX_PKT_BURST * 2];\n-\tstruct rte_mbuf *pkts[MAX_PKT_BURST * 2];\n-\tuint32_t res[MAX_PKT_BURST * 2];\n-\tuint32_t num;\n-};\n-\n-struct ipsec_traffic {\n-\tstruct traffic_type ipsec;\n-\tstruct traffic_type ip4;\n-\tstruct traffic_type ip6;\n-};\n-\n static inline void\n prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)\n {\n@@ -245,6 +232,8 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)\n \t\t\tt->ip4.data[t->ip4.num] = nlp;\n \t\t\tt->ip4.pkts[(t->ip4.num)++] = pkt;\n \t\t}\n+\t\tpkt->l2_len = 0;\n+\t\tpkt->l3_len = sizeof(struct ip);\n \t} else if (eth->ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6)) {\n \t\tnlp = (uint8_t *)rte_pktmbuf_adj(pkt, ETHER_HDR_LEN);\n \t\tnlp = RTE_PTR_ADD(nlp, offsetof(struct ip6_hdr, ip6_nxt));\n@@ -254,6 +243,8 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t)\n \t\t\tt->ip6.data[t->ip6.num] = nlp;\n \t\t\tt->ip6.pkts[(t->ip6.num)++] = pkt;\n \t\t}\n+\t\tpkt->l2_len = 0;\n+\t\tpkt->l3_len = sizeof(struct ip6_hdr);\n \t} else {\n \t\t/* Unknown/Unsupported type, drop the packet */\n \t\tRTE_LOG(ERR, IPSEC, \"Unsupported packet type\\n\");\n@@ -503,10 +494,15 @@ process_pkts_inbound(struct ipsec_ctx *ipsec_ctx,\n \tn_ip4 = traffic->ip4.num;\n \tn_ip6 = traffic->ip6.num;\n \n-\tnb_pkts_in = ipsec_inbound(ipsec_ctx, traffic->ipsec.pkts,\n-\t\t\ttraffic->ipsec.num, MAX_PKT_BURST);\n-\n-\tsplit46_traffic(traffic, traffic->ipsec.pkts, nb_pkts_in);\n+\tif (app_sa_prm.enable == 0) {\n+\t\tnb_pkts_in = ipsec_inbound(ipsec_ctx, traffic->ipsec.pkts,\n+\t\t\t\ttraffic->ipsec.num, MAX_PKT_BURST);\n+\t\tsplit46_traffic(traffic, traffic->ipsec.pkts, nb_pkts_in);\n+\t} else {\n+\t\tinbound_sa_lookup(ipsec_ctx->sa_ctx, traffic->ipsec.pkts,\n+\t\t\ttraffic->ipsec.saptr, traffic->ipsec.num);\n+\t\tipsec_process(ipsec_ctx, traffic);\n+\t}\n \n \tinbound_sp_sa(ipsec_ctx->sp4_ctx, ipsec_ctx->sa_ctx, &traffic->ip4,\n \t\t\tn_ip4);\n@@ -562,20 +558,27 @@ process_pkts_outbound(struct ipsec_ctx *ipsec_ctx,\n \n \toutbound_sp(ipsec_ctx->sp6_ctx, &traffic->ip6, &traffic->ipsec);\n \n-\tnb_pkts_out = ipsec_outbound(ipsec_ctx, traffic->ipsec.pkts,\n-\t\t\ttraffic->ipsec.res, traffic->ipsec.num,\n-\t\t\tMAX_PKT_BURST);\n-\n-\tfor (i = 0; i < nb_pkts_out; i++) {\n-\t\tm = traffic->ipsec.pkts[i];\n-\t\tstruct ip *ip = rte_pktmbuf_mtod(m, struct ip *);\n-\t\tif (ip->ip_v == IPVERSION) {\n-\t\t\tidx = traffic->ip4.num++;\n-\t\t\ttraffic->ip4.pkts[idx] = m;\n-\t\t} else {\n-\t\t\tidx = traffic->ip6.num++;\n-\t\t\ttraffic->ip6.pkts[idx] = m;\n+\tif (app_sa_prm.enable == 0) {\n+\n+\t\tnb_pkts_out = ipsec_outbound(ipsec_ctx, traffic->ipsec.pkts,\n+\t\t\t\ttraffic->ipsec.res, traffic->ipsec.num,\n+\t\t\t\tMAX_PKT_BURST);\n+\n+\t\tfor (i = 0; i < nb_pkts_out; i++) {\n+\t\t\tm = traffic->ipsec.pkts[i];\n+\t\t\tstruct ip *ip = rte_pktmbuf_mtod(m, struct ip *);\n+\t\t\tif (ip->ip_v == IPVERSION) {\n+\t\t\t\tidx = traffic->ip4.num++;\n+\t\t\t\ttraffic->ip4.pkts[idx] = m;\n+\t\t\t} else {\n+\t\t\t\tidx = traffic->ip6.num++;\n+\t\t\t\ttraffic->ip6.pkts[idx] = m;\n+\t\t\t}\n \t\t}\n+\t} else {\n+\t\toutbound_sa_lookup(ipsec_ctx->sa_ctx, traffic->ipsec.res,\n+\t\t\ttraffic->ipsec.saptr, traffic->ipsec.num);\n+\t\tipsec_process(ipsec_ctx, traffic);\n \t}\n }\n \n@@ -598,19 +601,26 @@ process_pkts_inbound_nosp(struct ipsec_ctx *ipsec_ctx,\n \n \ttraffic->ip6.num = 0;\n \n-\tnb_pkts_in = ipsec_inbound(ipsec_ctx, traffic->ipsec.pkts,\n-\t\t\ttraffic->ipsec.num, MAX_PKT_BURST);\n+\tif (app_sa_prm.enable == 0) {\n \n-\tfor (i = 0; i < nb_pkts_in; i++) {\n-\t\tm = traffic->ipsec.pkts[i];\n-\t\tstruct ip *ip = rte_pktmbuf_mtod(m, struct ip *);\n-\t\tif (ip->ip_v == IPVERSION) {\n-\t\t\tidx = traffic->ip4.num++;\n-\t\t\ttraffic->ip4.pkts[idx] = m;\n-\t\t} else {\n-\t\t\tidx = traffic->ip6.num++;\n-\t\t\ttraffic->ip6.pkts[idx] = m;\n+\t\tnb_pkts_in = ipsec_inbound(ipsec_ctx, traffic->ipsec.pkts,\n+\t\t\t\ttraffic->ipsec.num, MAX_PKT_BURST);\n+\n+\t\tfor (i = 0; i < nb_pkts_in; i++) {\n+\t\t\tm = traffic->ipsec.pkts[i];\n+\t\t\tstruct ip *ip = rte_pktmbuf_mtod(m, struct ip *);\n+\t\t\tif (ip->ip_v == IPVERSION) {\n+\t\t\t\tidx = traffic->ip4.num++;\n+\t\t\t\ttraffic->ip4.pkts[idx] = m;\n+\t\t\t} else {\n+\t\t\t\tidx = traffic->ip6.num++;\n+\t\t\t\ttraffic->ip6.pkts[idx] = m;\n+\t\t\t}\n \t\t}\n+\t} else {\n+\t\tinbound_sa_lookup(ipsec_ctx->sa_ctx, traffic->ipsec.pkts,\n+\t\t\ttraffic->ipsec.saptr, traffic->ipsec.num);\n+\t\tipsec_process(ipsec_ctx, traffic);\n \t}\n }\n \n@@ -642,20 +652,28 @@ process_pkts_outbound_nosp(struct ipsec_ctx *ipsec_ctx,\n \ttraffic->ip6.num = 0;\n \ttraffic->ipsec.num = n;\n \n-\tnb_pkts_out = ipsec_outbound(ipsec_ctx, traffic->ipsec.pkts,\n-\t\t\ttraffic->ipsec.res, traffic->ipsec.num,\n-\t\t\tMAX_PKT_BURST);\n+\tif (app_sa_prm.enable == 0) {\n \n-\t/* They all sue the same SA (ip4 or ip6 tunnel) */\n-\tm = traffic->ipsec.pkts[i];\n-\tip = rte_pktmbuf_mtod(m, struct ip *);\n-\tif (ip->ip_v == IPVERSION) {\n-\t\ttraffic->ip4.num = nb_pkts_out;\n-\t\tfor (i = 0; i < nb_pkts_out; i++)\n-\t\t\ttraffic->ip4.pkts[i] = traffic->ipsec.pkts[i];\n+\t\tnb_pkts_out = ipsec_outbound(ipsec_ctx, traffic->ipsec.pkts,\n+\t\t\t\ttraffic->ipsec.res, traffic->ipsec.num,\n+\t\t\t\tMAX_PKT_BURST);\n+\n+\t\t/* They all sue the same SA (ip4 or ip6 tunnel) */\n+\t\tm = traffic->ipsec.pkts[0];\n+\t\tip = rte_pktmbuf_mtod(m, struct ip *);\n+\t\tif (ip->ip_v == IPVERSION) {\n+\t\t\ttraffic->ip4.num = nb_pkts_out;\n+\t\t\tfor (i = 0; i < nb_pkts_out; i++)\n+\t\t\t\ttraffic->ip4.pkts[i] = traffic->ipsec.pkts[i];\n+\t\t} else {\n+\t\t\ttraffic->ip6.num = nb_pkts_out;\n+\t\t\tfor (i = 0; i < nb_pkts_out; i++)\n+\t\t\t\ttraffic->ip6.pkts[i] = traffic->ipsec.pkts[i];\n+\t\t}\n \t} else {\n-\t\ttraffic->ip6.num = nb_pkts_out;\n-\t\ttraffic->ip6.pkts[i] = traffic->ipsec.pkts[i];\n+\t\toutbound_sa_lookup(ipsec_ctx->sa_ctx, traffic->ipsec.res,\n+\t\t\ttraffic->ipsec.saptr, traffic->ipsec.num);\n+\t\tipsec_process(ipsec_ctx, traffic);\n \t}\n }\n \n@@ -856,25 +874,31 @@ drain_inbound_crypto_queues(const struct lcore_conf *qconf,\n \tuint32_t n;\n \tstruct ipsec_traffic trf;\n \n-\t/* dequeue packets from crypto-queue */\n-\tn = ipsec_inbound_cqp_dequeue(ctx, trf.ipsec.pkts,\n+\tif (app_sa_prm.enable == 0) {\n+\n+\t\t/* dequeue packets from crypto-queue */\n+\t\tn = ipsec_inbound_cqp_dequeue(ctx, trf.ipsec.pkts,\n \t\t\tRTE_DIM(trf.ipsec.pkts));\n-\tif (n == 0)\n-\t\treturn;\n \n-\ttrf.ip4.num = 0;\n-\ttrf.ip6.num = 0;\n+\t\ttrf.ip4.num = 0;\n+\t\ttrf.ip6.num = 0;\n \n-\t/* split traffic by ipv4-ipv6 */\n-\tsplit46_traffic(&trf, trf.ipsec.pkts, n);\n+\t\t/* split traffic by ipv4-ipv6 */\n+\t\tsplit46_traffic(&trf, trf.ipsec.pkts, n);\n+\t} else\n+\t\tipsec_cqp_process(ctx, &trf);\n \n \t/* process ipv4 packets */\n-\tinbound_sp_sa(ctx->sp4_ctx, ctx->sa_ctx, &trf.ip4, 0);\n-\troute4_pkts(qconf->rt4_ctx, trf.ip4.pkts, trf.ip4.num);\n+\tif (trf.ip4.num != 0) {\n+\t\tinbound_sp_sa(ctx->sp4_ctx, ctx->sa_ctx, &trf.ip4, 0);\n+\t\troute4_pkts(qconf->rt4_ctx, trf.ip4.pkts, trf.ip4.num);\n+\t}\n \n \t/* process ipv6 packets */\n-\tinbound_sp_sa(ctx->sp6_ctx, ctx->sa_ctx, &trf.ip6, 0);\n-\troute6_pkts(qconf->rt6_ctx, trf.ip6.pkts, trf.ip6.num);\n+\tif (trf.ip6.num != 0) {\n+\t\tinbound_sp_sa(ctx->sp6_ctx, ctx->sa_ctx, &trf.ip6, 0);\n+\t\troute6_pkts(qconf->rt6_ctx, trf.ip6.pkts, trf.ip6.num);\n+\t}\n }\n \n static void\n@@ -884,23 +908,27 @@ drain_outbound_crypto_queues(const struct lcore_conf *qconf,\n \tuint32_t n;\n \tstruct ipsec_traffic trf;\n \n-\t/* dequeue packets from crypto-queue */\n-\tn = ipsec_outbound_cqp_dequeue(ctx, trf.ipsec.pkts,\n+\tif (app_sa_prm.enable == 0) {\n+\n+\t\t/* dequeue packets from crypto-queue */\n+\t\tn = ipsec_outbound_cqp_dequeue(ctx, trf.ipsec.pkts,\n \t\t\tRTE_DIM(trf.ipsec.pkts));\n-\tif (n == 0)\n-\t\treturn;\n \n-\ttrf.ip4.num = 0;\n-\ttrf.ip6.num = 0;\n+\t\ttrf.ip4.num = 0;\n+\t\ttrf.ip6.num = 0;\n \n-\t/* split traffic by ipv4-ipv6 */\n-\tsplit46_traffic(&trf, trf.ipsec.pkts, n);\n+\t\t/* split traffic by ipv4-ipv6 */\n+\t\tsplit46_traffic(&trf, trf.ipsec.pkts, n);\n+\t} else\n+\t\tipsec_cqp_process(ctx, &trf);\n \n \t/* process ipv4 packets */\n-\troute4_pkts(qconf->rt4_ctx, trf.ip4.pkts, trf.ip4.num);\n+\tif (trf.ip4.num != 0)\n+\t\troute4_pkts(qconf->rt4_ctx, trf.ip4.pkts, trf.ip4.num);\n \n \t/* process ipv6 packets */\n-\troute6_pkts(qconf->rt6_ctx, trf.ip6.pkts, trf.ip6.num);\n+\tif (trf.ip6.num != 0)\n+\t\troute6_pkts(qconf->rt6_ctx, trf.ip6.pkts, trf.ip6.num);\n }\n \n /* main processing loop */\ndiff --git a/examples/ipsec-secgw/ipsec.c b/examples/ipsec-secgw/ipsec.c\nindex 8bf928a23..8e7fc3639 100644\n--- a/examples/ipsec-secgw/ipsec.c\n+++ b/examples/ipsec-secgw/ipsec.c\n@@ -39,7 +39,7 @@ set_ipsec_conf(struct ipsec_sa *sa, struct rte_security_ipsec_xform *ipsec)\n \tipsec->esn_soft_limit = IPSEC_OFFLOAD_ESN_SOFTLIMIT;\n }\n \n-static inline int\n+int\n create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa)\n {\n \tstruct rte_cryptodev_info cdev_info;\ndiff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h\nindex b089fe54b..f0e2e79af 100644\n--- a/examples/ipsec-secgw/ipsec.h\n+++ b/examples/ipsec-secgw/ipsec.h\n@@ -190,6 +190,20 @@ struct cnt_blk {\n \tuint32_t cnt;\n } __attribute__((packed));\n \n+struct traffic_type {\n+\tconst uint8_t *data[MAX_PKT_BURST * 2];\n+\tstruct rte_mbuf *pkts[MAX_PKT_BURST * 2];\n+\tstruct ipsec_sa *saptr[MAX_PKT_BURST * 2];\n+\tuint32_t res[MAX_PKT_BURST * 2];\n+\tuint32_t num;\n+};\n+\n+struct ipsec_traffic {\n+\tstruct traffic_type ipsec;\n+\tstruct traffic_type ip4;\n+\tstruct traffic_type ip6;\n+};\n+\n uint16_t\n ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],\n \t\tuint16_t nb_pkts, uint16_t len);\n@@ -206,6 +220,12 @@ uint16_t\n ipsec_outbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],\n \t\tuint16_t len);\n \n+void\n+ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf);\n+\n+void\n+ipsec_cqp_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf);\n+\n static inline uint16_t\n ipsec_metadata_size(void)\n {\n@@ -283,4 +303,7 @@ add_dst_ethaddr(uint16_t port, const struct ether_addr *addr);\n void\n enqueue_cop_burst(struct cdev_qp *cqp);\n \n+int\n+create_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa);\n+\n #endif /* __IPSEC_H__ */\ndiff --git a/examples/ipsec-secgw/ipsec_process.c b/examples/ipsec-secgw/ipsec_process.c\nnew file mode 100644\nindex 000000000..7ab378f6a\n--- /dev/null\n+++ b/examples/ipsec-secgw/ipsec_process.c\n@@ -0,0 +1,341 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2016-2017 Intel Corporation\n+ */\n+#include <sys/types.h>\n+#include <netinet/in.h>\n+#include <netinet/ip.h>\n+\n+#include <rte_branch_prediction.h>\n+#include <rte_log.h>\n+#include <rte_cryptodev.h>\n+#include <rte_ethdev.h>\n+#include <rte_mbuf.h>\n+\n+#include \"ipsec.h\"\n+\n+#define SATP_OUT_IPV4(t)\t\\\n+\t((((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TRANS && \\\n+\t(((t) & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)) || \\\n+\t((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TUNLV4)\n+\n+\n+/* helper routine to free bulk of packets */\n+static inline void\n+free_pkts(struct rte_mbuf *mb[], uint32_t n)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i != n; i++)\n+\t\trte_pktmbuf_free(mb[i]);\n+}\n+\n+/* helper routine to free bulk of crypto-ops and related packets */\n+static inline void\n+free_cops(struct rte_crypto_op *cop[], uint32_t n)\n+{\n+\tuint32_t i;\n+\n+\tfor (i = 0; i != n; i++)\n+\t\trte_pktmbuf_free(cop[i]->sym->m_src);\n+}\n+\n+/* helper routine to enqueue bulk of crypto ops */\n+static inline void\n+enqueue_cop_bulk(struct cdev_qp *cqp, struct rte_crypto_op *cop[], uint32_t num)\n+{\n+\tuint32_t i, k, len, n;\n+\n+\tlen = cqp->len;\n+\n+\t/*\n+\t * if cqp is empty and we have enough ops,\n+\t * then queue them to the PMD straightway.\n+\t */\n+\tif (num >= RTE_DIM(cqp->buf) * 3 / 4 && len == 0) {\n+\t\tn = rte_cryptodev_enqueue_burst(cqp->id, cqp->qp, cop, num);\n+\t\tcqp->in_flight += n;\n+\t\tfree_cops(cop + n, num - n);\n+\t\treturn;\n+\t}\n+\n+\tk = 0;\n+\n+\tdo {\n+\t\tn = RTE_DIM(cqp->buf) - len;\n+\t\tn = RTE_MIN(num - k, n);\n+\n+\t\t/* put packets into cqp */\n+\t\tfor (i = 0; i != n; i++)\n+\t\t\tcqp->buf[len + i] = cop[k + i];\n+\n+\t\tlen += n;\n+\t\tk += n;\n+\n+\t\t/* if cqp is full then, enqueue crypto-ops to PMD */\n+\t\tif (len == RTE_DIM(cqp->buf)) {\n+\t\t\tn = rte_cryptodev_enqueue_burst(cqp->id, cqp->qp,\n+\t\t\t\t\tcqp->buf, len);\n+\t\t\tcqp->in_flight += n;\n+\t\t\tfree_cops(cqp->buf + n, len - n);\n+\t\t\tlen = 0;\n+\t\t}\n+\n+\n+\t} while (k != num);\n+\n+\tcqp->len = len;\n+}\n+\n+static inline int\n+fill_ipsec_session(struct rte_ipsec_session *ss, const struct ipsec_sa *sa)\n+{\n+\t/* setup crypto section */\n+\tif (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {\n+\t\tss->crypto.ses = sa->crypto_session;\n+\t/* setup session action type */\n+\t} else {\n+\t\tss->security.ses = sa->sec_session;\n+\t\tss->security.ctx = sa->security_ctx;\n+\t\tss->security.ol_flags = sa->ol_flags;\n+\t}\n+\n+\treturn rte_ipsec_session_prepare(ss);\n+}\n+\n+/*\n+ * group input packets byt the SA they belong to.\n+ */\n+static uint32_t\n+sa_group(struct ipsec_sa *sa_ptr[], struct rte_mbuf *pkts[],\n+\tstruct rte_ipsec_group grp[], uint32_t num)\n+{\n+\tuint32_t i, n, spi;\n+\tvoid *sa;\n+\tvoid * const nosa = &spi;\n+\n+\tsa = nosa;\n+\tfor (i = 0, n = 0; i != num; i++) {\n+\n+\t\tif (sa != sa_ptr[i]) {\n+\t\t\tgrp[n].cnt = pkts + i - grp[n].m;\n+\t\t\tn += (sa != nosa);\n+\t\t\tgrp[n].id.ptr = sa_ptr[i];\n+\t\t\tgrp[n].m = pkts + i;\n+\t\t\tsa = sa_ptr[i];\n+\t\t}\n+\t}\n+\n+\t/* terminate last group */\n+\tif (sa != nosa) {\n+\t\tgrp[n].cnt = pkts + i - grp[n].m;\n+\t\tn++;\n+\t}\n+\n+\treturn n;\n+}\n+\n+/*\n+ * helper function, splits processed packets into ipv4/ipv6 traffic.\n+ */\n+static inline void\n+copy_to_trf(struct ipsec_traffic *trf, uint64_t satp, struct rte_mbuf *mb[],\n+\tuint32_t num)\n+{\n+\tuint32_t j, ofs, s;\n+\tstruct traffic_type *out;\n+\n+\t/*\n+\t * determine traffic type(ipv4/ipv6) and offset for ACL classify\n+\t * based on SA type\n+\t */\n+\tif ((satp & RTE_IPSEC_SATP_DIR_MASK) == RTE_IPSEC_SATP_DIR_IB) {\n+\t\tif ((satp & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4) {\n+\t\t\tout = &trf->ip4;\n+\t\t\tofs = offsetof(struct ip, ip_p);\n+\t\t} else {\n+\t\t\tout = &trf->ip6;\n+\t\t\tofs = offsetof(struct ip6_hdr, ip6_nxt);\n+\t\t}\n+\t} else if (SATP_OUT_IPV4(satp)) {\n+\t\tout = &trf->ip4;\n+\t\tofs = offsetof(struct ip, ip_p);\n+\t} else {\n+\t\tout = &trf->ip6;\n+\t\tofs = offsetof(struct ip6_hdr, ip6_nxt);\n+\t}\n+\n+\tfor (j = 0, s = out->num; j != num; j++) {\n+\t\tout->data[s + j] = rte_pktmbuf_mtod_offset(mb[j],\n+\t\t\t\tvoid *, ofs);\n+\t\tout->pkts[s + j] = mb[j];\n+\t}\n+\n+\tout->num += num;\n+}\n+\n+/*\n+ * Process ipsec packets.\n+ * If packet belong to SA that is subject of inline-crypto,\n+ * then process it immediately.\n+ * Otherwise do necessary preparations and queue it to related\n+ * crypto-dev queue.\n+ */\n+void\n+ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)\n+{\n+\tuint64_t satp;\n+\tuint32_t i, j, k, n;\n+\tstruct ipsec_sa *sa;\n+\tstruct ipsec_mbuf_metadata *priv;\n+\tstruct rte_ipsec_group *pg;\n+\tstruct rte_ipsec_session *ips;\n+\tstruct cdev_qp *cqp;\n+\tstruct rte_crypto_op *cop[RTE_DIM(trf->ipsec.pkts)];\n+\tstruct rte_ipsec_group grp[RTE_DIM(trf->ipsec.pkts)];\n+\n+\tn = sa_group(trf->ipsec.saptr, trf->ipsec.pkts, grp, trf->ipsec.num);\n+\n+\tfor (i = 0; i != n; i++) {\n+\n+\t\tpg = grp + i;\n+\t\tsa = pg->id.ptr;\n+\n+\t\t/* no valid SA found */\n+\t\tif (sa == NULL)\n+\t\t\tk = 0;\n+\n+\t\tips = &sa->ips;\n+\t\tsatp = rte_ipsec_sa_type(ips->sa);\n+\n+\t\t/* no valid HW session for that SA, try to create one */\n+\t\tif (ips->crypto.ses == NULL &&\n+\t\t\t\t(create_session(ctx, sa) != 0 ||\n+\t\t\t\tfill_ipsec_session(ips, sa) != 0))\n+\t\t\tk = 0;\n+\n+\t\t/* process packets inline */\n+\t\telse if (sa->type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO ||\n+\t\t\t\tsa->type ==\n+\t\t\t\tRTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {\n+\n+\t\t\t/*\n+\t\t\t * This is just to satisfy inbound_sa_check()\n+\t\t\t * and get_hop_for_offload_pkt().\n+\t\t\t * Should be removed in future.\n+\t\t\t */\n+\t\t\tfor (j = 0; j != pg->cnt; j++) {\n+\t\t\t\tpriv = get_priv(pg->m[j]);\n+\t\t\t\tpriv->sa = sa;\n+\t\t\t}\n+\n+\t\t\tk = rte_ipsec_pkt_process(ips, pg->m, pg->cnt);\n+\t\t\tcopy_to_trf(trf, satp, pg->m, k);\n+\n+\t\t/* enqueue packets to crypto dev */\n+\t\t} else {\n+\n+\t\t\tcqp = &ctx->tbl[sa->cdev_id_qp];\n+\n+\t\t\t/* for that app each mbuf has it's own crypto op */\n+\t\t\tfor (j = 0; j != pg->cnt; j++) {\n+\t\t\t\tpriv = get_priv(pg->m[j]);\n+\t\t\t\tcop[j] = &priv->cop;\n+\t\t\t\t/*\n+\t\t\t\t * this is just to satisfy inbound_sa_check()\n+\t\t\t\t * should be removed in future.\n+\t\t\t\t */\n+\t\t\t\tpriv->sa = sa;\n+\t\t\t}\n+\n+\t\t\t/* prepare and enqueue crypto ops */\n+\t\t\tk = rte_ipsec_pkt_crypto_prepare(ips, pg->m, cop,\n+\t\t\t\tpg->cnt);\n+\t\t\tif (k != 0)\n+\t\t\t\tenqueue_cop_bulk(cqp, cop, k);\n+\t\t}\n+\n+\t\t/* drop packets that cannot be enqueued/processed */\n+\t\tif (k != pg->cnt)\n+\t\t\tfree_pkts(pg->m + k, pg->cnt - k);\n+\t}\n+}\n+\n+static inline uint32_t\n+cqp_dequeue(struct cdev_qp *cqp, struct rte_crypto_op *cop[], uint32_t num)\n+{\n+\tuint32_t n;\n+\n+\tif (cqp->in_flight == 0)\n+\t\treturn 0;\n+\n+\tn = rte_cryptodev_dequeue_burst(cqp->id, cqp->qp, cop, num);\n+\tRTE_ASSERT(cqp->in_flight >= n);\n+\tcqp->in_flight -= n;\n+\n+\treturn n;\n+}\n+\n+static inline uint32_t\n+ctx_dequeue(struct ipsec_ctx *ctx, struct rte_crypto_op *cop[], uint32_t num)\n+{\n+\tuint32_t i, n;\n+\n+\tn = 0;\n+\n+\tfor (i = ctx->last_qp; n != num && i != ctx->nb_qps; i++)\n+\t\tn += cqp_dequeue(ctx->tbl + i, cop + n, num - n);\n+\n+\tfor (i = 0; n != num && i != ctx->last_qp; i++)\n+\t\tn += cqp_dequeue(ctx->tbl + i, cop + n, num - n);\n+\n+\tctx->last_qp = i;\n+\treturn n;\n+}\n+\n+/*\n+ * dequeue packets from crypto-queues and finalize processing.\n+ */\n+void\n+ipsec_cqp_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf)\n+{\n+\tuint64_t satp;\n+\tuint32_t i, k, n, ng;\n+\tstruct rte_ipsec_session *ss;\n+\tstruct traffic_type *out;\n+\tstruct rte_ipsec_group *pg;\n+\tstruct rte_crypto_op *cop[RTE_DIM(trf->ipsec.pkts)];\n+\tstruct rte_ipsec_group grp[RTE_DIM(trf->ipsec.pkts)];\n+\n+\ttrf->ip4.num = 0;\n+\ttrf->ip6.num = 0;\n+\n+\tout = &trf->ipsec;\n+\n+\t/* dequeue completed crypto-ops */\n+\tn = ctx_dequeue(ctx, cop, RTE_DIM(cop));\n+\tif (n == 0)\n+\t\treturn;\n+\n+\t/* group them by ipsec session */\n+\tng = rte_ipsec_pkt_crypto_group((const struct rte_crypto_op **)\n+\t\t(uintptr_t)cop, out->pkts, grp, n);\n+\n+\t/* process each group of packets */\n+\tfor (i = 0; i != ng; i++) {\n+\n+\t\tpg = grp + i;\n+\t\tss = pg->id.ptr;\n+\t\tsatp = rte_ipsec_sa_type(ss->sa);\n+\n+\t\tk = rte_ipsec_pkt_process(ss, pg->m, pg->cnt);\n+\t\tcopy_to_trf(trf, satp, pg->m, k);\n+\n+\t\t/* free bad packets, if any */\n+\t\tfree_pkts(pg->m + k, pg->cnt - k);\n+\n+\t\tn -= pg->cnt;\n+\t}\n+\n+\t/* we should never have packet with unknown SA here */\n+\tRTE_VERIFY(n == 0);\n+}\ndiff --git a/examples/ipsec-secgw/meson.build b/examples/ipsec-secgw/meson.build\nindex 31f68fee2..81c146ebc 100644\n--- a/examples/ipsec-secgw/meson.build\n+++ b/examples/ipsec-secgw/meson.build\n@@ -9,6 +9,6 @@\n deps += ['security', 'lpm', 'acl', 'hash', 'ipsec']\n allow_experimental_apis = true\n sources = files(\n-\t'esp.c', 'ipsec.c', 'ipsec-secgw.c', 'parser.c',\n-\t'rt.c', 'sa.c', 'sp4.c', 'sp6.c'\n+\t'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c',\n+\t'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c'\n )\ndiff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c\nindex 04eb8bce8..49da966a3 100644\n--- a/examples/ipsec-secgw/sa.c\n+++ b/examples/ipsec-secgw/sa.c\n@@ -1164,10 +1164,15 @@ int\n inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx)\n {\n \tstruct ipsec_mbuf_metadata *priv;\n+\tstruct ipsec_sa *sa;\n \n \tpriv = get_priv(m);\n+\tsa = priv->sa;\n+\tif (sa != NULL)\n+\t\treturn (sa_ctx->sa[sa_idx].spi == sa->spi);\n \n-\treturn (sa_ctx->sa[sa_idx].spi == priv->sa->spi);\n+\tRTE_LOG(ERR, IPSEC, \"SA not saved in private data\\n\");\n+\treturn 0;\n }\n \n static inline void\n",
    "prefixes": [
        "v4",
        "7/9"
    ]
}