get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 44759,
    "url": "http://patches.dpdk.org/api/patches/44759/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1537105328-9367-1-git-send-email-dekelp@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": "<1537105328-9367-1-git-send-email-dekelp@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1537105328-9367-1-git-send-email-dekelp@mellanox.com",
    "date": "2018-09-16T13:42:08",
    "name": "net/mlx5: support metadata as flow rule criteria",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fcff95a6ec12014c8e71ebc4d7db2f6163fc56d7",
    "submitter": {
        "id": 1082,
        "url": "http://patches.dpdk.org/api/people/1082/?format=api",
        "name": "Dekel Peled",
        "email": "dekelp@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1537105328-9367-1-git-send-email-dekelp@mellanox.com/mbox/",
    "series": [
        {
            "id": 1335,
            "url": "http://patches.dpdk.org/api/series/1335/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1335",
            "date": "2018-09-16T13:42:08",
            "name": "net/mlx5: support metadata as flow rule criteria",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/1335/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/44759/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/44759/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 0AC7F343C;\n\tSun, 16 Sep 2018 15:43:10 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby dpdk.org (Postfix) with ESMTP id EEBBE2C4F\n\tfor <dev@dpdk.org>; Sun, 16 Sep 2018 15:43:07 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\tdekelp@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 16 Sep 2018 15:47:27 +0200",
            "from mtl-vdi-280.wap.labs.mlnx. (mtl-vdi-280.wap.labs.mlnx\n\t[10.128.130.87])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w8GDh7wB026324;\n\tSun, 16 Sep 2018 16:43:07 +0300"
        ],
        "From": "Dekel Peled <dekelp@mellanox.com>",
        "To": "dev@dpdk.org, shahafs@mellanox.com, yskoh@mellanox.com",
        "Cc": "orika@mellanox.com",
        "Date": "Sun, 16 Sep 2018 16:42:08 +0300",
        "Message-Id": "<1537105328-9367-1-git-send-email-dekelp@mellanox.com>",
        "X-Mailer": "git-send-email 1.7.1",
        "Subject": "[dpdk-dev] [PATCH] net/mlx5: support metadata as flow rule criteria",
        "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": "As described in series starting at [1], it adds option to set metadata\nvalue as match pattern when creating a new flow rule.\n\nThis patch adds metadata support in mlx5 driver, in several parts:\n- Add the setting of metadata value in matcher when creating\na new flow rule.\n- Add the passing of metadata value from mbuf to wqe when\nindicated by ol_flag, in different burst functions.\n- Allow flow rule with attribute egress in specific cases.\n\nThis patch must be built together with the files in series [1].\n\n[1] \"ethdev: support metadata as flow rule criteria\"\n\nSigned-off-by: Dekel Peled <dekelp@mellanox.com>\n---\n drivers/net/mlx5/mlx5_flow.c          |  60 +++++++++++++----\n drivers/net/mlx5/mlx5_flow.h          |  22 +++++--\n drivers/net/mlx5/mlx5_flow_dv.c       | 120 ++++++++++++++++++++++++++++++----\n drivers/net/mlx5/mlx5_flow_verbs.c    |  21 ++++--\n drivers/net/mlx5/mlx5_prm.h           |   2 +-\n drivers/net/mlx5/mlx5_rxtx.c          |  34 ++++++++--\n drivers/net/mlx5/mlx5_rxtx_vec.c      |  28 ++++++--\n drivers/net/mlx5/mlx5_rxtx_vec.h      |   1 +\n drivers/net/mlx5/mlx5_rxtx_vec_neon.h |   4 +-\n drivers/net/mlx5/mlx5_rxtx_vec_sse.h  |   4 +-\n drivers/net/mlx5/mlx5_txq.c           |   6 ++\n 11 files changed, 255 insertions(+), 47 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 4234be6..7932e0f 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -402,7 +402,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev,\n  * @return\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n-static int\n+int\n mlx5_flow_item_acceptable(const struct rte_flow_item *item,\n \t\t\t  const uint8_t *mask,\n \t\t\t  const uint8_t *nic_mask,\n@@ -602,7 +602,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_flag(uint64_t action_flags,\n-\t\t\t\t   struct rte_flow_error *error)\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \n \tif (action_flags & MLX5_ACTION_DROP)\n@@ -624,6 +625,11 @@ int mlx5_flow_validate_action_flag(uint64_t action_flags,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"can't have 2 flag\"\n \t\t\t\t\t  \" actions in same flow\");\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"flag action not supported for egress\");\n \treturn 0;\n }\n \n@@ -642,8 +648,9 @@ int mlx5_flow_validate_action_flag(uint64_t action_flags,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_mark(uint64_t action_flags,\n-\t\t\t\t   const struct rte_flow_action *action,\n-\t\t\t\t   struct rte_flow_error *error)\n+\t\t\t\tconst struct rte_flow_action *action,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tconst struct rte_flow_action_mark *mark = action->conf;\n \n@@ -677,6 +684,11 @@ int mlx5_flow_validate_action_mark(uint64_t action_flags,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"can't have 2 flag actions in same\"\n \t\t\t\t\t  \" flow\");\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"mark action not supported for egress\");\n \treturn 0;\n }\n \n@@ -693,7 +705,8 @@ int mlx5_flow_validate_action_mark(uint64_t action_flags,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_drop(uint64_t action_flags,\n-\t\t\t\t   struct rte_flow_error *error)\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tif (action_flags & MLX5_ACTION_FLAG)\n \t\treturn rte_flow_error_set(error,\n@@ -715,6 +728,11 @@ int mlx5_flow_validate_action_drop(uint64_t action_flags,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"can't have 2 fate actions in\"\n \t\t\t\t\t  \" same flow\");\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"drop action not supported for egress\");\n \treturn 0;\n }\n \n@@ -735,9 +753,10 @@ int mlx5_flow_validate_action_drop(uint64_t action_flags,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_queue(uint64_t action_flags,\n-\t\t\t\t    struct rte_eth_dev *dev,\n-\t\t\t\t    const struct rte_flow_action *action,\n-\t\t\t\t    struct rte_flow_error *error)\n+\t\t\t\tstruct rte_eth_dev *dev,\n+\t\t\t\tconst struct rte_flow_action *action,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tstruct priv *priv = dev->data->dev_private;\n \tconst struct rte_flow_action_queue *queue = action->conf;\n@@ -760,6 +779,11 @@ int mlx5_flow_validate_action_queue(uint64_t action_flags,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION_CONF,\n \t\t\t\t\t  &queue->index,\n \t\t\t\t\t  \"queue is not configured\");\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"queue action not supported for egress\");\n \treturn 0;\n }\n \n@@ -780,9 +804,10 @@ int mlx5_flow_validate_action_queue(uint64_t action_flags,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_rss(uint64_t action_flags,\n-\t\t\t\t  struct rte_eth_dev *dev,\n-\t\t\t\t  const struct rte_flow_action *action,\n-\t\t\t\t  struct rte_flow_error *error)\n+\t\t\t\tstruct rte_eth_dev *dev,\n+\t\t\t\tconst struct rte_flow_action *action,\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tstruct priv *priv = dev->data->dev_private;\n \tconst struct rte_flow_action_rss *rss = action->conf;\n@@ -839,6 +864,11 @@ int mlx5_flow_validate_action_rss(uint64_t action_flags,\n \t\t\t\t\t\t  &rss->queue[i],\n \t\t\t\t\t\t  \"queue is not configured\");\n \t}\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"rss action not supported for egress\");\n \treturn 0;\n }\n \n@@ -855,7 +885,8 @@ int mlx5_flow_validate_action_rss(uint64_t action_flags,\n  *   0 on success, a negative errno value otherwise and rte_ernno is set.\n  */\n int mlx5_flow_validate_action_count(struct rte_eth_dev *dev,\n-\t\t\t\t    struct rte_flow_error *error)\n+\t\t\t\tconst struct rte_flow_attr *attr,\n+\t\t\t\tstruct rte_flow_error *error)\n {\n \tstruct priv *priv = dev->data->dev_private;\n \n@@ -864,6 +895,11 @@ int mlx5_flow_validate_action_count(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"flow counters are not supported.\");\n+\tif (attr->egress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n+\t\t\t\t\tNULL,\n+\t\t\t\t\t\"count action not supported for egress\");\n \treturn 0;\n }\n \ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex f1a72d4..e0446c5 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -43,6 +43,9 @@\n #define MLX5_FLOW_LAYER_GRE (1u << 14)\n #define MLX5_FLOW_LAYER_MPLS (1u << 15)\n \n+/* General pattern items bits. */\n+#define MLX5_FLOW_ITEM_METADATA (1u << 16)\n+\n /* Outer Masks. */\n #define MLX5_FLOW_LAYER_OUTER_L3 \\\n \t(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)\n@@ -237,21 +240,27 @@ struct mlx5_flow_driver_ops {\n \n /* mlx5_flow.c */\n int mlx5_flow_validate_action_flag(uint64_t action_flags,\n-\t\t\t\t   struct rte_flow_error *error);\n+\t\t\t\t    const struct rte_flow_attr *attr,\n+\t\t\t\t    struct rte_flow_error *error);\n int mlx5_flow_validate_action_mark(uint64_t action_flags,\n-\t\t\t\t   const struct rte_flow_action *action,\n-\t\t\t\t   struct rte_flow_error *error);\n+\t\t\t\t    const struct rte_flow_action *action,\n+\t\t\t\t    const struct rte_flow_attr *attr,\n+\t\t\t\t    struct rte_flow_error *error);\n int mlx5_flow_validate_action_drop(uint64_t action_flags,\n-\t\t\t\t   struct rte_flow_error *error);\n+\t\t\t\t    const struct rte_flow_attr *attr,\n+\t\t\t\t    struct rte_flow_error *error);\n int mlx5_flow_validate_action_queue(uint64_t action_flags,\n \t\t\t\t    struct rte_eth_dev *dev,\n \t\t\t\t    const struct rte_flow_action *action,\n+\t\t\t\t    const struct rte_flow_attr *attr,\n \t\t\t\t    struct rte_flow_error *error);\n int mlx5_flow_validate_action_rss(uint64_t action_flags,\n \t\t\t\t  struct rte_eth_dev *dev,\n \t\t\t\t  const struct rte_flow_action *action,\n+\t\t\t\t  const struct rte_flow_attr *attr,\n \t\t\t\t  struct rte_flow_error *error);\n int mlx5_flow_validate_action_count(struct rte_eth_dev *dev,\n+\t\t\t\t    const struct rte_flow_attr *attr,\n \t\t\t\t    struct rte_flow_error *error);\n int mlx5_flow_validate_attributes(struct rte_eth_dev *dev,\n \t\t\t\t  const struct rte_flow_attr *attributes,\n@@ -294,6 +303,11 @@ int mlx5_flow_validate_item_mpls(uint64_t item_flags,\n void mlx5_flow_init_driver_ops(struct rte_eth_dev *dev);\n uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n \t\t\t\t   uint32_t subpriority);\n+int mlx5_flow_item_acceptable(const struct rte_flow_item *item,\n+\t\t\t      const uint8_t *mask,\n+\t\t\t      const uint8_t *nic_mask,\n+\t\t\t      unsigned int size,\n+\t\t\t      struct rte_flow_error *error);\n \n /* mlx5_flow_dv.c */\n void mlx5_flow_dv_get_driver_ops(struct mlx5_flow_driver_ops *flow_ops);\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex 4090c5f..3b52181 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -37,6 +37,47 @@\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \n /**\n+ * Validate META item.\n+ *\n+ * @param[in] item\n+ *   Item specification.\n+ * @param[out] error\n+ *   Pointer to error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_flow_validate_item_meta(const struct rte_flow_item *item,\n+\t\t\tconst struct rte_flow_attr *attributes,\n+\t\t\tstruct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_meta *mask = item->mask;\n+\n+\tconst struct rte_flow_item_meta nic_mask = {\n+\t\t.data = RTE_BE32(UINT32_MAX)\n+\t};\n+\n+\tint ret;\n+\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_meta_mask;\n+\tret = mlx5_flow_item_acceptable\n+\t\t(item, (const uint8_t *)mask,\n+\t\t(const uint8_t *)&nic_mask,\n+\t\tsizeof(struct rte_flow_item_meta), error);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tif (attributes->ingress)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,\n+\t\t\t\t\t  NULL,\n+\t\t\t\t\t  \"pattern not supported for ingress\");\n+\treturn 0;\n+}\n+\n+/**\n  * Verify the @p attributes will be correctly understood by the NIC and store\n  * them in the @p flow if everything is correct.\n  *\n@@ -68,21 +109,17 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"priority out of range\");\n-\tif (attributes->egress)\n-\t\treturn rte_flow_error_set(error, ENOTSUP,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,\n-\t\t\t\t\t  NULL,\n-\t\t\t\t\t  \"egress is not supported\");\n \tif (attributes->transfer)\n \t\treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"transfer is not supported\");\n-\tif (!attributes->ingress)\n+\tif (!(attributes->egress ^ attributes->ingress))\n \t\treturn rte_flow_error_set(error, ENOTSUP,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR,\n \t\t\t\t\t  NULL,\n-\t\t\t\t\t  \"ingress attribute is mandatory\");\n+\t\t\t\t\t  \"must specify exactly one of \"\n+\t\t\t\t\t  \"ingress or egress\");\n \treturn 0;\n }\n \n@@ -219,6 +256,12 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \t\t\t\treturn ret;\n \t\t\titem_flags |= MLX5_FLOW_LAYER_MPLS;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_META:\n+\t\t\tret = mlx5_flow_validate_item_meta(items, attr, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_ITEM_METADATA;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM,\n@@ -233,6 +276,7 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_FLAG:\n \t\t\tret = mlx5_flow_validate_action_flag(action_flags,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n@@ -241,6 +285,7 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \t\tcase RTE_FLOW_ACTION_TYPE_MARK:\n \t\t\tret = mlx5_flow_validate_action_mark(action_flags,\n \t\t\t\t\t\t\t     actions,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n@@ -248,27 +293,36 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n \t\t\tret = mlx5_flow_validate_action_drop(action_flags,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_DROP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n-\t\t\tret = mlx5_flow_validate_action_queue(action_flags, dev,\n-\t\t\t\t\t\t\t      actions, error);\n+\t\t\tret = mlx5_flow_validate_action_queue(action_flags,\n+\t\t\t\t\t\t\t      dev,\n+\t\t\t\t\t\t\t      actions,\n+\t\t\t\t\t\t\t      attr,\n+\t\t\t\t\t\t\t      error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_QUEUE;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_RSS:\n-\t\t\tret = mlx5_flow_validate_action_rss(action_flags, dev,\n-\t\t\t\t\t\t\t    actions, error);\n+\t\t\tret = mlx5_flow_validate_action_rss(action_flags,\n+\t\t\t\t\t\t\t    dev,\n+\t\t\t\t\t\t\t    actions,\n+\t\t\t\t\t\t\t    attr,\n+\t\t\t\t\t\t\t    error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_RSS;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n-\t\t\tret = mlx5_flow_validate_action_count(dev, error);\n+\t\t\tret = mlx5_flow_validate_action_count(dev,\n+\t\t\t\t\t\t\t      attr,\n+\t\t\t\t\t\t\t      error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_COUNT;\n@@ -865,6 +919,43 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n }\n \n /**\n+ * Add META item to matcher\n+ *\n+ * @param[in, out] matcher\n+ *   Flow matcher.\n+ * @param[in, out] key\n+ *   Flow matcher value.\n+ * @param[in] item\n+ *   Flow pattern to translate.\n+ * @param[in] inner\n+ *   Item is inner pattern.\n+ */\n+static void\n+flow_dv_translate_item_meta(void *matcher, void *key,\n+\t\t\t\tconst struct rte_flow_item *item)\n+{\n+\tconst struct rte_flow_item_meta *metam;\n+\tconst struct rte_flow_item_meta *metav;\n+\n+\tvoid *misc2_m =\n+\t\tMLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2);\n+\tvoid *misc2_v =\n+\t\tMLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);\n+\n+\tmetam = (const void *)item->mask;\n+\tif (!metam)\n+\t\tmetam = &rte_flow_item_meta_mask;\n+\n+\tmetav = (const void *)item->spec;\n+\tif (metav) {\n+\t\tMLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,\n+\t\t\tRTE_BE32((uint32_t)rte_be_to_cpu_64(metam->data)));\n+\t\tMLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,\n+\t\t\tRTE_BE32((uint32_t)rte_be_to_cpu_64(metav->data)));\n+\t}\n+}\n+\n+/**\n  *\n  * Translate flow item.\n  *\n@@ -946,6 +1037,9 @@ static int flow_dv_validate_attributes(struct rte_eth_dev *dev,\n \tcase RTE_FLOW_ITEM_TYPE_VXLAN_GPE:\n \t\tflow_dv_translate_item_vxlan(tmatcher->key, key, item, inner);\n \t\tbreak;\n+\tcase RTE_FLOW_ITEM_TYPE_META:\n+\t\tflow_dv_translate_item_meta(tmatcher->key, key, item);\n+\t\tbreak;\n \tcase RTE_FLOW_ITEM_TYPE_ICMP:\n \tcase RTE_FLOW_ITEM_TYPE_MPLS:\n \tcase RTE_FLOW_ITEM_TYPE_SCTP:\ndiff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c\nindex 48e816d..3c42016 100644\n--- a/drivers/net/mlx5/mlx5_flow_verbs.c\n+++ b/drivers/net/mlx5/mlx5_flow_verbs.c\n@@ -1272,6 +1272,7 @@ struct ibv_spec_header {\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_FLAG:\n \t\t\tret = mlx5_flow_validate_action_flag(action_flags,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n@@ -1280,6 +1281,7 @@ struct ibv_spec_header {\n \t\tcase RTE_FLOW_ACTION_TYPE_MARK:\n \t\t\tret = mlx5_flow_validate_action_mark(action_flags,\n \t\t\t\t\t\t\t     actions,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n@@ -1287,27 +1289,36 @@ struct ibv_spec_header {\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n \t\t\tret = mlx5_flow_validate_action_drop(action_flags,\n+\t\t\t\t\t\t\t     attr,\n \t\t\t\t\t\t\t     error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_DROP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n-\t\t\tret = mlx5_flow_validate_action_queue(action_flags, dev,\n-\t\t\t\t\t\t\t      actions, error);\n+\t\t\tret = mlx5_flow_validate_action_queue(action_flags,\n+\t\t\t\t\t\t\t      dev,\n+\t\t\t\t\t\t\t      actions,\n+\t\t\t\t\t\t\t      attr,\n+\t\t\t\t\t\t\t      error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_QUEUE;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_RSS:\n-\t\t\tret = mlx5_flow_validate_action_rss(action_flags, dev,\n-\t\t\t\t\t\t\t    actions, error);\n+\t\t\tret = mlx5_flow_validate_action_rss(action_flags,\n+\t\t\t\t\t\t\t    dev,\n+\t\t\t\t\t\t\t    actions,\n+\t\t\t\t\t\t\t    attr,\n+\t\t\t\t\t\t\t    error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_RSS;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_COUNT:\n-\t\t\tret = mlx5_flow_validate_action_count(dev, error);\n+\t\t\tret = mlx5_flow_validate_action_count(dev,\n+\t\t\t\t\t\t\t      attr,\n+\t\t\t\t\t\t\t      error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \t\t\taction_flags |= MLX5_ACTION_COUNT;\ndiff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h\nindex 117cec7..2f33aef 100644\n--- a/drivers/net/mlx5/mlx5_prm.h\n+++ b/drivers/net/mlx5/mlx5_prm.h\n@@ -159,7 +159,7 @@ struct mlx5_wqe_eth_seg_small {\n \tuint8_t\tcs_flags;\n \tuint8_t\trsvd1;\n \tuint16_t mss;\n-\tuint32_t rsvd2;\n+\tuint32_t flow_table_metadata;\n \tuint16_t inline_hdr_sz;\n \tuint8_t inline_hdr[2];\n } __rte_aligned(MLX5_WQE_DWORD_SIZE);\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c\nindex 2d14f8a..080de57 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.c\n+++ b/drivers/net/mlx5/mlx5_rxtx.c\n@@ -523,6 +523,7 @@\n \t\tuint8_t tso = txq->tso_en && (buf->ol_flags & PKT_TX_TCP_SEG);\n \t\tuint32_t swp_offsets = 0;\n \t\tuint8_t swp_types = 0;\n+\t\tuint32_t metadata = 0;\n \t\tuint16_t tso_segsz = 0;\n #ifdef MLX5_PMD_SOFT_COUNTERS\n \t\tuint32_t total_length = 0;\n@@ -566,6 +567,9 @@\n \t\tcs_flags = txq_ol_cksum_to_cs(buf);\n \t\ttxq_mbuf_to_swp(txq, buf, (uint8_t *)&swp_offsets, &swp_types);\n \t\traw = ((uint8_t *)(uintptr_t)wqe) + 2 * MLX5_WQE_DWORD_SIZE;\n+\t\t/* Copy metadata from mbuf if valid */\n+\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\tmetadata = buf->hash.fdir.hi;\n \t\t/* Replace the Ethernet type by the VLAN if necessary. */\n \t\tif (buf->ol_flags & PKT_TX_VLAN_PKT) {\n \t\t\tuint32_t vlan = rte_cpu_to_be_32(0x81000000 |\n@@ -781,7 +785,7 @@\n \t\t\t\tswp_offsets,\n \t\t\t\tcs_flags | (swp_types << 8) |\n \t\t\t\t(rte_cpu_to_be_16(tso_segsz) << 16),\n-\t\t\t\t0,\n+\t\t\t\trte_cpu_to_be_32(metadata),\n \t\t\t\t(ehdr << 16) | rte_cpu_to_be_16(tso_header_sz),\n \t\t\t};\n \t\t} else {\n@@ -795,7 +799,7 @@\n \t\t\twqe->eseg = (rte_v128u32_t){\n \t\t\t\tswp_offsets,\n \t\t\t\tcs_flags | (swp_types << 8),\n-\t\t\t\t0,\n+\t\t\t\trte_cpu_to_be_32(metadata),\n \t\t\t\t(ehdr << 16) | rte_cpu_to_be_16(pkt_inline_sz),\n \t\t\t};\n \t\t}\n@@ -861,7 +865,7 @@\n \tmpw->wqe->eseg.inline_hdr_sz = 0;\n \tmpw->wqe->eseg.rsvd0 = 0;\n \tmpw->wqe->eseg.rsvd1 = 0;\n-\tmpw->wqe->eseg.rsvd2 = 0;\n+\tmpw->wqe->eseg.flow_table_metadata = 0;\n \tmpw->wqe->ctrl[0] = rte_cpu_to_be_32((MLX5_OPC_MOD_MPW << 24) |\n \t\t\t\t\t     (txq->wqe_ci << 8) |\n \t\t\t\t\t     MLX5_OPCODE_TSO);\n@@ -971,6 +975,8 @@\n \t\tif ((mpw.state == MLX5_MPW_STATE_OPENED) &&\n \t\t    ((mpw.len != length) ||\n \t\t     (segs_n != 1) ||\n+\t\t     (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t     (mpw.wqe->eseg.cs_flags != cs_flags)))\n \t\t\tmlx5_mpw_close(txq, &mpw);\n \t\tif (mpw.state == MLX5_MPW_STATE_CLOSED) {\n@@ -984,6 +990,8 @@\n \t\t\tmax_wqe -= 2;\n \t\t\tmlx5_mpw_new(txq, &mpw, length);\n \t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t}\n \t\t/* Multi-segment packets must be alone in their MPW. */\n \t\tassert((segs_n == 1) || (mpw.pkts_n == 0));\n@@ -1082,7 +1090,7 @@\n \tmpw->wqe->eseg.cs_flags = 0;\n \tmpw->wqe->eseg.rsvd0 = 0;\n \tmpw->wqe->eseg.rsvd1 = 0;\n-\tmpw->wqe->eseg.rsvd2 = 0;\n+\tmpw->wqe->eseg.flow_table_metadata = 0;\n \tinl = (struct mlx5_wqe_inl_small *)\n \t\t(((uintptr_t)mpw->wqe) + 2 * MLX5_WQE_DWORD_SIZE);\n \tmpw->data.raw = (uint8_t *)&inl->raw;\n@@ -1199,12 +1207,16 @@\n \t\tif (mpw.state == MLX5_MPW_STATE_OPENED) {\n \t\t\tif ((mpw.len != length) ||\n \t\t\t    (segs_n != 1) ||\n+\t\t\t    (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags))\n \t\t\t\tmlx5_mpw_close(txq, &mpw);\n \t\t} else if (mpw.state == MLX5_MPW_INL_STATE_OPENED) {\n \t\t\tif ((mpw.len != length) ||\n \t\t\t    (segs_n != 1) ||\n \t\t\t    (length > inline_room) ||\n+\t\t\t    (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags)) {\n \t\t\t\tmlx5_mpw_inline_close(txq, &mpw);\n \t\t\t\tinline_room =\n@@ -1224,12 +1236,20 @@\n \t\t\t\tmax_wqe -= 2;\n \t\t\t\tmlx5_mpw_new(txq, &mpw, length);\n \t\t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t\t} else {\n \t\t\t\tif (unlikely(max_wqe < wqe_inl_n))\n \t\t\t\t\tbreak;\n \t\t\t\tmax_wqe -= wqe_inl_n;\n \t\t\t\tmlx5_mpw_inline_new(txq, &mpw, length);\n \t\t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t\t}\n \t\t}\n \t\t/* Multi-segment packets must be alone in their MPW. */\n@@ -1482,6 +1502,8 @@\n \t\t\t    (length <= txq->inline_max_packet_sz &&\n \t\t\t     inl_pad + sizeof(inl_hdr) + length >\n \t\t\t     mpw_room) ||\n+\t\t\t    (mpw.wqe->eseg.flow_table_metadata !=\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi)) ||\n \t\t\t    (mpw.wqe->eseg.cs_flags != cs_flags))\n \t\t\t\tmax_wqe -= mlx5_empw_close(txq, &mpw);\n \t\t}\n@@ -1505,6 +1527,10 @@\n \t\t\t\t    sizeof(inl_hdr) + length <= mpw_room &&\n \t\t\t\t    !txq->mpw_hdr_dseg;\n \t\t\tmpw.wqe->eseg.cs_flags = cs_flags;\n+\t\t\t/* Copy metadata from mbuf if valid */\n+\t\t\tif (buf->ol_flags & PKT_TX_METADATA)\n+\t\t\t\tmpw.wqe->eseg.flow_table_metadata =\n+\t\t\t\t\trte_cpu_to_be_32(buf->hash.fdir.hi);\n \t\t} else {\n \t\t\t/* Evaluate whether the next packet can be inlined.\n \t\t\t * Inlininig is possible when:\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec.c b/drivers/net/mlx5/mlx5_rxtx_vec.c\nindex 0a4aed8..db36699 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec.c\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec.c\n@@ -48,25 +48,39 @@\n  *   Number of packets.\n  * @param cs_flags\n  *   Pointer of flags to be returned.\n+ * @param txq_offloads\n+ *   Offloads enabled on Tx queue\n  *\n  * @return\n  *   Number of packets having same ol_flags.\n+ *   If PKT_TX_METADATA is set in ol_flags, packets must have same metadata\n+ *   as well.\n  */\n static inline unsigned int\n-txq_calc_offload(struct rte_mbuf **pkts, uint16_t pkts_n, uint8_t *cs_flags)\n+txq_calc_offload(struct rte_mbuf **pkts, uint16_t pkts_n,\n+\t\tuint8_t *cs_flags, const uint64_t txq_offloads)\n {\n \tunsigned int pos;\n \tconst uint64_t ol_mask =\n \t\tPKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM |\n \t\tPKT_TX_UDP_CKSUM | PKT_TX_TUNNEL_GRE |\n-\t\tPKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM;\n+\t\tPKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM | PKT_TX_METADATA;\n \n \tif (!pkts_n)\n \t\treturn 0;\n \t/* Count the number of packets having same ol_flags. */\n-\tfor (pos = 1; pos < pkts_n; ++pos)\n-\t\tif ((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask)\n+\tfor (pos = 1; pos < pkts_n; ++pos) {\n+\t\tif ((txq_offloads & MLX5_VEC_TX_CKSUM_OFFLOAD_CAP) &&\n+\t\t\t((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask))\n \t\t\tbreak;\n+\t\t/* If the metadata ol_flag is set,\n+\t\t * metadata must be same in all packets.\n+\t\t */\n+\t\tif ((txq_offloads & DEV_TX_OFFLOAD_MATCH_METADATA) &&\n+\t\t\t(pkts[pos]->ol_flags & PKT_TX_METADATA) &&\n+\t\t\tpkts[0]->hash.fdir.hi != pkts[pos]->hash.fdir.hi)\n+\t\t\tbreak;\n+\t}\n \t*cs_flags = txq_ol_cksum_to_cs(pkts[0]);\n \treturn pos;\n }\n@@ -137,8 +151,10 @@\n \t\tn = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST);\n \t\tif (txq->offloads & DEV_TX_OFFLOAD_MULTI_SEGS)\n \t\t\tn = txq_count_contig_single_seg(&pkts[nb_tx], n);\n-\t\tif (txq->offloads & MLX5_VEC_TX_CKSUM_OFFLOAD_CAP)\n-\t\t\tn = txq_calc_offload(&pkts[nb_tx], n, &cs_flags);\n+\t\tif (txq->offloads & (MLX5_VEC_TX_CKSUM_OFFLOAD_CAP |\n+\t\t\t\t\tDEV_TX_OFFLOAD_MATCH_METADATA))\n+\t\t\tn = txq_calc_offload(&pkts[nb_tx], n,\n+\t\t\t\t\t     &cs_flags, txq->offloads);\n \t\tret = txq_burst_v(txq, &pkts[nb_tx], n, cs_flags);\n \t\tnb_tx += ret;\n \t\tif (!ret)\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec.h b/drivers/net/mlx5/mlx5_rxtx_vec.h\nindex fb884f9..fda7004 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec.h\n@@ -22,6 +22,7 @@\n /* HW offload capabilities of vectorized Tx. */\n #define MLX5_VEC_TX_OFFLOAD_CAP \\\n \t(MLX5_VEC_TX_CKSUM_OFFLOAD_CAP | \\\n+\t DEV_TX_OFFLOAD_MATCH_METADATA | \\\n \t DEV_TX_OFFLOAD_MULTI_SEGS)\n \n /*\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\nindex b37b738..20c9427 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h\n@@ -237,6 +237,7 @@\n \tuint8x16_t *t_wqe;\n \tuint8_t *dseg;\n \tuint8x16_t ctrl;\n+\tuint32_t md; /* metadata */\n \n \t/* Make sure all packets can fit into a single WQE. */\n \tassert(elts_n > pkts_n);\n@@ -293,10 +294,11 @@\n \tctrl = vqtbl1q_u8(ctrl, ctrl_shuf_m);\n \tvst1q_u8((void *)t_wqe, ctrl);\n \t/* Fill ESEG in the header. */\n+\tmd = pkts[0]->hash.fdir.hi;\n \tvst1q_u8((void *)(t_wqe + 1),\n \t\t ((uint8x16_t) { 0, 0, 0, 0,\n \t\t\t\t cs_flags, 0, 0, 0,\n-\t\t\t\t 0, 0, 0, 0,\n+\t\t\t\t md >> 24, md >> 16, md >> 8, md,\n \t\t\t\t 0, 0, 0, 0 }));\n #ifdef MLX5_PMD_SOFT_COUNTERS\n \ttxq->stats.opackets += pkts_n;\ndiff --git a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\nindex 54b3783..7c8535c 100644\n--- a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\n+++ b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h\n@@ -236,6 +236,7 @@\n \t\t\t      0,  1,  2,  3  /* bswap32 */);\n \t__m128i *t_wqe, *dseg;\n \t__m128i ctrl;\n+\tuint32_t md; /* metadata */\n \n \t/* Make sure all packets can fit into a single WQE. */\n \tassert(elts_n > pkts_n);\n@@ -292,9 +293,10 @@\n \tctrl = _mm_shuffle_epi8(ctrl, shuf_mask_ctrl);\n \t_mm_store_si128(t_wqe, ctrl);\n \t/* Fill ESEG in the header. */\n+\tmd = pkts[0]->hash.fdir.hi;\n \t_mm_store_si128(t_wqe + 1,\n \t\t\t_mm_set_epi8(0, 0, 0, 0,\n-\t\t\t\t     0, 0, 0, 0,\n+\t\t\t\t     md, md >> 8, md >> 16, md >> 24,\n \t\t\t\t     0, 0, 0, cs_flags,\n \t\t\t\t     0, 0, 0, 0));\n #ifdef MLX5_PMD_SOFT_COUNTERS\ndiff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c\nindex f9bc473..7263fb1 100644\n--- a/drivers/net/mlx5/mlx5_txq.c\n+++ b/drivers/net/mlx5/mlx5_txq.c\n@@ -128,6 +128,12 @@\n \t\t\toffloads |= (DEV_TX_OFFLOAD_VXLAN_TNL_TSO |\n \t\t\t\t     DEV_TX_OFFLOAD_GRE_TNL_TSO);\n \t}\n+\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tif (config->dv_flow_en)\n+\t\toffloads |= DEV_TX_OFFLOAD_MATCH_METADATA;\n+#endif\n+\n \treturn offloads;\n }\n \n",
    "prefixes": []
}