get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45803,
    "url": "http://patchwork.dpdk.org/api/patches/45803/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1538461807-37507-4-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-4-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1538461807-37507-4-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-10-02T06:30:40",
    "name": "[4/5] net/mlx5: e-switch VXLAN flow translation routine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "7b795462f2b69127ef31b3ca43dbe5d590d8206e",
    "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-4-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/45803/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/45803/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 175F94F90;\n\tTue,  2 Oct 2018 08:30:44 +0200 (CEST)",
            "from EUR01-DB5-obe.outbound.protection.outlook.com\n\t(mail-db5eur01on0086.outbound.protection.outlook.com [104.47.2.86])\n\tby dpdk.org (Postfix) with ESMTP id 1DC684C8B\n\tfor <dev@dpdk.org>; Tue,  2 Oct 2018 08:30:42 +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:40 +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:40 +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=x7eXpmzu0W1IpwYEsIkwgU5wtVD9ihHaaRc8y4meCnE=;\n\tb=JbAE3euVN95m1S6HFmBsSzJxpxIGA3L9njABEN5lENLtoBv2WvK43qJZzW5QEItC5frFGgmNr5ZsAhhN8jyCa6+e4COxaLt6uwzVyHlBjmTBUGW5UzbpW8lX/x8esT+j45dgrC5MkJO/4AHifPyOeHLyWgXM+6uT9PpXdIGzagI=",
        "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 4/5] net/mlx5: e-switch VXLAN flow translation routine",
        "Thread-Index": "AQHUWhlwMhlHfQkdIEa8oEfa/cy22Q==",
        "Date": "Tue, 2 Oct 2018 06:30:40 +0000",
        "Message-ID": "<1538461807-37507-4-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:s20gdf566GyZ/A/bRlGALDWOn3n7QBwJaeqb1ll1SjfQgIEGQOMUoNdRISfKzQ7XGwLm6iykw7gPcOeZMlxWSVUP1dR/k1ZEE0y4q584iIuZtChIxnn57ZXfSdzx+XVTdWEOtYgL92j2gvrFLsfLgN8CmsKcRxOrePOOhro/hoWqwHvVCLalqJ7bsbKo11Ga4wdegpZlbPx+gCdkefs7CQD4T+ekXnDE/xo75bWKVvWJXQ3cNUa4rtJpVOq6pL7jOaouNQ32HuTkV/TyIsY4hjtDLyvcM5TDiwUN1/CXwQb+0YGg6+M9boFpVJWwNZ1UT4U3ITkR96LPp8OwlqIO5qjFRcIs6L3e06NeLwGarj+1YXSAHiaxH8EZaoYQL2/bBUrkrhMGRU2JxwRoh0a0F4M8SPH9Sn4NYbp1DSkb9G9Fn6GtCT/wEy7FSvpTdCYU6REw57TAkYHVOyPrxrsqPQ==;\n\t5:46gL7V6h16F93BtRt831sDJPuI8CXyFDb319o/YYg/KRjJPpVglEsMYhlPmUsx218jxkGm4L/f+YeZAhh1VVw+OMbaOThnjdReOfj+NGuGUr2ZZlfoXzH9NJsrR+GBjgXUDDosgnNlypezAX+jF+GC5O99nH7r7o7YtOGylW91c=;\n\t7:Xob5ldP+j9kunNjdVnnwoehnEeYUD/ap8BhxpXN81Xu1cxqmnEpegkEN1qh27fnpLSlkwCuxW028dLYFH6ow6JsFV+36tS3u0o4uvveWBJjYt/NvUz0kiDUhCIRkpJ7v2N4v70BrmI3VZMcZ4PA3hBqWiU3wSSVd7yJCtkT38zvzaYjShx7RqvJZiWksuXJE/lfCAaGHZuoSRkIQiBj9obxk4XwFKM4iXFpHlcfKbwaHZj0Po05kN1CI5e8ZF+kW",
        "x-ms-office365-filtering-correlation-id": "9d5b3bc7-9e53-49de-3c2d-08d62830927c",
        "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": "<AM4PR05MB3443763815A432383F61A9CFD2E80@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)(52314003)(189003)(199004)(5640700003)(256004)(25786009)(14444005)(26005)(106356001)(54906003)(186003)(316002)(102836004)(68736007)(105586002)(6116002)(3846002)(97736004)(14454004)(81156014)(1730700003)(86362001)(2351001)(2900100001)(8676002)(575784001)(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": "FU6gMpOi9vUB5PryWqWTkgrLQA8kkMtQ4Ti0b2xug2cPW6Wbgpr4iPRwOIxJz6/pd0P0CEPWowKg4gM1FR1dT8V3Ny+HBd0qUjCFU/J9HURzyEejz3qqh6zhfm3zTf1e11Xo82vz9SqekK0ZSoUnCR2TscDbvyWBYzGRKVLqnpbSYDI/qQwGbU3g3oRUCvkP3kdY3tj4373kNj+mCKHS1UktX5ksTBKzA05FzP1qiSUqrvJsg8Xr+1tlErpjRL5TTz8FyqxXqusYcaU6BQ8iFUh7jq2lO20BZhSYwS6imoOmHCGO+3wlxATHiYMN9+/RNPIrjSgnDa0xMQMV2IyRG9/ifSighD0WAifUZqThzCs=",
        "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": "9d5b3bc7-9e53-49de-3c2d-08d62830927c",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "02 Oct 2018 06:30:40.4963\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 4/5] net/mlx5: e-switch VXLAN flow translation\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 of VXLAN-related items and\nactions to the flow translation routine. If some of them are\nspecified in the rule, the extra space for tunnel description\nstructure is allocated. Later some tunnel types, other than VXLAN\ncan be addedd (GRE). No VTEP devices are created at this point,\nthe flow rule is just translated, not applied yet.\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 | 671 ++++++++++++++++++++++++++++++++++-----\n 1 file changed, 591 insertions(+), 80 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex 97451bd..dfffc50 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -1597,7 +1597,7 @@ struct flow_tcf_ptoi {\n \n \tsize += SZ_NLATTR_STRZ_OF(\"flower\") +\n \t\tSZ_NLATTR_NEST + /* TCA_OPTIONS. */\n-\t\tSZ_NLATTR_TYPE_OF(uint32_t); /* TCA_CLS_FLAGS_SKIP_SW. */\n+\t\tSZ_NLATTR_TYPE_OF_UINT32; /* TCA_CLS_FLAGS_SKIP_SW. */\n \tfor (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {\n \t\tswitch (items->type) {\n \t\tcase RTE_FLOW_ITEM_TYPE_VOID:\n@@ -1605,45 +1605,49 @@ struct flow_tcf_ptoi {\n \t\tcase RTE_FLOW_ITEM_TYPE_PORT_ID:\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_ETH:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT16 + /* Ether type. */\n \t\t\t\tSZ_NLATTR_DATA_OF(ETHER_ADDR_LEN) * 4;\n \t\t\t\t/* dst/src MAC addr and mask. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_L2;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_VLAN:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t) +\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT16 + /* Ether type. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16 +\n \t\t\t\t/* VLAN Ether type. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint8_t) + /* VLAN prio. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t); /* VLAN ID. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8 + /* VLAN prio. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16; /* VLAN ID. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_VLAN;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint32_t) * 4;\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT16 + /* Ether type. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8 + /* IP proto. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT32 * 4;\n \t\t\t\t/* dst/src IP addr and mask. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_L3_IPV4;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint16_t) + /* Ether type. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT16 + /* Ether type. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8 + /* IP proto. */\n \t\t\t\tSZ_NLATTR_TYPE_OF(IPV6_ADDR_LEN) * 4;\n \t\t\t\t/* dst/src IP addr and mask. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_L3_IPV6;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t) * 4;\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT8 + /* IP proto. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16 * 4;\n \t\t\t\t/* dst/src port and mask. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_L4_UDP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_TCP:\n-\t\t\tsize += SZ_NLATTR_TYPE_OF(uint8_t) + /* IP proto. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t) * 4;\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT8 + /* IP proto. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16 * 4;\n \t\t\t\t/* dst/src port and mask. */\n \t\t\tflags |= MLX5_FLOW_LAYER_OUTER_L4_TCP;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tsize += SZ_NLATTR_TYPE_OF_UINT32;\n+\t\t\tflags |= MLX5_FLOW_LAYER_VXLAN;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\tDRV_LOG(WARNING,\n \t\t\t\t\"unsupported item %p type %d,\"\n@@ -1657,6 +1661,265 @@ struct flow_tcf_ptoi {\n }\n \n /**\n+ * Helper function to process RTE_FLOW_ITEM_TYPE_ETH entry in configuration\n+ * of action RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. Fills the MAC address fields\n+ * in the encapsulation parameters structure. The item must be prevalidated,\n+ * no any validation checks performed by function.\n+ *\n+ * @param[in] spec\n+ *   RTE_FLOW_ITEM_TYPE_ETH entry specification.\n+ * @param[in] mask\n+ *   RTE_FLOW_ITEM_TYPE_ETH entry mask.\n+ * @param[out] encap\n+ *   Structure to fill the gathered MAC address data.\n+ *\n+ * @return\n+ *   The size needed the Netlink message tunnel_key\n+ *   parameter buffer to store the item attributes.\n+ */\n+static int\n+flow_tcf_parse_vxlan_encap_eth(const struct rte_flow_item_eth *spec,\n+\t\t\t       const struct rte_flow_item_eth *mask,\n+\t\t\t       struct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\t/* Item must be validated before. No redundant checks. */\n+\tassert(spec);\n+\tif (!mask || !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/*\n+\t\t * Ethernet addresses are not supported by\n+\t\t * tc as tunnel_key parameters. Destination\n+\t\t * address is needed to form encap packet\n+\t\t * header and retrieved by kernel from\n+\t\t * implicit sources (ARP table, etc),\n+\t\t * address masks are not supported at all.\n+\t\t */\n+\t\tencap->eth.dst = spec->dst;\n+\t\tencap->mask |= MLX5_FLOW_TCF_ENCAP_ETH_DST;\n+\t}\n+\tif (!mask || !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/*\n+\t\t * Ethernet addresses are not supported by\n+\t\t * tc as tunnel_key parameters. Source ethernet\n+\t\t * address is ignored anyway.\n+\t\t */\n+\t\tencap->eth.src = spec->src;\n+\t\tencap->mask |= MLX5_FLOW_TCF_ENCAP_ETH_SRC;\n+\t}\n+\t/*\n+\t * No space allocated for ethernet addresses within Netlink\n+\t * message tunnel_key record - these ones are not\n+\t * supported by tc.\n+\t */\n+\treturn 0;\n+}\n+\n+/**\n+ * Helper function to process RTE_FLOW_ITEM_TYPE_IPV4 entry in configuration\n+ * of action RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. Fills the IPV4 address fields\n+ * in the encapsulation parameters structure. The item must be prevalidated,\n+ * no any validation checks performed by function.\n+ *\n+ * @param[in] spec\n+ *   RTE_FLOW_ITEM_TYPE_IPV4 entry specification.\n+ * @param[out] encap\n+ *   Structure to fill the gathered IPV4 address data.\n+ *\n+ * @return\n+ *   The size needed the Netlink message tunnel_key\n+ *   parameter buffer to store the item attributes.\n+ */\n+static int\n+flow_tcf_parse_vxlan_encap_ipv4(const struct rte_flow_item_ipv4 *spec,\n+\t\t\t\tstruct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\t/* Item must be validated before. No redundant checks. */\n+\tassert(spec);\n+\tencap->ipv4.dst = spec->hdr.dst_addr;\n+\tencap->ipv4.src = spec->hdr.src_addr;\n+\tencap->mask |= MLX5_FLOW_TCF_ENCAP_IPV4_SRC |\n+\t\t       MLX5_FLOW_TCF_ENCAP_IPV4_DST;\n+\treturn SZ_NLATTR_TYPE_OF_UINT32 * 2;\n+}\n+\n+/**\n+ * Helper function to process RTE_FLOW_ITEM_TYPE_IPV6 entry in configuration\n+ * of action RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. Fills the IPV6 address fields\n+ * in the encapsulation parameters structure. The item must be prevalidated,\n+ * no any validation checks performed by function.\n+ *\n+ * @param[in] spec\n+ *   RTE_FLOW_ITEM_TYPE_IPV6 entry specification.\n+ * @param[out] encap\n+ *   Structure to fill the gathered IPV6 address data.\n+ *\n+ * @return\n+ *   The size needed the Netlink message tunnel_key\n+ *   parameter buffer to store the item attributes.\n+ */\n+static int\n+flow_tcf_parse_vxlan_encap_ipv6(const struct rte_flow_item_ipv6 *spec,\n+\t\t\t\tstruct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\t/* Item must be validated before. No redundant checks. */\n+\tassert(spec);\n+\tmemcpy(encap->ipv6.dst, spec->hdr.dst_addr, sizeof(encap->ipv6.dst));\n+\tmemcpy(encap->ipv6.src, spec->hdr.src_addr, sizeof(encap->ipv6.src));\n+\tencap->mask |= MLX5_FLOW_TCF_ENCAP_IPV6_SRC |\n+\t\t       MLX5_FLOW_TCF_ENCAP_IPV6_DST;\n+\treturn SZ_NLATTR_TYPE_OF(IPV6_ADDR_LEN) * 2;\n+}\n+\n+/**\n+ * Helper function to process RTE_FLOW_ITEM_TYPE_UDP entry in configuration\n+ * of action RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. Fills the UDP port fields\n+ * in the encapsulation parameters structure. The item must be prevalidated,\n+ * no any validation checks performed by function.\n+ *\n+ * @param[in] spec\n+ *   RTE_FLOW_ITEM_TYPE_UDP entry specification.\n+ * @param[in] mask\n+ *   RTE_FLOW_ITEM_TYPE_UDP entry mask.\n+ * @param[out] encap\n+ *   Structure to fill the gathered UDP port data.\n+ *\n+ * @return\n+ *   The size needed the Netlink message tunnel_key\n+ *   parameter buffer to store the item attributes.\n+ */\n+static int\n+flow_tcf_parse_vxlan_encap_udp(const struct rte_flow_item_udp *spec,\n+\t\t\t       const struct rte_flow_item_udp *mask,\n+\t\t\t       struct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\tint size = SZ_NLATTR_TYPE_OF_UINT16;\n+\n+\tassert(spec);\n+\tencap->udp.dst = spec->hdr.dst_port;\n+\tencap->mask |= MLX5_FLOW_TCF_ENCAP_UDP_DST;\n+\tif (!mask || mask->hdr.src_port != RTE_BE16(0x0000)) {\n+\t\tencap->udp.src = spec->hdr.src_port;\n+\t\tsize += SZ_NLATTR_TYPE_OF_UINT16;\n+\t\tencap->mask |= MLX5_FLOW_TCF_ENCAP_IPV4_SRC;\n+\t}\n+\treturn size;\n+}\n+\n+/**\n+ * Helper function to process RTE_FLOW_ITEM_TYPE_VXLAN entry in configuration\n+ * of action RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. Fills the VNI fields\n+ * in the encapsulation parameters structure. The item must be prevalidated,\n+ * no any validation checks performed by function.\n+ *\n+ * @param[in] spec\n+ *   RTE_FLOW_ITEM_TYPE_VXLAN entry specification.\n+ * @param[out] encap\n+ *   Structure to fill the gathered VNI address data.\n+ *\n+ * @return\n+ *   The size needed the Netlink message tunnel_key\n+ *   parameter buffer to store the item attributes.\n+ */\n+static int\n+flow_tcf_parse_vxlan_encap_vni(const struct rte_flow_item_vxlan *spec,\n+\t\t\t       struct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\t/* Item must be validated before. Do not redundant checks. */\n+\tassert(spec);\n+\tmemcpy(encap->vxlan.vni, spec->vni, sizeof(encap->vxlan.vni));\n+\tencap->mask |= MLX5_FLOW_TCF_ENCAP_VXLAN_VNI;\n+\treturn SZ_NLATTR_TYPE_OF_UINT32;\n+}\n+\n+/**\n+ * Populate consolidated encapsulation object from list of pattern items.\n+ *\n+ * Helper function to process configuration of action such as\n+ * RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP. The item list should be\n+ * validated, there is no way to return an meaningful error.\n+ *\n+ * @param[in] action\n+ *   RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP action object.\n+ *   List of pattern items to gather data from.\n+ * @param[out] src\n+ *   Structure to fill gathered data.\n+ *\n+ * @return\n+ *   The size the part of Netlink message buffer to store the item\n+ *   attributes on success, zero otherwise. The mask field in\n+ *   result structure reflects correctly parsed items.\n+ */\n+static int\n+flow_tcf_vxlan_encap_parse(const struct rte_flow_action *action,\n+\t\t\t   struct mlx5_flow_tcf_vxlan_encap *encap)\n+{\n+\tunion {\n+\t\tconst struct rte_flow_item_eth *eth;\n+\t\tconst struct rte_flow_item_ipv4 *ipv4;\n+\t\tconst struct rte_flow_item_ipv6 *ipv6;\n+\t\tconst struct rte_flow_item_udp *udp;\n+\t\tconst struct rte_flow_item_vxlan *vxlan;\n+\t} spec, mask;\n+\tconst struct rte_flow_item *items;\n+\tint size = 0;\n+\n+\tassert(action->type == RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP);\n+\tassert(action->conf);\n+\n+\titems = ((const struct rte_flow_action_vxlan_encap *)\n+\t\t\t\t\taction->conf)->definition;\n+\tassert(items);\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\tmask.eth = items->mask;\n+\t\t\tspec.eth = items->spec;\n+\t\t\tsize += flow_tcf_parse_vxlan_encap_eth(spec.eth,\n+\t\t\t\t\t\t\t       mask.eth,\n+\t\t\t\t\t\t\t       encap);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n+\t\t\tspec.ipv4 = items->spec;\n+\t\t\tsize += flow_tcf_parse_vxlan_encap_ipv4(spec.ipv4,\n+\t\t\t\t\t\t\t\tencap);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n+\t\t\tspec.ipv6 = items->spec;\n+\t\t\tsize += flow_tcf_parse_vxlan_encap_ipv6(spec.ipv6,\n+\t\t\t\t\t\t\t\tencap);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n+\t\t\tmask.udp = items->mask;\n+\t\t\tspec.udp = items->spec;\n+\t\t\tsize += flow_tcf_parse_vxlan_encap_udp(spec.udp,\n+\t\t\t\t\t\t\t       mask.udp,\n+\t\t\t\t\t\t\t       encap);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tspec.vxlan = items->spec;\n+\t\t\tsize += flow_tcf_parse_vxlan_encap_vni(spec.vxlan,\n+\t\t\t\t\t\t\t       encap);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tassert(false);\n+\t\t\tDRV_LOG(WARNING,\n+\t\t\t\t\"unsupported item %p type %d,\"\n+\t\t\t\t\" items must be validated\"\n+\t\t\t\t\" before flow creation\",\n+\t\t\t\t(const void *)items, items->type);\n+\t\t\tencap->mask = 0;\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\treturn size;\n+}\n+\n+/**\n  * Calculate maximum size of memory for flow actions of Linux TC flower and\n  * extract specified actions.\n  *\n@@ -1664,13 +1927,16 @@ struct flow_tcf_ptoi {\n  *   Pointer to the list of actions.\n  * @param[out] action_flags\n  *   Pointer to the detected actions.\n+ * @param[out] tunnel\n+ *   Pointer to tunnel encapsulation parameters structure to fill.\n  *\n  * @return\n  *   Maximum size of memory for actions.\n  */\n static int\n flow_tcf_get_actions_and_size(const struct rte_flow_action actions[],\n-\t\t\t      uint64_t *action_flags)\n+\t\t\t      uint64_t *action_flags,\n+\t\t\t      void *tunnel)\n {\n \tint size = 0;\n \tuint64_t flags = 0;\n@@ -1684,14 +1950,14 @@ struct flow_tcf_ptoi {\n \t\t\tsize += SZ_NLATTR_NEST + /* na_act_index. */\n \t\t\t\tSZ_NLATTR_STRZ_OF(\"mirred\") +\n \t\t\t\tSZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(struct tc_mirred);\n+\t\t\t\tSZ_NLATTR_TYPE_OF_STRUCT(tc_mirred);\n \t\t\tflags |= MLX5_ACTION_PORT_ID;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n \t\t\tsize += SZ_NLATTR_NEST + /* na_act_index. */\n \t\t\t\tSZ_NLATTR_STRZ_OF(\"gact\") +\n \t\t\t\tSZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(struct tc_gact);\n+\t\t\t\tSZ_NLATTR_TYPE_OF_STRUCT(tc_gact);\n \t\t\tflags |= MLX5_ACTION_DROP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:\n@@ -1710,11 +1976,34 @@ struct flow_tcf_ptoi {\n \t\t\tsize += SZ_NLATTR_NEST + /* na_act_index. */\n \t\t\t\tSZ_NLATTR_STRZ_OF(\"vlan\") +\n \t\t\t\tSZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(struct tc_vlan) +\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t) +\n+\t\t\t\tSZ_NLATTR_TYPE_OF_STRUCT(tc_vlan) +\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16 +\n \t\t\t\t/* VLAN protocol. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint16_t) + /* VLAN ID. */\n-\t\t\t\tSZ_NLATTR_TYPE_OF(uint8_t); /* VLAN prio. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT16 + /* VLAN ID. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8; /* VLAN prio. */\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\t\tsize += SZ_NLATTR_NEST + /* na_act_index. */\n+\t\t\t\tSZ_NLATTR_STRZ_OF(\"tunnel_key\") +\n+\t\t\t\tSZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8 + /* no UDP sum */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_STRUCT(tc_tunnel_key) +\n+\t\t\t\tflow_tcf_vxlan_encap_parse(actions, tunnel) +\n+\t\t\t\tRTE_ALIGN_CEIL /* preceding encap params. */\n+\t\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_encap),\n+\t\t\t\tMNL_ALIGNTO);\n+\t\t\tflags |= MLX5_ACTION_VXLAN_ENCAP;\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\tsize += SZ_NLATTR_NEST + /* na_act_index. */\n+\t\t\t\tSZ_NLATTR_STRZ_OF(\"tunnel_key\") +\n+\t\t\t\tSZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_UINT8 + /* no UDP sum */\n+\t\t\t\tSZ_NLATTR_TYPE_OF_STRUCT(tc_tunnel_key) +\n+\t\t\t\tRTE_ALIGN_CEIL /* preceding decap params. */\n+\t\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_decap),\n+\t\t\t\tMNL_ALIGNTO);\n+\t\t\tflags |= MLX5_ACTION_VXLAN_DECAP;\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tDRV_LOG(WARNING,\n@@ -1750,6 +2039,26 @@ struct flow_tcf_ptoi {\n }\n \n /**\n+ * Convert VXLAN VNI to 32-bit integer.\n+ *\n+ * @param[in] vni\n+ *   VXLAN VNI in 24-bit wire format.\n+ *\n+ * @return\n+ *   VXLAN VNI as a 32-bit integer value in network endian.\n+ */\n+static rte_be32_t\n+vxlan_vni_as_be32(const uint8_t vni[3])\n+{\n+\trte_be32_t ret;\n+\n+\tret = vni[0];\n+\tret = (ret << 8) | vni[1];\n+\tret = (ret << 8) | vni[2];\n+\treturn RTE_BE32(ret);\n+}\n+\n+/**\n  * Prepare a flow object for Linux TC flower. It calculates the maximum size of\n  * memory required, allocates the memory, initializes Netlink message headers\n  * and set unique TC message handle.\n@@ -1784,22 +2093,54 @@ struct flow_tcf_ptoi {\n \tstruct mlx5_flow *dev_flow;\n \tstruct nlmsghdr *nlh;\n \tstruct tcmsg *tcm;\n+\tstruct mlx5_flow_tcf_vxlan_encap encap = {.mask = 0};\n+\tuint8_t *sp, *tun = NULL;\n \n \tsize += flow_tcf_get_items_and_size(items, item_flags);\n-\tsize += flow_tcf_get_actions_and_size(actions, action_flags);\n-\tdev_flow = rte_zmalloc(__func__, size, MNL_ALIGNTO);\n+\tsize += flow_tcf_get_actions_and_size(actions, action_flags, &encap);\n+\tdev_flow = rte_zmalloc(__func__, size,\n+\t\t\tRTE_MAX(alignof(struct mlx5_flow_tcf_tunnel_hdr),\n+\t\t\t\t(size_t)MNL_ALIGNTO));\n \tif (!dev_flow) {\n \t\trte_flow_error_set(error, ENOMEM,\n \t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t   \"not enough memory to create E-Switch flow\");\n \t\treturn NULL;\n \t}\n-\tnlh = mnl_nlmsg_put_header((void *)(dev_flow + 1));\n+\tsp = (uint8_t *)(dev_flow + 1);\n+\tif (*action_flags & MLX5_ACTION_VXLAN_ENCAP) {\n+\t\ttun = sp;\n+\t\tsp += RTE_ALIGN_CEIL\n+\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_encap),\n+\t\t\tMNL_ALIGNTO);\n+\t\tsize -= RTE_ALIGN_CEIL\n+\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_encap),\n+\t\t\tMNL_ALIGNTO);\n+\t\tencap.hdr.type = MLX5_FLOW_TCF_TUNACT_VXLAN_ENCAP;\n+\t\tmemcpy(tun, &encap,\n+\t\t       sizeof(struct mlx5_flow_tcf_vxlan_encap));\n+\t} else if (*action_flags & MLX5_ACTION_VXLAN_DECAP) {\n+\t\ttun = sp;\n+\t\tsp += RTE_ALIGN_CEIL\n+\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_decap),\n+\t\t\tMNL_ALIGNTO);\n+\t\tsize -= RTE_ALIGN_CEIL\n+\t\t\t(sizeof(struct mlx5_flow_tcf_vxlan_decap),\n+\t\t\tMNL_ALIGNTO);\n+\t\tencap.hdr.type = MLX5_FLOW_TCF_TUNACT_VXLAN_DECAP;\n+\t\tmemcpy(tun, &encap,\n+\t\t       sizeof(struct mlx5_flow_tcf_vxlan_decap));\n+\t}\n+\tnlh = mnl_nlmsg_put_header(sp);\n \ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n \t*dev_flow = (struct mlx5_flow){\n \t\t.tcf = (struct mlx5_flow_tcf){\n+\t\t\t.nlsize = size,\n \t\t\t.nlh = nlh,\n \t\t\t.tcm = tcm,\n+\t\t\t.tunnel = (struct mlx5_flow_tcf_tunnel_hdr *)tun,\n+\t\t\t.item_flags = *item_flags,\n+\t\t\t.action_flags = *action_flags,\n \t\t},\n \t};\n \t/*\n@@ -1853,6 +2194,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@@ -1862,6 +2204,14 @@ struct flow_tcf_ptoi {\n \t\tconst struct rte_flow_action_of_set_vlan_pcp *\n \t\t\tof_set_vlan_pcp;\n \t} conf;\n+\tunion {\n+\t\tstruct mlx5_flow_tcf_tunnel_hdr *hdr;\n+\t\tstruct mlx5_flow_tcf_vxlan_decap *vxlan;\n+\t} decap;\n+\tunion {\n+\t\tstruct mlx5_flow_tcf_tunnel_hdr *hdr;\n+\t\tstruct mlx5_flow_tcf_vxlan_encap *vxlan;\n+\t} encap;\n \tstruct flow_tcf_ptoi ptoi[PTOI_TABLE_SZ_MAX(dev)];\n \tstruct nlmsghdr *nlh = dev_flow->tcf.nlh;\n \tstruct tcmsg *tcm = dev_flow->tcf.tcm;\n@@ -1877,6 +2227,12 @@ struct flow_tcf_ptoi {\n \n \tclaim_nonzero(flow_tcf_build_ptoi_table(dev, ptoi,\n \t\t\t\t\t\tPTOI_TABLE_SZ_MAX(dev)));\n+\tencap.hdr = NULL;\n+\tdecap.hdr = NULL;\n+\tif (dev_flow->tcf.action_flags & MLX5_ACTION_VXLAN_ENCAP)\n+\t\tencap.vxlan = dev_flow->tcf.vxlan_encap;\n+\tif (dev_flow->tcf.action_flags & MLX5_ACTION_VXLAN_DECAP)\n+\t\tdecap.vxlan = dev_flow->tcf.vxlan_decap;\n \tnlh = dev_flow->tcf.nlh;\n \ttcm = dev_flow->tcf.tcm;\n \t/* Prepare API must have been called beforehand. */\n@@ -1892,7 +2248,6 @@ struct flow_tcf_ptoi {\n \t\t\t\t  RTE_BE16(ETH_P_ALL));\n \tmnl_attr_put_strz(nlh, TCA_KIND, \"flower\");\n \tna_flower = mnl_attr_nest_start(nlh, TCA_OPTIONS);\n-\tmnl_attr_put_u32(nlh, TCA_FLOWER_FLAGS, TCA_CLS_FLAGS_SKIP_SW);\n \tfor (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {\n \t\tunsigned int i;\n \n@@ -1935,6 +2290,12 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t\t spec.eth->type);\n \t\t\t\teth_type_set = 1;\n \t\t\t}\n+\t\t\t/*\n+\t\t\t * Send L2 addresses/masks anyway, including\n+\t\t\t * VXLAN encap/decap cases, sometimes kernel\n+\t\t\t * returns an error if no L2 address provided\n+\t\t\t * and skip_sw flag is set\n+\t\t\t */\n \t\t\tif (!is_zero_ether_addr(&mask.eth->dst)) {\n \t\t\t\tmnl_attr_put(nlh, TCA_FLOWER_KEY_ETH_DST,\n \t\t\t\t\t     ETHER_ADDR_LEN,\n@@ -1951,8 +2312,19 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t     ETHER_ADDR_LEN,\n \t\t\t\t\t     mask.eth->src.addr_bytes);\n \t\t\t}\n+\t\t\tif (decap.hdr) {\n+\t\t\t\tDRV_LOG(WARNING,\n+\t\t\t\t\"ethernet addresses are treated \"\n+\t\t\t\t\"as inner ones for tunnel decapsulation\");\n+\t\t\t}\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_VLAN:\n+\t\t\tif (encap.hdr || decap.hdr)\n+\t\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ITEM, NULL,\n+\t\t\t\t\t  \"outer VLAN is not \"\n+\t\t\t\t\t  \"supported for tunnels\");\n \t\t\tmask.vlan = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_vlan_mask,\n \t\t\t\t &flow_tcf_mask_supported.vlan,\n@@ -1983,6 +2355,7 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t\t rte_be_to_cpu_16\n \t\t\t\t\t\t (spec.vlan->tci &\n \t\t\t\t\t\t  RTE_BE16(0x0fff)));\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_IPV4:\n \t\t\tmask.ipv4 = flow_tcf_item_mask\n@@ -1992,36 +2365,53 @@ struct flow_tcf_ptoi {\n \t\t\t\t sizeof(flow_tcf_mask_supported.ipv4),\n \t\t\t\t error);\n \t\t\tassert(mask.ipv4);\n-\t\t\tif (!eth_type_set || !vlan_eth_type_set)\n-\t\t\t\tmnl_attr_put_u16(nlh,\n-\t\t\t\t\t\t vlan_present ?\n-\t\t\t\t\t\t TCA_FLOWER_KEY_VLAN_ETH_TYPE :\n-\t\t\t\t\t\t TCA_FLOWER_KEY_ETH_TYPE,\n-\t\t\t\t\t\t RTE_BE16(ETH_P_IP));\n-\t\t\teth_type_set = 1;\n-\t\t\tvlan_eth_type_set = 1;\n-\t\t\tif (mask.ipv4 == &flow_tcf_mask_empty.ipv4)\n-\t\t\t\tbreak;\n \t\t\tspec.ipv4 = items->spec;\n-\t\t\tif (mask.ipv4->hdr.next_proto_id) {\n-\t\t\t\tmnl_attr_put_u8(nlh, TCA_FLOWER_KEY_IP_PROTO,\n+\t\t\tif (!decap.vxlan) {\n+\t\t\t\tif (!eth_type_set || !vlan_eth_type_set) {\n+\t\t\t\t\tmnl_attr_put_u16(nlh,\n+\t\t\t\t\t\tvlan_present ?\n+\t\t\t\t\t\tTCA_FLOWER_KEY_VLAN_ETH_TYPE :\n+\t\t\t\t\t\tTCA_FLOWER_KEY_ETH_TYPE,\n+\t\t\t\t\t\tRTE_BE16(ETH_P_IP));\n+\t\t\t\t}\n+\t\t\t\teth_type_set = 1;\n+\t\t\t\tvlan_eth_type_set = 1;\n+\t\t\t\tif (mask.ipv4 == &flow_tcf_mask_empty.ipv4)\n+\t\t\t\t\tbreak;\n+\t\t\t\tif (mask.ipv4->hdr.next_proto_id) {\n+\t\t\t\t\tmnl_attr_put_u8\n+\t\t\t\t\t\t(nlh, TCA_FLOWER_KEY_IP_PROTO,\n \t\t\t\t\t\tspec.ipv4->hdr.next_proto_id);\n-\t\t\t\tip_proto_set = 1;\n+\t\t\t\t\tip_proto_set = 1;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tassert(mask.ipv4 != &flow_tcf_mask_empty.ipv4);\n \t\t\t}\n \t\t\tif (mask.ipv4->hdr.src_addr) {\n-\t\t\t\tmnl_attr_put_u32(nlh, TCA_FLOWER_KEY_IPV4_SRC,\n-\t\t\t\t\t\t spec.ipv4->hdr.src_addr);\n-\t\t\t\tmnl_attr_put_u32(nlh,\n-\t\t\t\t\t\t TCA_FLOWER_KEY_IPV4_SRC_MASK,\n-\t\t\t\t\t\t mask.ipv4->hdr.src_addr);\n+\t\t\t\tmnl_attr_put_u32\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_IPV4_SRC :\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\t\tmnl_attr_put_u32\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK :\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\t}\n \t\t\tif (mask.ipv4->hdr.dst_addr) {\n-\t\t\t\tmnl_attr_put_u32(nlh, TCA_FLOWER_KEY_IPV4_DST,\n-\t\t\t\t\t\t spec.ipv4->hdr.dst_addr);\n-\t\t\t\tmnl_attr_put_u32(nlh,\n-\t\t\t\t\t\t TCA_FLOWER_KEY_IPV4_DST_MASK,\n-\t\t\t\t\t\t mask.ipv4->hdr.dst_addr);\n+\t\t\t\tmnl_attr_put_u32\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_IPV4_DST :\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\t\tmnl_attr_put_u32\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_IPV4_DST_MASK :\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\t}\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_IPV6:\n \t\t\tmask.ipv6 = flow_tcf_item_mask\n@@ -2031,38 +2421,53 @@ struct flow_tcf_ptoi {\n \t\t\t\t sizeof(flow_tcf_mask_supported.ipv6),\n \t\t\t\t error);\n \t\t\tassert(mask.ipv6);\n-\t\t\tif (!eth_type_set || !vlan_eth_type_set)\n-\t\t\t\tmnl_attr_put_u16(nlh,\n+\t\t\tspec.ipv6 = items->spec;\n+\t\t\tif (!decap.vxlan) {\n+\t\t\t\tif (!eth_type_set || !vlan_eth_type_set) {\n+\t\t\t\t\tmnl_attr_put_u16(nlh,\n \t\t\t\t\t\t vlan_present ?\n \t\t\t\t\t\t TCA_FLOWER_KEY_VLAN_ETH_TYPE :\n \t\t\t\t\t\t TCA_FLOWER_KEY_ETH_TYPE,\n \t\t\t\t\t\t RTE_BE16(ETH_P_IPV6));\n-\t\t\teth_type_set = 1;\n-\t\t\tvlan_eth_type_set = 1;\n-\t\t\tif (mask.ipv6 == &flow_tcf_mask_empty.ipv6)\n-\t\t\t\tbreak;\n-\t\t\tspec.ipv6 = items->spec;\n-\t\t\tif (mask.ipv6->hdr.proto) {\n-\t\t\t\tmnl_attr_put_u8(nlh, TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t\t\t\tspec.ipv6->hdr.proto);\n-\t\t\t\tip_proto_set = 1;\n+\t\t\t\t}\n+\t\t\t\teth_type_set = 1;\n+\t\t\t\tvlan_eth_type_set = 1;\n+\t\t\t\tif (mask.ipv6 == &flow_tcf_mask_empty.ipv6)\n+\t\t\t\t\tbreak;\n+\t\t\t\tif (mask.ipv6->hdr.proto) {\n+\t\t\t\t\tmnl_attr_put_u8\n+\t\t\t\t\t\t(nlh, TCA_FLOWER_KEY_IP_PROTO,\n+\t\t\t\t\t\t spec.ipv6->hdr.proto);\n+\t\t\t\t\tip_proto_set = 1;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tassert(mask.ipv6 != &flow_tcf_mask_empty.ipv6);\n \t\t\t}\n \t\t\tif (!IN6_IS_ADDR_UNSPECIFIED(mask.ipv6->hdr.src_addr)) {\n-\t\t\t\tmnl_attr_put(nlh, TCA_FLOWER_KEY_IPV6_SRC,\n+\t\t\t\tmnl_attr_put(nlh, decap.vxlan ?\n+\t\t\t\t\t     TCA_FLOWER_KEY_ENC_IPV6_SRC :\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\t\tmnl_attr_put(nlh, TCA_FLOWER_KEY_IPV6_SRC_MASK,\n+\t\t\t\tmnl_attr_put(nlh, decap.vxlan ?\n+\t\t\t\t\t     TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK :\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\t}\n \t\t\tif (!IN6_IS_ADDR_UNSPECIFIED(mask.ipv6->hdr.dst_addr)) {\n-\t\t\t\tmnl_attr_put(nlh, TCA_FLOWER_KEY_IPV6_DST,\n+\t\t\t\tmnl_attr_put(nlh, decap.vxlan ?\n+\t\t\t\t\t     TCA_FLOWER_KEY_ENC_IPV6_DST :\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\t\tmnl_attr_put(nlh, TCA_FLOWER_KEY_IPV6_DST_MASK,\n+\t\t\t\tmnl_attr_put(nlh, decap.vxlan ?\n+\t\t\t\t\t     TCA_FLOWER_KEY_ENC_IPV6_DST_MASK :\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\t}\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_UDP:\n \t\t\tmask.udp = flow_tcf_item_mask\n@@ -2072,27 +2477,45 @@ struct flow_tcf_ptoi {\n \t\t\t\t sizeof(flow_tcf_mask_supported.udp),\n \t\t\t\t error);\n \t\t\tassert(mask.udp);\n-\t\t\tif (!ip_proto_set)\n-\t\t\t\tmnl_attr_put_u8(nlh, TCA_FLOWER_KEY_IP_PROTO,\n-\t\t\t\t\t\tIPPROTO_UDP);\n-\t\t\tif (mask.udp == &flow_tcf_mask_empty.udp)\n-\t\t\t\tbreak;\n \t\t\tspec.udp = items->spec;\n+\t\t\tif (!decap.vxlan) {\n+\t\t\t\tif (!ip_proto_set)\n+\t\t\t\t\tmnl_attr_put_u8\n+\t\t\t\t\t\t(nlh, TCA_FLOWER_KEY_IP_PROTO,\n+\t\t\t\t\t\tIPPROTO_UDP);\n+\t\t\t\tif (mask.udp == &flow_tcf_mask_empty.udp)\n+\t\t\t\t\tbreak;\n+\t\t\t} else {\n+\t\t\t\tassert(mask.udp != &flow_tcf_mask_empty.udp);\n+\t\t\t\tdecap.vxlan->udp_port\n+\t\t\t\t\t= RTE_BE16(spec.udp->hdr.dst_port);\n+\t\t\t}\n \t\t\tif (mask.udp->hdr.src_port) {\n-\t\t\t\tmnl_attr_put_u16(nlh, TCA_FLOWER_KEY_UDP_SRC,\n-\t\t\t\t\t\t spec.udp->hdr.src_port);\n-\t\t\t\tmnl_attr_put_u16(nlh,\n-\t\t\t\t\t\t TCA_FLOWER_KEY_UDP_SRC_MASK,\n-\t\t\t\t\t\t mask.udp->hdr.src_port);\n+\t\t\t\tmnl_attr_put_u16\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_UDP_SRC_PORT :\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\t\tmnl_attr_put_u16\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK :\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\t}\n \t\t\tif (mask.udp->hdr.dst_port) {\n-\t\t\t\tmnl_attr_put_u16(nlh, TCA_FLOWER_KEY_UDP_DST,\n-\t\t\t\t\t\t spec.udp->hdr.dst_port);\n-\t\t\t\tmnl_attr_put_u16(nlh,\n-\t\t\t\t\t\t TCA_FLOWER_KEY_UDP_DST_MASK,\n-\t\t\t\t\t\t mask.udp->hdr.dst_port);\n+\t\t\t\tmnl_attr_put_u16\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_UDP_DST_PORT :\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\t\tmnl_attr_put_u16\n+\t\t\t\t\t(nlh, decap.vxlan ?\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK :\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\t}\n-\t\t\tbreak;\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n+\t\tbreak;\n \t\tcase RTE_FLOW_ITEM_TYPE_TCP:\n \t\t\tmask.tcp = flow_tcf_item_mask\n \t\t\t\t(items, &rte_flow_item_tcp_mask,\n@@ -2121,6 +2544,15 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t\t TCA_FLOWER_KEY_TCP_DST_MASK,\n \t\t\t\t\t\t mask.tcp->hdr.dst_port);\n \t\t\t}\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ITEM_TYPE_VXLAN:\n+\t\t\tassert(decap.vxlan);\n+\t\t\tspec.vxlan = items->spec;\n+\t\t\tmnl_attr_put_u32(nlh,\n+\t\t\t\t\t TCA_FLOWER_KEY_ENC_KEY_ID,\n+\t\t\t\t\t vxlan_vni_as_be32(spec.vxlan->vni));\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n@@ -2154,6 +2586,14 @@ struct flow_tcf_ptoi {\n \t\t\tmnl_attr_put_strz(nlh, TCA_ACT_KIND, \"mirred\");\n \t\t\tna_act = mnl_attr_nest_start(nlh, TCA_ACT_OPTIONS);\n \t\t\tassert(na_act);\n+\t\t\tif (encap.hdr) {\n+\t\t\t\tassert(dev_flow->tcf.tunnel);\n+\t\t\t\tdev_flow->tcf.tunnel->ifindex_ptr =\n+\t\t\t\t\t&((struct tc_mirred *)\n+\t\t\t\t\tmnl_attr_get_payload\n+\t\t\t\t\t(mnl_nlmsg_get_payload_tail\n+\t\t\t\t\t\t(nlh)))->ifindex;\n+\t\t\t}\n \t\t\tmnl_attr_put(nlh, TCA_MIRRED_PARMS,\n \t\t\t\t     sizeof(struct tc_mirred),\n \t\t\t\t     &(struct tc_mirred){\n@@ -2163,6 +2603,7 @@ struct flow_tcf_ptoi {\n \t\t\t\t     });\n \t\t\tmnl_attr_nest_end(nlh, na_act);\n \t\t\tmnl_attr_nest_end(nlh, na_act_index);\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n \t\t\tna_act_index =\n@@ -2243,6 +2684,74 @@ struct flow_tcf_ptoi {\n \t\t\t\t\t(na_vlan_priority) =\n \t\t\t\t\tconf.of_set_vlan_pcp->vlan_pcp;\n \t\t\t}\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:\n+\t\t\tassert(decap.vxlan);\n+\t\t\tassert(dev_flow->tcf.tunnel);\n+\t\t\tdev_flow->tcf.tunnel->ifindex_ptr\n+\t\t\t\t= (unsigned int *)&tcm->tcm_ifindex;\n+\t\t\tna_act_index =\n+\t\t\t\tmnl_attr_nest_start(nlh, na_act_index_cur++);\n+\t\t\tassert(na_act_index);\n+\t\t\tmnl_attr_put_strz(nlh, TCA_ACT_KIND, \"tunnel_key\");\n+\t\t\tna_act = mnl_attr_nest_start(nlh, TCA_ACT_OPTIONS);\n+\t\t\tassert(na_act);\n+\t\t\tmnl_attr_put(nlh, TCA_TUNNEL_KEY_PARMS,\n+\t\t\t\tsizeof(struct tc_tunnel_key),\n+\t\t\t\t&(struct tc_tunnel_key){\n+\t\t\t\t\t.action = TC_ACT_PIPE,\n+\t\t\t\t\t.t_action = TCA_TUNNEL_KEY_ACT_RELEASE,\n+\t\t\t\t\t});\n+\t\t\tmnl_attr_nest_end(nlh, na_act);\n+\t\t\tmnl_attr_nest_end(nlh, na_act_index);\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:\n+\t\t\tassert(encap.vxlan);\n+\t\t\tna_act_index =\n+\t\t\t\tmnl_attr_nest_start(nlh, na_act_index_cur++);\n+\t\t\tassert(na_act_index);\n+\t\t\tmnl_attr_put_strz(nlh, TCA_ACT_KIND, \"tunnel_key\");\n+\t\t\tna_act = mnl_attr_nest_start(nlh, TCA_ACT_OPTIONS);\n+\t\t\tassert(na_act);\n+\t\t\tmnl_attr_put(nlh, TCA_TUNNEL_KEY_PARMS,\n+\t\t\t\tsizeof(struct tc_tunnel_key),\n+\t\t\t\t&(struct tc_tunnel_key){\n+\t\t\t\t\t.action = TC_ACT_PIPE,\n+\t\t\t\t\t.t_action = TCA_TUNNEL_KEY_ACT_SET,\n+\t\t\t\t\t});\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_UDP_DST)\n+\t\t\t\tmnl_attr_put_u16(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_DST_PORT,\n+\t\t\t\t\t encap.vxlan->udp.dst);\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_IPV4_SRC)\n+\t\t\t\tmnl_attr_put_u32(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_IPV4_SRC,\n+\t\t\t\t\t encap.vxlan->ipv4.src);\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_IPV4_DST)\n+\t\t\t\tmnl_attr_put_u32(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_IPV4_DST,\n+\t\t\t\t\t encap.vxlan->ipv4.dst);\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_IPV6_SRC)\n+\t\t\t\tmnl_attr_put(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_IPV6_SRC,\n+\t\t\t\t\t sizeof(encap.vxlan->ipv6.src),\n+\t\t\t\t\t &encap.vxlan->ipv6.src);\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_IPV6_DST)\n+\t\t\t\tmnl_attr_put(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_IPV6_DST,\n+\t\t\t\t\t sizeof(encap.vxlan->ipv6.dst),\n+\t\t\t\t\t &encap.vxlan->ipv6.dst);\n+\t\t\tif (encap.vxlan->mask & MLX5_FLOW_TCF_ENCAP_VXLAN_VNI)\n+\t\t\t\tmnl_attr_put_u32(nlh,\n+\t\t\t\t\t TCA_TUNNEL_KEY_ENC_KEY_ID,\n+\t\t\t\t\t vxlan_vni_as_be32\n+\t\t\t\t\t\t(encap.vxlan->vxlan.vni));\n+\t\t\tmnl_attr_put_u8(nlh, TCA_TUNNEL_KEY_NO_CSUM, 0);\n+\t\t\tmnl_attr_nest_end(nlh, na_act);\n+\t\t\tmnl_attr_nest_end(nlh, na_act_index);\n+\t\t\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n@@ -2254,7 +2763,9 @@ struct flow_tcf_ptoi {\n \tassert(na_flower);\n \tassert(na_flower_act);\n \tmnl_attr_nest_end(nlh, na_flower_act);\n+\tmnl_attr_put_u32(nlh, TCA_FLOWER_FLAGS, TCA_CLS_FLAGS_SKIP_SW);\n \tmnl_attr_nest_end(nlh, na_flower);\n+\tassert(dev_flow->tcf.nlsize >= nlh->nlmsg_len);\n \treturn 0;\n }\n \n",
    "prefixes": [
        "4/5"
    ]
}