get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45250,
    "url": "http://patches.dpdk.org/api/patches/45250/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20180924231721.15799-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": "<20180924231721.15799-3-yskoh@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180924231721.15799-3-yskoh@mellanox.com",
    "date": "2018-09-24T23:17:37",
    "name": "[v3,02/11] net/mlx5: add flow prepare function",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "0ffdcee038f8af0ad263fd625128c0245e1a8f86",
    "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/20180924231721.15799-3-yskoh@mellanox.com/mbox/",
    "series": [
        {
            "id": 1476,
            "url": "http://patches.dpdk.org/api/series/1476/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1476",
            "date": "2018-09-24T23:17:33",
            "name": "net/mlx5: add Direct Verbs flow driver support",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/1476/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/45250/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/45250/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 006DF1B111;\n\tTue, 25 Sep 2018 01:17:42 +0200 (CEST)",
            "from EUR02-HE1-obe.outbound.protection.outlook.com\n\t(mail-eopbgr10053.outbound.protection.outlook.com [40.107.1.53])\n\tby dpdk.org (Postfix) with ESMTP id 164761B0FE\n\tfor <dev@dpdk.org>; Tue, 25 Sep 2018 01:17:39 +0200 (CEST)",
            "from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by\n\tDB3PR0502MB3996.eurprd05.prod.outlook.com (52.134.65.142) 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 23:17:37 +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 23:17:37 +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=ijOZWHuhX7AwNbe0V1k1D3Jl8qFmRQ1RqIO7zyrzYVg=;\n\tb=fbuxBm+WB7xI1EswHgwOM5EAayDf4QO/KkRFUcZFsjL1y/rnfzVLEcApnXeOJdh21DpTbWtVBTwhFHJA9MXPunxwMCfdNAsNTYIlQ3ghMewRALT8Hh20n8Bfhz3dFtDCSE6jTBauI7Eelx8M3GbDAZ8Hhj4ndMti1JcMu5aI3nw=",
        "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>, Ori Kam <orika@mellanox.com>",
        "Thread-Topic": "[PATCH v3 02/11] net/mlx5: add flow prepare function",
        "Thread-Index": "AQHUVFzI+b8IuG10tkagPGrub+nj6A==",
        "Date": "Mon, 24 Sep 2018 23:17:37 +0000",
        "Message-ID": "<20180924231721.15799-3-yskoh@mellanox.com>",
        "References": "<20180919072143.23211-1-yskoh@mellanox.com>\n\t<20180924231721.15799-1-yskoh@mellanox.com>",
        "In-Reply-To": "<20180924231721.15799-1-yskoh@mellanox.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "BN6PR03CA0021.namprd03.prod.outlook.com\n\t(2603:10b6:404:23::31) 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; DB3PR0502MB3996;\n\t6:D3Dhxz9WGrJLuM9Rl/Ls1NCJGVK663colE5dP90VKa/ecTwd4c768WoR9jr/oKKtC3Cqlq8wiTUK21kCQQZqqbB8jSl/Rtik3nmLM80bkp6fvLjC2U9PmJRUFsMPA6eCfrf4/2u0OHw2d7Z8cHgzEDZutTYgCkJTCJsUnd4oM8lnH51nfQLK1RS6XRGW0aVHDG0IXHKaII9FxWU4zbHK2Cb7VQzaRq9iztOryNn1kAiVKyskiHR637db3QiUUf6qW5zL5/aIDRTV0gQ8PghE/znCjgxAsZOddR2U6n+Yb9Z9Fknbi/sKLhOknm82UdNXZLvswRLZh2bzVP7Y19XkM55jrT1UffTgga/LPGm5WQ2ybZOXEUkfVS4G/02q8icL6LvQuoaRGtmh5GUpVep9ShM9Irdaq6WSoe4hoR65wEFbyiqam+fLGuDZwCZZvU5v5fh1vB3RuW1cHVRPGp9ydw==;\n\t5:A4k/95vrvHecfL5qfoniOn+pcLUr2BTBqf/AYA6OEC/DrOh4y4l+du/xDs+CK/z17a3hamGPGepgKuggndVxVY4dgfeLsumIiERUon6ghoJxZ5Tin5VJ/MGhK2Ki6MSSiR3HNj4ua8eC1ZJv7KfigzoJl1wUMNJ/6phj/f8djaA=;\n\t7:T3i+ETHm0NiLqkpGyZrI7/RiD6w2VT2jgcuSdh4i9VTQfS8O16CnMNwKsjYbJ7D3N9SUSGVKKtra69FJJJqSCQutxQypFqTap8XGLGdGXwvyMTDXh8ZxPmhDVbk+aQFVIea3ZjvxXLLXRHm3NlnjJptaCzalz/s1fCCTLDnDK/+PL+la5+dDo5chagb2RMkuWvAah6JrRT/f5FVT1oAaJBEI/SWlhs2gY38sr3ydBjVBUu032m47BqO77G6fKOAQ",
        "x-ms-office365-filtering-correlation-id": "e124f667-b841-40b1-a54c-08d62273ea81",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020);\n\tSRVR:DB3PR0502MB3996; ",
        "x-ms-traffictypediagnostic": "DB3PR0502MB3996:",
        "x-ld-processed": "a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr",
        "x-microsoft-antispam-prvs": "<DB3PR0502MB3996D51C0291D3BF7CEC700CC3170@DB3PR0502MB3996.eurprd05.prod.outlook.com>",
        "x-exchange-antispam-report-test": "UriScan:;",
        "x-ms-exchange-senderadcheck": "1",
        "x-exchange-antispam-report-cfa-test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3002001)(93006095)(93001095)(3231355)(944501410)(52105095)(6055026)(149066)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123560045)(20161123562045)(20161123564045)(201708071742011)(7699051);\n\tSRVR:DB3PR0502MB3996; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB3996; ",
        "x-forefront-prvs": "0805EC9467",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(396003)(376002)(346002)(366004)(39860400002)(136003)(199004)(189003)(51234002)(66066001)(2616005)(476003)(446003)(486006)(11346002)(6436002)(305945005)(7736002)(575784001)(386003)(6506007)(6486002)(6512007)(186003)(102836004)(5250100002)(76176011)(25786009)(26005)(68736007)(6116002)(54906003)(110136005)(99286004)(1076002)(3846002)(71200400001)(52116002)(86362001)(53936002)(71190400001)(97736004)(8936002)(107886003)(14444005)(256004)(4326008)(316002)(2900100001)(81156014)(8676002)(36756003)(81166006)(105586002)(2906002)(106356001)(6636002)(478600001)(5660300001)(14454004);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB3996;\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": "wu6W2pJT+zjEcfHbj2q+FNoaj0MLx/34k0VNOv+GO2ghj6jyrsSo3Pts/s7ihJ1H+YfXj3rAmK4K9l/PhSUiPD9LeRsA67CRkSLm/LZHXk0uHBPA/pxuuQoyLHPNiIL2MsO7ksy+4RfRwQTAvHktVzWql7Q5REZm9w2fxod8SsuBBOr0a3deHRsmWeMBOowYkZd+YakCDuzXpeQfOABv2YPysKx7XqLBiGfYE05L2AMeAFLVV5hq93Ak5iw/eskadxxMU0JFz3LWovl0pK1Zc8vozQ05esHblRNIXuWmQ0wjtCC53v0bd1hcT0+qJugcc4+BKg2yOVN0vLu6Dugunf9BSF4toYmzcj2lG8RstKY=",
        "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": "e124f667-b841-40b1-a54c-08d62273ea81",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "24 Sep 2018 23:17:37.5764\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DB3PR0502MB3996",
        "Subject": "[dpdk-dev] [PATCH v3 02/11] net/mlx5: add flow prepare function",
        "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": "From: Ori Kam <orika@mellanox.com>\n\nIn current implementation the calculation of the flow size is done\nduring the validation stage, and the same function is also used to\ntranslate the input parameters into verbs spec. This is hard to maintain\nand error prone. Another issue is that dev-flows (flows that are created\nimplicitly in order to support the requested flow for example when the\nuser request RSS on UDP 2 rules need to be created one for IPv4 and one\nfor IPv6). In current implementation the dev-flows are created on the same\nmemory allocation. This will be harder to implement in future drivers.\n\nThe commits extract the calculation and creation of the dev-flow from\nthe translation part (the part that converts the parameters into the\nformat required by the driver). This results in that the prepare\nfunction only function is to allocate the dev-flow.\n\nSigned-off-by: Ori Kam <orika@mellanox.com>\nAcked-by: Yongseok Koh <yskoh@mellanox.com>\n---\n drivers/net/mlx5/mlx5_flow.c | 269 ++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 263 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 799064c0c..166fee555 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -292,6 +292,15 @@ struct mlx5_flow_verbs {\n \tuint64_t hash_fields; /**< Verbs hash Rx queue hash fields. */\n };\n \n+/** Device flow structure. */\n+struct mlx5_flow {\n+\tLIST_ENTRY(mlx5_flow) next;\n+\tstruct rte_flow *flow; /**< Pointer to the main flow. */\n+\tunion {\n+\t\tstruct mlx5_flow_verbs verbs; /**< Holds the verbs dev-flow. */\n+\t};\n+};\n+\n /* Counters information. */\n struct mlx5_flow_counter {\n \tLIST_ENTRY(mlx5_flow_counter) next; /**< Pointer to the next counter. */\n@@ -321,6 +330,8 @@ struct rte_flow {\n \tuint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */\n \tuint16_t (*queue)[]; /**< Destination queues to redirect traffic to. */\n \tvoid *nl_flow; /**< Netlink flow buffer if relevant. */\n+\tLIST_HEAD(dev_flows, mlx5_flow) dev_flows;\n+\t/**< Device flows that are part of the flow. */\n };\n \n static const struct rte_flow_ops mlx5_flow_ops = {\n@@ -2322,7 +2333,7 @@ mlx5_flow_rxq_flags_clear(struct rte_eth_dev *dev)\n  *   Pointer to error structure.\n  *\n  * @return\n- *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n static int\n mlx5_flow_validate_action_flag(uint64_t action_flags,\n@@ -2425,7 +2436,6 @@ mlx5_flow_validate_action_drop(uint64_t action_flags,\n }\n \n /*\n- *\n  * Validate the queue action.\n  *\n  * @param[in] action\n@@ -2469,7 +2479,6 @@ mlx5_flow_validate_action_queue(const struct rte_flow_action *action,\n }\n \n /*\n- *\n  * Validate the rss action.\n  *\n  * @param[in] action\n@@ -3211,7 +3220,7 @@ mlx5_flow_validate_item_mpls(const struct rte_flow_item *item __rte_unused,\n \tif (ret < 0)\n \t\treturn ret;\n \treturn 0;\n-#endif /* !HAVE_IBV_DEVICE_MPLS_SUPPORT */\n+#endif\n \treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, item,\n \t\t\t\t  \"MPLS is not supported by Verbs, please\"\n@@ -3219,7 +3228,6 @@ mlx5_flow_validate_item_mpls(const struct rte_flow_item *item __rte_unused,\n }\n \n /**\n- *\n  * Internal validation function.\n  *\n  * @param[in] dev\n@@ -3444,6 +3452,222 @@ mlx5_flow_validate(struct rte_eth_dev *dev,\n }\n \n /**\n+ * Calculate the required bytes that are needed for the action part of the verbs\n+ * flow, in addtion returns bit-fields with all the detected action, in order to\n+ * avoid another interation over the actions.\n+ *\n+ * @param[in] actions\n+ *   Pointer to the list of actions.\n+ * @param[out] action_flags\n+ *   Pointer to the detected actions.\n+ *\n+ * @return\n+ *   The size of the memory needed for all actions.\n+ */\n+static int\n+mlx5_flow_verbs_get_actions_and_size(const struct rte_flow_action actions[],\n+\t\t\t\t     uint64_t *action_flags)\n+{\n+\tint size = 0;\n+\tuint64_t detected_actions = 0;\n+\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {\n+\t\tswitch (actions->type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_FLAG:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_action_tag);\n+\t\t\tdetected_actions |= MLX5_ACTION_FLAG;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_MARK:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_action_tag);\n+\t\t\tdetected_actions |= MLX5_ACTION_MARK;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_action_drop);\n+\t\t\tdetected_actions |= MLX5_ACTION_DROP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n+\t\t\tdetected_actions |= MLX5_ACTION_QUEUE;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_RSS:\n+\t\t\tdetected_actions |= MLX5_ACTION_RSS;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n+#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT\n+\t\t\tsize += sizeof(struct ibv_flow_spec_counter_action);\n+#endif\n+\t\t\tdetected_actions |= MLX5_ACTION_COUNT;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\t*action_flags = detected_actions;\n+\treturn size;\n+}\n+\n+/**\n+ * Calculate the required bytes that are needed for the item part of the verbs\n+ * flow, in addtion returns bit-fields with all the detected action, in order to\n+ * avoid another interation over the actions.\n+ *\n+ * @param[in] actions\n+ *   Pointer to the list of items.\n+ * @param[in, out] item_flags\n+ *   Pointer to the detected items.\n+ *\n+ * @return\n+ *   The size of the memory needed for all items.\n+ */\n+static int\n+mlx5_flow_verbs_get_items_and_size(const struct rte_flow_item items[],\n+\t\t\t\t   uint64_t *item_flags)\n+{\n+\tint size = 0;\n+\tuint64_t detected_items = 0;\n+\tconst int tunnel = !!(*item_flags & MLX5_FLOW_LAYER_TUNNEL);\n+\n+\tfor (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {\n+\t\tswitch (items->type) {\n+\t\tcase RTE_FLOW_ITEM_TYPE_VOID:\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_ETH:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_eth);\n+\t\t\tdetected_items |= tunnel ? MLX5_FLOW_LAYER_INNER_L2 :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_L2;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VLAN:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_eth);\n+\t\t\tdetected_items |= tunnel ? MLX5_FLOW_LAYER_INNER_VLAN :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_VLAN;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_ipv4_ext);\n+\t\t\tdetected_items |= tunnel ?\n+\t\t\t\t\tMLX5_FLOW_LAYER_INNER_L3_IPV4 :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_L3_IPV4;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_ipv6);\n+\t\t\tdetected_items |= tunnel ?\n+\t\t\t\tMLX5_FLOW_LAYER_INNER_L3_IPV6 :\n+\t\t\t\tMLX5_FLOW_LAYER_OUTER_L3_IPV6;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_tcp_udp);\n+\t\t\tdetected_items |= tunnel ?\n+\t\t\t\t\tMLX5_FLOW_LAYER_INNER_L4_UDP :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_L4_UDP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_TCP:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_tcp_udp);\n+\t\t\tdetected_items |= tunnel ?\n+\t\t\t\t\tMLX5_FLOW_LAYER_INNER_L4_TCP :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_L4_TCP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_tunnel);\n+\t\t\tdetected_items |= MLX5_FLOW_LAYER_VXLAN;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN_GPE:\n+\t\t\tsize += sizeof(struct ibv_flow_spec_tunnel);\n+\t\t\tdetected_items |= MLX5_FLOW_LAYER_VXLAN_GPE;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_GRE:\n+#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT\n+\t\t\tsize += sizeof(struct ibv_flow_spec_gre);\n+\t\t\tdetected_items |= MLX5_FLOW_LAYER_GRE;\n+#else\n+\t\t\tsize += sizeof(struct ibv_flow_spec_tunnel);\n+\t\t\tdetected_items |= MLX5_FLOW_LAYER_TUNNEL;\n+#endif\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_MPLS:\n+#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT\n+\t\t\tsize += sizeof(struct ibv_flow_spec_mpls);\n+\t\t\tdetected_items |= MLX5_FLOW_LAYER_MPLS;\n+#endif\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\t*item_flags = detected_items;\n+\treturn size;\n+}\n+\n+/**\n+ * Get RSS action from the action list.\n+ *\n+ * @param[in] actions\n+ *   Pointer to the list of actions.\n+ *\n+ * @return\n+ *   Pointer to the RSS action if exist, else return NULL.\n+ */\n+static const struct rte_flow_action_rss*\n+mlx5_flow_get_rss_action(const struct rte_flow_action actions[])\n+{\n+\tfor (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {\n+\t\tswitch (actions->type) {\n+\t\tcase RTE_FLOW_ACTION_TYPE_RSS:\n+\t\t\treturn (const struct rte_flow_action_rss *)\n+\t\t\t       actions->conf;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn NULL;\n+}\n+\n+/**\n+ * Internal preparation function. Allocate mlx5_flow with the required size.\n+ * The required size is calculate based on the actions and items. This function\n+ * also returns the detected actions and items for later use.\n+ *\n+ * @param[in] attr\n+ *   Pointer to the flow attributes.\n+ * @param[in] items\n+ *   Pointer to the list of items.\n+ * @param[in] actions\n+ *   Pointer to the list of actions.\n+ * @param[out] item_flags\n+ *   Pointer to bit mask of all items detected.\n+ * @param[out] action_flags\n+ *   Pointer to bit mask of all actions detected.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   Pointer to mlx5_flow object on success, otherwise NULL and rte_errno\n+ *   is set.\n+ */\n+static struct mlx5_flow *\n+mlx5_flow_verbs_prepare(const struct rte_flow_attr *attr __rte_unused,\n+\t\t\tconst struct rte_flow_item items[],\n+\t\t\tconst struct rte_flow_action actions[],\n+\t\t\tuint64_t *item_flags,\n+\t\t\tuint64_t *action_flags,\n+\t\t\tstruct rte_flow_error *error)\n+{\n+\tuint32_t size = sizeof(struct ibv_flow_attr);\n+\tstruct mlx5_flow *flow;\n+\n+\tsize += mlx5_flow_verbs_get_actions_and_size(actions, action_flags);\n+\tsize += mlx5_flow_verbs_get_items_and_size(items, item_flags);\n+\tflow = rte_calloc(__func__, 1, size, 0);\n+\tif (!flow) {\n+\t\trte_flow_error_set(error, ENOMEM,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t   NULL,\n+\t\t\t\t   \"not enough memory to create flow\");\n+\t\treturn NULL;\n+\t}\n+\treturn flow;\n+}\n+\n+/**\n  * Remove the flow.\n  *\n  * @param[in] dev\n@@ -3594,12 +3818,46 @@ mlx5_flow_list_create(struct rte_eth_dev *dev,\n \t\t      struct rte_flow_error *error)\n {\n \tstruct rte_flow *flow = NULL;\n+\tstruct mlx5_flow *dev_flow;\n \tsize_t size = 0;\n+\tuint64_t action_flags = 0;\n+\tuint64_t item_flags = 0;\n+\tconst struct rte_flow_action_rss *rss;\n+\tunion {\n+\t\tstruct rte_flow_expand_rss buf;\n+\t\tuint8_t buffer[2048];\n+\t} expand_buffer;\n+\tstruct rte_flow_expand_rss *buf = &expand_buffer.buf;\n \tint ret;\n+\tuint32_t i;\n \n \tret = mlx5_flow_validate(dev, attr, items, actions, error);\n \tif (ret < 0)\n \t\treturn NULL;\n+\tflow = rte_calloc(__func__, 1, sizeof(*flow), 0);\n+\tLIST_INIT(&flow->dev_flows);\n+\trss = mlx5_flow_get_rss_action(actions);\n+\tif (rss && rss->types) {\n+\t\tunsigned int graph_root;\n+\n+\t\tgraph_root = mlx5_find_graph_root(items, rss->level);\n+\t\tret = rte_flow_expand_rss(buf, sizeof(expand_buffer.buffer),\n+\t\t\t\t\t  items, rss->types,\n+\t\t\t\t\t  mlx5_support_expansion,\n+\t\t\t\t\t  graph_root);\n+\t\tassert(ret > 0 &&\n+\t\t       (unsigned int)ret < sizeof(expand_buffer.buffer));\n+\t} else {\n+\t\tbuf->entries = 1;\n+\t\tbuf->entry[0].pattern = (void *)(uintptr_t)items;\n+\t}\n+\tfor (i = 0; i < buf->entries; ++i) {\n+\t\tdev_flow = mlx5_flow_verbs_prepare(attr, buf->entry[i].pattern,\n+\t\t\t\t\t\t   actions, &item_flags,\n+\t\t\t\t\t\t   &action_flags, error);\n+\t\tdev_flow->flow = flow;\n+\t\tLIST_INSERT_HEAD(&flow->dev_flows, dev_flow, next);\n+\t}\n \tret = mlx5_flow_merge(dev, flow, size, attr, items, actions, error);\n \tif (ret < 0)\n \t\treturn NULL;\n@@ -4091,7 +4349,6 @@ mlx5_fdir_filter_convert(struct rte_eth_dev *dev,\n \t\t\t.dst_addr = input->flow.ip4_flow.dst_ip,\n \t\t\t.time_to_live = input->flow.ip4_flow.ttl,\n \t\t\t.type_of_service = input->flow.ip4_flow.tos,\n-\t\t\t.next_proto_id = input->flow.ip4_flow.proto,\n \t\t};\n \t\tattributes->l3_mask.ipv4.hdr = (struct ipv4_hdr){\n \t\t\t.src_addr = mask->ipv4_mask.src_ip,\n",
    "prefixes": [
        "v3",
        "02/11"
    ]
}