get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41725,
    "url": "http://patches.dpdk.org/api/patches/41725/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20180627173355.4718-5-adrien.mazarguil@6wind.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": "<20180627173355.4718-5-adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180627173355.4718-5-adrien.mazarguil@6wind.com",
    "date": "2018-06-27T18:08:16",
    "name": "[4/6] net/mlx5: add L2-L4 pattern items to switch flow rules",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4c38372636303b4e6e822a82fbc68e7c860f2187",
    "submitter": {
        "id": 165,
        "url": "http://patches.dpdk.org/api/people/165/?format=api",
        "name": "Adrien Mazarguil",
        "email": "adrien.mazarguil@6wind.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20180627173355.4718-5-adrien.mazarguil@6wind.com/mbox/",
    "series": [
        {
            "id": 273,
            "url": "http://patches.dpdk.org/api/series/273/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=273",
            "date": "2018-06-27T18:08:08",
            "name": "net/mlx5: add support for switch flow rules",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/273/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/41725/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/41725/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 55E091C3A6;\n\tWed, 27 Jun 2018 20:08:37 +0200 (CEST)",
            "from mail-wr0-f195.google.com (mail-wr0-f195.google.com\n\t[209.85.128.195]) by dpdk.org (Postfix) with ESMTP id C16621C39B\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 20:08:33 +0200 (CEST)",
            "by mail-wr0-f195.google.com with SMTP id e18-v6so2945716wrs.5\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 11:08:33 -0700 (PDT)",
            "from 6wind.com (host.78.145.23.62.rev.coltfrance.com.\n\t[62.23.145.78]) by smtp.gmail.com with ESMTPSA id\n\tm10-v6sm3468867wrj.35.2018.06.27.11.08.32\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 27 Jun 2018 11:08:32 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:in-reply-to;\n\tbh=BlvwWX0nKitl8LKGfZMpmAt7D6l8wCjYNhZa6UUrEz4=;\n\tb=P3yW1XZ/apPty/boRDdob81RIiGzayrxUgge9EoQB0mOh2DeGlziBxWQenihf8mVFb\n\tMqgEscB0CXR1pjw8yKcZRWqEJtf+2eJRWgZoNcKbB7bw6+7NDnsL0KsjOsQH0o4wYmwZ\n\tRllYJzeQNjS4VfIxXnvzzxvXcicArdHOE5hQfu9D8goTIlEDb/PXMtOxJOq8ngoAgXVR\n\tFBVhUXlXfhq/bVYc1tAvpL0Xutj66NIUwEcNQ2/e4OE27ipCJ3c0Py7AmYi0YECOrvT/\n\tl8bXFqjCnKnfzlKJ1tZkFZ7Rdh5LHOKc/Ix3YRZ8Knn3EW4MTVdvEqQ4Sei6MrA7OmjK\n\tIJUA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:in-reply-to;\n\tbh=BlvwWX0nKitl8LKGfZMpmAt7D6l8wCjYNhZa6UUrEz4=;\n\tb=sKpL9r9xZxfmiGp1SFgU0xancdjg3ATjHMdzFrs54JtwvaABU1+XQxBli1QcqIE7nI\n\tFx1+0xk/iHS2oBjTxecV+/LXzS6RAJPtmGb/va/hDBvAmo0ZjNx7dKBluvDe2eKPQCkF\n\tTDoFuNTzZTSee6oZqYhhItaQyWp18UazaaeuEFZjUh324dZ88hVkGv3PfB1lhWLESht4\n\tAqyeCQQmnqp+BPQDJ/j/zSlDIDoxVSMME7jv5iBA58Y45M6QZsAsX54xq5nCiKiQvfCj\n\tw91K+lyTh8Q5J5td66G1lQ4t2aga0gq/R1UhYciqnbIh6S4AzC8GdDs9W2FUla0MoRGK\n\t3Hkg==",
        "X-Gm-Message-State": "APt69E0EJc0n/TscHuY95u4L7m/bWKAPd0WH7XywpGFDNWjQu8NIV/+/\n\tYTg1XEUbLSCih4xNlgV6AkpchLsL",
        "X-Google-Smtp-Source": "AAOMgpfMsIzw1ypKnHgumPtrmKdO7QHj/PTOQKeQy1Ese10oJ28mf2OJVvBSptKpBrdl1rUeMka7qw==",
        "X-Received": "by 2002:a5d:4d8d:: with SMTP id\n\tb13-v6mr5874803wru.80.1530122913356; \n\tWed, 27 Jun 2018 11:08:33 -0700 (PDT)",
        "Date": "Wed, 27 Jun 2018 20:08:16 +0200",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "Shahaf Shuler <shahafs@mellanox.com>",
        "Cc": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>,\n\tYongseok Koh <yskoh@mellanox.com>, dev@dpdk.org",
        "Message-ID": "<20180627173355.4718-5-adrien.mazarguil@6wind.com>",
        "References": "<20180627173355.4718-1-adrien.mazarguil@6wind.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=us-ascii",
        "Content-Disposition": "inline",
        "In-Reply-To": "<20180627173355.4718-1-adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.11.0",
        "Subject": "[dpdk-dev] [PATCH 4/6] net/mlx5: add L2-L4 pattern items to switch\n\tflow rules",
        "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": "This enables flow rules to explicitly match supported combinations of\nEthernet, IPv4, IPv6, TCP and UDP headers at the switch level.\n\nTestpmd example:\n\n- Dropping TCPv4 traffic with a specific destination on port ID 2:\n\n  flow create 2 ingress transfer pattern eth / ipv4 / tcp dst is 42 / end\n     actions drop / end\n\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\n---\n drivers/net/mlx5/mlx5_nl_flow.c | 397 ++++++++++++++++++++++++++++++++++-\n 1 file changed, 396 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_nl_flow.c b/drivers/net/mlx5/mlx5_nl_flow.c\nindex 70da85fd5..ad1e001c6 100644\n--- a/drivers/net/mlx5/mlx5_nl_flow.c\n+++ b/drivers/net/mlx5/mlx5_nl_flow.c\n@@ -3,6 +3,7 @@\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@@ -12,7 +13,9 @@\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@@ -20,6 +23,7 @@\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@@ -31,6 +35,11 @@ enum mlx5_nl_flow_trans {\n \tATTR,\n \tPATTERN,\n \tITEM_VOID,\n+\tITEM_ETH,\n+\tITEM_IPV4,\n+\tITEM_IPV6,\n+\tITEM_TCP,\n+\tITEM_UDP,\n \tACTIONS,\n \tACTION_VOID,\n \tACTION_PORT_ID,\n@@ -52,8 +61,13 @@ 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(PATTERN_COMMON),\n+\t[PATTERN] = TRANS(ITEM_ETH, PATTERN_COMMON),\n \t[ITEM_VOID] = TRANS(BACK),\n+\t[ITEM_ETH] = 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@@ -61,6 +75,126 @@ static const enum mlx5_nl_flow_trans *const mlx5_nl_flow_trans[] = {\n \t[END] = NULL,\n };\n \n+/** Empty masks for known item types. */\n+static const union {\n+\tstruct rte_flow_item_eth eth;\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_eth eth;\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.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.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@@ -107,6 +241,8 @@ mlx5_nl_flow_transpose(void *buf,\n \tconst struct rte_flow_action *action;\n \tunsigned int n;\n \tuint32_t act_index_cur;\n+\tbool eth_type_set;\n+\tbool ip_proto_set;\n \tstruct nlattr *na_flower;\n \tstruct nlattr *na_flower_act;\n \tconst enum mlx5_nl_flow_trans *trans;\n@@ -119,6 +255,8 @@ mlx5_nl_flow_transpose(void *buf,\n \taction = actions;\n \tn = 0;\n \tact_index_cur = 0;\n+\teth_type_set = false;\n+\tip_proto_set = false;\n \tna_flower = NULL;\n \tna_flower_act = NULL;\n \ttrans = TRANS(ATTR);\n@@ -126,6 +264,13 @@ mlx5_nl_flow_transpose(void *buf,\n trans:\n \tswitch (trans[n++]) {\n \t\tunion {\n+\t\t\tconst struct rte_flow_item_eth *eth;\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} conf;\n \t\tstruct nlmsghdr *nlh;\n@@ -214,6 +359,256 @@ mlx5_nl_flow_transpose(void *buf,\n \t\t\tgoto trans;\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_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 &&\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_IP)))\n+\t\t\tgoto error_nobufs;\n+\t\teth_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 &&\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_IPV6)))\n+\t\t\tgoto error_nobufs;\n+\t\teth_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     mask.tcp->hdr.src_port != RTE_BE16(0xffff)) ||\n+\t\t    (mask.tcp->hdr.dst_port &&\n+\t\t     mask.tcp->hdr.dst_port != 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.tcp,\n+\t\t\t\t \"no support for partial masks on\"\n+\t\t\t\t \" \\\"hdr.src_port\\\" and \\\"hdr.dst_port\\\"\"\n+\t\t\t\t \" fields\");\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     mask.udp->hdr.src_port != RTE_BE16(0xffff)) ||\n+\t\t    (mask.udp->hdr.dst_port &&\n+\t\t     mask.udp->hdr.dst_port != 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.udp,\n+\t\t\t\t \"no support for partial masks on\"\n+\t\t\t\t \" \\\"hdr.src_port\\\" and \\\"hdr.dst_port\\\"\"\n+\t\t\t\t \" fields\");\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",
    "prefixes": [
        "4/6"
    ]
}