get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45802,
    "url": "http://patchwork.dpdk.org/api/patches/45802/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1538461807-37507-3-git-send-email-viacheslavo@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<1538461807-37507-3-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1538461807-37507-3-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-10-02T06:30:38",
    "name": "[3/5] net/mlx5: e-switch VXLAN flow validation routine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4fe55990f05b8822106c408fbf14188f2bed3618",
    "submitter": {
        "id": 1102,
        "url": "http://patchwork.dpdk.org/api/people/1102/?format=api",
        "name": "Slava Ovsiienko",
        "email": "viacheslavo@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patchwork.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/1538461807-37507-3-git-send-email-viacheslavo@mellanox.com/mbox/",
    "series": [
        {
            "id": 1626,
            "url": "http://patchwork.dpdk.org/api/series/1626/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=1626",
            "date": "2018-10-02T06:30:36",
            "name": null,
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/1626/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/45802/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/45802/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 45E894CA6;\n\tTue,  2 Oct 2018 08:30:42 +0200 (CEST)",
            "from EUR01-DB5-obe.outbound.protection.outlook.com\n\t(mail-db5eur01on0078.outbound.protection.outlook.com [104.47.2.78])\n\tby dpdk.org (Postfix) with ESMTP id 9022D4CA2\n\tfor <dev@dpdk.org>; Tue,  2 Oct 2018 08:30:40 +0200 (CEST)",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com (10.171.186.150) by\n\tAM4PR05MB3443.eurprd05.prod.outlook.com (10.171.187.148) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1185.25; Tue, 2 Oct 2018 06:30:38 +0000",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::81a1:b719:2345:50e5]) by\n\tAM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::81a1:b719:2345:50e5%5]) with mapi id 15.20.1185.024;\n\tTue, 2 Oct 2018 06:30:38 +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=HWH7sittDM+MqHJjb7PIUTtodkJWhMCaTQ9t0bIRDIc=;\n\tb=Ic220li8IafP+q/TOyl26QVj4IBuSw9fnZq+SRm3vIWFOUuRseJ6CVaYsbXhkXG2mP5Wzqd1YlwEuMnO7P41Qi4HqitogGWk3NKwVIkwITs6T4nPRqx2+CwZgSOre4tybDCSXTtEYg7RanDS4hOtxLJED6bjTXctz3hrHz3Exuw=",
        "From": "Slava Ovsiienko <viacheslavo@mellanox.com>",
        "To": "\"dev@dpdk.org\" <dev@dpdk.org>",
        "CC": "Shahaf Shuler <shahafs@mellanox.com>, Slava Ovsiienko\n\t<viacheslavo@mellanox.com>",
        "Thread-Topic": "[PATCH 3/5] net/mlx5: e-switch VXLAN flow validation routine",
        "Thread-Index": "AQHUWhlv9c2nk6IFnEC7AZTKZn5zWg==",
        "Date": "Tue, 2 Oct 2018 06:30:38 +0000",
        "Message-ID": "<1538461807-37507-3-git-send-email-viacheslavo@mellanox.com>",
        "References": "<1538461807-37507-1-git-send-email-viacheslavo@mellanox.com>",
        "In-Reply-To": "<1538461807-37507-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": "AM0PR02CA0019.eurprd02.prod.outlook.com\n\t(2603:10a6:208:3e::32) 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; AM4PR05MB3443;\n\t6:uT0sFqKxjgEFbSUHNrT0GD39JI7YyvpKr+ws8KPK6RnLCwMR0V/NxZpMmXSTnHms1TxWc6yU9oUoqQCZi22r47tVPw+raok35mtc6TENrGP1gPFNa+oPDUiE4CqofJSUhQqVRDI447+lvJMNuYyiEP4BY7bO/murJKWzJcJpXaI3Zthd4P3V9C4FMK3mcqgUrxPjOqGJqYsIrxksxR8rksz5hbJuiJEbC+re+lLOU7X1Zo566tw5cXla8/1CsNVKJyVcvYfh9HzJCXvIPRW18i+R/rjeAAuQ4YtZbA+3L7t2hbAjyYZyiB333Z26IXIeFLaDe6kWUVQyFE3IIVLrKGE/tmuG6S5Vct0yfvn9inWJRAY4Zc7YBc1CLf9Ee0yg/wqQdSqtkBq9dAdeBy4Fij3SNQ8ew7+vjsv00R4oltevwcXnoKn2WP1/CSVLW6UoU17lRGKXIlSpRXpwxfqU7w==;\n\t5:7EQVTjyczXoDsFFo/ewOGwxZbdT0InwQY7AfjyV1FPu3MfoyqGrPpN2sNaLdfFuFNT0ylJgUy5diI4uICTA//J//U3l8UR+G1ufF+pFFhpk92TZFTMyuCuxiiZvc6jDNV0OBPFlqqgGagAdnioUDUQYRQYzoIvd7+2IVGo7nBa4=;\n\t7:4VFTyotL+2GvZDvcuvZvLQl32IH4cHBNopGDXrY9uNIDaDLEh6yCx9KfzJn0bYHE8Tq0VaXW1bpsRvu/iaAeRoMP6m6e/WhksOSK8+fjjAAhSXD+P9hWxO8Y1fiIaqoFuDILtA6XY6zagF+AZtX1YqDqOzW0xrjdiuJBs1c7jHv/NU7dTRzXoaSMEUS+jLZYix7q91JD9YHNhA1Jdl4hcKC65o/HiwMtfWiEkWyaLAwJt1PLG+Trqz67WGsPM8iI",
        "x-ms-office365-filtering-correlation-id": "4f0b4fa7-bd60-4b93-0421-08d628309171",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:AM4PR05MB3443; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB3443:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB34433CDC05F7420628E1730FD2E80@AM4PR05MB3443.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)(3231355)(944501410)(52105095)(3002001)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123560045)(20161123558120)(20161123562045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699051);\n\tSRVR:AM4PR05MB3443; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB3443; ",
        "x-forefront-prvs": "0813C68E65",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(396003)(136003)(39860400002)(376002)(366004)(346002)(189003)(199004)(5640700003)(256004)(25786009)(14444005)(26005)(106356001)(54906003)(186003)(316002)(102836004)(68736007)(105586002)(6116002)(3846002)(97736004)(14454004)(81156014)(1730700003)(86362001)(2351001)(2900100001)(8676002)(7736002)(2616005)(8936002)(476003)(305945005)(446003)(11346002)(81166006)(6486002)(52116002)(386003)(6436002)(6506007)(53936002)(2906002)(4326008)(71200400001)(36756003)(478600001)(486006)(99286004)(5250100002)(66066001)(76176011)(5660300001)(6512007)(2501003)(6916009)(53946003)(4744004)(71190400001)(107886003)(579004)(559001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3443;\n\tH:AM4PR05MB3265.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en;\n\tPTR:InfoNoRecords; MX:1; A:1; ",
        "received-spf": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "x-microsoft-antispam-message-info": "4uAcgANfvf0iUmoS9lJtFbK8dt/U2FYzY37UohH6jOSHHun32/LBDyPgifNBORmQ4e1kErVLv2E8jN84jHf11eyzOhGu9++x5BpSuXDK273EdTNTTWu91v7eioFD6NNKz86Xxelnev0hfygh7r4SfFpMhaLh0CRdSDO70hk1SC1Ubnom2b4Q1j8yZKTe3o3ieL6jCOY8dnduh8xiLfO5728mHPTne6yC1L/GIJDhqoD/1fl6V7wrjrX4+x0hywCvirCzMMNqCHYaLybC+Pxarj1O41EFu+1dJv+N5/8qG6AXhRel1Y0ZGgB3CKRLaH2zJwDF1pJ5i3yXQqI/q20Kr/PjFRlwTRIgkPj+5rRSz4Y=",
        "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": "4f0b4fa7-bd60-4b93-0421-08d628309171",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "02 Oct 2018 06:30:38.7511\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB3443",
        "Subject": "[dpdk-dev] [PATCH 3/5] net/mlx5: e-switch VXLAN flow validation\n\troutine",
        "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 part of patchset adds support for flow item/actions lists\nvalidation. The 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\t- outer source IP should coincide with outer egress\n          interface assigned address\n\t- outer source MAC address will be always unconditionally\n\t  set to the one of MAC addresses of outer egress interface\n\t- no way to specify source UDP port\n\t- all abovementioned parameters are ignored if specified\n\t  in the rule, warning messages are sent to the log\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 | 717 ++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 713 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex 15e250c..97451bd 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -558,6 +558,630 @@ struct flow_tcf_ptoi {\n }\n \n /**\n+ * Validate VXLAN_ENCAP action RTE_FLOW_ITEM_TYPE_ETH item for E-Switch.\n+ *\n+ * @param[in] item\n+ *   Pointer to the itemn 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.\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\t/*\n+\t\t * Ethernet addresses are not supported by\n+\t\t * tc as tunnel_key parameters. Destination\n+\t\t * L2 address is needed to form encap packet\n+\t\t * header and retrieved by kernel from implicit\n+\t\t * sources (ARP table, etc), address masks are\n+\t\t * not supported at all.\n+\t\t */\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"outer ethernet destination address \"\n+\t\t\t\"cannot be forced for VXLAN \"\n+\t\t\t\"encapsulation, parameter ignored\");\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\tDRV_LOG(WARNING,\n+\t\t\t\"outer ethernet source address \"\n+\t\t\t\"cannot be forced for VXLAN \"\n+\t\t\t\"encapsulation, parameter ignored\");\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+ *\n+ * @param[in] item\n+ *   Pointer to the itemn 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 L3 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 L3 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/* More L3 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination L3 address to determine\n+\t\t * the routing path and obtain the L2 destination\n+\t\t * address, so L3 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 L3 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/* More L3 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the source L3 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_IPV6 item for E-Switch.\n+ *\n+ * @param[in] item\n+ *   Pointer to the itemn 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 L3 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 L3 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   sizeof(flow_tcf_mask_empty.ipv6.hdr.dst_addr))) {\n+\t\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t   &rte_flow_item_ipv6_mask.hdr.dst_addr,\n+\t\t   sizeof(rte_flow_item_ipv6_mask.hdr.dst_addr)))\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/* More L3 address validations can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the destination L3 address to determine\n+\t\t * the routing path and obtain the L2 destination\n+\t\t * address (heigh or gate), so L3 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 L3 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   sizeof(flow_tcf_mask_empty.ipv6.hdr.src_addr))) {\n+\t\tif (memcmp(&mask->hdr.src_addr,\n+\t\t   &rte_flow_item_ipv6_mask.hdr.src_addr,\n+\t\t   sizeof(rte_flow_item_ipv6_mask.hdr.src_addr)))\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/* More L3 address validation can be put here. */\n+\t} else {\n+\t\t/*\n+\t\t * Kernel uses the source L3 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+ *\n+ * @param[in] item\n+ *   Pointer to the itemn 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\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 \"zero encap remote UDP port\");\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\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+ *\n+ * @param[in] item\n+ *   Pointer to the itemn 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] != 0 ||\n+\t    mask->vni[1] != 0 ||\n+\t    mask->vni[2] != 0) {\n+\t\tif (mask->vni[0] != 0xff ||\n+\t\t    mask->vni[1] != 0xff ||\n+\t\t    mask->vni[2] != 0xff)\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 \" \\\"vxlan.vni\\\" field\");\n+\t\tif (spec->vni[0] == 0 &&\n+\t\t    spec->vni[1] == 0 &&\n+\t\t    spec->vni[2] == 0)\n+\t\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+\t} else {\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM,\n+\t\t\t\t item,\n+\t\t\t\t \"outer VNI must be specified \"\n+\t\t\t\t \"for VXLAN encapsulation\");\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * Validate VXLAN_ENCAP action item list for E-Switch.\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+\tassert(action->type == RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP);\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 L3 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 L4 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 VXLAN_DECAP action outer tunnel items for E-Switch.\n+ *\n+ * @param[in] item_flags\n+ *   Mask of provided outer tunnel parameters\n+ * @param[in] ipv4\n+ *   Outer IPv4 address item (if any, NULL otherwise).\n+ * @param[in] ipv6\n+ *   Outer IPv6 address item (if any, NULL otherwise).\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(uint32_t item_flags,\n+\t\t\t      const struct rte_flow_action *action,\n+\t\t\t      const struct rte_flow_item *ipv4,\n+\t\t\t      const struct rte_flow_item *ipv6,\n+\t\t\t      const struct rte_flow_item *udp,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tif (!ipv4 && !ipv6)\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 L3 layer found\"\n+\t\t\t\t\t  \" for VXLAN decapsulation\");\n+\tif (ipv4) {\n+\t\tconst struct rte_flow_item_ipv4 *spec = ipv4->spec;\n+\t\tconst struct rte_flow_item_ipv4 *mask = ipv4->mask;\n+\n+\t\tif (!spec)\n+\t\t\t/*\n+\t\t\t * Specification for L3 addresses cannot be empty\n+\t\t\t * because it is required as decap parameter.\n+\t\t\t */\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, ipv4,\n+\t\t\t\t \"NULL outer L3 address specification \"\n+\t\t\t\t \" for VXLAN decapsulation\");\n+\t\tif (!mask)\n+\t\t\tmask = &rte_flow_item_ipv4_mask;\n+\t\tif (mask->hdr.dst_addr != RTE_BE32(0x00000000)) {\n+\t\t\tif (mask->hdr.dst_addr != RTE_BE32(0xffffffff))\n+\t\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\t/* More L3 address validations can be put here. */\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * Kernel uses the destination L3 address\n+\t\t\t * to determine the ingress network interface\n+\t\t\t * for traffic being decapculated.\n+\t\t\t */\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, ipv4,\n+\t\t\t\t \"outer L3 destination address must be \"\n+\t\t\t\t \"specified for VXLAN decapsulation\");\n+\t\t}\n+\t\t/* Source L3 address is optional for decap. */\n+\t\tif (mask->hdr.src_addr != RTE_BE32(0x00000000))\n+\t\t\tif (mask->hdr.src_addr != RTE_BE32(0xffffffff))\n+\t\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.src_addr\\\" field\");\n+\t} else {\n+\t\tconst struct rte_flow_item_ipv6 *spec = ipv6->spec;\n+\t\tconst struct rte_flow_item_ipv6 *mask = ipv6->mask;\n+\n+\t\tif (!spec)\n+\t\t\t/*\n+\t\t\t * Specification for L3 addresses cannot be empty\n+\t\t\t * because it is required as decap parameter.\n+\t\t\t */\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, ipv6,\n+\t\t\t\t \"NULL outer L3 address specification \"\n+\t\t\t\t \" for VXLAN decapsulation\");\n+\t\tif (!mask)\n+\t\t\tmask = &rte_flow_item_ipv6_mask;\n+\t\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t\t   &flow_tcf_mask_empty.ipv6.hdr.dst_addr,\n+\t\t\t   sizeof(flow_tcf_mask_empty.ipv6.hdr.dst_addr))) {\n+\t\t\tif (memcmp(&mask->hdr.dst_addr,\n+\t\t\t\t&rte_flow_item_ipv6_mask.hdr.dst_addr,\n+\t\t\t\tsizeof(rte_flow_item_ipv6_mask.hdr.dst_addr)))\n+\t\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/* More L3 address validations can be put here. */\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * Kernel uses the destination L3 address\n+\t\t\t * to determine the ingress network interface\n+\t\t\t * for traffic being decapculated.\n+\t\t\t */\n+\t\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t RTE_FLOW_ERROR_TYPE_ITEM, ipv6,\n+\t\t\t\t \"outer L3 destination address must be \"\n+\t\t\t\t \"specified for VXLAN decapsulation\");\n+\t\t}\n+\t\t/* Source L3 address is optional for decap. */\n+\t\tif (memcmp(&mask->hdr.src_addr,\n+\t\t\t   &flow_tcf_mask_empty.ipv6.hdr.src_addr,\n+\t\t\t   sizeof(flow_tcf_mask_empty.ipv6.hdr.src_addr))) {\n+\t\t\tif (memcmp(&mask->hdr.src_addr,\n+\t\t\t\t   &rte_flow_item_ipv6_mask.hdr.src_addr,\n+\t\t\t\t   sizeof(mask->hdr.src_addr)))\n+\t\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_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.src_addr\\\" field\");\n+\t\t}\n+\t}\n+\tif (!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 L4 layer found\"\n+\t\t\t\t\t  \" for VXLAN decapsulation\");\n+\t} else {\n+\t\tconst struct rte_flow_item_udp *spec = udp->spec;\n+\t\tconst struct rte_flow_item_udp *mask = udp->mask;\n+\n+\t\tif (!spec)\n+\t\t\t/*\n+\t\t\t * Specification for UDP ports cannot be empty\n+\t\t\t * because it is required as decap parameter.\n+\t\t\t */\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 \"NULL UDP port specification \"\n+\t\t\t\t\t \" for VXLAN decapsulation\");\n+\t\tif (!mask)\n+\t\t\tmask = &rte_flow_item_udp_mask;\n+\t\tif (mask->hdr.dst_port != RTE_BE16(0x0000)) {\n+\t\t\tif (mask->hdr.dst_port != RTE_BE16(0xffff))\n+\t\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\t\tif (!spec->hdr.dst_port)\n+\t\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\t} else {\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 \"outer UDP destination port must be \"\n+\t\t\t\t\t \"specified for VXLAN decapsulation\");\n+\t\t}\n+\t\tif (mask->hdr.src_port != RTE_BE16(0x0000)) {\n+\t\t\tif (mask->hdr.src_port != RTE_BE16(0xffff))\n+\t\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\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\t}\n+\t}\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 decapsulation\");\n+\t/* VNI is already validated, extra check can be put here. */\n+\treturn 0;\n+}\n+/**\n  * Validate flow for E-Switch.\n  *\n  * @param[in] priv\n@@ -589,6 +1213,7 @@ struct flow_tcf_ptoi {\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@@ -597,7 +1222,11 @@ struct flow_tcf_ptoi {\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} conf;\n+\tconst struct rte_flow_item *ipv4 = NULL; /* storage to check */\n+\tconst struct rte_flow_item *ipv6 = NULL; /* outer tunnel. */\n+\tconst struct rte_flow_item *udp = NULL;  /* parameters. */\n \tuint32_t item_flags = 0;\n \tuint32_t action_flags = 0;\n \tuint8_t next_protocol = -1;\n@@ -724,7 +1353,6 @@ struct flow_tcf_ptoi {\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_L3_IPV4;\n \t\t\tmask.ipv4 = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_ipv4_mask,\n \t\t\t\t &flow_tcf_mask_supported.ipv4,\n@@ -745,13 +1373,22 @@ struct flow_tcf_ptoi {\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 (item_flags & MLX5_FLOW_LAYER_OUTER_L3_IPV4) {\n+\t\t\t\t/*\n+\t\t\t\t * Multiple outer items are not allowed as\n+\t\t\t\t * tunnel parameters\n+\t\t\t\t */\n+\t\t\t\tipv4 = NULL;\n+\t\t\t} else {\n+\t\t\t\tipv4 = items;\n+\t\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV4;\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 \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_L3_IPV6;\n \t\t\tmask.ipv6 = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_ipv6_mask,\n \t\t\t\t &flow_tcf_mask_supported.ipv6,\n@@ -772,13 +1409,22 @@ struct flow_tcf_ptoi {\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 (item_flags & MLX5_FLOW_LAYER_OUTER_L3_IPV6) {\n+\t\t\t\t/*\n+\t\t\t\t *Multiple outer items are not allowed as\n+\t\t\t\t * tunnel parameters\n+\t\t\t\t */\n+\t\t\t\tipv6 = NULL;\n+\t\t\t} else {\n+\t\t\t\tipv6 = items;\n+\t\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L3_IPV6;\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 \t\t\t\t\t\t\t  next_protocol, 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\tmask.udp = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_udp_mask,\n \t\t\t\t &flow_tcf_mask_supported.udp,\n@@ -787,13 +1433,18 @@ struct flow_tcf_ptoi {\n \t\t\t\t error);\n \t\t\tif (!mask.udp)\n \t\t\t\treturn -rte_errno;\n+\t\t\tif (item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP) {\n+\t\t\t\tudp = NULL;\n+\t\t\t} else {\n+\t\t\t\tudp = items;\n+\t\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L4_UDP;\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(items, item_flags,\n \t\t\t\t\t\t\t  next_protocol, error);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n-\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L4_TCP;\n \t\t\tmask.tcp = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_tcp_mask,\n \t\t\t\t &flow_tcf_mask_supported.tcp,\n@@ -802,6 +1453,31 @@ struct flow_tcf_ptoi {\n \t\t\t\t error);\n \t\t\tif (!mask.tcp)\n \t\t\t\treturn -rte_errno;\n+\t\t\titem_flags |= MLX5_FLOW_LAYER_OUTER_L4_TCP;\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\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),\n+\t\t\t\t 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\titem_flags |= MLX5_FLOW_LAYER_VXLAN;\n \t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n@@ -857,6 +1533,33 @@ struct flow_tcf_ptoi {\n \t\tcase RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:\n \t\t\taction_flags |= MLX5_ACTION_OF_SET_VLAN_PCP;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\t\tif (action_flags & (MLX5_ACTION_VXLAN_ENCAP\n+\t\t\t\t\t   | MLX5_ACTION_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_ACTION, actions,\n+\t\t\t\t\t \"can't have multiple vxlan actions\");\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\taction_flags |= MLX5_ACTION_VXLAN_ENCAP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\tif (action_flags & (MLX5_ACTION_VXLAN_ENCAP\n+\t\t\t\t\t   | MLX5_ACTION_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_ACTION, actions,\n+\t\t\t\t\t \"can't have multiple vxlan actions\");\n+\t\t\tret = flow_tcf_validate_vxlan_decap(item_flags,\n+\t\t\t\t\t\t\t    actions,\n+\t\t\t\t\t\t\t    ipv4, ipv6, udp,\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_VXLAN_DECAP;\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_ACTION,\n@@ -864,6 +1567,12 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t\t  \"action not supported\");\n \t\t}\n \t}\n+\tif ((item_flags & MLX5_FLOW_LAYER_VXLAN) &&\n+\t    !(action_flags & MLX5_ACTION_VXLAN_DECAP))\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 \"VNI pattern should be followed \"\n+\t\t\t\t\t \" by VXLAN_DECAP action\");\n \treturn 0;\n }\n \n",
    "prefixes": [
        "3/5"
    ]
}