get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 86537,
    "url": "http://patches.dpdk.org/api/patches/86537/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210114070743.2377-8-shirik@nvidia.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": "<20210114070743.2377-8-shirik@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210114070743.2377-8-shirik@nvidia.com",
    "date": "2021-01-14T07:07:41",
    "name": "[v6,7/9] net/mlx5: add GENEVE TLV option flow validation",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "884618050bb1e2b962e55975946b673dc0bfe622",
    "submitter": {
        "id": 1894,
        "url": "http://patches.dpdk.org/api/people/1894/?format=api",
        "name": "Shiri Kuzin",
        "email": "shirik@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210114070743.2377-8-shirik@nvidia.com/mbox/",
    "series": [
        {
            "id": 14717,
            "url": "http://patches.dpdk.org/api/series/14717/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=14717",
            "date": "2021-01-14T07:07:34",
            "name": "ethdev: introduce GENEVE header TLV option item",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/14717/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/86537/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/86537/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 7DD1FA0A02;\n\tThu, 14 Jan 2021 08:09:48 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 7509C140F31;\n\tThu, 14 Jan 2021 08:09:05 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 37A20140EB6\n for <dev@dpdk.org>; Thu, 14 Jan 2021 08:09:02 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n shirik@nvidia.com) with SMTP; 14 Jan 2021 09:08:57 +0200",
            "from nvidia.com (c-141-140-1-007.mtl.labs.mlnx [10.141.140.7])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10E78GjK013095;\n Thu, 14 Jan 2021 09:08:57 +0200"
        ],
        "From": "Shiri Kuzin <shirik@nvidia.com>",
        "To": "dev@dpdk.org",
        "Cc": "viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com,\n ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com,\n andrew.rybchenko@oktetlabs.ru",
        "Date": "Thu, 14 Jan 2021 09:07:41 +0200",
        "Message-Id": "<20210114070743.2377-8-shirik@nvidia.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20210114070743.2377-1-shirik@nvidia.com>",
        "References": "<20210112140241.15914-1-shirik@nvidia.com>\n <20210114070743.2377-1-shirik@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v6 7/9] net/mlx5: add GENEVE TLV option flow\n validation",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch adds validation routine for the GENEVE\nheader TLV option.\n\nThe GENEVE TLV option match must include all fields\nwith full masks due to NIC does not support masking\non option class, type and length.\n\nThe option data length must be non zero and provided\ndata pattern should be zero neither due to hardware\nlimitations.\n\nSigned-off-by: Shiri Kuzin <shirik@nvidia.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>\n---\n drivers/net/mlx5/mlx5_flow.c    | 143 ++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_flow.h    |   8 ++\n drivers/net/mlx5/mlx5_flow_dv.c |  12 +++\n 3 files changed, 163 insertions(+)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex 1790e774ba..3c4ef6d7d2 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -2622,6 +2622,149 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,\n \treturn 0;\n }\n \n+/**\n+ * Validate Geneve TLV option item.\n+ *\n+ * @param[in] item\n+ *   Item specification.\n+ * @param[in] last_item\n+ *   Previous validated item in the pattern items.\n+ * @param[in] geneve_item\n+ *   Previous GENEVE item specification.\n+ * @param[in] dev\n+ *   Pointer to the rte_eth_dev structure.\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+int\n+mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,\n+\t\t\t\t   uint64_t last_item,\n+\t\t\t\t   const struct rte_flow_item *geneve_item,\n+\t\t\t\t   struct rte_eth_dev *dev,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_dev_ctx_shared *sh = priv->sh;\n+\tstruct mlx5_geneve_tlv_option_resource *geneve_opt_resource;\n+\tstruct mlx5_hca_attr *hca_attr = &priv->config.hca_attr;\n+\tuint8_t data_max_supported =\n+\t\t\thca_attr->max_geneve_tlv_option_data_len * 4;\n+\tstruct mlx5_dev_config *config = &priv->config;\n+\tconst struct rte_flow_item_geneve *geneve_spec;\n+\tconst struct rte_flow_item_geneve *geneve_mask;\n+\tconst struct rte_flow_item_geneve_opt *spec = item->spec;\n+\tconst struct rte_flow_item_geneve_opt *mask = item->mask;\n+\tunsigned int i;\n+\tunsigned int data_len;\n+\tuint8_t tlv_option_len;\n+\tuint16_t optlen_m, optlen_v;\n+\tconst struct rte_flow_item_geneve_opt full_mask = {\n+\t\t.option_class = RTE_BE16(0xffff),\n+\t\t.option_type = 0xff,\n+\t\t.option_len = 0x1f,\n+\t};\n+\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_geneve_opt_mask;\n+\tif (!spec)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt class/type/length must be specified\");\n+\tif ((uint32_t)spec->option_len > MLX5_GENEVE_OPTLEN_MASK)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt length exceeeds the limit (31)\");\n+\t/* Check if class type and length masks are full. */\n+\tif (full_mask.option_class != mask->option_class ||\n+\t    full_mask.option_type != mask->option_type ||\n+\t    full_mask.option_len != (mask->option_len & full_mask.option_len))\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt class/type/length masks must be full\");\n+\t/* Check if length is supported */\n+\tif ((uint32_t)spec->option_len >\n+\t\t\tconfig->hca_attr.max_geneve_tlv_option_data_len)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt length not supported\");\n+\tif (config->hca_attr.max_geneve_tlv_options > 1)\n+\t\tDRV_LOG(DEBUG,\n+\t\t\t\"max_geneve_tlv_options supports more than 1 option\");\n+\t/* Check GENEVE item preceding. */\n+\tif (!geneve_item || !(last_item & MLX5_FLOW_LAYER_GENEVE))\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve opt item must be preceded with Geneve item\");\n+\tgeneve_spec = geneve_item->spec;\n+\tgeneve_mask = geneve_item->mask ? geneve_item->mask :\n+\t\t\t\t\t  &rte_flow_item_geneve_mask;\n+\t/* Check if GENEVE TLV option size doesn't exceed option length */\n+\tif (geneve_spec && (geneve_mask->ver_opt_len_o_c_rsvd0 ||\n+\t\t\t    geneve_spec->ver_opt_len_o_c_rsvd0)) {\n+\t\ttlv_option_len = spec->option_len & mask->option_len;\n+\t\toptlen_v = rte_be_to_cpu_16(geneve_spec->ver_opt_len_o_c_rsvd0);\n+\t\toptlen_v = MLX5_GENEVE_OPTLEN_VAL(optlen_v);\n+\t\toptlen_m = rte_be_to_cpu_16(geneve_mask->ver_opt_len_o_c_rsvd0);\n+\t\toptlen_m = MLX5_GENEVE_OPTLEN_VAL(optlen_m);\n+\t\tif ((optlen_v & optlen_m) <= tlv_option_len)\n+\t\t\treturn rte_flow_error_set\n+\t\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"GENEVE TLV option length exceeds optlen\");\n+\t}\n+\t/* Check if length is 0 or data is 0. */\n+\tif (spec->data == NULL || spec->option_len == 0)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt with zero data/length not supported\");\n+\t/* Check not all data & mask are 0. */\n+\tdata_len = spec->option_len * 4;\n+\tif (mask->data == NULL) {\n+\t\tfor (i = 0; i < data_len; i++)\n+\t\t\tif (spec->data[i])\n+\t\t\t\tbreak;\n+\t\tif (i == data_len)\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\"Can't match on Geneve option data 0\");\n+\t} else {\n+\t\tfor (i = 0; i < data_len; i++)\n+\t\t\tif (spec->data[i] & mask->data[i])\n+\t\t\t\tbreak;\n+\t\tif (i == data_len)\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\"Can't match on Geneve option data and mask 0\");\n+\t\t/* Check data mask supported. */\n+\t\tfor (i = data_max_supported; i < data_len ; i++)\n+\t\t\tif (mask->data[i])\n+\t\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\t\"Data mask is of unsupported size\");\n+\t}\n+\t/* Check GENEVE option is supported in NIC. */\n+\tif (!config->hca_attr.geneve_tlv_opt)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\"Geneve TLV opt not supported\");\n+\t/* Check if we already have geneve option with different type/class. */\n+\trte_spinlock_lock(&sh->geneve_tlv_opt_sl);\n+\tgeneve_opt_resource = sh->geneve_tlv_option_resource;\n+\tif (geneve_opt_resource != NULL)\n+\t\tif (geneve_opt_resource->option_class != spec->option_class ||\n+\t\t    geneve_opt_resource->option_type != spec->option_type ||\n+\t\t    geneve_opt_resource->length != spec->option_len) {\n+\t\t\trte_spinlock_unlock(&sh->geneve_tlv_opt_sl);\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\"Only one Geneve TLV option supported\");\n+\t\t}\n+\trte_spinlock_unlock(&sh->geneve_tlv_opt_sl);\n+\treturn 0;\n+}\n+\n /**\n  * Validate MPLS item.\n  *\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 3d6ba9f610..e52f902448 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -138,6 +138,9 @@ enum mlx5_feature_name {\n #define MLX5_FLOW_LAYER_OUTER_L3_IPV6_FRAG_EXT (1u << 30)\n #define MLX5_FLOW_LAYER_INNER_L3_IPV6_FRAG_EXT (1u << 31)\n \n+/* Pattern tunnel Layer bits (continued). */\n+#define MLX5_FLOW_LAYER_GENEVE_OPT (UINT64_C(1) << 32)\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@@ -1396,6 +1399,11 @@ int mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,\n \t\t\t\t   uint64_t item_flags,\n \t\t\t\t   struct rte_eth_dev *dev,\n \t\t\t\t   struct rte_flow_error *error);\n+int mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,\n+\t\t\t\t   uint64_t last_item,\n+\t\t\t\t   const struct rte_flow_item *geneve_item,\n+\t\t\t\t   struct rte_eth_dev *dev,\n+\t\t\t\t   struct rte_flow_error *error);\n int mlx5_flow_validate_item_ecpri(const struct rte_flow_item *item,\n \t\t\t\t  uint64_t item_flags,\n \t\t\t\t  uint64_t last_item,\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex 0a657cea41..ba10b7c706 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -5237,6 +5237,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,\n \tuint16_t ether_type = 0;\n \tint actions_n = 0;\n \tuint8_t item_ipv6_proto = 0;\n+\tconst struct rte_flow_item *geneve_item = NULL;\n \tconst struct rte_flow_item *gre_item = NULL;\n \tconst struct rte_flow_action_raw_decap *decap;\n \tconst struct rte_flow_action_raw_encap *encap;\n@@ -5518,8 +5519,19 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *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\tgeneve_item = items;\n \t\t\tlast_item = MLX5_FLOW_LAYER_GENEVE;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_GENEVE_OPT:\n+\t\t\tret = mlx5_flow_validate_item_geneve_opt(items,\n+\t\t\t\t\t\t\t\t last_item,\n+\t\t\t\t\t\t\t\t geneve_item,\n+\t\t\t\t\t\t\t\t dev,\n+\t\t\t\t\t\t\t\t error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tlast_item = MLX5_FLOW_LAYER_GENEVE_OPT;\n+\t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_MPLS:\n \t\t\tret = mlx5_flow_validate_item_mpls(dev, items,\n \t\t\t\t\t\t\t   item_flags,\n",
    "prefixes": [
        "v6",
        "7/9"
    ]
}