get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45240,
    "url": "http://patches.dpdk.org/api/patches/45240/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20180924195503.18894-3-yskoh@mellanox.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": "<20180924195503.18894-3-yskoh@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180924195503.18894-3-yskoh@mellanox.com",
    "date": "2018-09-24T19:55:16",
    "name": "[v2,2/3] net/mlx5: remove Netlink flow driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "b625c83d70b90726b0cc71b8bcee41611fd1700c",
    "submitter": {
        "id": 636,
        "url": "http://patches.dpdk.org/api/people/636/?format=api",
        "name": "Yongseok Koh",
        "email": "yskoh@mellanox.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/20180924195503.18894-3-yskoh@mellanox.com/mbox/",
    "series": [
        {
            "id": 1474,
            "url": "http://patches.dpdk.org/api/series/1474/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1474",
            "date": "2018-09-24T19:55:12",
            "name": "net/mlx5: migrate Linux TC flower driver to new flow engine",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/1474/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/45240/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/45240/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 C4BBB1B145;\n\tMon, 24 Sep 2018 21:55:20 +0200 (CEST)",
            "from EUR03-DB5-obe.outbound.protection.outlook.com\n\t(mail-eopbgr40070.outbound.protection.outlook.com [40.107.4.70])\n\tby dpdk.org (Postfix) with ESMTP id 1F4E61B120\n\tfor <dev@dpdk.org>; Mon, 24 Sep 2018 21:55:18 +0200 (CEST)",
            "from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by\n\tDB3PR0502MB3995.eurprd05.prod.outlook.com (52.134.72.30) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1164.25; Mon, 24 Sep 2018 19:55:16 +0000",
            "from DB3PR0502MB3980.eurprd05.prod.outlook.com\n\t([fe80::1cb0:661b:ecab:6045]) by\n\tDB3PR0502MB3980.eurprd05.prod.outlook.com\n\t([fe80::1cb0:661b:ecab:6045%2]) with mapi id 15.20.1164.017;\n\tMon, 24 Sep 2018 19:55:16 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=6Z9syhJ4Coghhurzqr81FWDgKX/JRJ9DFn/pGAeR1vo=;\n\tb=aNpJoM5LZxm12TXIoG9DM+yblhd+RONFXi6M2PEvYkDVI8UnOXAYcdq//fHhHxR3GZ7nmTJgr42n8N8oSz4FwiV/2JMxsPvC3vdwpGNex4rd64Hkjae4oDBbklaX75rhr4RTZGGB0EuCL/NjEKzbhTzn3GPsJKdbvnLNnsYOD0Y=",
        "From": "Yongseok Koh <yskoh@mellanox.com>",
        "To": "Thomas Monjalon <thomas@monjalon.net>,\n\tShahaf Shuler <shahafs@mellanox.com>",
        "CC": "\"dev@dpdk.org\" <dev@dpdk.org>, Yongseok Koh <yskoh@mellanox.com>",
        "Thread-Topic": "[PATCH v2 2/3] net/mlx5: remove Netlink flow driver",
        "Thread-Index": "AQHUVECDcmImSLPZZkikH6mdl79Tig==",
        "Date": "Mon, 24 Sep 2018 19:55:16 +0000",
        "Message-ID": "<20180924195503.18894-3-yskoh@mellanox.com>",
        "References": "<20180919072143.23211-1-yskoh@mellanox.com>\n\t<20180924195503.18894-1-yskoh@mellanox.com>",
        "In-Reply-To": "<20180924195503.18894-1-yskoh@mellanox.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "MWHPR2001CA0016.namprd20.prod.outlook.com\n\t(2603:10b6:301:15::26) To DB3PR0502MB3980.eurprd05.prod.outlook.com\n\t(2603:10a6:8:10::27)",
        "authentication-results": "spf=none (sender IP is )\n\tsmtp.mailfrom=yskoh@mellanox.com; ",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-originating-ip": "[209.116.155.178]",
        "x-ms-publictraffictype": "Email",
        "x-microsoft-exchange-diagnostics": "1; DB3PR0502MB3995;\n\t6:XpqcBUB8LYZFpiZshQc5pivLnvy28322olCNRo+MlxeUGuga/HHWGg92edZGSDax4H+HDSwY9nmDq8Ns/YaQXm2rxZth9Hv+EVsxHxAIYRUw3JxGLEzbETFCB8q+zJG99GwjvxvHLqmfpzUGfXWABLTR9R1N5CbsvjvtGRptOo4YYRQFALTc1Shl/UXFEvZrM3jyUyPIU7YmVTf3uOEKFob6h+hLpDX7MgjZ0TaWyNkAKV32iWOJNRjVaw+sTqUF72BD4WwcP/paSnsbI11AHNu8B5L3zoYgNKZxf0Dto1bejS2JIcKH9zH2WsZPupbj/r7nr+5a/IUquUpFBo7aBSnp+Wo6u9rb8Cb2Bq0bUpP271Nn7GSGR8Pl64MRTSBHSwJEvW86mehZI6pPJQNppXqbNtbQBNW+TKpiTwSJz0WO74ZARZghVUCDhpOgj8Vd8+Ht5UsljtrzTbMGmHiAZw==;\n\t5:B8P4PnyAnAyAngMJS+YJNknrGNZOa1ln7hpVA1MtdyaNLhPznkGLqFumb23gsBL/hNfXYCoZxABiudWkjUTOl/faUsoE76vw4dqGqTWWr0HlY/bYH5hgCxEI+j8SSRWdO7aorPwS6qV5WlcuZjfEw9AMO0LRj0BusAFrGLVDPZQ=;\n\t7:GHLoEkseMXuEa8SFqwW1bvzVsQCEZdQKxWSM5rFe84ATzPJwR36xrpH9DC7bPDmrBMJJXHbRKl/QexX+XWORRv+G/jC+RBcH7hgDL1MPTvjWYkJdXAydpNqsPUObLV1AI736B9Bazc++Kngg+KtuUt0vIMKF8p8O72TCvIW5BMv3q0QD25+m5LsJV/BFqyx3teOloxu7swJ7JE1wJJcRS3pv9D3tJGwVECXMMq+TuZPeAcwghnFLbM81mMvrk7tj",
        "x-ms-office365-filtering-correlation-id": "70eebe49-4a8c-4e7e-ba79-08d62257a5ae",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:DB3PR0502MB3995; ",
        "x-ms-traffictypediagnostic": "DB3PR0502MB3995:",
        "x-ld-processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "x-microsoft-antispam-prvs": "<DB3PR0502MB3995107E285427F0BDD41CA5C3170@DB3PR0502MB3995.eurprd05.prod.outlook.com>",
        "x-exchange-antispam-report-test": "UriScan:(269456686620040)(211171220733660); ",
        "x-ms-exchange-senderadcheck": "1",
        "x-exchange-antispam-report-cfa-test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3231355)(944501410)(52105095)(93006095)(93001095)(3002001)(6055026)(149066)(150027)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123562045)(201708071742011)(7699051);\n\tSRVR:DB3PR0502MB3995; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB3995; ",
        "x-forefront-prvs": "0805EC9467",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(136003)(346002)(396003)(376002)(366004)(39860400002)(199004)(189003)(486006)(2906002)(14444005)(99286004)(105586002)(106356001)(110136005)(71200400001)(68736007)(54906003)(107886003)(25786009)(5250100002)(316002)(11346002)(446003)(4326008)(7736002)(53936002)(476003)(2616005)(305945005)(66066001)(5660300001)(6436002)(26005)(6116002)(102836004)(1076002)(3846002)(8676002)(8936002)(478600001)(14454004)(6506007)(81156014)(386003)(81166006)(53946003)(36756003)(16200700003)(6636002)(6486002)(71190400001)(52116002)(86362001)(76176011)(97736004)(5024004)(2900100001)(575784001)(256004)(186003)(6512007)(579004)(559001)(569006);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB3995;\n\tH:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; \n\tPTR:InfoNoRecords; A:1; MX:1; ",
        "received-spf": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "x-microsoft-antispam-message-info": "h8V9XwUhcn2xl83iSzVtuUyoWI71kIZe3sZVpyk+qT/yubYabb0RZKHnMMyEcl925fnjIe8SA/0/f7jpBq2VEXd8sw+lF4jAl5HhVzRPYcEm0m3Re+4OgCibE+k3OoIwMdJW4a/HdsQUqJEx5JofAlW/Zmz/6CYOgOyEv1gxDTZxciZklW/kZhGva62fDu8yBHlLzs16WB1y70UpWToQ6Zf6kFPEIU9HJ7a4Oxz4MX6vZNZf0f/3GEhc100jH9wJn/31GRkzHTbB8tleRZeYZf/iabzg271mjGnVS0e5U6e74fIYrj8Q8+Vq0ZRuoVZXH08vMam43jYDpt3UMOmFJ/yZkJ6fOlngELqKtwNd2Co=",
        "spamdiagnosticoutput": "1:99",
        "spamdiagnosticmetadata": "NSPM",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "70eebe49-4a8c-4e7e-ba79-08d62257a5ae",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "24 Sep 2018 19:55:16.2632\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DB3PR0502MB3995",
        "Subject": "[dpdk-dev] [PATCH v2 2/3] net/mlx5: remove Netlink flow driver",
        "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": "Netlink based E-Switch flow engine will be migrated to the new flow engine.\nnl_flow will be renamed to flow_tcf as it goes through Linux TC flower\ninterface.\n\nSigned-off-by: Yongseok Koh <yskoh@mellanox.com>\n---\n drivers/net/mlx5/Makefile       |    1 -\n drivers/net/mlx5/meson.build    |    1 -\n drivers/net/mlx5/mlx5.c         |   32 -\n drivers/net/mlx5/mlx5.h         |   25 -\n drivers/net/mlx5/mlx5_nl_flow.c | 1228 ---------------------------------------\n 5 files changed, 1287 deletions(-)\n delete mode 100644 drivers/net/mlx5/mlx5_nl_flow.c",
    "diff": "diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile\nindex 4243b37ca..9c1044808 100644\n--- a/drivers/net/mlx5/Makefile\n+++ b/drivers/net/mlx5/Makefile\n@@ -35,7 +35,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_dv.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_verbs.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl.c\n-SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl_flow.c\n \n ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)\n INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE)\ndiff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build\nindex 3d09ece4f..e5376291c 100644\n--- a/drivers/net/mlx5/meson.build\n+++ b/drivers/net/mlx5/meson.build\n@@ -36,7 +36,6 @@ if build\n \t\t'mlx5_mac.c',\n \t\t'mlx5_mr.c',\n \t\t'mlx5_nl.c',\n-\t\t'mlx5_nl_flow.c',\n \t\t'mlx5_rss.c',\n \t\t'mlx5_rxmode.c',\n \t\t'mlx5_rxq.c',\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 2f7d046e0..bb9a63fba 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -286,8 +286,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)\n \t\tclose(priv->nl_socket_route);\n \tif (priv->nl_socket_rdma >= 0)\n \t\tclose(priv->nl_socket_rdma);\n-\tif (priv->mnl_socket)\n-\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n \tret = mlx5_hrxq_ibv_verify(dev);\n \tif (ret)\n \t\tDRV_LOG(WARNING, \"port %u some hash Rx queue still remain\",\n@@ -1137,34 +1135,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \tclaim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));\n \tif (vf && config.vf_nl_en)\n \t\tmlx5_nl_mac_addr_sync(eth_dev);\n-\tpriv->mnl_socket = mlx5_nl_flow_socket_create();\n-\tif (!priv->mnl_socket) {\n-\t\terr = -rte_errno;\n-\t\tDRV_LOG(WARNING,\n-\t\t\t\"flow rules relying on switch offloads will not be\"\n-\t\t\t\" supported: cannot open libmnl socket: %s\",\n-\t\t\tstrerror(rte_errno));\n-\t} else {\n-\t\tstruct rte_flow_error error;\n-\t\tunsigned int ifindex = mlx5_ifindex(eth_dev);\n-\n-\t\tif (!ifindex) {\n-\t\t\terr = -rte_errno;\n-\t\t\terror.message =\n-\t\t\t\t\"cannot retrieve network interface index\";\n-\t\t} else {\n-\t\t\terr = mlx5_nl_flow_init(priv->mnl_socket, ifindex,\n-\t\t\t\t\t\t&error);\n-\t\t}\n-\t\tif (err) {\n-\t\t\tDRV_LOG(WARNING,\n-\t\t\t\t\"flow rules relying on switch offloads will\"\n-\t\t\t\t\" not be supported: %s: %s\",\n-\t\t\t\terror.message, strerror(rte_errno));\n-\t\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n-\t\t\tpriv->mnl_socket = NULL;\n-\t\t}\n-\t}\n \tTAILQ_INIT(&priv->flows);\n \tTAILQ_INIT(&priv->ctrl_flows);\n \t/* Hint libmlx5 to use PMD allocator for data plane resources */\n@@ -1217,8 +1187,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,\n \t\t\tclose(priv->nl_socket_route);\n \t\tif (priv->nl_socket_rdma >= 0)\n \t\t\tclose(priv->nl_socket_rdma);\n-\t\tif (priv->mnl_socket)\n-\t\t\tmlx5_nl_flow_socket_destroy(priv->mnl_socket);\n \t\tif (own_domain_id)\n \t\t\tclaim_zero(rte_eth_switch_domain_free(priv->domain_id));\n \t\trte_free(priv);\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 8bb619d9e..8de0d74ce 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -158,12 +158,6 @@ struct mlx5_drop {\n \tstruct mlx5_rxq_ibv *rxq; /* Verbs Rx queue. */\n };\n \n-/** DPDK port to network interface index (ifindex) conversion. */\n-struct mlx5_nl_flow_ptoi {\n-\tuint16_t port_id; /**< DPDK port ID. */\n-\tunsigned int ifindex; /**< Network interface index. */\n-};\n-\n struct mnl_socket;\n \n struct priv {\n@@ -399,23 +393,4 @@ unsigned int mlx5_nl_ifindex(int nl, const char *name);\n int mlx5_nl_switch_info(int nl, unsigned int ifindex,\n \t\t\tstruct mlx5_switch_info *info);\n \n-/* mlx5_nl_flow.c */\n-\n-int mlx5_nl_flow_transpose(void *buf,\n-\t\t\t   size_t size,\n-\t\t\t   const struct mlx5_nl_flow_ptoi *ptoi,\n-\t\t\t   const struct rte_flow_attr *attr,\n-\t\t\t   const struct rte_flow_item *pattern,\n-\t\t\t   const struct rte_flow_action *actions,\n-\t\t\t   struct rte_flow_error *error);\n-void mlx5_nl_flow_brand(void *buf, uint32_t handle);\n-int mlx5_nl_flow_create(struct mnl_socket *nl, void *buf,\n-\t\t\tstruct rte_flow_error *error);\n-int mlx5_nl_flow_destroy(struct mnl_socket *nl, void *buf,\n-\t\t\t struct rte_flow_error *error);\n-int mlx5_nl_flow_init(struct mnl_socket *nl, unsigned int ifindex,\n-\t\t      struct rte_flow_error *error);\n-struct mnl_socket *mlx5_nl_flow_socket_create(void);\n-void mlx5_nl_flow_socket_destroy(struct mnl_socket *nl);\n-\n #endif /* RTE_PMD_MLX5_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_nl_flow.c b/drivers/net/mlx5/mlx5_nl_flow.c\ndeleted file mode 100644\nindex beb03c911..000000000\n--- a/drivers/net/mlx5/mlx5_nl_flow.c\n+++ /dev/null\n@@ -1,1228 +0,0 @@\n-/* SPDX-License-Identifier: BSD-3-Clause\n- * Copyright 2018 6WIND S.A.\n- * Copyright 2018 Mellanox Technologies, Ltd\n- */\n-\n-#include <assert.h>\n-#include <errno.h>\n-#include <libmnl/libmnl.h>\n-#include <linux/if_ether.h>\n-#include <linux/netlink.h>\n-#include <linux/pkt_cls.h>\n-#include <linux/pkt_sched.h>\n-#include <linux/rtnetlink.h>\n-#include <linux/tc_act/tc_gact.h>\n-#include <linux/tc_act/tc_mirred.h>\n-#include <netinet/in.h>\n-#include <stdalign.h>\n-#include <stdbool.h>\n-#include <stddef.h>\n-#include <stdint.h>\n-#include <stdlib.h>\n-#include <sys/socket.h>\n-\n-#include <rte_byteorder.h>\n-#include <rte_errno.h>\n-#include <rte_ether.h>\n-#include <rte_flow.h>\n-\n-#include \"mlx5.h\"\n-#include \"mlx5_autoconf.h\"\n-\n-#ifdef HAVE_TC_ACT_VLAN\n-\n-#include <linux/tc_act/tc_vlan.h>\n-\n-#else /* HAVE_TC_ACT_VLAN */\n-\n-#define TCA_VLAN_ACT_POP 1\n-#define TCA_VLAN_ACT_PUSH 2\n-#define TCA_VLAN_ACT_MODIFY 3\n-#define TCA_VLAN_PARMS 2\n-#define TCA_VLAN_PUSH_VLAN_ID 3\n-#define TCA_VLAN_PUSH_VLAN_PROTOCOL 4\n-#define TCA_VLAN_PAD 5\n-#define TCA_VLAN_PUSH_VLAN_PRIORITY 6\n-\n-struct tc_vlan {\n-\ttc_gen;\n-\tint v_action;\n-};\n-\n-#endif /* HAVE_TC_ACT_VLAN */\n-\n-/* Normally found in linux/netlink.h. */\n-#ifndef NETLINK_CAP_ACK\n-#define NETLINK_CAP_ACK 10\n-#endif\n-\n-/* Normally found in linux/pkt_sched.h. */\n-#ifndef TC_H_MIN_INGRESS\n-#define TC_H_MIN_INGRESS 0xfff2u\n-#endif\n-\n-/* Normally found in linux/pkt_cls.h. */\n-#ifndef TCA_CLS_FLAGS_SKIP_SW\n-#define TCA_CLS_FLAGS_SKIP_SW (1 << 1)\n-#endif\n-#ifndef HAVE_TCA_FLOWER_ACT\n-#define TCA_FLOWER_ACT 3\n-#endif\n-#ifndef HAVE_TCA_FLOWER_FLAGS\n-#define TCA_FLOWER_FLAGS 22\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_ETH_TYPE\n-#define TCA_FLOWER_KEY_ETH_TYPE 8\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_ETH_DST\n-#define TCA_FLOWER_KEY_ETH_DST 4\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_ETH_DST_MASK\n-#define TCA_FLOWER_KEY_ETH_DST_MASK 5\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_ETH_SRC\n-#define TCA_FLOWER_KEY_ETH_SRC 6\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_ETH_SRC_MASK\n-#define TCA_FLOWER_KEY_ETH_SRC_MASK 7\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IP_PROTO\n-#define TCA_FLOWER_KEY_IP_PROTO 9\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV4_SRC\n-#define TCA_FLOWER_KEY_IPV4_SRC 10\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV4_SRC_MASK\n-#define TCA_FLOWER_KEY_IPV4_SRC_MASK 11\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV4_DST\n-#define TCA_FLOWER_KEY_IPV4_DST 12\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV4_DST_MASK\n-#define TCA_FLOWER_KEY_IPV4_DST_MASK 13\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV6_SRC\n-#define TCA_FLOWER_KEY_IPV6_SRC 14\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV6_SRC_MASK\n-#define TCA_FLOWER_KEY_IPV6_SRC_MASK 15\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV6_DST\n-#define TCA_FLOWER_KEY_IPV6_DST 16\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_IPV6_DST_MASK\n-#define TCA_FLOWER_KEY_IPV6_DST_MASK 17\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_TCP_SRC\n-#define TCA_FLOWER_KEY_TCP_SRC 18\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_TCP_SRC_MASK\n-#define TCA_FLOWER_KEY_TCP_SRC_MASK 35\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_TCP_DST\n-#define TCA_FLOWER_KEY_TCP_DST 19\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_TCP_DST_MASK\n-#define TCA_FLOWER_KEY_TCP_DST_MASK 36\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_UDP_SRC\n-#define TCA_FLOWER_KEY_UDP_SRC 20\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_UDP_SRC_MASK\n-#define TCA_FLOWER_KEY_UDP_SRC_MASK 37\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_UDP_DST\n-#define TCA_FLOWER_KEY_UDP_DST 21\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_UDP_DST_MASK\n-#define TCA_FLOWER_KEY_UDP_DST_MASK 38\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_VLAN_ID\n-#define TCA_FLOWER_KEY_VLAN_ID 23\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_VLAN_PRIO\n-#define TCA_FLOWER_KEY_VLAN_PRIO 24\n-#endif\n-#ifndef HAVE_TCA_FLOWER_KEY_VLAN_ETH_TYPE\n-#define TCA_FLOWER_KEY_VLAN_ETH_TYPE 25\n-#endif\n-\n-/** Parser state definitions for mlx5_nl_flow_trans[]. */\n-enum mlx5_nl_flow_trans {\n-\tINVALID,\n-\tBACK,\n-\tATTR,\n-\tPATTERN,\n-\tITEM_VOID,\n-\tITEM_PORT_ID,\n-\tITEM_ETH,\n-\tITEM_VLAN,\n-\tITEM_IPV4,\n-\tITEM_IPV6,\n-\tITEM_TCP,\n-\tITEM_UDP,\n-\tACTIONS,\n-\tACTION_VOID,\n-\tACTION_PORT_ID,\n-\tACTION_DROP,\n-\tACTION_OF_POP_VLAN,\n-\tACTION_OF_PUSH_VLAN,\n-\tACTION_OF_SET_VLAN_VID,\n-\tACTION_OF_SET_VLAN_PCP,\n-\tEND,\n-};\n-\n-#define TRANS(...) (const enum mlx5_nl_flow_trans []){ __VA_ARGS__, INVALID, }\n-\n-#define PATTERN_COMMON \\\n-\tITEM_VOID, ITEM_PORT_ID, ACTIONS\n-#define ACTIONS_COMMON \\\n-\tACTION_VOID, ACTION_OF_POP_VLAN, ACTION_OF_PUSH_VLAN, \\\n-\tACTION_OF_SET_VLAN_VID, ACTION_OF_SET_VLAN_PCP\n-#define ACTIONS_FATE \\\n-\tACTION_PORT_ID, ACTION_DROP\n-\n-/** Parser state transitions used by mlx5_nl_flow_transpose(). */\n-static const enum mlx5_nl_flow_trans *const mlx5_nl_flow_trans[] = {\n-\t[INVALID] = NULL,\n-\t[BACK] = NULL,\n-\t[ATTR] = TRANS(PATTERN),\n-\t[PATTERN] = TRANS(ITEM_ETH, PATTERN_COMMON),\n-\t[ITEM_VOID] = TRANS(BACK),\n-\t[ITEM_PORT_ID] = TRANS(BACK),\n-\t[ITEM_ETH] = TRANS(ITEM_IPV4, ITEM_IPV6, ITEM_VLAN, PATTERN_COMMON),\n-\t[ITEM_VLAN] = TRANS(ITEM_IPV4, ITEM_IPV6, PATTERN_COMMON),\n-\t[ITEM_IPV4] = TRANS(ITEM_TCP, ITEM_UDP, PATTERN_COMMON),\n-\t[ITEM_IPV6] = TRANS(ITEM_TCP, ITEM_UDP, PATTERN_COMMON),\n-\t[ITEM_TCP] = TRANS(PATTERN_COMMON),\n-\t[ITEM_UDP] = TRANS(PATTERN_COMMON),\n-\t[ACTIONS] = TRANS(ACTIONS_FATE, ACTIONS_COMMON),\n-\t[ACTION_VOID] = TRANS(BACK),\n-\t[ACTION_PORT_ID] = TRANS(ACTION_VOID, END),\n-\t[ACTION_DROP] = TRANS(ACTION_VOID, END),\n-\t[ACTION_OF_POP_VLAN] = TRANS(ACTIONS_FATE, ACTIONS_COMMON),\n-\t[ACTION_OF_PUSH_VLAN] = TRANS(ACTIONS_FATE, ACTIONS_COMMON),\n-\t[ACTION_OF_SET_VLAN_VID] = TRANS(ACTIONS_FATE, ACTIONS_COMMON),\n-\t[ACTION_OF_SET_VLAN_PCP] = TRANS(ACTIONS_FATE, ACTIONS_COMMON),\n-\t[END] = NULL,\n-};\n-\n-/** Empty masks for known item types. */\n-static const union {\n-\tstruct rte_flow_item_port_id port_id;\n-\tstruct rte_flow_item_eth eth;\n-\tstruct rte_flow_item_vlan vlan;\n-\tstruct rte_flow_item_ipv4 ipv4;\n-\tstruct rte_flow_item_ipv6 ipv6;\n-\tstruct rte_flow_item_tcp tcp;\n-\tstruct rte_flow_item_udp udp;\n-} mlx5_nl_flow_mask_empty;\n-\n-/** Supported masks for known item types. */\n-static const struct {\n-\tstruct rte_flow_item_port_id port_id;\n-\tstruct rte_flow_item_eth eth;\n-\tstruct rte_flow_item_vlan vlan;\n-\tstruct rte_flow_item_ipv4 ipv4;\n-\tstruct rte_flow_item_ipv6 ipv6;\n-\tstruct rte_flow_item_tcp tcp;\n-\tstruct rte_flow_item_udp udp;\n-} mlx5_nl_flow_mask_supported = {\n-\t.port_id = {\n-\t\t.id = 0xffffffff,\n-\t},\n-\t.eth = {\n-\t\t.type = RTE_BE16(0xffff),\n-\t\t.dst.addr_bytes = \"\\xff\\xff\\xff\\xff\\xff\\xff\",\n-\t\t.src.addr_bytes = \"\\xff\\xff\\xff\\xff\\xff\\xff\",\n-\t},\n-\t.vlan = {\n-\t\t/* PCP and VID only, no DEI. */\n-\t\t.tci = RTE_BE16(0xefff),\n-\t\t.inner_type = RTE_BE16(0xffff),\n-\t},\n-\t.ipv4.hdr = {\n-\t\t.next_proto_id = 0xff,\n-\t\t.src_addr = RTE_BE32(0xffffffff),\n-\t\t.dst_addr = RTE_BE32(0xffffffff),\n-\t},\n-\t.ipv6.hdr = {\n-\t\t.proto = 0xff,\n-\t\t.src_addr =\n-\t\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\"\n-\t\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n-\t\t.dst_addr =\n-\t\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\"\n-\t\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\",\n-\t},\n-\t.tcp.hdr = {\n-\t\t.src_port = RTE_BE16(0xffff),\n-\t\t.dst_port = RTE_BE16(0xffff),\n-\t},\n-\t.udp.hdr = {\n-\t\t.src_port = RTE_BE16(0xffff),\n-\t\t.dst_port = RTE_BE16(0xffff),\n-\t},\n-};\n-\n-/**\n- * Retrieve mask for pattern item.\n- *\n- * This function does basic sanity checks on a pattern item in order to\n- * return the most appropriate mask for it.\n- *\n- * @param[in] item\n- *   Item specification.\n- * @param[in] mask_default\n- *   Default mask for pattern item as specified by the flow API.\n- * @param[in] mask_supported\n- *   Mask fields supported by the implementation.\n- * @param[in] mask_empty\n- *   Empty mask to return when there is no specification.\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n- *\n- * @return\n- *   Either @p item->mask or one of the mask parameters on success, NULL\n- *   otherwise and rte_errno is set.\n- */\n-static const void *\n-mlx5_nl_flow_item_mask(const struct rte_flow_item *item,\n-\t\t       const void *mask_default,\n-\t\t       const void *mask_supported,\n-\t\t       const void *mask_empty,\n-\t\t       size_t mask_size,\n-\t\t       struct rte_flow_error *error)\n-{\n-\tconst uint8_t *mask;\n-\tsize_t i;\n-\n-\t/* item->last and item->mask cannot exist without item->spec. */\n-\tif (!item->spec && (item->mask || item->last)) {\n-\t\trte_flow_error_set\n-\t\t\t(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item,\n-\t\t\t \"\\\"mask\\\" or \\\"last\\\" field provided without a\"\n-\t\t\t \" corresponding \\\"spec\\\"\");\n-\t\treturn NULL;\n-\t}\n-\t/* No spec, no mask, no problem. */\n-\tif (!item->spec)\n-\t\treturn mask_empty;\n-\tmask = item->mask ? item->mask : mask_default;\n-\tassert(mask);\n-\t/*\n-\t * Single-pass check to make sure that:\n-\t * - Mask is supported, no bits are set outside mask_supported.\n-\t * - Both item->spec and item->last are included in mask.\n-\t */\n-\tfor (i = 0; i != mask_size; ++i) {\n-\t\tif (!mask[i])\n-\t\t\tcontinue;\n-\t\tif ((mask[i] | ((const uint8_t *)mask_supported)[i]) !=\n-\t\t    ((const uint8_t *)mask_supported)[i]) {\n-\t\t\trte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask, \"unsupported field found in \\\"mask\\\"\");\n-\t\t\treturn NULL;\n-\t\t}\n-\t\tif (item->last &&\n-\t\t    (((const uint8_t *)item->spec)[i] & mask[i]) !=\n-\t\t    (((const uint8_t *)item->last)[i] & mask[i])) {\n-\t\t\trte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_LAST,\n-\t\t\t\t item->last,\n-\t\t\t\t \"range between \\\"spec\\\" and \\\"last\\\" not\"\n-\t\t\t\t \" comprised in \\\"mask\\\"\");\n-\t\t\treturn NULL;\n-\t\t}\n-\t}\n-\treturn mask;\n-}\n-\n-/**\n- * Transpose flow rule description to rtnetlink message.\n- *\n- * This function transposes a flow rule description to a traffic control\n- * (TC) filter creation message ready to be sent over Netlink.\n- *\n- * Target interface is specified as the first entry of the @p ptoi table.\n- * Subsequent entries enable this function to resolve other DPDK port IDs\n- * found in the flow rule.\n- *\n- * @param[out] buf\n- *   Output message buffer. May be NULL when @p size is 0.\n- * @param size\n- *   Size of @p buf. Message may be truncated if not large enough.\n- * @param[in] ptoi\n- *   DPDK port ID to network interface index translation table. This table\n- *   is terminated by an entry with a zero ifindex value.\n- * @param[in] attr\n- *   Flow rule attributes.\n- * @param[in] pattern\n- *   Pattern specification.\n- * @param[in] actions\n- *   Associated actions.\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n- *\n- * @return\n- *   A positive value representing the exact size of the message in bytes\n- *   regardless of the @p size parameter on success, a negative errno value\n- *   otherwise and rte_errno is set.\n- */\n-int\n-mlx5_nl_flow_transpose(void *buf,\n-\t\t       size_t size,\n-\t\t       const struct mlx5_nl_flow_ptoi *ptoi,\n-\t\t       const struct rte_flow_attr *attr,\n-\t\t       const struct rte_flow_item *pattern,\n-\t\t       const struct rte_flow_action *actions,\n-\t\t       struct rte_flow_error *error)\n-{\n-\talignas(struct nlmsghdr)\n-\tuint8_t buf_tmp[mnl_nlmsg_size(sizeof(struct tcmsg) + 1024)];\n-\tconst struct rte_flow_item *item;\n-\tconst struct rte_flow_action *action;\n-\tunsigned int n;\n-\tuint32_t act_index_cur;\n-\tbool in_port_id_set;\n-\tbool eth_type_set;\n-\tbool vlan_present;\n-\tbool vlan_eth_type_set;\n-\tbool ip_proto_set;\n-\tstruct nlattr *na_flower;\n-\tstruct nlattr *na_flower_act;\n-\tstruct nlattr *na_vlan_id;\n-\tstruct nlattr *na_vlan_priority;\n-\tconst enum mlx5_nl_flow_trans *trans;\n-\tconst enum mlx5_nl_flow_trans *back;\n-\n-\tif (!size)\n-\t\tgoto error_nobufs;\n-init:\n-\titem = pattern;\n-\taction = actions;\n-\tn = 0;\n-\tact_index_cur = 0;\n-\tin_port_id_set = false;\n-\teth_type_set = false;\n-\tvlan_present = false;\n-\tvlan_eth_type_set = false;\n-\tip_proto_set = false;\n-\tna_flower = NULL;\n-\tna_flower_act = NULL;\n-\tna_vlan_id = NULL;\n-\tna_vlan_priority = NULL;\n-\ttrans = TRANS(ATTR);\n-\tback = trans;\n-trans:\n-\tswitch (trans[n++]) {\n-\t\tunion {\n-\t\t\tconst struct rte_flow_item_port_id *port_id;\n-\t\t\tconst struct rte_flow_item_eth *eth;\n-\t\t\tconst struct rte_flow_item_vlan *vlan;\n-\t\t\tconst struct rte_flow_item_ipv4 *ipv4;\n-\t\t\tconst struct rte_flow_item_ipv6 *ipv6;\n-\t\t\tconst struct rte_flow_item_tcp *tcp;\n-\t\t\tconst struct rte_flow_item_udp *udp;\n-\t\t} spec, mask;\n-\t\tunion {\n-\t\t\tconst struct rte_flow_action_port_id *port_id;\n-\t\t\tconst struct rte_flow_action_of_push_vlan *of_push_vlan;\n-\t\t\tconst struct rte_flow_action_of_set_vlan_vid *\n-\t\t\t\tof_set_vlan_vid;\n-\t\t\tconst struct rte_flow_action_of_set_vlan_pcp *\n-\t\t\t\tof_set_vlan_pcp;\n-\t\t} conf;\n-\t\tstruct nlmsghdr *nlh;\n-\t\tstruct tcmsg *tcm;\n-\t\tstruct nlattr *act_index;\n-\t\tstruct nlattr *act;\n-\t\tunsigned int i;\n-\n-\tcase INVALID:\n-\t\tif (item->type)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,\n-\t\t\t\t item, \"unsupported pattern item combination\");\n-\t\telse if (action->type)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,\n-\t\t\t\t action, \"unsupported action combination\");\n-\t\treturn rte_flow_error_set\n-\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t \"flow rule lacks some kind of fate action\");\n-\tcase BACK:\n-\t\ttrans = back;\n-\t\tn = 0;\n-\t\tgoto trans;\n-\tcase ATTR:\n-\t\t/*\n-\t\t * Supported attributes: no groups, some priorities and\n-\t\t * ingress only. Don't care about transfer as it is the\n-\t\t * caller's problem.\n-\t\t */\n-\t\tif (attr->group)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP,\n-\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR_GROUP,\n-\t\t\t\t attr, \"groups are not supported\");\n-\t\tif (attr->priority > 0xfffe)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP,\n-\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,\n-\t\t\t\t attr, \"lowest priority level is 0xfffe\");\n-\t\tif (!attr->ingress)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP,\n-\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,\n-\t\t\t\t attr, \"only ingress is supported\");\n-\t\tif (attr->egress)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP,\n-\t\t\t\t RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,\n-\t\t\t\t attr, \"egress is not supported\");\n-\t\tif (size < mnl_nlmsg_size(sizeof(*tcm)))\n-\t\t\tgoto error_nobufs;\n-\t\tnlh = mnl_nlmsg_put_header(buf);\n-\t\tnlh->nlmsg_type = 0;\n-\t\tnlh->nlmsg_flags = 0;\n-\t\tnlh->nlmsg_seq = 0;\n-\t\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n-\t\ttcm->tcm_family = AF_UNSPEC;\n-\t\ttcm->tcm_ifindex = ptoi[0].ifindex;\n-\t\t/*\n-\t\t * Let kernel pick a handle by default. A predictable handle\n-\t\t * can be set by the caller on the resulting buffer through\n-\t\t * mlx5_nl_flow_brand().\n-\t\t */\n-\t\ttcm->tcm_handle = 0;\n-\t\ttcm->tcm_parent = TC_H_MAKE(TC_H_INGRESS, TC_H_MIN_INGRESS);\n-\t\t/*\n-\t\t * Priority cannot be zero to prevent the kernel from\n-\t\t * picking one automatically.\n-\t\t */\n-\t\ttcm->tcm_info = TC_H_MAKE((attr->priority + 1) << 16,\n-\t\t\t\t\t  RTE_BE16(ETH_P_ALL));\n-\t\tbreak;\n-\tcase PATTERN:\n-\t\tif (!mnl_attr_put_strz_check(buf, size, TCA_KIND, \"flower\"))\n-\t\t\tgoto error_nobufs;\n-\t\tna_flower = mnl_attr_nest_start_check(buf, size, TCA_OPTIONS);\n-\t\tif (!na_flower)\n-\t\t\tgoto error_nobufs;\n-\t\tif (!mnl_attr_put_u32_check(buf, size, TCA_FLOWER_FLAGS,\n-\t\t\t\t\t    TCA_CLS_FLAGS_SKIP_SW))\n-\t\t\tgoto error_nobufs;\n-\t\tbreak;\n-\tcase ITEM_VOID:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_VOID)\n-\t\t\tgoto trans;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_PORT_ID:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_PORT_ID)\n-\t\t\tgoto trans;\n-\t\tmask.port_id = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_port_id_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.port_id,\n-\t\t\t &mlx5_nl_flow_mask_empty.port_id,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.port_id), error);\n-\t\tif (!mask.port_id)\n-\t\t\treturn -rte_errno;\n-\t\tif (mask.port_id == &mlx5_nl_flow_mask_empty.port_id) {\n-\t\t\tin_port_id_set = 1;\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.port_id = item->spec;\n-\t\tif (mask.port_id->id && mask.port_id->id != 0xffffffff)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask.port_id,\n-\t\t\t\t \"no support for partial mask on\"\n-\t\t\t\t \" \\\"id\\\" field\");\n-\t\tif (!mask.port_id->id)\n-\t\t\ti = 0;\n-\t\telse\n-\t\t\tfor (i = 0; ptoi[i].ifindex; ++i)\n-\t\t\t\tif (ptoi[i].port_id == spec.port_id->id)\n-\t\t\t\t\tbreak;\n-\t\tif (!ptoi[i].ifindex)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENODEV, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,\n-\t\t\t\t spec.port_id,\n-\t\t\t\t \"missing data to convert port ID to ifindex\");\n-\t\ttcm = mnl_nlmsg_get_payload(buf);\n-\t\tif (in_port_id_set &&\n-\t\t    ptoi[i].ifindex != (unsigned int)tcm->tcm_ifindex)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,\n-\t\t\t\t spec.port_id,\n-\t\t\t\t \"cannot match traffic for several port IDs\"\n-\t\t\t\t \" through a single flow rule\");\n-\t\ttcm->tcm_ifindex = ptoi[i].ifindex;\n-\t\tin_port_id_set = 1;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_ETH:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_ETH)\n-\t\t\tgoto trans;\n-\t\tmask.eth = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_eth_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.eth,\n-\t\t\t &mlx5_nl_flow_mask_empty.eth,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.eth), error);\n-\t\tif (!mask.eth)\n-\t\t\treturn -rte_errno;\n-\t\tif (mask.eth == &mlx5_nl_flow_mask_empty.eth) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.eth = item->spec;\n-\t\tif (mask.eth->type && mask.eth->type != RTE_BE16(0xffff))\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask.eth,\n-\t\t\t\t \"no support for partial mask on\"\n-\t\t\t\t \" \\\"type\\\" field\");\n-\t\tif (mask.eth->type) {\n-\t\t\tif (!mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t\t    TCA_FLOWER_KEY_ETH_TYPE,\n-\t\t\t\t\t\t    spec.eth->type))\n-\t\t\t\tgoto error_nobufs;\n-\t\t\teth_type_set = 1;\n-\t\t}\n-\t\tif ((!is_zero_ether_addr(&mask.eth->dst) &&\n-\t\t     (!mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_ETH_DST,\n-\t\t\t\t\t  ETHER_ADDR_LEN,\n-\t\t\t\t\t  spec.eth->dst.addr_bytes) ||\n-\t\t      !mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_ETH_DST_MASK,\n-\t\t\t\t\t  ETHER_ADDR_LEN,\n-\t\t\t\t\t  mask.eth->dst.addr_bytes))) ||\n-\t\t    (!is_zero_ether_addr(&mask.eth->src) &&\n-\t\t     (!mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_ETH_SRC,\n-\t\t\t\t\t  ETHER_ADDR_LEN,\n-\t\t\t\t\t  spec.eth->src.addr_bytes) ||\n-\t\t      !mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_ETH_SRC_MASK,\n-\t\t\t\t\t  ETHER_ADDR_LEN,\n-\t\t\t\t\t  mask.eth->src.addr_bytes))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_VLAN:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_VLAN)\n-\t\t\tgoto trans;\n-\t\tmask.vlan = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_vlan_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.vlan,\n-\t\t\t &mlx5_nl_flow_mask_empty.vlan,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.vlan), error);\n-\t\tif (!mask.vlan)\n-\t\t\treturn -rte_errno;\n-\t\tif (!eth_type_set &&\n-\t\t    !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t    TCA_FLOWER_KEY_ETH_TYPE,\n-\t\t\t\t\t    RTE_BE16(ETH_P_8021Q)))\n-\t\t\tgoto error_nobufs;\n-\t\teth_type_set = 1;\n-\t\tvlan_present = 1;\n-\t\tif (mask.vlan == &mlx5_nl_flow_mask_empty.vlan) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.vlan = item->spec;\n-\t\tif ((mask.vlan->tci & RTE_BE16(0xe000) &&\n-\t\t     (mask.vlan->tci & RTE_BE16(0xe000)) != RTE_BE16(0xe000)) ||\n-\t\t    (mask.vlan->tci & RTE_BE16(0x0fff) &&\n-\t\t     (mask.vlan->tci & RTE_BE16(0x0fff)) != RTE_BE16(0x0fff)) ||\n-\t\t    (mask.vlan->inner_type &&\n-\t\t     mask.vlan->inner_type != RTE_BE16(0xffff)))\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask.vlan,\n-\t\t\t\t \"no support for partial masks on\"\n-\t\t\t\t \" \\\"tci\\\" (PCP and VID parts) and\"\n-\t\t\t\t \" \\\"inner_type\\\" fields\");\n-\t\tif (mask.vlan->inner_type) {\n-\t\t\tif (!mnl_attr_put_u16_check\n-\t\t\t    (buf, size, TCA_FLOWER_KEY_VLAN_ETH_TYPE,\n-\t\t\t     spec.vlan->inner_type))\n-\t\t\t\tgoto error_nobufs;\n-\t\t\tvlan_eth_type_set = 1;\n-\t\t}\n-\t\tif ((mask.vlan->tci & RTE_BE16(0xe000) &&\n-\t\t     !mnl_attr_put_u8_check\n-\t\t     (buf, size, TCA_FLOWER_KEY_VLAN_PRIO,\n-\t\t      (rte_be_to_cpu_16(spec.vlan->tci) >> 13) & 0x7)) ||\n-\t\t    (mask.vlan->tci & RTE_BE16(0x0fff) &&\n-\t\t     !mnl_attr_put_u16_check\n-\t\t     (buf, size, TCA_FLOWER_KEY_VLAN_ID,\n-\t\t      rte_be_to_cpu_16(spec.vlan->tci & RTE_BE16(0x0fff)))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_IPV4:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_IPV4)\n-\t\t\tgoto trans;\n-\t\tmask.ipv4 = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_ipv4_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.ipv4,\n-\t\t\t &mlx5_nl_flow_mask_empty.ipv4,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.ipv4), error);\n-\t\tif (!mask.ipv4)\n-\t\t\treturn -rte_errno;\n-\t\tif ((!eth_type_set || !vlan_eth_type_set) &&\n-\t\t    !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t    vlan_present ?\n-\t\t\t\t\t    TCA_FLOWER_KEY_VLAN_ETH_TYPE :\n-\t\t\t\t\t    TCA_FLOWER_KEY_ETH_TYPE,\n-\t\t\t\t\t    RTE_BE16(ETH_P_IP)))\n-\t\t\tgoto error_nobufs;\n-\t\teth_type_set = 1;\n-\t\tvlan_eth_type_set = 1;\n-\t\tif (mask.ipv4 == &mlx5_nl_flow_mask_empty.ipv4) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.ipv4 = item->spec;\n-\t\tif (mask.ipv4->hdr.next_proto_id &&\n-\t\t    mask.ipv4->hdr.next_proto_id != 0xff)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask.ipv4,\n-\t\t\t\t \"no support for partial mask on\"\n-\t\t\t\t \" \\\"hdr.next_proto_id\\\" field\");\n-\t\tif (mask.ipv4->hdr.next_proto_id) {\n-\t\t\tif (!mnl_attr_put_u8_check\n-\t\t\t    (buf, size, TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t     spec.ipv4->hdr.next_proto_id))\n-\t\t\t\tgoto error_nobufs;\n-\t\t\tip_proto_set = 1;\n-\t\t}\n-\t\tif ((mask.ipv4->hdr.src_addr &&\n-\t\t     (!mnl_attr_put_u32_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_IPV4_SRC,\n-\t\t\t\t\t      spec.ipv4->hdr.src_addr) ||\n-\t\t      !mnl_attr_put_u32_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_IPV4_SRC_MASK,\n-\t\t\t\t\t      mask.ipv4->hdr.src_addr))) ||\n-\t\t    (mask.ipv4->hdr.dst_addr &&\n-\t\t     (!mnl_attr_put_u32_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_IPV4_DST,\n-\t\t\t\t\t      spec.ipv4->hdr.dst_addr) ||\n-\t\t      !mnl_attr_put_u32_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_IPV4_DST_MASK,\n-\t\t\t\t\t      mask.ipv4->hdr.dst_addr))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_IPV6:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_IPV6)\n-\t\t\tgoto trans;\n-\t\tmask.ipv6 = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_ipv6_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.ipv6,\n-\t\t\t &mlx5_nl_flow_mask_empty.ipv6,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.ipv6), error);\n-\t\tif (!mask.ipv6)\n-\t\t\treturn -rte_errno;\n-\t\tif ((!eth_type_set || !vlan_eth_type_set) &&\n-\t\t    !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t    vlan_present ?\n-\t\t\t\t\t    TCA_FLOWER_KEY_VLAN_ETH_TYPE :\n-\t\t\t\t\t    TCA_FLOWER_KEY_ETH_TYPE,\n-\t\t\t\t\t    RTE_BE16(ETH_P_IPV6)))\n-\t\t\tgoto error_nobufs;\n-\t\teth_type_set = 1;\n-\t\tvlan_eth_type_set = 1;\n-\t\tif (mask.ipv6 == &mlx5_nl_flow_mask_empty.ipv6) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.ipv6 = item->spec;\n-\t\tif (mask.ipv6->hdr.proto && mask.ipv6->hdr.proto != 0xff)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n-\t\t\t\t mask.ipv6,\n-\t\t\t\t \"no support for partial mask on\"\n-\t\t\t\t \" \\\"hdr.proto\\\" field\");\n-\t\tif (mask.ipv6->hdr.proto) {\n-\t\t\tif (!mnl_attr_put_u8_check\n-\t\t\t    (buf, size, TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t     spec.ipv6->hdr.proto))\n-\t\t\t\tgoto error_nobufs;\n-\t\t\tip_proto_set = 1;\n-\t\t}\n-\t\tif ((!IN6_IS_ADDR_UNSPECIFIED(mask.ipv6->hdr.src_addr) &&\n-\t\t     (!mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_IPV6_SRC,\n-\t\t\t\t\t  sizeof(spec.ipv6->hdr.src_addr),\n-\t\t\t\t\t  spec.ipv6->hdr.src_addr) ||\n-\t\t      !mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_IPV6_SRC_MASK,\n-\t\t\t\t\t  sizeof(mask.ipv6->hdr.src_addr),\n-\t\t\t\t\t  mask.ipv6->hdr.src_addr))) ||\n-\t\t    (!IN6_IS_ADDR_UNSPECIFIED(mask.ipv6->hdr.dst_addr) &&\n-\t\t     (!mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_IPV6_DST,\n-\t\t\t\t\t  sizeof(spec.ipv6->hdr.dst_addr),\n-\t\t\t\t\t  spec.ipv6->hdr.dst_addr) ||\n-\t\t      !mnl_attr_put_check(buf, size,\n-\t\t\t\t\t  TCA_FLOWER_KEY_IPV6_DST_MASK,\n-\t\t\t\t\t  sizeof(mask.ipv6->hdr.dst_addr),\n-\t\t\t\t\t  mask.ipv6->hdr.dst_addr))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_TCP:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_TCP)\n-\t\t\tgoto trans;\n-\t\tmask.tcp = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_tcp_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.tcp,\n-\t\t\t &mlx5_nl_flow_mask_empty.tcp,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.tcp), error);\n-\t\tif (!mask.tcp)\n-\t\t\treturn -rte_errno;\n-\t\tif (!ip_proto_set &&\n-\t\t    !mnl_attr_put_u8_check(buf, size,\n-\t\t\t\t\t   TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t\t\t   IPPROTO_TCP))\n-\t\t\tgoto error_nobufs;\n-\t\tif (mask.tcp == &mlx5_nl_flow_mask_empty.tcp) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.tcp = item->spec;\n-\t\tif ((mask.tcp->hdr.src_port &&\n-\t\t     (!mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_TCP_SRC,\n-\t\t\t\t\t      spec.tcp->hdr.src_port) ||\n-\t\t      !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_TCP_SRC_MASK,\n-\t\t\t\t\t      mask.tcp->hdr.src_port))) ||\n-\t\t    (mask.tcp->hdr.dst_port &&\n-\t\t     (!mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_TCP_DST,\n-\t\t\t\t\t      spec.tcp->hdr.dst_port) ||\n-\t\t      !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_TCP_DST_MASK,\n-\t\t\t\t\t      mask.tcp->hdr.dst_port))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ITEM_UDP:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_UDP)\n-\t\t\tgoto trans;\n-\t\tmask.udp = mlx5_nl_flow_item_mask\n-\t\t\t(item, &rte_flow_item_udp_mask,\n-\t\t\t &mlx5_nl_flow_mask_supported.udp,\n-\t\t\t &mlx5_nl_flow_mask_empty.udp,\n-\t\t\t sizeof(mlx5_nl_flow_mask_supported.udp), error);\n-\t\tif (!mask.udp)\n-\t\t\treturn -rte_errno;\n-\t\tif (!ip_proto_set &&\n-\t\t    !mnl_attr_put_u8_check(buf, size,\n-\t\t\t\t\t   TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t\t\t   IPPROTO_UDP))\n-\t\t\tgoto error_nobufs;\n-\t\tif (mask.udp == &mlx5_nl_flow_mask_empty.udp) {\n-\t\t\t++item;\n-\t\t\tbreak;\n-\t\t}\n-\t\tspec.udp = item->spec;\n-\t\tif ((mask.udp->hdr.src_port &&\n-\t\t     (!mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_UDP_SRC,\n-\t\t\t\t\t      spec.udp->hdr.src_port) ||\n-\t\t      !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_UDP_SRC_MASK,\n-\t\t\t\t\t      mask.udp->hdr.src_port))) ||\n-\t\t    (mask.udp->hdr.dst_port &&\n-\t\t     (!mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_UDP_DST,\n-\t\t\t\t\t      spec.udp->hdr.dst_port) ||\n-\t\t      !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t      TCA_FLOWER_KEY_UDP_DST_MASK,\n-\t\t\t\t\t      mask.udp->hdr.dst_port))))\n-\t\t\tgoto error_nobufs;\n-\t\t++item;\n-\t\tbreak;\n-\tcase ACTIONS:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_END)\n-\t\t\tgoto trans;\n-\t\tassert(na_flower);\n-\t\tassert(!na_flower_act);\n-\t\tna_flower_act =\n-\t\t\tmnl_attr_nest_start_check(buf, size, TCA_FLOWER_ACT);\n-\t\tif (!na_flower_act)\n-\t\t\tgoto error_nobufs;\n-\t\tact_index_cur = 1;\n-\t\tbreak;\n-\tcase ACTION_VOID:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_VOID)\n-\t\t\tgoto trans;\n-\t\t++action;\n-\t\tbreak;\n-\tcase ACTION_PORT_ID:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_PORT_ID)\n-\t\t\tgoto trans;\n-\t\tconf.port_id = action->conf;\n-\t\tif (conf.port_id->original)\n-\t\t\ti = 0;\n-\t\telse\n-\t\t\tfor (i = 0; ptoi[i].ifindex; ++i)\n-\t\t\t\tif (ptoi[i].port_id == conf.port_id->id)\n-\t\t\t\t\tbreak;\n-\t\tif (!ptoi[i].ifindex)\n-\t\t\treturn rte_flow_error_set\n-\t\t\t\t(error, ENODEV, RTE_FLOW_ERROR_TYPE_ACTION_CONF,\n-\t\t\t\t conf.port_id,\n-\t\t\t\t \"missing data to convert port ID to ifindex\");\n-\t\tact_index =\n-\t\t\tmnl_attr_nest_start_check(buf, size, act_index_cur++);\n-\t\tif (!act_index ||\n-\t\t    !mnl_attr_put_strz_check(buf, size, TCA_ACT_KIND, \"mirred\"))\n-\t\t\tgoto error_nobufs;\n-\t\tact = mnl_attr_nest_start_check(buf, size, TCA_ACT_OPTIONS);\n-\t\tif (!act)\n-\t\t\tgoto error_nobufs;\n-\t\tif (!mnl_attr_put_check(buf, size, TCA_MIRRED_PARMS,\n-\t\t\t\t\tsizeof(struct tc_mirred),\n-\t\t\t\t\t&(struct tc_mirred){\n-\t\t\t\t\t\t.action = TC_ACT_STOLEN,\n-\t\t\t\t\t\t.eaction = TCA_EGRESS_REDIR,\n-\t\t\t\t\t\t.ifindex = ptoi[i].ifindex,\n-\t\t\t\t\t}))\n-\t\t\tgoto error_nobufs;\n-\t\tmnl_attr_nest_end(buf, act);\n-\t\tmnl_attr_nest_end(buf, act_index);\n-\t\t++action;\n-\t\tbreak;\n-\tcase ACTION_DROP:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_DROP)\n-\t\t\tgoto trans;\n-\t\tact_index =\n-\t\t\tmnl_attr_nest_start_check(buf, size, act_index_cur++);\n-\t\tif (!act_index ||\n-\t\t    !mnl_attr_put_strz_check(buf, size, TCA_ACT_KIND, \"gact\"))\n-\t\t\tgoto error_nobufs;\n-\t\tact = mnl_attr_nest_start_check(buf, size, TCA_ACT_OPTIONS);\n-\t\tif (!act)\n-\t\t\tgoto error_nobufs;\n-\t\tif (!mnl_attr_put_check(buf, size, TCA_GACT_PARMS,\n-\t\t\t\t\tsizeof(struct tc_gact),\n-\t\t\t\t\t&(struct tc_gact){\n-\t\t\t\t\t\t.action = TC_ACT_SHOT,\n-\t\t\t\t\t}))\n-\t\t\tgoto error_nobufs;\n-\t\tmnl_attr_nest_end(buf, act);\n-\t\tmnl_attr_nest_end(buf, act_index);\n-\t\t++action;\n-\t\tbreak;\n-\tcase ACTION_OF_POP_VLAN:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_OF_POP_VLAN)\n-\t\t\tgoto trans;\n-\t\tconf.of_push_vlan = NULL;\n-\t\ti = TCA_VLAN_ACT_POP;\n-\t\tgoto action_of_vlan;\n-\tcase ACTION_OF_PUSH_VLAN:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN)\n-\t\t\tgoto trans;\n-\t\tconf.of_push_vlan = action->conf;\n-\t\ti = TCA_VLAN_ACT_PUSH;\n-\t\tgoto action_of_vlan;\n-\tcase ACTION_OF_SET_VLAN_VID:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID)\n-\t\t\tgoto trans;\n-\t\tconf.of_set_vlan_vid = action->conf;\n-\t\tif (na_vlan_id)\n-\t\t\tgoto override_na_vlan_id;\n-\t\ti = TCA_VLAN_ACT_MODIFY;\n-\t\tgoto action_of_vlan;\n-\tcase ACTION_OF_SET_VLAN_PCP:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP)\n-\t\t\tgoto trans;\n-\t\tconf.of_set_vlan_pcp = action->conf;\n-\t\tif (na_vlan_priority)\n-\t\t\tgoto override_na_vlan_priority;\n-\t\ti = TCA_VLAN_ACT_MODIFY;\n-\t\tgoto action_of_vlan;\n-action_of_vlan:\n-\t\tact_index =\n-\t\t\tmnl_attr_nest_start_check(buf, size, act_index_cur++);\n-\t\tif (!act_index ||\n-\t\t    !mnl_attr_put_strz_check(buf, size, TCA_ACT_KIND, \"vlan\"))\n-\t\t\tgoto error_nobufs;\n-\t\tact = mnl_attr_nest_start_check(buf, size, TCA_ACT_OPTIONS);\n-\t\tif (!act)\n-\t\t\tgoto error_nobufs;\n-\t\tif (!mnl_attr_put_check(buf, size, TCA_VLAN_PARMS,\n-\t\t\t\t\tsizeof(struct tc_vlan),\n-\t\t\t\t\t&(struct tc_vlan){\n-\t\t\t\t\t\t.action = TC_ACT_PIPE,\n-\t\t\t\t\t\t.v_action = i,\n-\t\t\t\t\t}))\n-\t\t\tgoto error_nobufs;\n-\t\tif (i == TCA_VLAN_ACT_POP) {\n-\t\t\tmnl_attr_nest_end(buf, act);\n-\t\t\tmnl_attr_nest_end(buf, act_index);\n-\t\t\t++action;\n-\t\t\tbreak;\n-\t\t}\n-\t\tif (i == TCA_VLAN_ACT_PUSH &&\n-\t\t    !mnl_attr_put_u16_check(buf, size,\n-\t\t\t\t\t    TCA_VLAN_PUSH_VLAN_PROTOCOL,\n-\t\t\t\t\t    conf.of_push_vlan->ethertype))\n-\t\t\tgoto error_nobufs;\n-\t\tna_vlan_id = mnl_nlmsg_get_payload_tail(buf);\n-\t\tif (!mnl_attr_put_u16_check(buf, size, TCA_VLAN_PAD, 0))\n-\t\t\tgoto error_nobufs;\n-\t\tna_vlan_priority = mnl_nlmsg_get_payload_tail(buf);\n-\t\tif (!mnl_attr_put_u8_check(buf, size, TCA_VLAN_PAD, 0))\n-\t\t\tgoto error_nobufs;\n-\t\tmnl_attr_nest_end(buf, act);\n-\t\tmnl_attr_nest_end(buf, act_index);\n-\t\tif (action->type == RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID) {\n-override_na_vlan_id:\n-\t\t\tna_vlan_id->nla_type = TCA_VLAN_PUSH_VLAN_ID;\n-\t\t\t*(uint16_t *)mnl_attr_get_payload(na_vlan_id) =\n-\t\t\t\trte_be_to_cpu_16\n-\t\t\t\t(conf.of_set_vlan_vid->vlan_vid);\n-\t\t} else if (action->type ==\n-\t\t\t   RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP) {\n-override_na_vlan_priority:\n-\t\t\tna_vlan_priority->nla_type =\n-\t\t\t\tTCA_VLAN_PUSH_VLAN_PRIORITY;\n-\t\t\t*(uint8_t *)mnl_attr_get_payload(na_vlan_priority) =\n-\t\t\t\tconf.of_set_vlan_pcp->vlan_pcp;\n-\t\t}\n-\t\t++action;\n-\t\tbreak;\n-\tcase END:\n-\t\tif (item->type != RTE_FLOW_ITEM_TYPE_END ||\n-\t\t    action->type != RTE_FLOW_ACTION_TYPE_END)\n-\t\t\tgoto trans;\n-\t\tif (na_flower_act)\n-\t\t\tmnl_attr_nest_end(buf, na_flower_act);\n-\t\tif (na_flower)\n-\t\t\tmnl_attr_nest_end(buf, na_flower);\n-\t\tnlh = buf;\n-\t\treturn nlh->nlmsg_len;\n-\t}\n-\tback = trans;\n-\ttrans = mlx5_nl_flow_trans[trans[n - 1]];\n-\tn = 0;\n-\tgoto trans;\n-error_nobufs:\n-\tif (buf != buf_tmp) {\n-\t\tbuf = buf_tmp;\n-\t\tsize = sizeof(buf_tmp);\n-\t\tgoto init;\n-\t}\n-\treturn rte_flow_error_set\n-\t\t(error, ENOBUFS, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t \"generated TC message is too large\");\n-}\n-\n-/**\n- * Brand rtnetlink buffer with unique handle.\n- *\n- * This handle should be unique for a given network interface to avoid\n- * collisions.\n- *\n- * @param buf\n- *   Flow rule buffer previously initialized by mlx5_nl_flow_transpose().\n- * @param handle\n- *   Unique 32-bit handle to use.\n- */\n-void\n-mlx5_nl_flow_brand(void *buf, uint32_t handle)\n-{\n-\tstruct tcmsg *tcm = mnl_nlmsg_get_payload(buf);\n-\n-\ttcm->tcm_handle = handle;\n-}\n-\n-/**\n- * Send Netlink message with acknowledgment.\n- *\n- * @param nl\n- *   Libmnl socket to use.\n- * @param nlh\n- *   Message to send. This function always raises the NLM_F_ACK flag before\n- *   sending.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-static int\n-mlx5_nl_flow_nl_ack(struct mnl_socket *nl, struct nlmsghdr *nlh)\n-{\n-\talignas(struct nlmsghdr)\n-\tuint8_t ans[mnl_nlmsg_size(sizeof(struct nlmsgerr)) +\n-\t\t    nlh->nlmsg_len - sizeof(*nlh)];\n-\tuint32_t seq = random();\n-\tint ret;\n-\n-\tnlh->nlmsg_flags |= NLM_F_ACK;\n-\tnlh->nlmsg_seq = seq;\n-\tret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);\n-\tif (ret != -1)\n-\t\tret = mnl_socket_recvfrom(nl, ans, sizeof(ans));\n-\tif (ret != -1)\n-\t\tret = mnl_cb_run\n-\t\t\t(ans, ret, seq, mnl_socket_get_portid(nl), NULL, NULL);\n-\tif (!ret)\n-\t\treturn 0;\n-\trte_errno = errno;\n-\treturn -rte_errno;\n-}\n-\n-/**\n- * Create a Netlink flow rule.\n- *\n- * @param nl\n- *   Libmnl socket to use.\n- * @param buf\n- *   Flow rule buffer previously initialized by mlx5_nl_flow_transpose().\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-int\n-mlx5_nl_flow_create(struct mnl_socket *nl, void *buf,\n-\t\t    struct rte_flow_error *error)\n-{\n-\tstruct nlmsghdr *nlh = buf;\n-\n-\tnlh->nlmsg_type = RTM_NEWTFILTER;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n-\tif (!mlx5_nl_flow_nl_ack(nl, nlh))\n-\t\treturn 0;\n-\treturn rte_flow_error_set\n-\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t \"netlink: failed to create TC flow rule\");\n-}\n-\n-/**\n- * Destroy a Netlink flow rule.\n- *\n- * @param nl\n- *   Libmnl socket to use.\n- * @param buf\n- *   Flow rule buffer previously initialized by mlx5_nl_flow_transpose().\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-int\n-mlx5_nl_flow_destroy(struct mnl_socket *nl, void *buf,\n-\t\t     struct rte_flow_error *error)\n-{\n-\tstruct nlmsghdr *nlh = buf;\n-\n-\tnlh->nlmsg_type = RTM_DELTFILTER;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST;\n-\tif (!mlx5_nl_flow_nl_ack(nl, nlh))\n-\t\treturn 0;\n-\treturn rte_flow_error_set\n-\t\t(error, errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t \"netlink: failed to destroy TC flow rule\");\n-}\n-\n-/**\n- * Initialize ingress qdisc of a given network interface.\n- *\n- * @param nl\n- *   Libmnl socket of the @p NETLINK_ROUTE kind.\n- * @param ifindex\n- *   Index of network interface to initialize.\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n- *\n- * @return\n- *   0 on success, a negative errno value otherwise and rte_errno is set.\n- */\n-int\n-mlx5_nl_flow_init(struct mnl_socket *nl, unsigned int ifindex,\n-\t\t  struct rte_flow_error *error)\n-{\n-\tstruct nlmsghdr *nlh;\n-\tstruct tcmsg *tcm;\n-\talignas(struct nlmsghdr)\n-\tuint8_t buf[mnl_nlmsg_size(sizeof(*tcm) + 128)];\n-\n-\t/* Destroy existing ingress qdisc and everything attached to it. */\n-\tnlh = mnl_nlmsg_put_header(buf);\n-\tnlh->nlmsg_type = RTM_DELQDISC;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST;\n-\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n-\ttcm->tcm_family = AF_UNSPEC;\n-\ttcm->tcm_ifindex = ifindex;\n-\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n-\ttcm->tcm_parent = TC_H_INGRESS;\n-\t/* Ignore errors when qdisc is already absent. */\n-\tif (mlx5_nl_flow_nl_ack(nl, nlh) &&\n-\t    rte_errno != EINVAL && rte_errno != ENOENT)\n-\t\treturn rte_flow_error_set\n-\t\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n-\t\t\t NULL, \"netlink: failed to remove ingress qdisc\");\n-\t/* Create fresh ingress qdisc. */\n-\tnlh = mnl_nlmsg_put_header(buf);\n-\tnlh->nlmsg_type = RTM_NEWQDISC;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n-\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n-\ttcm->tcm_family = AF_UNSPEC;\n-\ttcm->tcm_ifindex = ifindex;\n-\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n-\ttcm->tcm_parent = TC_H_INGRESS;\n-\tmnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, \"ingress\");\n-\tif (mlx5_nl_flow_nl_ack(nl, nlh))\n-\t\treturn rte_flow_error_set\n-\t\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n-\t\t\t NULL, \"netlink: failed to create ingress qdisc\");\n-\treturn 0;\n-}\n-\n-/**\n- * Create and configure a libmnl socket for Netlink flow rules.\n- *\n- * @return\n- *   A valid libmnl socket object pointer on success, NULL otherwise and\n- *   rte_errno is set.\n- */\n-struct mnl_socket *\n-mlx5_nl_flow_socket_create(void)\n-{\n-\tstruct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE);\n-\n-\tif (nl) {\n-\t\tmnl_socket_setsockopt(nl, NETLINK_CAP_ACK, &(int){ 1 },\n-\t\t\t\t      sizeof(int));\n-\t\tif (!mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID))\n-\t\t\treturn nl;\n-\t}\n-\trte_errno = errno;\n-\tif (nl)\n-\t\tmnl_socket_close(nl);\n-\treturn NULL;\n-}\n-\n-/**\n- * Destroy a libmnl socket.\n- */\n-void\n-mlx5_nl_flow_socket_destroy(struct mnl_socket *nl)\n-{\n-\tmnl_socket_close(nl);\n-}\n",
    "prefixes": [
        "v2",
        "2/3"
    ]
}