get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 65539,
    "url": "http://patches.dpdk.org/api/patches/65539/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200204131258.17632-6-marcinx.smoczynski@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": "<20200204131258.17632-6-marcinx.smoczynski@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200204131258.17632-6-marcinx.smoczynski@intel.com",
    "date": "2020-02-04T13:12:55",
    "name": "[v6,5/8] ipsec: introduce support for cpu crypto mode",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "0896c6ed62a047eab21f4c447ccac801311a5f05",
    "submitter": {
        "id": 1293,
        "url": "http://patches.dpdk.org/api/people/1293/?format=api",
        "name": "Marcin Smoczynski",
        "email": "marcinx.smoczynski@intel.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/20200204131258.17632-6-marcinx.smoczynski@intel.com/mbox/",
    "series": [
        {
            "id": 8413,
            "url": "http://patches.dpdk.org/api/series/8413/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8413",
            "date": "2020-02-04T13:12:50",
            "name": "Introduce CPU crypto mode",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/8413/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/65539/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/65539/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 13DBFA0534;\n\tTue,  4 Feb 2020 14:13:58 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 510D91C1C0;\n\tTue,  4 Feb 2020 14:13:18 +0100 (CET)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n by dpdk.org (Postfix) with ESMTP id CEEB41C1BC\n for <dev@dpdk.org>; Tue,  4 Feb 2020 14:13:15 +0100 (CET)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n 04 Feb 2020 05:13:15 -0800",
            "from msmoczyx-mobl.ger.corp.intel.com ([10.103.102.190])\n by fmsmga005.fm.intel.com with ESMTP; 04 Feb 2020 05:13:13 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.70,401,1574150400\"; d=\"scan'208\";a=\"429800428\"",
        "From": "Marcin Smoczynski <marcinx.smoczynski@intel.com>",
        "To": "akhil.goyal@nxp.com, konstantin.ananyev@intel.com,\n roy.fan.zhang@intel.com,\n declan.doherty@intel.com, radu.nicolau@intel.com,\n pablo.de.lara.guarch@intel.com",
        "Cc": "dev@dpdk.org,\n\tMarcin Smoczynski <marcinx.smoczynski@intel.com>",
        "Date": "Tue,  4 Feb 2020 14:12:55 +0100",
        "Message-Id": "<20200204131258.17632-6-marcinx.smoczynski@intel.com>",
        "X-Mailer": "git-send-email 2.21.0.windows.1",
        "In-Reply-To": "<20200204131258.17632-1-marcinx.smoczynski@intel.com>",
        "References": "<20200128142220.16644-1-marcinx.smoczynski@intel.com>\n <20200204131258.17632-1-marcinx.smoczynski@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v6 5/8] ipsec: introduce support for cpu crypto\n\tmode",
        "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 <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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Update library to handle CPU cypto security mode which utilizes\ncryptodev's synchronous, CPU accelerated crypto operations.\n\nSigned-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>\nSigned-off-by: Marcin Smoczynski <marcinx.smoczynski@intel.com>\nAcked-by: Fan Zhang <roy.fan.zhang@intel.com>\nTested-by: Konstantin Ananyev <konstantin.ananyev@intel.com>\n---\n doc/guides/prog_guide/ipsec_lib.rst |  10 +-\n lib/librte_ipsec/esp_inb.c          | 156 ++++++++++++++++++++++++----\n lib/librte_ipsec/esp_outb.c         | 136 ++++++++++++++++++++++--\n lib/librte_ipsec/misc.h             |  73 ++++++++++++-\n lib/librte_ipsec/rte_ipsec.h        |  20 +++-\n lib/librte_ipsec/sa.c               | 114 ++++++++++++++++----\n lib/librte_ipsec/sa.h               |  19 +++-\n lib/librte_ipsec/ses.c              |   5 +-\n 8 files changed, 475 insertions(+), 58 deletions(-)",
    "diff": "diff --git a/doc/guides/prog_guide/ipsec_lib.rst b/doc/guides/prog_guide/ipsec_lib.rst\nindex 1ce0db453..0a860eb47 100644\n--- a/doc/guides/prog_guide/ipsec_lib.rst\n+++ b/doc/guides/prog_guide/ipsec_lib.rst\n@@ -1,5 +1,5 @@\n ..  SPDX-License-Identifier: BSD-3-Clause\n-    Copyright(c) 2018 Intel Corporation.\n+    Copyright(c) 2018-2020 Intel Corporation.\n \n IPsec Packet Processing Library\n ===============================\n@@ -81,6 +81,14 @@ In that mode the library functions perform\n   - verify that crypto device operations (encryption, ICV generation)\n     were completed successfully\n \n+RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+In that mode the library functions perform same operations as in\n+``RTE_SECURITY_ACTION_TYPE_NONE``. The only differnce is that crypto operations\n+are performed with CPU crypto synchronous API.\n+\n+\n RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \ndiff --git a/lib/librte_ipsec/esp_inb.c b/lib/librte_ipsec/esp_inb.c\nindex 5c653dd39..7b8ab81f6 100644\n--- a/lib/librte_ipsec/esp_inb.c\n+++ b/lib/librte_ipsec/esp_inb.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #include <rte_ipsec.h>\n@@ -105,6 +105,39 @@ inb_cop_prepare(struct rte_crypto_op *cop,\n \t}\n }\n \n+static inline uint32_t\n+inb_cpu_crypto_prepare(const struct rte_ipsec_sa *sa, struct rte_mbuf *mb,\n+\tuint32_t *pofs, uint32_t plen, void *iv)\n+{\n+\tstruct aead_gcm_iv *gcm;\n+\tstruct aesctr_cnt_blk *ctr;\n+\tuint64_t *ivp;\n+\tuint32_t clen;\n+\n+\tivp = rte_pktmbuf_mtod_offset(mb, uint64_t *,\n+\t\t*pofs + sizeof(struct rte_esp_hdr));\n+\tclen = 0;\n+\n+\tswitch (sa->algo_type) {\n+\tcase ALGO_TYPE_AES_GCM:\n+\t\tgcm = (struct aead_gcm_iv *)iv;\n+\t\taead_gcm_iv_fill(gcm, ivp[0], sa->salt);\n+\t\tbreak;\n+\tcase ALGO_TYPE_AES_CBC:\n+\tcase ALGO_TYPE_3DES_CBC:\n+\t\tcopy_iv(iv, ivp, sa->iv_len);\n+\t\tbreak;\n+\tcase ALGO_TYPE_AES_CTR:\n+\t\tctr = (struct aesctr_cnt_blk *)iv;\n+\t\taes_ctr_cnt_blk_fill(ctr, ivp[0], sa->salt);\n+\t\tbreak;\n+\t}\n+\n+\t*pofs += sa->ctp.auth.offset;\n+\tclen = plen - sa->ctp.auth.length;\n+\treturn clen;\n+}\n+\n /*\n  * Helper function for prepare() to deal with situation when\n  * ICV is spread by two segments. Tries to move ICV completely into the\n@@ -157,17 +190,12 @@ inb_pkt_xprepare(const struct rte_ipsec_sa *sa, rte_be64_t sqc,\n \t}\n }\n \n-/*\n- * setup/update packet data and metadata for ESP inbound tunnel case.\n- */\n-static inline int32_t\n-inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n-\tstruct rte_mbuf *mb, uint32_t hlen, union sym_op_data *icv)\n+static inline int\n+inb_get_sqn(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n+\tstruct rte_mbuf *mb, uint32_t hlen, rte_be64_t *sqc)\n {\n \tint32_t rc;\n \tuint64_t sqn;\n-\tuint32_t clen, icv_len, icv_ofs, plen;\n-\tstruct rte_mbuf *ml;\n \tstruct rte_esp_hdr *esph;\n \n \tesph = rte_pktmbuf_mtod_offset(mb, struct rte_esp_hdr *, hlen);\n@@ -179,12 +207,21 @@ inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n \tsqn = rte_be_to_cpu_32(esph->seq);\n \tif (IS_ESN(sa))\n \t\tsqn = reconstruct_esn(rsn->sqn, sqn, sa->replay.win_sz);\n+\t*sqc = rte_cpu_to_be_64(sqn);\n \n+\t/* check IPsec window */\n \trc = esn_inb_check_sqn(rsn, sa, sqn);\n-\tif (rc != 0)\n-\t\treturn rc;\n \n-\tsqn = rte_cpu_to_be_64(sqn);\n+\treturn rc;\n+}\n+\n+/* prepare packet for upcoming processing */\n+static inline int32_t\n+inb_prepare(const struct rte_ipsec_sa *sa, struct rte_mbuf *mb,\n+\tuint32_t hlen, union sym_op_data *icv)\n+{\n+\tuint32_t clen, icv_len, icv_ofs, plen;\n+\tstruct rte_mbuf *ml;\n \n \t/* start packet manipulation */\n \tplen = mb->pkt_len;\n@@ -217,7 +254,8 @@ inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n \n \ticv_ofs += sa->sqh_len;\n \n-\t/* we have to allocate space for AAD somewhere,\n+\t/*\n+\t * we have to allocate space for AAD somewhere,\n \t * right now - just use free trailing space at the last segment.\n \t * Would probably be more convenient to reserve space for AAD\n \t * inside rte_crypto_op itself\n@@ -238,10 +276,28 @@ inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n \tmb->pkt_len += sa->sqh_len;\n \tml->data_len += sa->sqh_len;\n \n-\tinb_pkt_xprepare(sa, sqn, icv);\n \treturn plen;\n }\n \n+static inline int32_t\n+inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,\n+\tstruct rte_mbuf *mb, uint32_t hlen, union sym_op_data *icv)\n+{\n+\tint rc;\n+\trte_be64_t sqn;\n+\n+\trc = inb_get_sqn(sa, rsn, mb, hlen, &sqn);\n+\tif (rc != 0)\n+\t\treturn rc;\n+\n+\trc = inb_prepare(sa, mb, hlen, icv);\n+\tif (rc < 0)\n+\t\treturn rc;\n+\n+\tinb_pkt_xprepare(sa, sqn, icv);\n+\treturn rc;\n+}\n+\n /*\n  * setup/update packets and crypto ops for ESP inbound case.\n  */\n@@ -270,17 +326,17 @@ esp_inb_pkt_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n \t\t\tlksd_none_cop_prepare(cop[k], cs, mb[i]);\n \t\t\tinb_cop_prepare(cop[k], sa, mb[i], &icv, hl, rc);\n \t\t\tk++;\n-\t\t} else\n+\t\t} else {\n \t\t\tdr[i - k] = i;\n+\t\t\trte_errno = -rc;\n+\t\t}\n \t}\n \n \trsn_release(sa, rsn);\n \n \t/* copy not prepared mbufs beyond good ones */\n-\tif (k != num && k != 0) {\n+\tif (k != num && k != 0)\n \t\tmove_bad_mbufs(mb, dr, num, num - k);\n-\t\trte_errno = EBADMSG;\n-\t}\n \n \treturn k;\n }\n@@ -512,7 +568,6 @@ tun_process(const struct rte_ipsec_sa *sa, struct rte_mbuf *mb[],\n \treturn k;\n }\n \n-\n /*\n  * *process* function for tunnel packets\n  */\n@@ -612,7 +667,7 @@ esp_inb_pkt_process(struct rte_ipsec_sa *sa, struct rte_mbuf *mb[],\n \tif (k != num && k != 0)\n \t\tmove_bad_mbufs(mb, dr, num, num - k);\n \n-\t/* update SQN and replay winow */\n+\t/* update SQN and replay window */\n \tn = esp_inb_rsn_update(sa, sqn, dr, k);\n \n \t/* handle mbufs with wrong SQN */\n@@ -625,6 +680,67 @@ esp_inb_pkt_process(struct rte_ipsec_sa *sa, struct rte_mbuf *mb[],\n \treturn n;\n }\n \n+/*\n+ * Prepare (plus actual crypto/auth) routine for inbound CPU-CRYPTO\n+ * (synchronous mode).\n+ */\n+uint16_t\n+cpu_inb_pkt_prepare(const struct rte_ipsec_session *ss,\n+\tstruct rte_mbuf *mb[], uint16_t num)\n+{\n+\tint32_t rc;\n+\tuint32_t i, k;\n+\tstruct rte_ipsec_sa *sa;\n+\tstruct replay_sqn *rsn;\n+\tunion sym_op_data icv;\n+\tvoid *iv[num];\n+\tvoid *aad[num];\n+\tvoid *dgst[num];\n+\tuint32_t dr[num];\n+\tuint32_t l4ofs[num];\n+\tuint32_t clen[num];\n+\tuint64_t ivbuf[num][IPSEC_MAX_IV_QWORD];\n+\n+\tsa = ss->sa;\n+\n+\t/* grab rsn lock */\n+\trsn = rsn_acquire(sa);\n+\n+\t/* do preparation for all packets */\n+\tfor (i = 0, k = 0; i != num; i++) {\n+\n+\t\t/* calculate ESP header offset */\n+\t\tl4ofs[k] = mb[i]->l2_len + mb[i]->l3_len;\n+\n+\t\t/* prepare ESP packet for processing */\n+\t\trc = inb_pkt_prepare(sa, rsn, mb[i], l4ofs[k], &icv);\n+\t\tif (rc >= 0) {\n+\t\t\t/* get encrypted data offset and length */\n+\t\t\tclen[k] = inb_cpu_crypto_prepare(sa, mb[i],\n+\t\t\t\tl4ofs + k, rc, ivbuf[k]);\n+\n+\t\t\t/* fill iv, digest and aad */\n+\t\t\tiv[k] = ivbuf[k];\n+\t\t\taad[k] = icv.va + sa->icv_len;\n+\t\t\tdgst[k++] = icv.va;\n+\t\t} else {\n+\t\t\tdr[i - k] = i;\n+\t\t\trte_errno = -rc;\n+\t\t}\n+\t}\n+\n+\t/* release rsn lock */\n+\trsn_release(sa, rsn);\n+\n+\t/* copy not prepared mbufs beyond good ones */\n+\tif (k != num && k != 0)\n+\t\tmove_bad_mbufs(mb, dr, num, num - k);\n+\n+\t/* convert mbufs to iovecs and do actual crypto/auth processing */\n+\tcpu_crypto_bulk(ss, sa->cofs, mb, iv, aad, dgst, l4ofs, clen, k);\n+\treturn k;\n+}\n+\n /*\n  * process group of ESP inbound tunnel packets.\n  */\ndiff --git a/lib/librte_ipsec/esp_outb.c b/lib/librte_ipsec/esp_outb.c\nindex e983b25a3..b6d9cbe98 100644\n--- a/lib/librte_ipsec/esp_outb.c\n+++ b/lib/librte_ipsec/esp_outb.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #include <rte_ipsec.h>\n@@ -15,6 +15,9 @@\n #include \"misc.h\"\n #include \"pad.h\"\n \n+typedef int32_t (*esp_outb_prepare_t)(struct rte_ipsec_sa *sa, rte_be64_t sqc,\n+\tconst uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,\n+\tunion sym_op_data *icv, uint8_t sqh_len);\n \n /*\n  * helper function to fill crypto_sym op for cipher+auth algorithms.\n@@ -177,6 +180,7 @@ outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,\n \tespt->pad_len = pdlen;\n \tespt->next_proto = sa->proto;\n \n+\t/* set icv va/pa value(s) */\n \ticv->va = rte_pktmbuf_mtod_offset(ml, void *, pdofs);\n \ticv->pa = rte_pktmbuf_iova_offset(ml, pdofs);\n \n@@ -270,8 +274,7 @@ esp_outb_tun_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n static inline int32_t\n outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,\n \tconst uint64_t ivp[IPSEC_MAX_IV_QWORD], struct rte_mbuf *mb,\n-\tuint32_t l2len, uint32_t l3len, union sym_op_data *icv,\n-\tuint8_t sqh_len)\n+\tunion sym_op_data *icv, uint8_t sqh_len)\n {\n \tuint8_t np;\n \tuint32_t clen, hlen, pdlen, pdofs, plen, tlen, uhlen;\n@@ -280,6 +283,10 @@ outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,\n \tstruct rte_esp_tail *espt;\n \tchar *ph, *pt;\n \tuint64_t *iv;\n+\tuint32_t l2len, l3len;\n+\n+\tl2len = mb->l2_len;\n+\tl3len = mb->l3_len;\n \n \tuhlen = l2len + l3len;\n \tplen = mb->pkt_len - uhlen;\n@@ -340,6 +347,7 @@ outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,\n \tespt->pad_len = pdlen;\n \tespt->next_proto = np;\n \n+\t/* set icv va/pa value(s) */\n \ticv->va = rte_pktmbuf_mtod_offset(ml, void *, pdofs);\n \ticv->pa = rte_pktmbuf_iova_offset(ml, pdofs);\n \n@@ -381,8 +389,8 @@ esp_outb_trs_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n \t\tgen_iv(iv, sqc);\n \n \t\t/* try to update the packet itself */\n-\t\trc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], l2, l3, &icv,\n-\t\t\t\t\t  sa->sqh_len);\n+\t\trc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv,\n+\t\t\t\t  sa->sqh_len);\n \t\t/* success, setup crypto op */\n \t\tif (rc >= 0) {\n \t\t\toutb_pkt_xprepare(sa, sqc, &icv);\n@@ -403,6 +411,116 @@ esp_outb_trs_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n \treturn k;\n }\n \n+\n+static inline uint32_t\n+outb_cpu_crypto_prepare(const struct rte_ipsec_sa *sa, uint32_t *pofs,\n+\tuint32_t plen, void *iv)\n+{\n+\tuint64_t *ivp = iv;\n+\tstruct aead_gcm_iv *gcm;\n+\tstruct aesctr_cnt_blk *ctr;\n+\tuint32_t clen;\n+\n+\tswitch (sa->algo_type) {\n+\tcase ALGO_TYPE_AES_GCM:\n+\t\tgcm = iv;\n+\t\taead_gcm_iv_fill(gcm, ivp[0], sa->salt);\n+\t\tbreak;\n+\tcase ALGO_TYPE_AES_CTR:\n+\t\tctr = iv;\n+\t\taes_ctr_cnt_blk_fill(ctr, ivp[0], sa->salt);\n+\t\tbreak;\n+\t}\n+\n+\t*pofs += sa->ctp.auth.offset;\n+\tclen = plen + sa->ctp.auth.length;\n+\treturn clen;\n+}\n+\n+static uint16_t\n+cpu_outb_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num,\n+\t\tesp_outb_prepare_t prepare, uint32_t cofs_mask)\n+{\n+\tint32_t rc;\n+\tuint64_t sqn;\n+\trte_be64_t sqc;\n+\tstruct rte_ipsec_sa *sa;\n+\tuint32_t i, k, n;\n+\tuint32_t l2, l3;\n+\tunion sym_op_data icv;\n+\tvoid *iv[num];\n+\tvoid *aad[num];\n+\tvoid *dgst[num];\n+\tuint32_t dr[num];\n+\tuint32_t l4ofs[num];\n+\tuint32_t clen[num];\n+\tuint64_t ivbuf[num][IPSEC_MAX_IV_QWORD];\n+\n+\tsa = ss->sa;\n+\n+\tn = num;\n+\tsqn = esn_outb_update_sqn(sa, &n);\n+\tif (n != num)\n+\t\trte_errno = EOVERFLOW;\n+\n+\tfor (i = 0, k = 0; i != n; i++) {\n+\n+\t\tl2 = mb[i]->l2_len;\n+\t\tl3 = mb[i]->l3_len;\n+\n+\t\t/* calculate ESP header offset */\n+\t\tl4ofs[k] = (l2 + l3) & cofs_mask;\n+\n+\t\tsqc = rte_cpu_to_be_64(sqn + i);\n+\t\tgen_iv(ivbuf[k], sqc);\n+\n+\t\t/* try to update the packet itself */\n+\t\trc = prepare(sa, sqc, ivbuf[k], mb[i], &icv, sa->sqh_len);\n+\n+\t\t/* success, proceed with preparations */\n+\t\tif (rc >= 0) {\n+\n+\t\t\toutb_pkt_xprepare(sa, sqc, &icv);\n+\n+\t\t\t/* get encrypted data offset and length */\n+\t\t\tclen[k] = outb_cpu_crypto_prepare(sa, l4ofs + k, rc,\n+\t\t\t\tivbuf[k]);\n+\n+\t\t\t/* fill iv, digest and aad */\n+\t\t\tiv[k] = ivbuf[k];\n+\t\t\taad[k] = icv.va + sa->icv_len;\n+\t\t\tdgst[k++] = icv.va;\n+\t\t} else {\n+\t\t\tdr[i - k] = i;\n+\t\t\trte_errno = -rc;\n+\t\t}\n+\t}\n+\n+\t/* copy not prepared mbufs beyond good ones */\n+\tif (k != n && k != 0)\n+\t\tmove_bad_mbufs(mb, dr, n, n - k);\n+\n+\t/* convert mbufs to iovecs and do actual crypto/auth processing */\n+\tcpu_crypto_bulk(ss, sa->cofs, mb, iv, aad, dgst, l4ofs, clen, k);\n+\treturn k;\n+}\n+\n+uint16_t\n+cpu_outb_tun_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num)\n+{\n+\treturn cpu_outb_pkt_prepare(ss, mb, num, outb_tun_pkt_prepare, 0);\n+}\n+\n+uint16_t\n+cpu_outb_trs_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num)\n+{\n+\treturn cpu_outb_pkt_prepare(ss, mb, num, outb_trs_pkt_prepare,\n+\t\tUINT32_MAX);\n+}\n+\n /*\n  * process outbound packets for SA with ESN support,\n  * for algorithms that require SQN.hibits to be implictly included\n@@ -526,7 +644,7 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session *ss,\n \tstruct rte_mbuf *mb[], uint16_t num)\n {\n \tint32_t rc;\n-\tuint32_t i, k, n, l2, l3;\n+\tuint32_t i, k, n;\n \tuint64_t sqn;\n \trte_be64_t sqc;\n \tstruct rte_ipsec_sa *sa;\n@@ -544,15 +662,11 @@ inline_outb_trs_pkt_process(const struct rte_ipsec_session *ss,\n \tk = 0;\n \tfor (i = 0; i != n; i++) {\n \n-\t\tl2 = mb[i]->l2_len;\n-\t\tl3 = mb[i]->l3_len;\n-\n \t\tsqc = rte_cpu_to_be_64(sqn + i);\n \t\tgen_iv(iv, sqc);\n \n \t\t/* try to update the packet itself */\n-\t\trc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i],\n-\t\t\t\tl2, l3, &icv, 0);\n+\t\trc = outb_trs_pkt_prepare(sa, sqc, iv, mb[i], &icv, 0);\n \n \t\tk += (rc >= 0);\n \ndiff --git a/lib/librte_ipsec/misc.h b/lib/librte_ipsec/misc.h\nindex fe4641bfc..53c0457af 100644\n--- a/lib/librte_ipsec/misc.h\n+++ b/lib/librte_ipsec/misc.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #ifndef _MISC_H_\n@@ -105,4 +105,75 @@ mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs,\n \tmb->pkt_len -= len;\n }\n \n+/*\n+ * process packets using sync crypto engine\n+ */\n+static inline void\n+cpu_crypto_bulk(const struct rte_ipsec_session *ss,\n+\tunion rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[],\n+\tvoid *iv[], void *aad[], void *dgst[], uint32_t l4ofs[],\n+\tuint32_t clen[], uint32_t num)\n+{\n+\tuint32_t i, j, n;\n+\tint32_t vcnt, vofs;\n+\tint32_t st[num];\n+\tstruct rte_crypto_sgl vecpkt[num];\n+\tstruct rte_crypto_vec vec[UINT8_MAX];\n+\tstruct rte_crypto_sym_vec symvec;\n+\n+\tconst uint32_t vnum = RTE_DIM(vec);\n+\n+\tj = 0, n = 0;\n+\tvofs = 0;\n+\tfor (i = 0; i != num; i++) {\n+\n+\t\tvcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],\n+\t\t\t&vec[vofs], vnum - vofs);\n+\n+\t\t/* not enough space in vec[] to hold all segments */\n+\t\tif (vcnt < 0) {\n+\t\t\t/* fill the request structure */\n+\t\t\tsymvec.sgl = &vecpkt[j];\n+\t\t\tsymvec.iv = &iv[j];\n+\t\t\tsymvec.aad = &aad[j];\n+\t\t\tsymvec.digest = &dgst[j];\n+\t\t\tsymvec.status = &st[j];\n+\t\t\tsymvec.num = i - j;\n+\n+\t\t\t/* flush vec array and try again */\n+\t\t\tn += rte_cryptodev_sym_cpu_crypto_process(\n+\t\t\t\tss->crypto.dev_id, ss->crypto.ses, ofs,\n+\t\t\t\t&symvec);\n+\t\t\tvofs = 0;\n+\t\t\tvcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],\n+\t\t\t\tvec, vnum);\n+\t\t\tRTE_ASSERT(vcnt > 0);\n+\t\t\tj = i;\n+\t\t}\n+\n+\t\tvecpkt[i].vec = &vec[vofs];\n+\t\tvecpkt[i].num = vcnt;\n+\t\tvofs += vcnt;\n+\t}\n+\n+\t/* fill the request structure */\n+\tsymvec.sgl = &vecpkt[j];\n+\tsymvec.iv = &iv[j];\n+\tsymvec.aad = &aad[j];\n+\tsymvec.digest = &dgst[j];\n+\tsymvec.status = &st[j];\n+\tsymvec.num = i - j;\n+\n+\tn += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id,\n+\t\tss->crypto.ses, ofs, &symvec);\n+\n+\tj = num - n;\n+\tfor (i = 0; j != 0 && i != num; i++) {\n+\t\tif (st[i] != 0) {\n+\t\t\tmb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED;\n+\t\t\tj--;\n+\t\t}\n+\t}\n+}\n+\n #endif /* _MISC_H_ */\ndiff --git a/lib/librte_ipsec/rte_ipsec.h b/lib/librte_ipsec/rte_ipsec.h\nindex f3b1f936b..6666cf761 100644\n--- a/lib/librte_ipsec/rte_ipsec.h\n+++ b/lib/librte_ipsec/rte_ipsec.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #ifndef _RTE_IPSEC_H_\n@@ -33,10 +33,15 @@ struct rte_ipsec_session;\n  *   (see rte_ipsec_pkt_process for more details).\n  */\n struct rte_ipsec_sa_pkt_func {\n-\tuint16_t (*prepare)(const struct rte_ipsec_session *ss,\n+\tunion {\n+\t\tuint16_t (*async)(const struct rte_ipsec_session *ss,\n \t\t\t\tstruct rte_mbuf *mb[],\n \t\t\t\tstruct rte_crypto_op *cop[],\n \t\t\t\tuint16_t num);\n+\t\tuint16_t (*sync)(const struct rte_ipsec_session *ss,\n+\t\t\t\tstruct rte_mbuf *mb[],\n+\t\t\t\tuint16_t num);\n+\t} prepare;\n \tuint16_t (*process)(const struct rte_ipsec_session *ss,\n \t\t\t\tstruct rte_mbuf *mb[],\n \t\t\t\tuint16_t num);\n@@ -62,6 +67,7 @@ struct rte_ipsec_session {\n \tunion {\n \t\tstruct {\n \t\t\tstruct rte_cryptodev_sym_session *ses;\n+\t\t\tuint8_t dev_id;\n \t\t} crypto;\n \t\tstruct {\n \t\t\tstruct rte_security_session *ses;\n@@ -114,7 +120,15 @@ static inline uint16_t\n rte_ipsec_pkt_crypto_prepare(const struct rte_ipsec_session *ss,\n \tstruct rte_mbuf *mb[], struct rte_crypto_op *cop[], uint16_t num)\n {\n-\treturn ss->pkt_func.prepare(ss, mb, cop, num);\n+\treturn ss->pkt_func.prepare.async(ss, mb, cop, num);\n+}\n+\n+__rte_experimental\n+static inline uint16_t\n+rte_ipsec_pkt_cpu_prepare(const struct rte_ipsec_session *ss,\n+\tstruct rte_mbuf *mb[], uint16_t num)\n+{\n+\treturn ss->pkt_func.prepare.sync(ss, mb, num);\n }\n \n /**\ndiff --git a/lib/librte_ipsec/sa.c b/lib/librte_ipsec/sa.c\nindex 6f1d92c3c..ada195cf8 100644\n--- a/lib/librte_ipsec/sa.c\n+++ b/lib/librte_ipsec/sa.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #include <rte_ipsec.h>\n@@ -243,10 +243,26 @@ static void\n esp_inb_init(struct rte_ipsec_sa *sa)\n {\n \t/* these params may differ with new algorithms support */\n-\tsa->ctp.auth.offset = 0;\n-\tsa->ctp.auth.length = sa->icv_len - sa->sqh_len;\n \tsa->ctp.cipher.offset = sizeof(struct rte_esp_hdr) + sa->iv_len;\n \tsa->ctp.cipher.length = sa->icv_len + sa->ctp.cipher.offset;\n+\n+\t/*\n+\t * for AEAD and NULL algorithms we can assume that\n+\t * auth and cipher offsets would be equal.\n+\t */\n+\tswitch (sa->algo_type) {\n+\tcase ALGO_TYPE_AES_GCM:\n+\tcase ALGO_TYPE_NULL:\n+\t\tsa->ctp.auth.raw = sa->ctp.cipher.raw;\n+\t\tbreak;\n+\tdefault:\n+\t\tsa->ctp.auth.offset = 0;\n+\t\tsa->ctp.auth.length = sa->icv_len - sa->sqh_len;\n+\t\tsa->cofs.ofs.cipher.tail = sa->sqh_len;\n+\t\tbreak;\n+\t}\n+\n+\tsa->cofs.ofs.cipher.head = sa->ctp.cipher.offset - sa->ctp.auth.offset;\n }\n \n /*\n@@ -269,13 +285,13 @@ esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)\n \n \tsa->sqn.outb.raw = 1;\n \n-\t/* these params may differ with new algorithms support */\n-\tsa->ctp.auth.offset = hlen;\n-\tsa->ctp.auth.length = sizeof(struct rte_esp_hdr) +\n-\t\tsa->iv_len + sa->sqh_len;\n-\n \talgo_type = sa->algo_type;\n \n+\t/*\n+\t * Setup auth and cipher length and offset.\n+\t * these params may differ with new algorithms support\n+\t */\n+\n \tswitch (algo_type) {\n \tcase ALGO_TYPE_AES_GCM:\n \tcase ALGO_TYPE_AES_CTR:\n@@ -286,11 +302,30 @@ esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)\n \t\tbreak;\n \tcase ALGO_TYPE_AES_CBC:\n \tcase ALGO_TYPE_3DES_CBC:\n-\t\tsa->ctp.cipher.offset = sa->hdr_len +\n-\t\t\tsizeof(struct rte_esp_hdr);\n+\t\tsa->ctp.cipher.offset = hlen + sizeof(struct rte_esp_hdr);\n \t\tsa->ctp.cipher.length = sa->iv_len;\n \t\tbreak;\n \t}\n+\n+\t/*\n+\t * for AEAD and NULL algorithms we can assume that\n+\t * auth and cipher offsets would be equal.\n+\t */\n+\tswitch (algo_type) {\n+\tcase ALGO_TYPE_AES_GCM:\n+\tcase ALGO_TYPE_NULL:\n+\t\tsa->ctp.auth.raw = sa->ctp.cipher.raw;\n+\t\tbreak;\n+\tdefault:\n+\t\tsa->ctp.auth.offset = hlen;\n+\t\tsa->ctp.auth.length = sizeof(struct rte_esp_hdr) +\n+\t\t\tsa->iv_len + sa->sqh_len;\n+\t\tbreak;\n+\t}\n+\n+\tsa->cofs.ofs.cipher.head = sa->ctp.cipher.offset - sa->ctp.auth.offset;\n+\tsa->cofs.ofs.cipher.tail = (sa->ctp.auth.offset + sa->ctp.auth.length) -\n+\t\t\t(sa->ctp.cipher.offset + sa->ctp.cipher.length);\n }\n \n /*\n@@ -544,9 +579,9 @@ lksd_proto_prepare(const struct rte_ipsec_session *ss,\n  * - inbound/outbound for RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL\n  * - outbound for RTE_SECURITY_ACTION_TYPE_NONE when ESN is disabled\n  */\n-static uint16_t\n-pkt_flag_process(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n-\tuint16_t num)\n+uint16_t\n+pkt_flag_process(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num)\n {\n \tuint32_t i, k;\n \tuint32_t dr[num];\n@@ -588,21 +623,59 @@ lksd_none_pkt_func_select(const struct rte_ipsec_sa *sa,\n \tswitch (sa->type & msk) {\n \tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TUNLV4):\n \tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TUNLV6):\n-\t\tpf->prepare = esp_inb_pkt_prepare;\n+\t\tpf->prepare.async = esp_inb_pkt_prepare;\n \t\tpf->process = esp_inb_tun_pkt_process;\n \t\tbreak;\n \tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TRANS):\n-\t\tpf->prepare = esp_inb_pkt_prepare;\n+\t\tpf->prepare.async = esp_inb_pkt_prepare;\n \t\tpf->process = esp_inb_trs_pkt_process;\n \t\tbreak;\n \tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4):\n \tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6):\n-\t\tpf->prepare = esp_outb_tun_prepare;\n+\t\tpf->prepare.async = esp_outb_tun_prepare;\n \t\tpf->process = (sa->sqh_len != 0) ?\n \t\t\tesp_outb_sqh_process : pkt_flag_process;\n \t\tbreak;\n \tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):\n-\t\tpf->prepare = esp_outb_trs_prepare;\n+\t\tpf->prepare.async = esp_outb_trs_prepare;\n+\t\tpf->process = (sa->sqh_len != 0) ?\n+\t\t\tesp_outb_sqh_process : pkt_flag_process;\n+\t\tbreak;\n+\tdefault:\n+\t\trc = -ENOTSUP;\n+\t}\n+\n+\treturn rc;\n+}\n+\n+static int\n+cpu_crypto_pkt_func_select(const struct rte_ipsec_sa *sa,\n+\t\tstruct rte_ipsec_sa_pkt_func *pf)\n+{\n+\tint32_t rc;\n+\n+\tstatic const uint64_t msk = RTE_IPSEC_SATP_DIR_MASK |\n+\t\t\tRTE_IPSEC_SATP_MODE_MASK;\n+\n+\trc = 0;\n+\tswitch (sa->type & msk) {\n+\tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TUNLV4):\n+\tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TUNLV6):\n+\t\tpf->prepare.sync = cpu_inb_pkt_prepare;\n+\t\tpf->process = esp_inb_tun_pkt_process;\n+\t\tbreak;\n+\tcase (RTE_IPSEC_SATP_DIR_IB | RTE_IPSEC_SATP_MODE_TRANS):\n+\t\tpf->prepare.sync = cpu_inb_pkt_prepare;\n+\t\tpf->process = esp_inb_trs_pkt_process;\n+\t\tbreak;\n+\tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV4):\n+\tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TUNLV6):\n+\t\tpf->prepare.sync = cpu_outb_tun_pkt_prepare;\n+\t\tpf->process = (sa->sqh_len != 0) ?\n+\t\t\tesp_outb_sqh_process : pkt_flag_process;\n+\t\tbreak;\n+\tcase (RTE_IPSEC_SATP_DIR_OB | RTE_IPSEC_SATP_MODE_TRANS):\n+\t\tpf->prepare.sync = cpu_outb_trs_pkt_prepare;\n \t\tpf->process = (sa->sqh_len != 0) ?\n \t\t\tesp_outb_sqh_process : pkt_flag_process;\n \t\tbreak;\n@@ -660,7 +733,7 @@ ipsec_sa_pkt_func_select(const struct rte_ipsec_session *ss,\n \tint32_t rc;\n \n \trc = 0;\n-\tpf[0] = (struct rte_ipsec_sa_pkt_func) { 0 };\n+\tpf[0] = (struct rte_ipsec_sa_pkt_func) { {NULL}, NULL };\n \n \tswitch (ss->type) {\n \tcase RTE_SECURITY_ACTION_TYPE_NONE:\n@@ -677,9 +750,12 @@ ipsec_sa_pkt_func_select(const struct rte_ipsec_session *ss,\n \t\t\tpf->process = inline_proto_outb_pkt_process;\n \t\tbreak;\n \tcase RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL:\n-\t\tpf->prepare = lksd_proto_prepare;\n+\t\tpf->prepare.async = lksd_proto_prepare;\n \t\tpf->process = pkt_flag_process;\n \t\tbreak;\n+\tcase RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO:\n+\t\trc = cpu_crypto_pkt_func_select(sa, pf);\n+\t\tbreak;\n \tdefault:\n \t\trc = -ENOTSUP;\n \t}\ndiff --git a/lib/librte_ipsec/sa.h b/lib/librte_ipsec/sa.h\nindex 51e69ad05..d22451b38 100644\n--- a/lib/librte_ipsec/sa.h\n+++ b/lib/librte_ipsec/sa.h\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #ifndef _SA_H_\n@@ -88,6 +88,8 @@ struct rte_ipsec_sa {\n \t\tunion sym_op_ofslen cipher;\n \t\tunion sym_op_ofslen auth;\n \t} ctp;\n+\t/* cpu-crypto offsets */\n+\tunion rte_crypto_sym_ofs cofs;\n \t/* tx_offload template for tunnel mbuf */\n \tstruct {\n \t\tuint64_t msk;\n@@ -156,6 +158,10 @@ uint16_t\n inline_inb_trs_pkt_process(const struct rte_ipsec_session *ss,\n \tstruct rte_mbuf *mb[], uint16_t num);\n \n+uint16_t\n+cpu_inb_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num);\n+\n /* outbound processing */\n \n uint16_t\n@@ -170,6 +176,10 @@ uint16_t\n esp_outb_sqh_process(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],\n \tuint16_t num);\n \n+uint16_t\n+pkt_flag_process(const struct rte_ipsec_session *ss,\n+\tstruct rte_mbuf *mb[], uint16_t num);\n+\n uint16_t\n inline_outb_tun_pkt_process(const struct rte_ipsec_session *ss,\n \tstruct rte_mbuf *mb[], uint16_t num);\n@@ -182,4 +192,11 @@ uint16_t\n inline_proto_outb_pkt_process(const struct rte_ipsec_session *ss,\n \tstruct rte_mbuf *mb[], uint16_t num);\n \n+uint16_t\n+cpu_outb_tun_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num);\n+uint16_t\n+cpu_outb_trs_pkt_prepare(const struct rte_ipsec_session *ss,\n+\t\tstruct rte_mbuf *mb[], uint16_t num);\n+\n #endif /* _SA_H_ */\ndiff --git a/lib/librte_ipsec/ses.c b/lib/librte_ipsec/ses.c\nindex 82c765a33..3d51ac498 100644\n--- a/lib/librte_ipsec/ses.c\n+++ b/lib/librte_ipsec/ses.c\n@@ -1,5 +1,5 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright(c) 2018 Intel Corporation\n+ * Copyright(c) 2018-2020 Intel Corporation\n  */\n \n #include <rte_ipsec.h>\n@@ -11,7 +11,8 @@ session_check(struct rte_ipsec_session *ss)\n \tif (ss == NULL || ss->sa == NULL)\n \t\treturn -EINVAL;\n \n-\tif (ss->type == RTE_SECURITY_ACTION_TYPE_NONE) {\n+\tif (ss->type == RTE_SECURITY_ACTION_TYPE_NONE ||\n+\t\tss->type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO) {\n \t\tif (ss->crypto.ses == NULL)\n \t\t\treturn -EINVAL;\n \t} else {\n",
    "prefixes": [
        "v6",
        "5/8"
    ]
}