Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/957186/?format=api
{ "id": 957186, "url": "http://patchwork.ozlabs.org/api/patches/957186/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1534185825-12451-8-git-send-email-shannon.nelson@oracle.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1534185825-12451-8-git-send-email-shannon.nelson@oracle.com>", "list_archive_url": null, "date": "2018-08-13T18:43:44", "name": "[next-queue,7/8] ixgbevf: add VF ipsec offload code", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "5e5ddc50cec8a8f2113a42fdea74264a95dbba7d", "submitter": { "id": 70766, "url": "http://patchwork.ozlabs.org/api/people/70766/?format=api", "name": "Shannon Nelson", "email": "shannon.nelson@oracle.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1534185825-12451-8-git-send-email-shannon.nelson@oracle.com/mbox/", "series": [ { "id": 60595, "url": "http://patchwork.ozlabs.org/api/series/60595/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=60595", "date": "2018-08-13T18:43:38", "name": "ixgbe/ixgbevf: IPsec offload support for VFs", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/60595/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/957186/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/957186/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.136; helo=silver.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=oracle.com", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=oracle.com header.i=@oracle.com\n\theader.b=\"KS/WYTNN\"; dkim-atps=neutral" ], "Received": [ "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 41q4Pz2gt7z9s8f\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 14 Aug 2018 04:44:07 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id C23F122E94;\n\tMon, 13 Aug 2018 18:44:05 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id o-ddmAyqboJy; Mon, 13 Aug 2018 18:44:02 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id D3E5222E3F;\n\tMon, 13 Aug 2018 18:44:02 +0000 (UTC)", "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id 7914B1C0574\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 13 Aug 2018 18:44:00 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 7593622E3F\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 13 Aug 2018 18:44:00 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id SKcsH4EGj7gN for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 13 Aug 2018 18:43:59 +0000 (UTC)", "from aserp2120.oracle.com (aserp2120.oracle.com [141.146.126.78])\n\tby silver.osuosl.org (Postfix) with ESMTPS id E2C7522E6E\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 13 Aug 2018 18:43:58 +0000 (UTC)", "from pps.filterd (aserp2120.oracle.com [127.0.0.1])\n\tby aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id\n\tw7DIdNxr037591; Mon, 13 Aug 2018 18:43:57 GMT", "from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71])\n\tby aserp2120.oracle.com with ESMTP id 2ksqrp5hvy-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256\n\tverify=OK); Mon, 13 Aug 2018 18:43:57 +0000", "from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236])\n\tby userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id\n\tw7DIht5F028089\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256\n\tverify=OK); Mon, 13 Aug 2018 18:43:56 GMT", "from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14])\n\tby aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id\n\tw7DIhtLT018415; Mon, 13 Aug 2018 18:43:55 GMT", "from slnelson-mint18.us.oracle.com (/10.159.144.11)\n\tby default (Oracle Beehive Gateway v4.0)\n\twith ESMTP ; Mon, 13 Aug 2018 11:43:55 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com;\n\th=from : to : cc :\n\tsubject : date : message-id : in-reply-to : references;\n\ts=corp-2018-07-02; \n\tbh=MrTf8Ad2+1hAJnsH1/r4MBKtWoY+QnW5edLi0K8x9qk=;\n\tb=KS/WYTNNUV/C79luKiYbo1OsvdBoS7Y5oqbXe2wLZg1jJQcD7wnHM4a8I0SO47lRQbtk\n\tgc/wYIPbRkXYdXgr0+XouMD0DpAj1i8qsjjWxjyohNW9OXDCeNa3EQkFDJV8/pK6xf4Y\n\tI0cudKxOyV0mspY5FYmLW3w98udjNs35B1zOj3gIsUNziunu43ZVJHheUq4zdXdUD9Fu\n\tfcCy3f3djedndOYNTv31bh7laTrCo8WKZQZA4Uh44kmfJL/KoI+k8AP+xCFp8lz/B6TJ\n\tQYveAdn48IcGwulMSf+xl+LDGInnM2AQEObvikCQWhg4NusDXcvUIrtZiBlMnwXbFlkm\n\tNQ== ", "From": "Shannon Nelson <shannon.nelson@oracle.com>", "To": "intel-wired-lan@lists.osuosl.org, jeffrey.t.kirsher@intel.com", "Date": "Mon, 13 Aug 2018 11:43:44 -0700", "Message-Id": "<1534185825-12451-8-git-send-email-shannon.nelson@oracle.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1534185825-12451-1-git-send-email-shannon.nelson@oracle.com>", "References": "<1534185825-12451-1-git-send-email-shannon.nelson@oracle.com>", "X-Proofpoint-Virus-Version": "vendor=nai engine=5900 definitions=8984\n\tsignatures=668707", "X-Proofpoint-Spam-Details": "rule=notspam policy=default score=0 suspectscore=0\n\tmalwarescore=0\n\tphishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999\n\tadultscore=0 classifier=spam adjust=0 reason=mlx scancount=1\n\tengine=8.0.1-1807170000 definitions=main-1808130188", "Subject": "[Intel-wired-lan] [PATCH next-queue 7/8] ixgbevf: add VF ipsec\n\toffload code", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Cc": "steffen.klassert@secunet.com, netdev@vger.kernel.org", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Add the ipsec offload support code. This is based off of the similar\ncode in ixgbe, but instead of writing the SA registers, the VF asks\nthe PF to setup the offload by sending the offload information to the\nPF via the standard mailbox.\n\nSigned-off-by: Shannon Nelson <shannon.nelson@oracle.com>\n---\n drivers/net/ethernet/intel/ixgbevf/Makefile | 1 +\n drivers/net/ethernet/intel/ixgbevf/ipsec.c | 673 +++++++++++++++++++++++++++\n drivers/net/ethernet/intel/ixgbevf/ipsec.h | 66 +++\n drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 8 +\n 4 files changed, 748 insertions(+)\n create mode 100644 drivers/net/ethernet/intel/ixgbevf/ipsec.c\n create mode 100644 drivers/net/ethernet/intel/ixgbevf/ipsec.h", "diff": "diff --git a/drivers/net/ethernet/intel/ixgbevf/Makefile b/drivers/net/ethernet/intel/ixgbevf/Makefile\nindex aba1e6a3..297d0f0 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/Makefile\n+++ b/drivers/net/ethernet/intel/ixgbevf/Makefile\n@@ -10,4 +10,5 @@ ixgbevf-objs := vf.o \\\n mbx.o \\\n ethtool.o \\\n ixgbevf_main.o\n+ixgbevf-$(CONFIG_XFRM_OFFLOAD) += ipsec.o\n \ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c\nnew file mode 100644\nindex 0000000..fac91c0\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c\n@@ -0,0 +1,673 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Copyright(c) 2018 Oracle and/or its affiliates. All rights reserved. */\n+\n+#include \"ixgbevf.h\"\n+#include <net/xfrm.h>\n+#include <crypto/aead.h>\n+\n+#define IXGBE_IPSEC_KEY_BITS 160\n+static const char aes_gcm_name[] = \"rfc4106(gcm(aes))\";\n+\n+/**\n+ * ixgbevf_ipsec_set_pf_sa - ask the PF to set up an SA\n+ * @adapter: board private structure\n+ * @xs: xfrm info to be sent to the PF\n+ *\n+ * Returns: positive offload handle from the PF, or negative error code\n+ **/\n+static int ixgbevf_ipsec_set_pf_sa(struct ixgbevf_adapter *adapter,\n+\t\t\t\t struct xfrm_state *xs)\n+{\n+\tu32 msgbuf[IXGBE_VFMAILBOX_SIZE] = { 0 };\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct sa_mbx_msg *sam;\n+\tu16 msglen;\n+\tint ret;\n+\n+\t/* send the important bits to the PF */\n+\tsam = (struct sa_mbx_msg *)(&msgbuf[1]);\n+\tsam->flags = xs->xso.flags;\n+\tsam->spi = xs->id.spi;\n+\tsam->proto = xs->id.proto;\n+\tsam->family = xs->props.family;\n+\n+\tif (xs->props.family == AF_INET6)\n+\t\tmemcpy(sam->addr, &xs->id.daddr.a6, sizeof(xs->id.daddr.a6));\n+\telse\n+\t\tmemcpy(sam->addr, &xs->id.daddr.a4, sizeof(xs->id.daddr.a4));\n+\tmemcpy(sam->key, xs->aead->alg_key, sizeof(sam->key));\n+\n+\tmsgbuf[0] = IXGBE_VF_IPSEC_ADD;\n+\tmsglen = sizeof(*sam) + sizeof(msgbuf[0]);\n+\n+\tspin_lock_bh(&adapter->mbx_lock);\n+\n+\tret = hw->mbx.ops.write_posted(hw, msgbuf, msglen);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tmsglen = sizeof(msgbuf[0]) * 2;\n+\tret = hw->mbx.ops.read_posted(hw, msgbuf, msglen);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tret = (int)msgbuf[1];\n+\tif (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK && ret >= 0)\n+\t\tret = -1;\n+\n+out:\n+\tspin_unlock_bh(&adapter->mbx_lock);\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_del_pf_sa - ask the PF to delete an SA\n+ * @adapter: board private structure\n+ * @pfsa: sa index returned from PF when created, -1 for all\n+ *\n+ * Returns: 0 on success, or negative error code\n+ **/\n+static int ixgbevf_ipsec_del_pf_sa(struct ixgbevf_adapter *adapter, int pfsa)\n+{\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tu32 msgbuf[2];\n+\tint err;\n+\n+\tmemset(msgbuf, 0, sizeof(msgbuf));\n+\tmsgbuf[0] = IXGBE_VF_IPSEC_DEL;\n+\tmsgbuf[1] = (u32)pfsa;\n+\n+\tspin_lock_bh(&adapter->mbx_lock);\n+\n+\terr = hw->mbx.ops.write_posted(hw, msgbuf, sizeof(msgbuf));\n+\tif (err)\n+\t\tgoto out;\n+\n+\terr = hw->mbx.ops.read_posted(hw, msgbuf, sizeof(msgbuf));\n+\tif (err)\n+\t\tgoto out;\n+\n+out:\n+\tspin_unlock_bh(&adapter->mbx_lock);\n+\treturn err;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_restore - restore the ipsec HW settings after a reset\n+ * @adapter: board private structure\n+ *\n+ * Reload the HW tables from the SW tables after they've been bashed\n+ * by a chip reset. While we're here, make sure any stale VF data is\n+ * removed, since we go through reset when num_vfs changes.\n+ **/\n+void ixgbevf_ipsec_restore(struct ixgbevf_adapter *adapter)\n+{\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\tstruct net_device *netdev = adapter->netdev;\n+\tint i;\n+\n+\tif (!(adapter->netdev->features & NETIF_F_HW_ESP))\n+\t\treturn;\n+\n+\t/* reload the Rx and Tx keys */\n+\tfor (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {\n+\t\tstruct rx_sa *r = &ipsec->rx_tbl[i];\n+\t\tstruct tx_sa *t = &ipsec->tx_tbl[i];\n+\t\tint ret;\n+\n+\t\tif (r->used) {\n+\t\t\tret = ixgbevf_ipsec_set_pf_sa(adapter, r->xs);\n+\t\t\tif (ret < 0)\n+\t\t\t\tnetdev_err(netdev, \"reload rx_tbl[%d] failed = %d\\n\",\n+\t\t\t\t\t i, ret);\n+\t\t}\n+\n+\t\tif (t->used) {\n+\t\t\tret = ixgbevf_ipsec_set_pf_sa(adapter, t->xs);\n+\t\t\tif (ret < 0)\n+\t\t\t\tnetdev_err(netdev, \"reload tx_tbl[%d] failed = %d\\n\",\n+\t\t\t\t\t i, ret);\n+\t\t}\n+\t}\n+}\n+\n+/**\n+ * ixgbevf_ipsec_find_empty_idx - find the first unused security parameter index\n+ * @ipsec: pointer to ipsec struct\n+ * @rxtable: true if we need to look in the Rx table\n+ *\n+ * Returns the first unused index in either the Rx or Tx SA table\n+ **/\n+static\n+int ixgbevf_ipsec_find_empty_idx(struct ixgbevf_ipsec *ipsec, bool rxtable)\n+{\n+\tu32 i;\n+\n+\tif (rxtable) {\n+\t\tif (ipsec->num_rx_sa == IXGBE_IPSEC_MAX_SA_COUNT)\n+\t\t\treturn -ENOSPC;\n+\n+\t\t/* search rx sa table */\n+\t\tfor (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (!ipsec->rx_tbl[i].used)\n+\t\t\t\treturn i;\n+\t\t}\n+\t} else {\n+\t\tif (ipsec->num_tx_sa == IXGBE_IPSEC_MAX_SA_COUNT)\n+\t\t\treturn -ENOSPC;\n+\n+\t\t/* search tx sa table */\n+\t\tfor (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (!ipsec->tx_tbl[i].used)\n+\t\t\t\treturn i;\n+\t\t}\n+\t}\n+\n+\treturn -ENOSPC;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_find_rx_state - find the state that matches\n+ * @ipsec: pointer to ipsec struct\n+ * @daddr: inbound address to match\n+ * @proto: protocol to match\n+ * @spi: SPI to match\n+ * @ip4: true if using an ipv4 address\n+ *\n+ * Returns a pointer to the matching SA state information\n+ **/\n+static\n+struct xfrm_state *ixgbevf_ipsec_find_rx_state(struct ixgbevf_ipsec *ipsec,\n+\t\t\t\t\t __be32 *daddr, u8 proto,\n+\t\t\t\t\t __be32 spi, bool ip4)\n+{\n+\tstruct xfrm_state *ret = NULL;\n+\tstruct rx_sa *rsa;\n+\n+\trcu_read_lock();\n+\thash_for_each_possible_rcu(ipsec->rx_sa_list, rsa, hlist,\n+\t\t\t\t (__force u32)spi) {\n+\t\tif (spi == rsa->xs->id.spi &&\n+\t\t ((ip4 && *daddr == rsa->xs->id.daddr.a4) ||\n+\t\t (!ip4 && !memcmp(daddr, &rsa->xs->id.daddr.a6,\n+\t\t\t\t sizeof(rsa->xs->id.daddr.a6)))) &&\n+\t\t proto == rsa->xs->id.proto) {\n+\t\t\tret = rsa->xs;\n+\t\t\txfrm_state_hold(ret);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\trcu_read_unlock();\n+\treturn ret;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_parse_proto_keys - find the key and salt based on the protocol\n+ * @xs: pointer to xfrm_state struct\n+ * @mykey: pointer to key array to populate\n+ * @mysalt: pointer to salt value to populate\n+ *\n+ * This copies the protocol keys and salt to our own data tables. The\n+ * 82599 family only supports the one algorithm.\n+ **/\n+static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,\n+\t\t\t\t\t u32 *mykey, u32 *mysalt)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tunsigned char *key_data;\n+\tchar *alg_name = NULL;\n+\tint key_len;\n+\n+\tif (!xs->aead) {\n+\t\tnetdev_err(dev, \"Unsupported IPsec algorithm\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (xs->aead->alg_icv_len != IXGBE_IPSEC_AUTH_BITS) {\n+\t\tnetdev_err(dev, \"IPsec offload requires %d bit authentication\\n\",\n+\t\t\t IXGBE_IPSEC_AUTH_BITS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tkey_data = &xs->aead->alg_key[0];\n+\tkey_len = xs->aead->alg_key_len;\n+\talg_name = xs->aead->alg_name;\n+\n+\tif (strcmp(alg_name, aes_gcm_name)) {\n+\t\tnetdev_err(dev, \"Unsupported IPsec algorithm - please use %s\\n\",\n+\t\t\t aes_gcm_name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* The key bytes come down in a bigendian array of bytes, so\n+\t * we don't need to do any byteswapping.\n+\t * 160 accounts for 16 byte key and 4 byte salt\n+\t */\n+\tif (key_len > IXGBE_IPSEC_KEY_BITS) {\n+\t\t*mysalt = ((u32 *)key_data)[4];\n+\t} else if (key_len == IXGBE_IPSEC_KEY_BITS) {\n+\t\t*mysalt = 0;\n+\t} else {\n+\t\tnetdev_err(dev, \"IPsec hw offload only supports keys up to 128 bits with a 32 bit salt\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tmemcpy(mykey, key_data, 16);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_add_sa - program device with a security association\n+ * @xs: pointer to transformer state struct\n+ **/\n+static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tstruct ixgbevf_adapter *adapter = netdev_priv(dev);\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\tu16 sa_idx;\n+\tint ret;\n+\n+\tif (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {\n+\t\tnetdev_err(dev, \"Unsupported protocol 0x%04x for ipsec offload\\n\",\n+\t\t\t xs->id.proto);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {\n+\t\tstruct rx_sa rsa;\n+\n+\t\tif (xs->calg) {\n+\t\t\tnetdev_err(dev, \"Compression offload not supported\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* find the first unused index */\n+\t\tret = ixgbevf_ipsec_find_empty_idx(ipsec, true);\n+\t\tif (ret < 0) {\n+\t\t\tnetdev_err(dev, \"No space for SA in Rx table!\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\tsa_idx = (u16)ret;\n+\n+\t\tmemset(&rsa, 0, sizeof(rsa));\n+\t\trsa.used = true;\n+\t\trsa.xs = xs;\n+\n+\t\tif (rsa.xs->id.proto & IPPROTO_ESP)\n+\t\t\trsa.decrypt = xs->ealg || xs->aead;\n+\n+\t\t/* get the key and salt */\n+\t\tret = ixgbevf_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);\n+\t\tif (ret) {\n+\t\t\tnetdev_err(dev, \"Failed to get key data for Rx SA table\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\t/* get ip for rx sa table */\n+\t\tif (xs->props.family == AF_INET6)\n+\t\t\tmemcpy(rsa.ipaddr, &xs->id.daddr.a6, 16);\n+\t\telse\n+\t\t\tmemcpy(&rsa.ipaddr[3], &xs->id.daddr.a4, 4);\n+\n+\t\trsa.mode = IXGBE_RXMOD_VALID;\n+\t\tif (rsa.xs->id.proto & IPPROTO_ESP)\n+\t\t\trsa.mode |= IXGBE_RXMOD_PROTO_ESP;\n+\t\tif (rsa.decrypt)\n+\t\t\trsa.mode |= IXGBE_RXMOD_DECRYPT;\n+\t\tif (rsa.xs->props.family == AF_INET6)\n+\t\t\trsa.mode |= IXGBE_RXMOD_IPV6;\n+\n+\t\tret = ixgbevf_ipsec_set_pf_sa(adapter, xs);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t\trsa.pfsa = ret;\n+\n+\t\t/* the preparations worked, so save the info */\n+\t\tmemcpy(&ipsec->rx_tbl[sa_idx], &rsa, sizeof(rsa));\n+\n+\t\txs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_RX_INDEX;\n+\n+\t\tipsec->num_rx_sa++;\n+\n+\t\t/* hash the new entry for faster search in Rx path */\n+\t\thash_add_rcu(ipsec->rx_sa_list, &ipsec->rx_tbl[sa_idx].hlist,\n+\t\t\t (__force u32)rsa.xs->id.spi);\n+\t} else {\n+\t\tstruct tx_sa tsa;\n+\n+\t\t/* find the first unused index */\n+\t\tret = ixgbevf_ipsec_find_empty_idx(ipsec, false);\n+\t\tif (ret < 0) {\n+\t\t\tnetdev_err(dev, \"No space for SA in Tx table\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\tsa_idx = (u16)ret;\n+\n+\t\tmemset(&tsa, 0, sizeof(tsa));\n+\t\ttsa.used = true;\n+\t\ttsa.xs = xs;\n+\n+\t\tif (xs->id.proto & IPPROTO_ESP)\n+\t\t\ttsa.encrypt = xs->ealg || xs->aead;\n+\n+\t\tret = ixgbevf_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);\n+\t\tif (ret) {\n+\t\t\tnetdev_err(dev, \"Failed to get key data for Tx SA table\\n\");\n+\t\t\tmemset(&tsa, 0, sizeof(tsa));\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tret = ixgbevf_ipsec_set_pf_sa(adapter, xs);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t\ttsa.pfsa = ret;\n+\n+\t\t/* the preparations worked, so save the info */\n+\t\tmemcpy(&ipsec->tx_tbl[sa_idx], &tsa, sizeof(tsa));\n+\n+\t\txs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_TX_INDEX;\n+\n+\t\tipsec->num_tx_sa++;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_del_sa - clear out this specific SA\n+ * @xs: pointer to transformer state struct\n+ **/\n+static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tstruct ixgbevf_adapter *adapter = netdev_priv(dev);\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\tu16 sa_idx;\n+\n+\tif (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {\n+\t\tsa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;\n+\n+\t\tif (!ipsec->rx_tbl[sa_idx].used) {\n+\t\t\tnetdev_err(dev, \"Invalid Rx SA selected sa_idx=%d offload_handle=%lu\\n\",\n+\t\t\t\t sa_idx, xs->xso.offload_handle);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tixgbevf_ipsec_del_pf_sa(adapter, ipsec->rx_tbl[sa_idx].pfsa);\n+\t\thash_del_rcu(&ipsec->rx_tbl[sa_idx].hlist);\n+\t\tmemset(&ipsec->rx_tbl[sa_idx], 0, sizeof(struct rx_sa));\n+\t\tipsec->num_rx_sa--;\n+\t} else {\n+\t\tsa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;\n+\n+\t\tif (!ipsec->tx_tbl[sa_idx].used) {\n+\t\t\tnetdev_err(dev, \"Invalid Tx SA selected sa_idx=%d offload_handle=%lu\\n\",\n+\t\t\t\t sa_idx, xs->xso.offload_handle);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tixgbevf_ipsec_del_pf_sa(adapter, ipsec->tx_tbl[sa_idx].pfsa);\n+\t\tmemset(&ipsec->tx_tbl[sa_idx], 0, sizeof(struct tx_sa));\n+\t\tipsec->num_tx_sa--;\n+\t}\n+}\n+\n+/**\n+ * ixgbevf_ipsec_offload_ok - can this packet use the xfrm hw offload\n+ * @skb: current data packet\n+ * @xs: pointer to transformer state struct\n+ **/\n+static bool ixgbevf_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)\n+{\n+\tif (xs->props.family == AF_INET) {\n+\t\t/* Offload with IPv4 options is not supported yet */\n+\t\tif (ip_hdr(skb)->ihl != 5)\n+\t\t\treturn false;\n+\t} else {\n+\t\t/* Offload with IPv6 extension headers is not support yet */\n+\t\tif (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))\n+\t\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+static const struct xfrmdev_ops ixgbevf_xfrmdev_ops = {\n+\t.xdo_dev_state_add = ixgbevf_ipsec_add_sa,\n+\t.xdo_dev_state_delete = ixgbevf_ipsec_del_sa,\n+\t.xdo_dev_offload_ok = ixgbevf_ipsec_offload_ok,\n+};\n+\n+/**\n+ * ixgbevf_ipsec_tx - setup Tx flags for ipsec offload\n+ * @tx_ring: outgoing context\n+ * @first: current data packet\n+ * @itd: ipsec Tx data for later use in building context descriptor\n+ **/\n+int ixgbevf_ipsec_tx(struct ixgbevf_ring *tx_ring,\n+\t\t struct ixgbevf_tx_buffer *first,\n+\t\t struct ixgbevf_ipsec_tx_data *itd)\n+{\n+\tstruct ixgbevf_adapter *adapter = netdev_priv(tx_ring->netdev);\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\tstruct xfrm_state *xs;\n+\tstruct tx_sa *tsa;\n+\tu16 sa_idx;\n+\n+\tif (unlikely(!first->skb->sp->len)) {\n+\t\tnetdev_err(tx_ring->netdev, \"%s: no xfrm state len = %d\\n\",\n+\t\t\t __func__, first->skb->sp->len);\n+\t\treturn 0;\n+\t}\n+\n+\txs = xfrm_input_state(first->skb);\n+\tif (unlikely(!xs)) {\n+\t\tnetdev_err(tx_ring->netdev, \"%s: no xfrm_input_state() xs = %p\\n\",\n+\t\t\t __func__, xs);\n+\t\treturn 0;\n+\t}\n+\n+\tsa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;\n+\tif (unlikely(sa_idx > IXGBE_IPSEC_MAX_SA_COUNT)) {\n+\t\tnetdev_err(tx_ring->netdev, \"%s: bad sa_idx=%d handle=%lu\\n\",\n+\t\t\t __func__, sa_idx, xs->xso.offload_handle);\n+\t\treturn 0;\n+\t}\n+\n+\ttsa = &ipsec->tx_tbl[sa_idx];\n+\tif (unlikely(!tsa->used)) {\n+\t\tnetdev_err(tx_ring->netdev, \"%s: unused sa_idx=%d\\n\",\n+\t\t\t __func__, sa_idx);\n+\t\treturn 0;\n+\t}\n+\n+\titd->pfsa = tsa->pfsa - IXGBE_IPSEC_BASE_TX_INDEX;\n+\n+\tfirst->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CSUM;\n+\n+\tif (xs->id.proto == IPPROTO_ESP) {\n+\t\titd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |\n+\t\t\t IXGBE_ADVTXD_TUCMD_L4T_TCP;\n+\t\tif (first->protocol == htons(ETH_P_IP))\n+\t\t\titd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;\n+\n+\t\t/* The actual trailer length is authlen (16 bytes) plus\n+\t\t * 2 bytes for the proto and the padlen values, plus\n+\t\t * padlen bytes of padding. This ends up not the same\n+\t\t * as the static value found in xs->props.trailer_len (21).\n+\t\t *\n+\t\t * ... but if we're doing GSO, don't bother as the stack\n+\t\t * doesn't add a trailer for those.\n+\t\t */\n+\t\tif (!skb_is_gso(first->skb)) {\n+\t\t\t/* The \"correct\" way to get the auth length would be\n+\t\t\t * to use\n+\t\t\t * authlen = crypto_aead_authsize(xs->data);\n+\t\t\t * but since we know we only have one size to worry\n+\t\t\t * about * we can let the compiler use the constant\n+\t\t\t * and save us a few CPU cycles.\n+\t\t\t */\n+\t\t\tconst int authlen = IXGBE_IPSEC_AUTH_BITS / 8;\n+\t\t\tstruct sk_buff *skb = first->skb;\n+\t\t\tu8 padlen;\n+\t\t\tint ret;\n+\n+\t\t\tret = skb_copy_bits(skb, skb->len - (authlen + 2),\n+\t\t\t\t\t &padlen, 1);\n+\t\t\tif (unlikely(ret))\n+\t\t\t\treturn 0;\n+\t\t\titd->trailer_len = authlen + 2 + padlen;\n+\t\t}\n+\t}\n+\tif (tsa->encrypt)\n+\t\titd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;\n+\n+\treturn 1;\n+}\n+\n+/**\n+ * ixgbevf_ipsec_rx - decode ipsec bits from Rx descriptor\n+ * @rx_ring: receiving ring\n+ * @rx_desc: receive data descriptor\n+ * @skb: current data packet\n+ *\n+ * Determine if there was an ipsec encapsulation noticed, and if so set up\n+ * the resulting status for later in the receive stack.\n+ **/\n+void ixgbevf_ipsec_rx(struct ixgbevf_ring *rx_ring,\n+\t\t union ixgbe_adv_rx_desc *rx_desc,\n+\t\t struct sk_buff *skb)\n+{\n+\tstruct ixgbevf_adapter *adapter = netdev_priv(rx_ring->netdev);\n+\t__le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;\n+\t__le16 ipsec_pkt_types = cpu_to_le16(IXGBE_RXDADV_PKTTYPE_IPSEC_AH |\n+\t\t\t\t\t IXGBE_RXDADV_PKTTYPE_IPSEC_ESP);\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\tstruct xfrm_offload *xo = NULL;\n+\tstruct xfrm_state *xs = NULL;\n+\tstruct ipv6hdr *ip6 = NULL;\n+\tstruct iphdr *ip4 = NULL;\n+\tvoid *daddr;\n+\t__be32 spi;\n+\tu8 *c_hdr;\n+\tu8 proto;\n+\n+\t/* Find the ip and crypto headers in the data.\n+\t * We can assume no vlan header in the way, b/c the\n+\t * hw won't recognize the IPsec packet and anyway the\n+\t * currently vlan device doesn't support xfrm offload.\n+\t */\n+\tif (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_IPV4)) {\n+\t\tip4 = (struct iphdr *)(skb->data + ETH_HLEN);\n+\t\tdaddr = &ip4->daddr;\n+\t\tc_hdr = (u8 *)ip4 + ip4->ihl * 4;\n+\t} else if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_IPV6)) {\n+\t\tip6 = (struct ipv6hdr *)(skb->data + ETH_HLEN);\n+\t\tdaddr = &ip6->daddr;\n+\t\tc_hdr = (u8 *)ip6 + sizeof(struct ipv6hdr);\n+\t} else {\n+\t\treturn;\n+\t}\n+\n+\tswitch (pkt_info & ipsec_pkt_types) {\n+\tcase cpu_to_le16(IXGBE_RXDADV_PKTTYPE_IPSEC_AH):\n+\t\tspi = ((struct ip_auth_hdr *)c_hdr)->spi;\n+\t\tproto = IPPROTO_AH;\n+\t\tbreak;\n+\tcase cpu_to_le16(IXGBE_RXDADV_PKTTYPE_IPSEC_ESP):\n+\t\tspi = ((struct ip_esp_hdr *)c_hdr)->spi;\n+\t\tproto = IPPROTO_ESP;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\txs = ixgbevf_ipsec_find_rx_state(ipsec, daddr, proto, spi, !!ip4);\n+\tif (unlikely(!xs))\n+\t\treturn;\n+\n+\tskb->sp = secpath_dup(skb->sp);\n+\tif (unlikely(!skb->sp))\n+\t\treturn;\n+\n+\tskb->sp->xvec[skb->sp->len++] = xs;\n+\tskb->sp->olen++;\n+\txo = xfrm_offload(skb);\n+\txo->flags = CRYPTO_DONE;\n+\txo->status = CRYPTO_SUCCESS;\n+\n+\tadapter->rx_ipsec++;\n+}\n+\n+/**\n+ * ixgbevf_init_ipsec_offload - initialize registers for IPSec operation\n+ * @adapter: board private structure\n+ **/\n+void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter)\n+{\n+\tstruct ixgbevf_ipsec *ipsec;\n+\tsize_t size;\n+\n+\tswitch (adapter->hw.api_version) {\n+\tcase ixgbe_mbox_api_14:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\tipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL);\n+\tif (!ipsec)\n+\t\tgoto err1;\n+\thash_init(ipsec->rx_sa_list);\n+\n+\tsize = sizeof(struct rx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;\n+\tipsec->rx_tbl = kzalloc(size, GFP_KERNEL);\n+\tif (!ipsec->rx_tbl)\n+\t\tgoto err2;\n+\n+\tsize = sizeof(struct tx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;\n+\tipsec->tx_tbl = kzalloc(size, GFP_KERNEL);\n+\tif (!ipsec->tx_tbl)\n+\t\tgoto err2;\n+\n+\tipsec->num_rx_sa = 0;\n+\tipsec->num_tx_sa = 0;\n+\n+\tadapter->ipsec = ipsec;\n+\n+\tadapter->netdev->xfrmdev_ops = &ixgbevf_xfrmdev_ops;\n+\n+#define IXGBEVF_ESP_FEATURES\t(NETIF_F_HW_ESP | \\\n+\t\t\t\t NETIF_F_HW_ESP_TX_CSUM | \\\n+\t\t\t\t NETIF_F_GSO_ESP)\n+\n+\tadapter->netdev->features |= IXGBEVF_ESP_FEATURES;\n+\tadapter->netdev->hw_enc_features |= IXGBEVF_ESP_FEATURES;\n+\n+\treturn;\n+\n+err2:\n+\tkfree(ipsec->rx_tbl);\n+\tkfree(ipsec->tx_tbl);\n+\tkfree(ipsec);\n+err1:\n+\tnetdev_err(adapter->netdev, \"Unable to allocate memory for SA tables\");\n+}\n+\n+/**\n+ * ixgbevf_stop_ipsec_offload - tear down the ipsec offload\n+ * @adapter: board private structure\n+ **/\n+void ixgbevf_stop_ipsec_offload(struct ixgbevf_adapter *adapter)\n+{\n+\tstruct ixgbevf_ipsec *ipsec = adapter->ipsec;\n+\n+\tadapter->ipsec = NULL;\n+\tif (ipsec) {\n+\t\tkfree(ipsec->rx_tbl);\n+\t\tkfree(ipsec->tx_tbl);\n+\t\tkfree(ipsec);\n+\t}\n+}\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.h b/drivers/net/ethernet/intel/ixgbevf/ipsec.h\nnew file mode 100644\nindex 0000000..3740725\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.h\n@@ -0,0 +1,66 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/* Copyright(c) 2018 Oracle and/or its affiliates. All rights reserved. */\n+\n+#ifndef _IXGBEVF_IPSEC_H_\n+#define _IXGBEVF_IPSEC_H_\n+\n+#define IXGBE_IPSEC_MAX_SA_COUNT\t1024\n+#define IXGBE_IPSEC_BASE_RX_INDEX\t0\n+#define IXGBE_IPSEC_BASE_TX_INDEX\tIXGBE_IPSEC_MAX_SA_COUNT\n+#define IXGBE_IPSEC_AUTH_BITS\t\t128\n+\n+#define IXGBE_RXMOD_VALID\t\t0x00000001\n+#define IXGBE_RXMOD_PROTO_ESP\t\t0x00000004\n+#define IXGBE_RXMOD_DECRYPT\t\t0x00000008\n+#define IXGBE_RXMOD_IPV6\t\t0x00000010\n+\n+struct rx_sa {\n+\tstruct hlist_node hlist;\n+\tstruct xfrm_state *xs;\n+\t__be32 ipaddr[4];\n+\tu32 key[4];\n+\tu32 salt;\n+\tu32 mode;\n+\tu32 pfsa;\n+\tbool used;\n+\tbool decrypt;\n+};\n+\n+struct rx_ip_sa {\n+\t__be32 ipaddr[4];\n+\tu32 ref_cnt;\n+\tbool used;\n+};\n+\n+struct tx_sa {\n+\tstruct xfrm_state *xs;\n+\tu32 key[4];\n+\tu32 salt;\n+\tu32 pfsa;\n+\tbool encrypt;\n+\tbool used;\n+};\n+\n+struct ixgbevf_ipsec_tx_data {\n+\tu32 flags;\n+\tu16 trailer_len;\n+\tu16 pfsa;\n+};\n+\n+struct ixgbevf_ipsec {\n+\tu16 num_rx_sa;\n+\tu16 num_tx_sa;\n+\tstruct rx_sa *rx_tbl;\n+\tstruct tx_sa *tx_tbl;\n+\tDECLARE_HASHTABLE(rx_sa_list, 10);\n+};\n+\n+struct sa_mbx_msg {\n+\t__be32 spi;\n+\tu8 flags;\n+\tu8 proto;\n+\tu16 family;\n+\t__be32 addr[4];\n+\tu32 key[5];\n+};\n+#endif /* _IXGBEVF_IPSEC_H_ */\ndiff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\nindex 56a1031..172637e 100644\n--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\n+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h\n@@ -14,6 +14,7 @@\n #include <net/xdp.h>\n \n #include \"vf.h\"\n+#include \"ipsec.h\"\n \n #define IXGBE_MAX_TXD_PWR\t14\n #define IXGBE_MAX_DATA_PER_TXD\tBIT(IXGBE_MAX_TXD_PWR)\n@@ -163,6 +164,7 @@ struct ixgbevf_ring {\n #define IXGBE_TX_FLAGS_VLAN\t\tBIT(1)\n #define IXGBE_TX_FLAGS_TSO\t\tBIT(2)\n #define IXGBE_TX_FLAGS_IPV4\t\tBIT(3)\n+#define IXGBE_TX_FLAGS_IPSEC\t\tBIT(4)\n #define IXGBE_TX_FLAGS_VLAN_MASK\t0xffff0000\n #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK\t0x0000e000\n #define IXGBE_TX_FLAGS_VLAN_SHIFT\t16\n@@ -338,6 +340,7 @@ struct ixgbevf_adapter {\n \tstruct ixgbevf_ring *tx_ring[MAX_TX_QUEUES]; /* One per active queue */\n \tu64 restart_queue;\n \tu32 tx_timeout_count;\n+\tu64 tx_ipsec;\n \n \t/* RX */\n \tint num_rx_queues;\n@@ -348,6 +351,7 @@ struct ixgbevf_adapter {\n \tu64 alloc_rx_page_failed;\n \tu64 alloc_rx_buff_failed;\n \tu64 alloc_rx_page;\n+\tu64 rx_ipsec;\n \n \tstruct msix_entry *msix_entries;\n \n@@ -384,6 +388,10 @@ struct ixgbevf_adapter {\n \tu8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE];\n \tu32 flags;\n #define IXGBEVF_FLAGS_LEGACY_RX\t\tBIT(1)\n+\n+#ifdef CONFIG_XFRM\n+\tstruct ixgbevf_ipsec *ipsec;\n+#endif /* CONFIG_XFRM */\n };\n \n enum ixbgevf_state_t {\n", "prefixes": [ "next-queue", "7/8" ] }