get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 47671,
    "url": "http://patches.dpdk.org/api/patches/47671/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1541074741-41368-12-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-12-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1541074741-41368-12-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-11-01T12:19:33",
    "name": "[v3,11/13] net/mlx5: add e-switch VXLAN tunnel devices management",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "6ddf5b650b861ab56d09cca01b374bd5af264583",
    "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-12-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/47671/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/47671/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 DA2B41B272;\n\tThu,  1 Nov 2018 13:19:43 +0100 (CET)",
            "from EUR03-AM5-obe.outbound.protection.outlook.com\n\t(mail-eopbgr30067.outbound.protection.outlook.com [40.107.3.67])\n\tby dpdk.org (Postfix) with ESMTP id E7EE01B160\n\tfor <dev@dpdk.org>; Thu,  1 Nov 2018 13:19:34 +0100 (CET)",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com (10.171.186.150) by\n\tAM4PR05MB1457.eurprd05.prod.outlook.com (10.164.79.27) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1273.20; Thu, 1 Nov 2018 12:19:33 +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:33 +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=+6o2YX0GPEdbRW25HXUPeBzTQnOaCZfQIItVMukiwn0=;\n\tb=L6rT/Sll8wBl3Te7ZySpA7Rp/P73oZwt3cSGpLn3svIFNa8T8palXkae/LrMyKexT+/Pl+Hp6SAhendtfCo27X9WLrGO2MxKp/TY23DnxpIhEDBLGUrgzvayW/9mZjrCuj6m3IHZsNcAHxJZYd+C/3Rf9f8lTzQk1oTqvbRiSpw=",
        "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 11/13] net/mlx5: add e-switch VXLAN tunnel devices\n\tmanagement",
        "Thread-Index": "AQHUcd0lNzSLXeeiUkWLI3y1LXBSZQ==",
        "Date": "Thu, 1 Nov 2018 12:19:33 +0000",
        "Message-ID": "<1541074741-41368-12-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; AM4PR05MB1457;\n\t6:H7UgVyfjKkvyWRqpJNTkL4hPRvxCgoapkkJdlwvJv9o155xLsEv5hp3d4473zXVBlERjO5xlMS/Y2acHQupARKhbWjhvXwjfkQ0LnsMLpMWmYramAkov2TYTJEHUVTGQNKcCraaIxKrErUeYmBadmWDSZPQt7d9deuMHUqNKgVADB7OBELV5LAJhg5tZv8/232JEufsMJIY2qABaVGT9X5sfJa2nvVymm2seyOpJExN0Yw08vbs+XnWv7eyJQeJO9DjTzUkkSEysxEDI2pJ3irgG+jXGUG9pCURz5DbKKZe6Whb8IvnPWQwz1dM3HUeQyqyRYtrOIwZdvFdpA2BB0AUpVwDxVsmXH39CMoLUsfwPzgUR2MRrT+cvTIEB/C+bU0Lj3uUV7QLl7niHyDYUG2+ly/Hjl2ToNmmzkGu7cCNv/lz/sLqX2BIqZYUghdcZdWVxjcdmAxZX/2OMFBYOyg==;\n\t5:eizUztkvPJAm4y4fU6SbBNstiGsWaYENUqsGJyrESbtF+VrvJUDOrdNURgfpFs6xsc95GrUUuFG6kY5djslTNRLRM5N6W842oKsGy2PyobkEa69aq7bllpBO43PNpYw+cTgcusjSibJgd+TsqU4hZFQE6oKpfUED5t3EJ06SZ5I=;\n\t7:r573hAmN5CwKDFuuZSeDJ9O7+V7reK6RU6fgj+dspfLYIO68IGZE34hCKlXufrN7Pvr8e9cFJUuu1Opuu8PmysijaXW6eJZvK9Y30lZp51GMCiJXquPFm4kFcpYiQClqeK80xSptsAafne2K78iqmg==",
        "x-ms-office365-filtering-correlation-id": "585b415f-865e-4824-abba-08d63ff447d7",
        "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:AM4PR05MB1457; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB1457:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB145714C86266C36A38B07DFFD2CE0@AM4PR05MB1457.eurprd05.prod.outlook.com>",
        "x-exchange-antispam-report-test": "UriScan:(211171220733660)(788757137089);",
        "x-ms-exchange-senderadcheck": "1",
        "x-exchange-antispam-report-cfa-test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231382)(944501410)(52105095)(93006095)(93001095)(10201501046)(3002001)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699051)(76991095);\n\tSRVR:AM4PR05MB1457; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB1457; ",
        "x-forefront-prvs": "0843C17679",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(376002)(396003)(39860400002)(346002)(136003)(366004)(199004)(189003)(11346002)(446003)(106356001)(476003)(105586002)(4326008)(97736004)(2616005)(478600001)(6636002)(5250100002)(99286004)(486006)(66066001)(6862004)(2900100001)(25786009)(37006003)(54906003)(5660300001)(316002)(8936002)(8676002)(81156014)(81166006)(4744004)(68736007)(7736002)(305945005)(3846002)(6116002)(76176011)(2906002)(102836004)(26005)(186003)(386003)(6506007)(107886003)(14454004)(6486002)(52116002)(53946003)(6512007)(53936002)(6436002)(36756003)(86362001)(71190400001)(71200400001)(14444005)(5024004)(256004);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB1457;\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": "C1paAfdLe7WZQAEHpSm6QrUcD5iKJUUwWC4XsVkxYI8Fgre45mOR3lTIVIh4pgzHKEazdx0jtXB/o5PZpz7twEtTtY3WxxcudL8MPnK5SxkvDNci0Qcfzje7dmeLQMEjwOQKxF7OGOuT/6hRelE+5kHpEmFrRaFA65PzWcfBWUGEfZEI2DQoDNgoLOTwtf4cWO5kS8A2LJfDY5mnFZ7PsqfaryC4tLAwovdBvZSrtUncv8HcdrsBH6h2sonrukhziU7DR5EaPoAGBc02KGeSMJWDSOANAWPBbmZ9okOBytmKYipWRON7a8VbKXXhjVEWa6/wC/mQJCOPi9YC4Pqjjj34bLBDDf1kWOINHPkcWak=",
        "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": "585b415f-865e-4824-abba-08d63ff447d7",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "01 Nov 2018 12:19:33.3921\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB1457",
        "Subject": "[dpdk-dev] [PATCH v3 11/13] net/mlx5: add e-switch VXLAN tunnel\n\tdevices management",
        "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": "VXLAN interfaces are dynamically created for each local UDP port\nof outer networks and then used as targets for TC \"flower\" filters\nin order to perform encapsulation. These VXLAN interfaces are\nsystem-wide, the only one device with given UDP port can exist\nin the system (the attempt of creating another device with the\nsame UDP local port returns EEXIST), so PMD should support the\nshared device instances database for PMD instances. These VXLAN\nimplicitly created devices are called VTEPs (Virtual Tunnel\nEnd Points).\n\nCreation of the VTEP occurs at the moment of rule applying. The\nlink is set up, root ingress qdisc is also initialized.\n\nEncapsulation VTEPs are created on per port basis, the single\nVTEP is attached to the outer interface and is shared for all\nencapsulation rules on this interface. The source UDP port is\nautomatically selected in range 30000-60000.\n\nFor decapsulaton one VTEP is created per every unique UDP\nlocal port to accept tunnel traffic. The name of created\nVTEP consists of prefix \"vmlx_\" and the number of UDP port in\ndecimal digits without leading zeros (vmlx_4789). The VTEP\ncan be preliminary created in the system before the launching\napplication, it allows to share\tUDP ports between primary\nand secondary processes.\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 | 461 ++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 455 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex 02b64d6..c6e07f5 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -3750,6 +3750,417 @@ struct pedit_parser {\n \treturn -err;\n }\n \n+#define MNL_BUF_EXTRA_SPACE 16\n+#define MNL_REQUEST_SIZE_MIN 256\n+#define MNL_REQUEST_SIZE_MAX 2048\n+#define MNL_REQUEST_SIZE RTE_MIN(RTE_MAX(sysconf(_SC_PAGESIZE), \\\n+\t\t\t\t MNL_REQUEST_SIZE_MIN), MNL_REQUEST_SIZE_MAX)\n+\n+/* VTEP device list is shared between PMD port instances. */\n+static LIST_HEAD(, tcf_vtep) vtep_list_vxlan = LIST_HEAD_INITIALIZER();\n+static pthread_mutex_t vtep_list_mutex = PTHREAD_MUTEX_INITIALIZER;\n+\n+/**\n+ * Deletes VTEP network device.\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] vtep\n+ *   Object represinting the network device to delete. Memory\n+ *   allocated for this object is freed by routine.\n+ */\n+static void\n+flow_tcf_vtep_delete(struct mlx5_flow_tcf_context *tcf,\n+\t\t     struct tcf_vtep *vtep)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct ifinfomsg *ifm;\n+\talignas(struct nlmsghdr)\n+\tuint8_t buf[mnl_nlmsg_size(MNL_ALIGN(sizeof(*ifm))) +\n+\t\t    MNL_BUF_EXTRA_SPACE];\n+\tint ret;\n+\n+\tassert(!vtep->refcnt);\n+\t/* Delete only ifaces those we actually created. */\n+\tif (vtep->created && vtep->ifindex) {\n+\t\tDRV_LOG(INFO, \"VTEP delete (%d)\", vtep->ifindex);\n+\t\tnlh = mnl_nlmsg_put_header(buf);\n+\t\tnlh->nlmsg_type = RTM_DELLINK;\n+\t\tnlh->nlmsg_flags = NLM_F_REQUEST;\n+\t\tifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));\n+\t\tifm->ifi_family = AF_UNSPEC;\n+\t\tifm->ifi_index = vtep->ifindex;\n+\t\tassert(sizeof(buf) >= nlh->nlmsg_len);\n+\t\tret = flow_tcf_nl_ack(tcf, nlh, 0, NULL, NULL);\n+\t\tif (ret)\n+\t\t\tDRV_LOG(WARNING, \"netlink: error deleting vxlan\"\n+\t\t\t\t\t \" encap/decap ifindex %u\",\n+\t\t\t\t\t ifm->ifi_index);\n+\t}\n+\trte_free(vtep);\n+}\n+\n+/**\n+ * Creates VTEP network device.\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] ifouter\n+ *   Outer interface to attach new-created VXLAN device\n+ *   If zero the VXLAN device will not be attached to any device.\n+ *   These VTEPs are used for decapsulation and can be precreated\n+ *   and shared between processes.\n+ * @param[in] port\n+ *   UDP port of created VTEP device.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ * Pointer to created device structure on success,\n+ * NULL otherwise and rte_errno is set.\n+ */\n+#ifdef HAVE_IFLA_VXLAN_COLLECT_METADATA\n+static struct tcf_vtep*\n+flow_tcf_vtep_create(struct mlx5_flow_tcf_context *tcf,\n+\t\t     unsigned int ifouter,\n+\t\t     uint16_t port, struct rte_flow_error *error)\n+{\n+\tstruct tcf_vtep *vtep;\n+\tstruct nlmsghdr *nlh;\n+\tstruct ifinfomsg *ifm;\n+\tchar name[sizeof(MLX5_VXLAN_DEVICE_PFX) + 24];\n+\talignas(struct nlmsghdr)\n+\tuint8_t buf[mnl_nlmsg_size(sizeof(*ifm)) +\n+\t\t    SZ_NLATTR_DATA_OF(sizeof(name)) +\n+\t\t    SZ_NLATTR_NEST * 2 +\n+\t\t    SZ_NLATTR_STRZ_OF(\"vxlan\") +\n+\t\t    SZ_NLATTR_DATA_OF(sizeof(uint32_t)) +\n+\t\t    SZ_NLATTR_DATA_OF(sizeof(uint16_t)) +\n+\t\t    SZ_NLATTR_DATA_OF(sizeof(uint8_t)) * 3 +\n+\t\t    MNL_BUF_EXTRA_SPACE];\n+\tstruct nlattr *na_info;\n+\tstruct nlattr *na_vxlan;\n+\trte_be16_t vxlan_port = rte_cpu_to_be_16(port);\n+\tint ret;\n+\n+\tvtep = rte_zmalloc(__func__, sizeof(*vtep), alignof(struct tcf_vtep));\n+\tif (!vtep) {\n+\t\trte_flow_error_set\n+\t\t\t(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"unadble to allocate memory for VTEP desc\");\n+\t\treturn NULL;\n+\t}\n+\t*vtep = (struct tcf_vtep){\n+\t\t\t.port = port,\n+\t\t\t.local = LIST_HEAD_INITIALIZER(),\n+\t\t\t.neigh = LIST_HEAD_INITIALIZER(),\n+\t};\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_NEWLINK;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE  | NLM_F_EXCL;\n+\tifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));\n+\tifm->ifi_family = AF_UNSPEC;\n+\tifm->ifi_type = 0;\n+\tifm->ifi_index = 0;\n+\tifm->ifi_flags = IFF_UP;\n+\tifm->ifi_change = 0xffffffff;\n+\tsnprintf(name, sizeof(name), \"%s%u\", MLX5_VXLAN_DEVICE_PFX, port);\n+\tmnl_attr_put_strz(nlh, IFLA_IFNAME, name);\n+\tna_info = mnl_attr_nest_start(nlh, IFLA_LINKINFO);\n+\tassert(na_info);\n+\tmnl_attr_put_strz(nlh, IFLA_INFO_KIND, \"vxlan\");\n+\tna_vxlan = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);\n+\tif (ifouter)\n+\t\tmnl_attr_put_u32(nlh, IFLA_VXLAN_LINK, ifouter);\n+\tassert(na_vxlan);\n+\tmnl_attr_put_u8(nlh, IFLA_VXLAN_COLLECT_METADATA, 1);\n+\tmnl_attr_put_u8(nlh, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, 1);\n+\tmnl_attr_put_u8(nlh, IFLA_VXLAN_LEARNING, 0);\n+\tmnl_attr_put_u16(nlh, IFLA_VXLAN_PORT, vxlan_port);\n+\tmnl_attr_nest_end(nlh, na_vxlan);\n+\tmnl_attr_nest_end(nlh, na_info);\n+\tassert(sizeof(buf) >= nlh->nlmsg_len);\n+\tret = flow_tcf_nl_ack(tcf, nlh, 0, NULL, NULL);\n+\tif (ret) {\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"netlink: VTEP %s create failure (%d)\",\n+\t\t\tname, rte_errno);\n+\t\tif (rte_errno != EEXIST || ifouter)\n+\t\t\t/*\n+\t\t\t * Some unhandled error occurred or device is\n+\t\t\t * for encapsulation and cannot be shared.\n+\t\t\t */\n+\t\t\tgoto error;\n+\t} else {\n+\t\t/*\n+\t\t * Mark device we actually created.\n+\t\t * We should explicitly delete\n+\t\t * when we do not need it anymore.\n+\t\t */\n+\t\tvtep->created = 1;\n+\t}\n+\t/* Try to get ifindex of created of pre-existing device. */\n+\tret = if_nametoindex(name);\n+\tif (!ret) {\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"VTEP %s failed to get index (%d)\", name, errno);\n+\t\trte_flow_error_set\n+\t\t\t(error, -errno,\n+\t\t\t RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t \"netlink: failed to retrieve VTEP ifindex\");\n+\t\tgoto error;\n+\t}\n+\tvtep->ifindex = ret;\n+\tvtep->ifouter = ifouter;\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_NEWLINK;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST;\n+\tifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));\n+\tifm->ifi_family = AF_UNSPEC;\n+\tifm->ifi_type = 0;\n+\tifm->ifi_index = vtep->ifindex;\n+\tifm->ifi_flags = IFF_UP;\n+\tifm->ifi_change = IFF_UP;\n+\tret = flow_tcf_nl_ack(tcf, nlh, 0, NULL, NULL);\n+\tif (ret) {\n+\t\trte_flow_error_set(error, -errno,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"netlink: failed to set VTEP link up\");\n+\t\tDRV_LOG(WARNING, \"netlink: VTEP %s set link up failure (%d)\",\n+\t\t\tname, rte_errno);\n+\t\tgoto clean;\n+\t}\n+\tret = mlx5_flow_tcf_init(tcf, vtep->ifindex, error);\n+\tif (ret) {\n+\t\tDRV_LOG(WARNING, \"VTEP %s init failure (%d)\", name, rte_errno);\n+\t\tgoto clean;\n+\t}\n+\tDRV_LOG(INFO, \"VTEP create (%d, %d)\", vtep->port, vtep->ifindex);\n+\tvtep->refcnt = 1;\n+\treturn vtep;\n+clean:\n+\tflow_tcf_vtep_delete(tcf, vtep);\n+\treturn NULL;\n+error:\n+\trte_free(vtep);\n+\treturn NULL;\n+}\n+#else\n+static struct tcf_vtep*\n+flow_tcf_vtep_create(struct mlx5_flow_tcf_context *tcf __rte_unused,\n+\t\t     unsigned int ifouter __rte_unused,\n+\t\t     uint16_t port __rte_unused,\n+\t\t     struct rte_flow_error *error)\n+{\n+\trte_flow_error_set(error, ENOTSUP,\n+\t\t\t RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t \"netlink: failed to create VTEP, \"\n+\t\t\t \"VXLAN metadata are not supported by kernel\");\n+\treturn NULL;\n+}\n+#endif /* HAVE_IFLA_VXLAN_COLLECT_METADATA */\n+\n+/**\n+ * Acquire target interface index for VXLAN tunneling decapsulation.\n+ * In order to share the UDP port within the other interfaces the\n+ * VXLAN device created as not attached to any interface (if created).\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] dev_flow\n+ *   Flow tcf object with tunnel structure pointer set.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ * @return\n+ *   Interface descriptor pointer on success,\n+ *   NULL otherwise and rte_errno is set.\n+ */\n+static struct tcf_vtep*\n+flow_tcf_decap_vtep_acquire(struct mlx5_flow_tcf_context *tcf,\n+\t\t\t    struct mlx5_flow *dev_flow,\n+\t\t\t    struct rte_flow_error *error)\n+{\n+\tstruct tcf_vtep *vtep;\n+\tuint16_t port = dev_flow->tcf.vxlan_decap->udp_port;\n+\n+\tLIST_FOREACH(vtep, &vtep_list_vxlan, next) {\n+\t\tif (vtep->port == port)\n+\t\t\tbreak;\n+\t}\n+\tif (vtep && vtep->ifouter) {\n+\t\trte_flow_error_set(error, -errno,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"Failed to create decap VTEP with specified\"\n+\t\t\t\t   \" UDP port, atatched device exists\");\n+\t\treturn NULL;\n+\t}\n+\tif (vtep) {\n+\t\t/* Device exists, just increment the reference counter. */\n+\t\tvtep->refcnt++;\n+\t\tassert(vtep->ifindex);\n+\t\treturn vtep;\n+\t}\n+\t/* No decapsulation device exists, try to create the new one. */\n+\tvtep = flow_tcf_vtep_create(tcf, 0, port, error);\n+\tif (vtep)\n+\t\tLIST_INSERT_HEAD(&vtep_list_vxlan, vtep, next);\n+\treturn vtep;\n+}\n+\n+/**\n+ * Aqcuire target interface index for VXLAN tunneling encapsulation.\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] ifouter\n+ *   Network interface index to attach VXLAN encap device to.\n+ * @param[in] dev_flow\n+ *   Flow tcf object with tunnel structure pointer set.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ * @return\n+ *   Interface descriptor pointer on success,\n+ *   NULL otherwise and rte_errno is set.\n+ */\n+static struct tcf_vtep*\n+flow_tcf_encap_vtep_acquire(struct mlx5_flow_tcf_context *tcf,\n+\t\t\t    unsigned int ifouter,\n+\t\t\t    struct mlx5_flow *dev_flow __rte_unused,\n+\t\t\t    struct rte_flow_error *error)\n+{\n+\tstatic uint16_t encap_port = MLX5_VXLAN_PORT_MIN - 1;\n+\tstruct tcf_vtep *vtep;\n+\n+\tassert(ifouter);\n+\t/* Look whether the attached VTEP for encap is created. */\n+\tLIST_FOREACH(vtep, &vtep_list_vxlan, next) {\n+\t\tif (vtep->ifouter == ifouter)\n+\t\t\tbreak;\n+\t}\n+\tif (vtep) {\n+\t\t/* VTEP already exists, just increment the reference. */\n+\t\tvtep->refcnt++;\n+\t} else {\n+\t\tuint16_t pcnt;\n+\n+\t\t/* Not found, we should create the new attached VTEP. */\n+\t\tfor (pcnt = 0; pcnt <= (MLX5_VXLAN_PORT_MAX\n+\t\t\t\t     - MLX5_VXLAN_PORT_MIN); pcnt++) {\n+\t\t\tencap_port++;\n+\t\t\t/* Wraparound the UDP port index. */\n+\t\t\tif (encap_port < MLX5_VXLAN_PORT_MIN ||\n+\t\t\t    encap_port > MLX5_VXLAN_PORT_MAX)\n+\t\t\t\tencap_port = MLX5_VXLAN_PORT_MIN;\n+\t\t\t/* Check whether UDP port is in already in use. */\n+\t\t\tLIST_FOREACH(vtep, &vtep_list_vxlan, next) {\n+\t\t\t\tif (vtep->port == encap_port)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (vtep) {\n+\t\t\t\t/* Port is in use, try the next one. */\n+\t\t\t\tvtep = NULL;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tvtep = flow_tcf_vtep_create(tcf, ifouter,\n+\t\t\t\t\t\t    encap_port, error);\n+\t\t\tif (vtep) {\n+\t\t\t\tLIST_INSERT_HEAD(&vtep_list_vxlan, vtep, next);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (rte_errno != EEXIST)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tif (!vtep)\n+\t\t\treturn NULL;\n+\t}\n+\tassert(vtep->ifouter == ifouter);\n+\tassert(vtep->ifindex);\n+\treturn vtep;\n+}\n+\n+/**\n+ * Acquires target interface index for tunneling of any type.\n+ * Creates the new VTEP if needed.\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] ifouter\n+ *   Network interface index to attach VXLAN encap device to.\n+ * @param[in] dev_flow\n+ *   Flow tcf object with tunnel structure pointer set.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ * @return\n+ *   Interface descriptor pointer on success,\n+ *   NULL otherwise and rte_errno is set.\n+ */\n+static struct tcf_vtep*\n+flow_tcf_vtep_acquire(struct mlx5_flow_tcf_context *tcf,\n+\t\t      unsigned int ifouter,\n+\t\t      struct mlx5_flow *dev_flow,\n+\t\t      struct rte_flow_error *error)\n+{\n+\tstruct tcf_vtep *vtep = NULL;\n+\n+\tassert(dev_flow->tcf.tunnel);\n+\tpthread_mutex_lock(&vtep_list_mutex);\n+\tswitch (dev_flow->tcf.tunnel->type) {\n+\tcase FLOW_TCF_TUNACT_VXLAN_ENCAP:\n+\t\tvtep = flow_tcf_encap_vtep_acquire(tcf, ifouter,\n+\t\t\t\t\t\t  dev_flow, error);\n+\t\tbreak;\n+\tcase FLOW_TCF_TUNACT_VXLAN_DECAP:\n+\t\tvtep = flow_tcf_decap_vtep_acquire(tcf, dev_flow, error);\n+\t\tbreak;\n+\tdefault:\n+\t\trte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\"unsupported tunnel type\");\n+\t\tbreak;\n+\t}\n+\tpthread_mutex_unlock(&vtep_list_mutex);\n+\treturn vtep;\n+}\n+\n+/**\n+ * Release tunneling interface by ifindex. Decrements reference\n+ * counter and actually removes the device if counter is zero.\n+ *\n+ * @param[in] tcf\n+ *   Context object initialized by mlx5_flow_tcf_context_create().\n+ * @param[in] vtep\n+ *   VTEP device descriptor structure.\n+ * @param[in] dev_flow\n+ *   Flow tcf object with tunnel structure pointer set.\n+ */\n+static void\n+flow_tcf_vtep_release(struct mlx5_flow_tcf_context *tcf,\n+\t\t      struct tcf_vtep *vtep,\n+\t\t      struct mlx5_flow *dev_flow)\n+{\n+\tassert(dev_flow->tcf.tunnel);\n+\tpthread_mutex_lock(&vtep_list_mutex);\n+\tswitch (dev_flow->tcf.tunnel->type) {\n+\tcase FLOW_TCF_TUNACT_VXLAN_DECAP:\n+\t\tbreak;\n+\tcase FLOW_TCF_TUNACT_VXLAN_ENCAP:\n+\t\tbreak;\n+\tdefault:\n+\t\tassert(false);\n+\t\tDRV_LOG(WARNING, \"Unsupported tunnel type\");\n+\t\tbreak;\n+\t}\n+\tassert(vtep->refcnt);\n+\tif (--vtep->refcnt == 0) {\n+\t\tLIST_REMOVE(vtep, next);\n+\t\tflow_tcf_vtep_delete(tcf, vtep);\n+\t}\n+\tpthread_mutex_unlock(&vtep_list_mutex);\n+}\n+\n+\n /**\n  * Apply flow to E-Switch by sending Netlink message.\n  *\n@@ -3775,11 +4186,35 @@ struct pedit_parser {\n \tdev_flow = LIST_FIRST(&flow->dev_flows);\n \t/* E-Switch flow can't be expanded. */\n \tassert(!LIST_NEXT(dev_flow, next));\n+\tif (dev_flow->tcf.applied)\n+\t\treturn 0;\n \tnlh = dev_flow->tcf.nlh;\n \tnlh->nlmsg_type = RTM_NEWTFILTER;\n \tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n-\tif (!flow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL))\n+\tif (dev_flow->tcf.tunnel) {\n+\t\t/*\n+\t\t * Replace the interface index, target for\n+\t\t * encapsulation, source for decapsulation.\n+\t\t */\n+\t\tassert(!dev_flow->tcf.tunnel->vtep);\n+\t\tassert(dev_flow->tcf.tunnel->ifindex_ptr);\n+\t\t/* Acquire actual VTEP device when rule is being applied. */\n+\t\tdev_flow->tcf.tunnel->vtep =\n+\t\t\tflow_tcf_vtep_acquire(ctx,\n+\t\t\t\t\tdev_flow->tcf.tunnel->ifindex_org,\n+\t\t\t\t\tdev_flow, error);\n+\t\tif (!dev_flow->tcf.tunnel->vtep)\n+\t\t\treturn -rte_errno;\n+\t\tDRV_LOG(INFO, \"Replace ifindex: %d->%d\",\n+\t\t\t\tdev_flow->tcf.tunnel->vtep->ifindex,\n+\t\t\t\tdev_flow->tcf.tunnel->ifindex_org);\n+\t\t*dev_flow->tcf.tunnel->ifindex_ptr =\n+\t\t\tdev_flow->tcf.tunnel->vtep->ifindex;\n+\t}\n+\tif (!flow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL)) {\n+\t\tdev_flow->tcf.applied = 1;\n \t\treturn 0;\n+\t}\n \treturn rte_flow_error_set(error, rte_errno,\n \t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t  \"netlink: failed to create TC flow rule\");\n@@ -3808,10 +4243,20 @@ struct pedit_parser {\n \t\treturn;\n \t/* E-Switch flow can't be expanded. */\n \tassert(!LIST_NEXT(dev_flow, next));\n-\tnlh = dev_flow->tcf.nlh;\n-\tnlh->nlmsg_type = RTM_DELTFILTER;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST;\n-\tflow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL);\n+\tif (dev_flow->tcf.applied) {\n+\t\tnlh = dev_flow->tcf.nlh;\n+\t\tnlh->nlmsg_type = RTM_DELTFILTER;\n+\t\tnlh->nlmsg_flags = NLM_F_REQUEST;\n+\t\tflow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL);\n+\t\tif (dev_flow->tcf.tunnel) {\n+\t\t\tassert(dev_flow->tcf.tunnel->vtep);\n+\t\t\tflow_tcf_vtep_release(ctx,\n+\t\t\t\tdev_flow->tcf.tunnel->vtep,\n+\t\t\t\tdev_flow);\n+\t\t\tdev_flow->tcf.tunnel->vtep = NULL;\n+\t\t}\n+\t\tdev_flow->tcf.applied = 0;\n+\t}\n }\n \n /**\n@@ -4338,7 +4783,9 @@ struct pedit_parser {\n \tstruct nlmsghdr *nlh;\n \tstruct tcmsg *tcm;\n \talignas(struct nlmsghdr)\n-\tuint8_t buf[mnl_nlmsg_size(sizeof(*tcm) + 128)];\n+\tuint8_t buf[mnl_nlmsg_size(sizeof(*tcm)) +\n+\t\t    SZ_NLATTR_STRZ_OF(\"ingress\") +\n+\t\t    MNL_BUF_EXTRA_SPACE];\n \n \t/* Destroy existing ingress qdisc and everything attached to it. */\n \tnlh = mnl_nlmsg_put_header(buf);\n@@ -4349,6 +4796,7 @@ struct pedit_parser {\n \ttcm->tcm_ifindex = ifindex;\n \ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n \ttcm->tcm_parent = TC_H_INGRESS;\n+\tassert(sizeof(buf) >= nlh->nlmsg_len);\n \t/* Ignore errors when qdisc is already absent. */\n \tif (flow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL) &&\n \t    rte_errno != EINVAL && rte_errno != ENOENT)\n@@ -4366,6 +4814,7 @@ struct pedit_parser {\n \ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n \ttcm->tcm_parent = TC_H_INGRESS;\n \tmnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, \"ingress\");\n+\tassert(sizeof(buf) >= nlh->nlmsg_len);\n \tif (flow_tcf_nl_ack(ctx, nlh, 0, NULL, NULL))\n \t\treturn rte_flow_error_set(error, rte_errno,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n",
    "prefixes": [
        "v3",
        "11/13"
    ]
}