get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 47666,
    "url": "http://patches.dpdk.org/api/patches/47666/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1541074741-41368-7-git-send-email-viacheslavo@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": "<1541074741-41368-7-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1541074741-41368-7-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-11-01T12:19:27",
    "name": "[v3,06/13] net/mlx5: add e-switch VXLAN support to validation routine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "3d44ddd2a0d1b2c4fdb002fc6cd2b1c3d054260a",
    "submitter": {
        "id": 1102,
        "url": "http://patches.dpdk.org/api/people/1102/?format=api",
        "name": "Slava Ovsiienko",
        "email": "viacheslavo@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/1541074741-41368-7-git-send-email-viacheslavo@mellanox.com/mbox/",
    "series": [
        {
            "id": 2204,
            "url": "http://patches.dpdk.org/api/series/2204/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=2204",
            "date": "2018-11-01T12:19:21",
            "name": "net/mlx5: e-switch VXLAN encap/decap hardware offload",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/2204/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/47666/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/47666/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 2CA901B1EA;\n\tThu,  1 Nov 2018 13:19:36 +0100 (CET)",
            "from EUR01-VE1-obe.outbound.protection.outlook.com\n\t(mail-ve1eur01on0042.outbound.protection.outlook.com [104.47.1.42])\n\tby dpdk.org (Postfix) with ESMTP id DC3841B120\n\tfor <dev@dpdk.org>; Thu,  1 Nov 2018 13:19:29 +0100 (CET)",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com (10.171.186.150) by\n\tAM4PR05MB3505.eurprd05.prod.outlook.com (10.171.188.10) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1294.24; Thu, 1 Nov 2018 12:19:28 +0000",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::544b:a68d:e6a5:ba6e]) by\n\tAM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::544b:a68d:e6a5:ba6e%2]) with mapi id 15.20.1273.030;\n\tThu, 1 Nov 2018 12:19:28 +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=lN9hptXDMSt2Fsu/51j2xFQCDI887aPmov2b/5+fAEo=;\n\tb=vsynT8ic5wpzIFXmUQ1W46asn/zqPzeB6O7zmbdny+VOKUyH70Vw36HTwgbVlWnPariws6s0sR1PtqtC1uvassJaij3U/HP6pZGlR/tgMl5WIiKOe3BysSlL52XDIfqQ2JmZFjeU+ugJKTCLHPyWGYLpT58Uo3d3axQVY0CAoGA=",
        "From": "Slava Ovsiienko <viacheslavo@mellanox.com>",
        "To": "Shahaf Shuler <shahafs@mellanox.com>",
        "CC": "\"dev@dpdk.org\" <dev@dpdk.org>, Yongseok Koh <yskoh@mellanox.com>, Slava\n\tOvsiienko <viacheslavo@mellanox.com>",
        "Thread-Topic": "[PATCH v3 06/13] net/mlx5: add e-switch VXLAN support to\n\tvalidation routine",
        "Thread-Index": "AQHUcd0ieAYvwNeW/kqdQr1VoS51pg==",
        "Date": "Thu, 1 Nov 2018 12:19:27 +0000",
        "Message-ID": "<1541074741-41368-7-git-send-email-viacheslavo@mellanox.com>",
        "References": "<1539612815-47199-1-git-send-email-viacheslavo@mellanox.com>\n\t<1541074741-41368-1-git-send-email-viacheslavo@mellanox.com>",
        "In-Reply-To": "<1541074741-41368-1-git-send-email-viacheslavo@mellanox.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "LO2P265CA0079.GBRP265.PROD.OUTLOOK.COM\n\t(2603:10a6:600:8::19) To AM4PR05MB3265.eurprd05.prod.outlook.com\n\t(2603:10a6:205:4::22)",
        "authentication-results": "spf=none (sender IP is )\n\tsmtp.mailfrom=viacheslavo@mellanox.com; ",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-originating-ip": "[37.142.13.130]",
        "x-ms-publictraffictype": "Email",
        "x-microsoft-exchange-diagnostics": "1; AM4PR05MB3505;\n\t6:uyWDgw4i6PiE4XY91qYAjnOOxt7FEatBaF1xzocSFaPeCfVg/OJa+1Pl98Z1dn86W/DE+HXLhvL+OZKwa+7PIxncVt8uXb9ElCxi00eEy5y1jEGtXDR6xD7L0j8TkBCsSQB7uFZwW7ynZ7vYhYoCJSgp4uHY+7t7EDFpK71/XyjVkN0lO09jGHni5PQjWEwjfhwl6Rws5S26uywbOV+6KWaV4wnjV0osGcI4v25p6HQqTfunMol5XHQIlA1oJl6YXGFzTHsoB/NYQ42t0xad9QZV7MRPIp9wfCjLW2RXrOm8ypspf/qkozQa54H4ifD1nYCrDMKduOLG+5Il8gtMjdp0+qDoeRCBgiFAalbMRqoWBB0MkubfTO5dVtuvVyh+lPbph/uM90Joc/y2Dh1tOwmPn8Q8YNW9Q84G2DeoXsRms9v6grzY7RzXMbj4AI5tLladmyexh9BB26WkcB+h3w==;\n\t5:yxMhufDdc1HTTiSMoOeimXk/zphcIXRyVVgIuoTJMyiR/4hdI8qo1vzdF6hqN4zcTzK19CQ7AStlEqxHGlDD2msDysIF8CnSvrVfrERnQxhrq4RH9KwKrp7NUFnIPfhe2HHbRJ+MvT1STXKuEaVbOa60OVPQO/LOn8Vzs/oK4jI=;\n\t7:ZLBWVo7SW+TZ/DrzPWuxRqNx55Kbc27LOizhFL8AijJnng3V/H0YdzVIi7ZRLRDwjExjSY+5Cu/o1otvdrpFjNWzYvTyst/LvMn4da1zqfOY9zXtH73ZeqZrq8+6bJoqdVe01FFgXHXsRkFydJAtvQ==",
        "x-ms-office365-filtering-correlation-id": "d0bbf46d-5f89-4c68-713d-08d63ff44490",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:AM4PR05MB3505; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB3505:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB35051939D497758BC1F14000D2CE0@AM4PR05MB3505.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)(3231382)(944501410)(52105095)(3002001)(10201501046)(93006095)(93001095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123560045)(20161123564045)(20161123558120)(201708071742011)(7699051)(76991095);\n\tSRVR:AM4PR05MB3505; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB3505; ",
        "x-forefront-prvs": "0843C17679",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(346002)(396003)(376002)(366004)(136003)(39860400002)(199004)(189003)(7736002)(4744004)(6506007)(386003)(486006)(14444005)(52116002)(76176011)(256004)(4326008)(36756003)(25786009)(8676002)(66066001)(81156014)(81166006)(5250100002)(99286004)(14454004)(6436002)(107886003)(6512007)(5660300001)(478600001)(53936002)(53946003)(68736007)(26005)(86362001)(102836004)(97736004)(305945005)(6636002)(2900100001)(6486002)(8936002)(71190400001)(71200400001)(316002)(2906002)(476003)(3846002)(6116002)(186003)(11346002)(54906003)(105586002)(446003)(2616005)(106356001)(6862004)(37006003)(559001)(579004);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3505;\n\tH:AM4PR05MB3265.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": "zbEADGOPmKRNerR34pCQL9xUdWgHn9Cg49YunE56JOdrjt0clnqSaob4pF1BnobEXhdCDVBPUyGHu15GAxTdwj0Y83pTawFdyRte0RdPaOrHmfwK9Qh8sNUW4mqmVACzagb5/Bf9EBcsgZJ+rYrBJYYF7jRcXkjRhk+x+yy048QecQDUe19hWuDBH69HeTuwO5rttnYZRPdoO6ts0V6nzMGaHThbYLJakUArhGhjRYV5JImqQdFVJSj/YuQYleFam3TNZEoDPMIQOgpG7AlwkeHGjtubJ4CPrX4fu0NXe5X6Fl/aCi0/DSpIGtq491XnHyXUCnC3MrMREJ3vaBaBg32ZBM+KcMmr9kjTydV5Z5g=",
        "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": "d0bbf46d-5f89-4c68-713d-08d63ff44490",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "01 Nov 2018 12:19:27.9234\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB3505",
        "Subject": "[dpdk-dev] [PATCH v3 06/13] net/mlx5: add e-switch VXLAN support to\n\tvalidation routine",
        "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 patch adds VXLAN support for flow item/action lists validation.\nThe following entities are now supported:\n\n- RTE_FLOW_ITEM_TYPE_VXLAN, contains the tunnel VNI\n\n- RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, if this action is specified\n  the items in the flow items list treated as outer  network\n  parameters for tunnel outer header match. The ethernet layer\n  addresses always are treated as inner ones.\n\n- RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP, contains the item list to\n  build the encapsulation header. In current implementation the\n  values is the subject for some constraints:\n    - outer source MAC address will be always unconditionally\n      set to the one of MAC addresses of outer egress interface\n    - no way to specify source UDP port\n    - all abovementioned parameters are ignored if specified\n      in the rule, warning messages are sent to the log\n\nMinimal tunneling support is also added. If VXLAN decapsulation\naction is specified the ETH item can follow the VXLAN VNI item,\nthe content of this ETH item is treated as inner MAC addresses\nand type. The outer ETH item for VXLAN decapsulation action\nis always ignored.\n\nSuggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5_flow_tcf.c | 741 ++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 739 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex 50f3bd1..7e00232 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -1116,6 +1116,633 @@ struct pedit_parser {\n }\n \n /**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_ETH item for E-Switch.\n+ * The routine checks the L2 fields to be used in encapsulation header.\n+ *\n+ * @param[in] item\n+ *   Pointer to the item structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap_eth(const struct rte_flow_item *item,\n+\t\t\t\t  struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_eth *spec = item->spec;\n+\tconst struct rte_flow_item_eth *mask = item->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for L2 addresses can be empty\n+\t\t * because these ones are optional and not\n+\t\t * required directly by tc rule. Kernel tries\n+\t\t * to resolve these ones on its own\n+\t\t */\n+\t\treturn 0;\n+\tif (!mask)\n+\t\t/* If mask is not specified use the default one. */\n+\t\tmask = &rte_flow_item_eth_mask;\n+\tif (memcmp(&mask->dst,\n+\t\t   &flow_tcf_mask_empty.eth.dst,\n+\t\t   sizeof(flow_tcf_mask_empty.eth.dst))) {\n+\t\tif (memcmp(&mask->dst,\n+\t\t\t   &rte_flow_item_eth_mask.dst,\n+\t\t\t   sizeof(rte_flow_item_eth_mask.dst)))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"eth.dst\\\" field\");\n+\t}\n+\tif (memcmp(&mask->src,\n+\t\t   &flow_tcf_mask_empty.eth.src,\n+\t\t   sizeof(flow_tcf_mask_empty.eth.src))) {\n+\t\tif (memcmp(&mask->src,\n+\t\t\t   &rte_flow_item_eth_mask.src,\n+\t\t\t   sizeof(rte_flow_item_eth_mask.src)))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"eth.src\\\" field\");\n+\t}\n+\tif (mask->type != RTE_BE16(0x0000)) {\n+\t\tif (mask->type != RTE_BE16(0xffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"eth.type\\\" field\");\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"outer ethernet type field\"\n+\t\t\t\" cannot be forced for vxlan\"\n+\t\t\t\" encapsulation, parameter ignored\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_IPV4 item for E-Switch.\n+ * The routine checks the IPv4 fields to be used in encapsulation header.\n+ *\n+ * @param[in] item\n+ *   Pointer to the item structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap_ipv4(const struct rte_flow_item *item,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_ipv4 *spec = item->spec;\n+\tconst struct rte_flow_item_ipv4 *mask = item->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for IP addresses cannot be empty\n+\t\t * because it is required by tunnel_key parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"NULL outer ipv4 address specification\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_ipv4_mask;\n+\tif (mask->hdr.dst_addr != RTE_BE32(0x00000000)) {\n+\t\tif (mask->hdr.dst_addr != RTE_BE32(0xffffffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"ipv4.hdr.dst_addr\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\t/* More IPv4 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination IP address to determine\n+\t\t * the routing path and obtain the MAC destination\n+\t\t * address, so IP destination address must be\n+\t\t * specified in the tc rule.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer ipv4 destination address must be\"\n+\t\t\t\t \" specified for vxlan encapsulation\");\n+\t}\n+\tif (mask->hdr.src_addr != RTE_BE32(0x00000000)) {\n+\t\tif (mask->hdr.src_addr != RTE_BE32(0xffffffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"ipv4.hdr.src_addr\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\t/* More IPv4 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the source IP address to select the\n+\t\t * interface for egress encapsulated traffic, so\n+\t\t * it must be specified in the tc rule.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer ipv4 source address must be\"\n+\t\t\t\t \" specified for vxlan encapsulation\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_IPV6 item for E-Switch.\n+ * The routine checks the IPv6 fields to be used in encapsulation header.\n+ *\n+ * @param[in] item\n+ *   Pointer to the item structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap_ipv6(const struct rte_flow_item *item,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_ipv6 *spec = item->spec;\n+\tconst struct rte_flow_item_ipv6 *mask = item->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for IP addresses cannot be empty\n+\t\t * because it is required by tunnel_key parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"NULL outer ipv6 address specification\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_ipv6_mask;\n+\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t   &flow_tcf_mask_empty.ipv6.hdr.dst_addr,\n+\t\t   IPV6_ADDR_LEN)) {\n+\t\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t\t   &rte_flow_item_ipv6_mask.hdr.dst_addr,\n+\t\t\t   IPV6_ADDR_LEN))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"ipv6.hdr.dst_addr\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\t/* More IPv6 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination IP address to determine\n+\t\t * the routing path and obtain the MAC destination\n+\t\t * address (heigh or gate), so IP destination address\n+\t\t * must be specified within the tc rule.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer ipv6 destination address must be\"\n+\t\t\t\t \" specified for vxlan encapsulation\");\n+\t}\n+\tif (memcmp(&mask->hdr.src_addr,\n+\t\t   &flow_tcf_mask_empty.ipv6.hdr.src_addr,\n+\t\t   IPV6_ADDR_LEN)) {\n+\t\tif (memcmp(&mask->hdr.src_addr,\n+\t\t\t   &rte_flow_item_ipv6_mask.hdr.src_addr,\n+\t\t\t   IPV6_ADDR_LEN))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"ipv6.hdr.src_addr\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\t/* More L3 address validation can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the source IP address to select the\n+\t\t * interface for egress encapsulated traffic, so\n+\t\t * it must be specified in the tc rule.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer L3 source address must be\"\n+\t\t\t\t \" specified for vxlan encapsulation\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_UDP item for E-Switch.\n+ * The routine checks the UDP fields to be used in encapsulation header.\n+ *\n+ * @param[in] item\n+ *   Pointer to the item structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap_udp(const struct rte_flow_item *item,\n+\t\t\t\t  struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_udp *spec = item->spec;\n+\tconst struct rte_flow_item_udp *mask = item->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for UDP ports cannot be empty\n+\t\t * because it is required by tunnel_key parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"NULL UDP port specification \"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_udp_mask;\n+\tif (mask->hdr.dst_port != RTE_BE16(0x0000)) {\n+\t\tif (mask->hdr.dst_port != RTE_BE16(0xffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"udp.hdr.dst_port\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\tif (!spec->hdr.dst_port)\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer UDP remote port cannot be\"\n+\t\t\t\t \" 0 for vxlan encapsulation\");\n+\t} else {\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"outer UDP remote port must be\"\n+\t\t\t\t \" specified for vxlan encapsulation\");\n+\t}\n+\tif (mask->hdr.src_port != RTE_BE16(0x0000)) {\n+\t\tif (mask->hdr.src_port != RTE_BE16(0xffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t \" \\\"udp.hdr.src_port\\\" field\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"outer UDP source port cannot be\"\n+\t\t\t\" forced for vxlan encapsulation,\"\n+\t\t\t\" parameter ignored\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_VXLAN item for E-Switch.\n+ * The routine checks the VNIP fields to be used in encapsulation header.\n+ *\n+ * @param[in] item\n+ *   Pointer to the item structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap_vni(const struct rte_flow_item *item,\n+\t\t\t\t  struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_vxlan *spec = item->spec;\n+\tconst struct rte_flow_item_vxlan *mask = item->mask;\n+\n+\tif (!spec)\n+\t\t/* Outer VNI is required by tunnel_key parameter. */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t \"NULL VNI specification\"\n+\t\t\t\t \" for vxlan encapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_vxlan_mask;\n+\tif (!mask->vni[0] && !mask->vni[1] && !mask->vni[2])\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\t  \"outer VNI must be specified \"\n+\t\t\t\t\t  \"for vxlan encapsulation\");\n+\tif (mask->vni[0] != 0xff ||\n+\t    mask->vni[1] != 0xff ||\n+\t    mask->vni[2] != 0xff)\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t  \"no support for partial mask on\"\n+\t\t\t\t\t  \" \\\"vxlan.vni\\\" field\");\n+\n+\tif (!spec->vni[0] && !spec->vni[1] && !spec->vni[2])\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\t  \"vxlan vni cannot be 0\");\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action item list for E-Switch.\n+ * The routine checks items to be used in encapsulation header.\n+ *\n+ * @param[in] action\n+ *   Pointer to the VXLAN_ENCAP action structure.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_encap(const struct rte_flow_action *action,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item *items;\n+\tint ret;\n+\tuint32_t item_flags = 0;\n+\n+\tif (!action->conf)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t action, \"Missing vxlan tunnel\"\n+\t\t\t\t \" action configuration\");\n+\titems = ((const struct rte_flow_action_vxlan_encap *)\n+\t\t\t\t\taction->conf)->definition;\n+\tif (!items)\n+\t\treturn rte_flow_error_set\n+\t\t\t(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t action, \"Missing vxlan tunnel\"\n+\t\t\t\t \" encapsulation parameters\");\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\tret = mlx5_flow_validate_item_eth(items, item_flags,\n+\t\t\t\t\t\t\t  error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tret = flow_tcf_validate_vxlan_encap_eth(items, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L2;\n+\t\t\tbreak;\n+\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n+\t\t\tret = mlx5_flow_validate_item_ipv4(items, item_flags,\n+\t\t\t\t\t\t\t   error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tret = flow_tcf_validate_vxlan_encap_ipv4(items, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV4;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n+\t\t\tret = mlx5_flow_validate_item_ipv6(items, item_flags,\n+\t\t\t\t\t\t\t   error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tret = flow_tcf_validate_vxlan_encap_ipv6(items, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV6;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n+\t\t\tret = mlx5_flow_validate_item_udp(items, item_flags,\n+\t\t\t\t\t\t\t   0xFF, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tret = flow_tcf_validate_vxlan_encap_udp(items, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L4_UDP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tret = mlx5_flow_validate_item_vxlan(items,\n+\t\t\t\t\t\t\t    item_flags, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tret = flow_tcf_validate_vxlan_encap_vni(items, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_VXLAN;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, items,\n+\t\t\t\t\t  \"vxlan encap item not supported\");\n+\t\t}\n+\t}\n+\tif (!(item_flags & MLX5_FLOW_LAYER_OUTER_L3))\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, action,\n+\t\t\t\t\t  \"no outer IP layer found\"\n+\t\t\t\t\t  \" for vxlan encapsulation\");\n+\tif (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP))\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, action,\n+\t\t\t\t\t  \"no outer UDP layer found\"\n+\t\t\t\t\t  \" for vxlan encapsulation\");\n+\tif (!(item_flags & MLX5_FLOW_LAYER_VXLAN))\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, action,\n+\t\t\t\t\t  \"no VXLAN VNI found\"\n+\t\t\t\t\t  \" for vxlan encapsulation\");\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate RTE_FLOW_ITEM_TYPE_IPV4 item if VXLAN_DECAP action\n+ * is present in actions list.\n+ *\n+ * @param[in] ipv4\n+ *   Outer IPv4 address item (if any, NULL otherwise).\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_decap_ipv4(const struct rte_flow_item *ipv4,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_ipv4 *spec = ipv4->spec;\n+\tconst struct rte_flow_item_ipv4 *mask = ipv4->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for IP addresses cannot be empty\n+\t\t * because it is required as decap parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, ipv4,\n+\t\t\t\t\t  \"NULL outer ipv4 address\"\n+\t\t\t\t\t  \" specification for vxlan\"\n+\t\t\t\t\t  \" for vxlan decapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_ipv4_mask;\n+\tif (mask->hdr.dst_addr != RTE_BE32(0x00000000)) {\n+\t\tif (mask->hdr.dst_addr != RTE_BE32(0xffffffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t\t \" \\\"ipv4.hdr.dst_addr\\\" field\");\n+\t\t/* More IP address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination IP address\n+\t\t * to determine the ingress network interface\n+\t\t * for traffic being decapsulated.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, ipv4,\n+\t\t\t\t\t  \"outer ipv4 destination address\"\n+\t\t\t\t\t  \" must be specified for\"\n+\t\t\t\t\t  \" vxlan decapsulation\");\n+\t}\n+\t/* Source IP address is optional for decap. */\n+\tif (mask->hdr.src_addr != RTE_BE32(0x00000000) &&\n+\t    mask->hdr.src_addr != RTE_BE32(0xffffffff))\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t  \"no support for partial mask on\"\n+\t\t\t\t\t  \" \\\"ipv4.hdr.src_addr\\\" field\");\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate RTE_FLOW_ITEM_TYPE_IPV6 item if VXLAN_DECAP action\n+ * is present in actions list.\n+ *\n+ * @param[in] ipv6\n+ *   Outer IPv6 address item (if any, NULL otherwise).\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_decap_ipv6(const struct rte_flow_item *ipv6,\n+\t\t\t\t   struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_ipv6 *spec = ipv6->spec;\n+\tconst struct rte_flow_item_ipv6 *mask = ipv6->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for IP addresses cannot be empty\n+\t\t * because it is required as decap parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, ipv6,\n+\t\t\t\t\t  \"NULL outer ipv6 address\"\n+\t\t\t\t\t  \" specification for vxlan\"\n+\t\t\t\t\t  \" decapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_ipv6_mask;\n+\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t   &flow_tcf_mask_empty.ipv6.hdr.dst_addr,\n+\t\t   IPV6_ADDR_LEN)) {\n+\t\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t\t&rte_flow_item_ipv6_mask.hdr.dst_addr,\n+\t\t\tIPV6_ADDR_LEN))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t  \"no support for partial mask on\"\n+\t\t\t\t\t  \" \\\"ipv6.hdr.dst_addr\\\" field\");\n+\t\t/* More IP address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination IP address\n+\t\t * to determine the ingress network interface\n+\t\t * for traffic being decapsulated.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, ipv6,\n+\t\t\t\t\t  \"outer ipv6 destination address must be \"\n+\t\t\t\t\t  \"specified for vxlan decapsulation\");\n+\t}\n+\t/* Source IP address is optional for decap. */\n+\tif (memcmp(&mask->hdr.src_addr,\n+\t\t   &flow_tcf_mask_empty.ipv6.hdr.src_addr,\n+\t\t   IPV6_ADDR_LEN)) {\n+\t\tif (memcmp(&mask->hdr.src_addr,\n+\t\t\t   &rte_flow_item_ipv6_mask.hdr.src_addr,\n+\t\t\t   IPV6_ADDR_LEN))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\"no support for partial mask on\"\n+\t\t\t\t\" \\\"ipv6.hdr.src_addr\\\" field\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate RTE_FLOW_ITEM_TYPE_UDP item if VXLAN_DECAP action\n+ * is present in actions list.\n+ *\n+ * @param[in] udp\n+ *   Outer UDP layer item (if any, NULL otherwise).\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_ernno is set.\n+ **/\n+static int\n+flow_tcf_validate_vxlan_decap_udp(const struct rte_flow_item *udp,\n+\t\t\t\t  struct rte_flow_error *error)\n+{\n+\tconst struct rte_flow_item_udp *spec = udp->spec;\n+\tconst struct rte_flow_item_udp *mask = udp->mask;\n+\n+\tif (!spec)\n+\t\t/*\n+\t\t * Specification for UDP ports cannot be empty\n+\t\t * because it is required as decap parameter.\n+\t\t */\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, udp,\n+\t\t\t\t\t  \"NULL UDP port specification\"\n+\t\t\t\t\t  \" for VXLAN decapsulation\");\n+\tif (!mask)\n+\t\tmask = &rte_flow_item_udp_mask;\n+\tif (mask->hdr.dst_port != RTE_BE16(0x0000)) {\n+\t\tif (mask->hdr.dst_port != RTE_BE16(0xffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t\t \" \\\"udp.hdr.dst_port\\\" field\");\n+\t\tif (!spec->hdr.dst_port)\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, udp,\n+\t\t\t\t\t \"zero decap local UDP port\");\n+\t} else {\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, udp,\n+\t\t\t\t\t  \"outer UDP destination port must be \"\n+\t\t\t\t\t  \"specified for vxlan decapsulation\");\n+\t}\n+\tif (mask->hdr.src_port != RTE_BE16(0x0000)) {\n+\t\tif (mask->hdr.src_port != RTE_BE16(0xffff))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK, mask,\n+\t\t\t\t\t \"no support for partial mask on\"\n+\t\t\t\t\t \" \\\"udp.hdr.src_port\\\" field\");\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"outer UDP local port cannot be \"\n+\t\t\t\"forced for VXLAN encapsulation, \"\n+\t\t\t\"parameter ignored\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n  * Validate flow for E-Switch.\n  *\n  * @param[in] priv\n@@ -1147,6 +1774,7 @@ struct pedit_parser {\n \t\tconst struct rte_flow_item_ipv6 *ipv6;\n \t\tconst struct rte_flow_item_tcp *tcp;\n \t\tconst struct rte_flow_item_udp *udp;\n+\t\tconst struct rte_flow_item_vxlan *vxlan;\n \t} spec, mask;\n \tunion {\n \t\tconst struct rte_flow_action_port_id *port_id;\n@@ -1156,6 +1784,7 @@ struct pedit_parser {\n \t\t\tof_set_vlan_vid;\n \t\tconst struct rte_flow_action_of_set_vlan_pcp *\n \t\t\tof_set_vlan_pcp;\n+\t\tconst struct rte_flow_action_vxlan_encap *vxlan_encap;\n \t\tconst struct rte_flow_action_set_ipv4 *set_ipv4;\n \t\tconst struct rte_flow_action_set_ipv6 *set_ipv6;\n \t} conf;\n@@ -1242,6 +1871,15 @@ struct pedit_parser {\n \t\t\t\t\t \" set action must follow push action\");\n \t\t\tcurrent_action_flag = MLX5_FLOW_ACTION_OF_SET_VLAN_PCP;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\tcurrent_action_flag = MLX5_FLOW_ACTION_VXLAN_DECAP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\t\tret = flow_tcf_validate_vxlan_encap(actions, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\tcurrent_action_flag = MLX5_FLOW_ACTION_VXLAN_ENCAP;\n+\t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:\n \t\t\tcurrent_action_flag = MLX5_FLOW_ACTION_SET_IPV4_SRC;\n \t\t\tbreak;\n@@ -1302,11 +1940,32 @@ struct pedit_parser {\n \t\t\t\t\t\t  actions,\n \t\t\t\t\t\t  \"can't have multiple fate\"\n \t\t\t\t\t\t  \" actions\");\n+\t\tif ((current_action_flag & MLX5_TCF_VXLAN_ACTIONS) &&\n+\t\t    (action_flags & MLX5_TCF_VXLAN_ACTIONS))\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  actions,\n+\t\t\t\t\t\t  \"can't have multiple vxlan\"\n+\t\t\t\t\t\t  \" actions\");\n+\t\tif ((current_action_flag & MLX5_TCF_VXLAN_ACTIONS) &&\n+\t\t    (action_flags & MLX5_TCF_VLAN_ACTIONS))\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  actions,\n+\t\t\t\t\t\t  \"can't have vxlan and vlan\"\n+\t\t\t\t\t\t  \" actions in the same rule\");\n \t\taction_flags |= current_action_flag;\n \t}\n \tfor (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {\n \t\tunsigned int i;\n \n+\t\tif ((item_flags & MLX5_FLOW_LAYER_TUNNEL) &&\n+\t\t    items->type != RTE_FLOW_ITEM_TYPE_ETH)\n+\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t\t  items,\n+\t\t\t\t\t\t  \"only L2 inner item\"\n+\t\t\t\t\t\t  \" is supported\");\n \t\tswitch (items->type) {\n \t\tcase RTE_FLOW_ITEM_TYPE_VOID:\n \t\t\tbreak;\n@@ -1360,7 +2019,9 @@ struct pedit_parser {\n \t\t\t\t\t\t\t  error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n-\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L2;\n+\t\t\titem_flags |= (item_flags & MLX5_FLOW_LAYER_TUNNEL) ?\n+\t\t\t\t\tMLX5_FLOW_LAYER_INNER_L2 :\n+\t\t\t\t\tMLX5_FLOW_LAYER_OUTER_L2;\n \t\t\t/* TODO:\n \t\t\t * Redundant check due to different supported mask.\n \t\t\t * Same for the rest of items.\n@@ -1438,6 +2099,12 @@ struct pedit_parser {\n \t\t\t\tnext_protocol =\n \t\t\t\t\t((const struct rte_flow_item_ipv4 *)\n \t\t\t\t\t (items->spec))->hdr.next_proto_id;\n+\t\t\tif (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) {\n+\t\t\t\tret = flow_tcf_validate_vxlan_decap_ipv4\n+\t\t\t\t\t\t\t\t(items, error);\n+\t\t\t\tif (ret < 0)\n+\t\t\t\t\treturn ret;\n+\t\t\t}\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n \t\t\tret = mlx5_flow_validate_item_ipv6(items, item_flags,\n@@ -1465,6 +2132,12 @@ struct pedit_parser {\n \t\t\t\tnext_protocol =\n \t\t\t\t\t((const struct rte_flow_item_ipv6 *)\n \t\t\t\t\t (items->spec))->hdr.proto;\n+\t\t\tif (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) {\n+\t\t\t\tret = flow_tcf_validate_vxlan_decap_ipv6\n+\t\t\t\t\t\t\t\t(items, error);\n+\t\t\t\tif (ret < 0)\n+\t\t\t\t\treturn ret;\n+\t\t\t}\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n \t\t\tret = mlx5_flow_validate_item_udp(items, item_flags,\n@@ -1480,6 +2153,12 @@ struct pedit_parser {\n \t\t\t\t error);\n \t\t\tif (!mask.udp)\n \t\t\t\treturn -rte_errno;\n+\t\t\tif (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) {\n+\t\t\t\tret = flow_tcf_validate_vxlan_decap_udp\n+\t\t\t\t\t\t\t\t(items, error);\n+\t\t\t\tif (ret < 0)\n+\t\t\t\t\treturn ret;\n+\t\t\t}\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_TCP:\n \t\t\tret = mlx5_flow_validate_item_tcp\n@@ -1499,10 +2178,40 @@ struct pedit_parser {\n \t\t\tif (!mask.tcp)\n \t\t\t\treturn -rte_errno;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tif (!(action_flags & RTE_FLOW_ACTION_TYPE_VXLAN_DECAP))\n+\t\t\t\treturn rte_flow_error_set\n+\t\t\t\t\t(error, ENOTSUP,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t\t items,\n+\t\t\t\t\t \"vni pattern should be followed by\"\n+\t\t\t\t\t \" vxlan decapsulation action\");\n+\t\t\tret = mlx5_flow_validate_item_vxlan(items,\n+\t\t\t\t\t\t\t    item_flags, error);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn ret;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_VXLAN;\n+\t\t\tmask.vxlan = flow_tcf_item_mask\n+\t\t\t\t(items, &rte_flow_item_vxlan_mask,\n+\t\t\t\t &flow_tcf_mask_supported.vxlan,\n+\t\t\t\t &flow_tcf_mask_empty.vxlan,\n+\t\t\t\t sizeof(flow_tcf_mask_supported.vxlan), error);\n+\t\t\tif (!mask.vxlan)\n+\t\t\t\treturn -rte_errno;\n+\t\t\tif (mask.vxlan->vni[0] != 0xff ||\n+\t\t\t    mask.vxlan->vni[1] != 0xff ||\n+\t\t\t    mask.vxlan->vni[2] != 0xff)\n+\t\t\t\treturn rte_flow_error_set\n+\t\t\t\t\t(error, ENOTSUP,\n+\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM_MASK,\n+\t\t\t\t\t mask.vxlan,\n+\t\t\t\t\t \"no support for partial or \"\n+\t\t\t\t\t \"empty mask on \\\"vxlan.vni\\\" field\");\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-\t\t\t\t\t\t  NULL, \"item not supported\");\n+\t\t\t\t\t\t  items, \"item not supported\");\n \t\t}\n \t}\n \tif ((action_flags & MLX5_TCF_PEDIT_ACTIONS) &&\n@@ -1571,6 +2280,12 @@ struct pedit_parser {\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, actions,\n \t\t\t\t\t  \"vlan actions are supported\"\n \t\t\t\t\t  \" only with port_id action\");\n+\tif ((action_flags & MLX5_TCF_VXLAN_ACTIONS) &&\n+\t    !(action_flags & MLX5_FLOW_ACTION_PORT_ID))\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t  \"vxlan actions are supported\"\n+\t\t\t\t\t  \" only with port_id action\");\n \tif (!(action_flags & MLX5_TCF_FATE_ACTIONS))\n \t\treturn rte_flow_error_set(error, EINVAL,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, actions,\n@@ -1594,6 +2309,28 @@ struct pedit_parser {\n \t\t\t\t\t\t  \"no ethernet found in\"\n \t\t\t\t\t\t  \" pattern\");\n \t}\n+\tif (action_flags & MLX5_FLOW_ACTION_VXLAN_DECAP) {\n+\t\tif (!(item_flags &\n+\t\t     (MLX5_FLOW_LAYER_OUTER_L3_IPV4 |\n+\t\t      MLX5_FLOW_LAYER_OUTER_L3_IPV6)))\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  NULL,\n+\t\t\t\t\t\t  \"no outer IP pattern found\"\n+\t\t\t\t\t\t  \" for vxlan decap action\");\n+\t\tif (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP))\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  NULL,\n+\t\t\t\t\t\t  \"no outer UDP pattern found\"\n+\t\t\t\t\t\t  \" for vxlan decap action\");\n+\t\tif (!(item_flags & MLX5_FLOW_LAYER_VXLAN))\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t  NULL,\n+\t\t\t\t\t\t  \"no VNI pattern found\"\n+\t\t\t\t\t\t  \" for vxlan decap action\");\n+\t}\n \treturn 0;\n }\n \n",
    "prefixes": [
        "v3",
        "06/13"
    ]
}