get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64971,
    "url": "http://patches.dpdk.org/api/patches/64971/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-35-git-send-email-matan@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": "<1579539790-3882-35-git-send-email-matan@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1579539790-3882-35-git-send-email-matan@mellanox.com",
    "date": "2020-01-20T17:03:06",
    "name": "[v1,34/38] net/mlx5: separate Netlink commands interface",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "21537e55ac3b001122e0db5fa9a68bb0b9678245",
    "submitter": {
        "id": 796,
        "url": "http://patches.dpdk.org/api/people/796/?format=api",
        "name": "Matan Azrad",
        "email": "matan@mellanox.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-35-git-send-email-matan@mellanox.com/mbox/",
    "series": [
        {
            "id": 8223,
            "url": "http://patches.dpdk.org/api/series/8223/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8223",
            "date": "2020-01-20T17:02:37",
            "name": "Introduce mlx5 vDPA driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/8223/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/64971/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/64971/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 95529A0526;\n\tMon, 20 Jan 2020 18:09:50 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 54DE01C0D8;\n\tMon, 20 Jan 2020 18:04:14 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id DCA511BFB2\n for <dev@dpdk.org>; Mon, 20 Jan 2020 18:03:14 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n asafp@mellanox.com)\n with ESMTPS (AES256-SHA encrypted); 20 Jan 2020 19:03:14 +0200",
            "from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx\n [10.210.16.112])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00KH3BGr024424;\n Mon, 20 Jan 2020 19:03:14 +0200"
        ],
        "From": "Matan Azrad <matan@mellanox.com>",
        "To": "dev@dpdk.org",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>,\n Thomas Monjalon <thomas@monjalon.net>",
        "Date": "Mon, 20 Jan 2020 17:03:06 +0000",
        "Message-Id": "<1579539790-3882-35-git-send-email-matan@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "References": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v1 34/38] net/mlx5: separate Netlink commands\n\tinterface",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The Netlink commands interfaces is included in the mlx5.h file with a\nlot of other PMD interfaces.\n\nAs an arrangement to make the Netlink commands shared with different\nPMDs, this patch moves the Netlink interface to a new file called\nmlx5_nl.h.\n\nMove non Netlink pure vlan commands from mlx5_nl.c to the\nmlx5_vlan.c.\n\nRename all the Netlink commands and structure to use prefix mlx5_nl.\n\nSigned-off-by: Matan Azrad <matan@mellanox.com>\n---\n drivers/net/mlx5/mlx5.h      |  72 +++------------------\n drivers/net/mlx5/mlx5_nl.c   | 149 +++----------------------------------------\n drivers/net/mlx5/mlx5_nl.h   |  69 ++++++++++++++++++++\n drivers/net/mlx5/mlx5_vlan.c | 134 ++++++++++++++++++++++++++++++++++++++\n 4 files changed, 220 insertions(+), 204 deletions(-)\n create mode 100644 drivers/net/mlx5/mlx5_nl.h",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex f6488e1..5cfcf99 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -39,6 +39,7 @@\n #include \"mlx5_defs.h\"\n #include \"mlx5_utils.h\"\n #include \"mlx5_mr.h\"\n+#include \"mlx5_nl.h\"\n #include \"mlx5_autoconf.h\"\n \n /* Request types for IPC. */\n@@ -75,24 +76,6 @@ struct mlx5_mp_param {\n /** Key string for IPC. */\n #define MLX5_MP_NAME \"net_mlx5_mp\"\n \n-/* Recognized Infiniband device physical port name types. */\n-enum mlx5_phys_port_name_type {\n-\tMLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */\n-\tMLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */\n-\tMLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */\n-\tMLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */\n-\tMLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */\n-};\n-\n-/** Switch information returned by mlx5_nl_switch_info(). */\n-struct mlx5_switch_info {\n-\tuint32_t master:1; /**< Master device. */\n-\tuint32_t representor:1; /**< Representor device. */\n-\tenum mlx5_phys_port_name_type name_type; /** < Port name type. */\n-\tint32_t pf_num; /**< PF number (valid for pfxvfx format only). */\n-\tint32_t port_name; /**< Representor port name. */\n-\tuint64_t switch_id; /**< Switch identifier. */\n-};\n \n LIST_HEAD(mlx5_dev_list, mlx5_ibv_shared);\n \n@@ -226,30 +209,12 @@ enum mlx5_verbs_alloc_type {\n \tMLX5_VERBS_ALLOC_TYPE_RX_QUEUE,\n };\n \n-/* VLAN netdev for VLAN workaround. */\n-struct mlx5_vlan_dev {\n-\tuint32_t refcnt;\n-\tuint32_t ifindex; /**< Own interface index. */\n-};\n-\n /* Structure for VF VLAN workaround. */\n struct mlx5_vf_vlan {\n \tuint32_t tag:12;\n \tuint32_t created:1;\n };\n \n-/*\n- * Array of VLAN devices created on the base of VF\n- * used for workaround in virtual environments.\n- */\n-struct mlx5_vlan_vmwa_context {\n-\tint nl_socket;\n-\tuint32_t nl_sn;\n-\tuint32_t vf_ifindex;\n-\tstruct rte_eth_dev *dev;\n-\tstruct mlx5_vlan_dev vlan_dev[4096];\n-};\n-\n /**\n  * Verbs allocator needs a context to know in the callback which kind of\n  * resources it is allocating.\n@@ -574,7 +539,7 @@ struct mlx5_priv {\n \tint nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */\n \tuint32_t nl_sn; /* Netlink message sequence number. */\n \tLIST_HEAD(dbrpage, mlx5_devx_dbr_page) dbrpgs; /* Door-bell pages. */\n-\tstruct mlx5_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */\n+\tstruct mlx5_nl_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */\n \tstruct mlx5_flow_id_pool *qrss_id_pool;\n \tstruct mlx5_hlist *mreg_cp_tbl;\n \t/* Hash table of Rx metadata register copy table. */\n@@ -670,6 +635,8 @@ int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,\n void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);\n int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,\n \t\t      uint32_t index, uint32_t vmdq);\n+struct mlx5_nl_vlan_vmwa_context *mlx5_vlan_vmwa_init\n+\t\t\t\t    (struct rte_eth_dev *dev, uint32_t ifindex);\n int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr);\n int mlx5_set_mc_addr_list(struct rte_eth_dev *dev,\n \t\t\tstruct rte_ether_addr *mc_addr_set,\n@@ -713,6 +680,11 @@ int mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused,\n int mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);\n void mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on);\n int mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask);\n+void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *ctx);\n+void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,\n+\t\t\t    struct mlx5_vf_vlan *vf_vlan);\n+void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,\n+\t\t\t    struct mlx5_vf_vlan *vf_vlan);\n \n /* mlx5_trigger.c */\n \n@@ -794,32 +766,6 @@ int mlx5_mp_req_queue_state_modify(struct rte_eth_dev *dev,\n int mlx5_pmd_socket_init(void);\n void mlx5_pmd_socket_uninit(void);\n \n-/* mlx5_nl.c */\n-\n-int mlx5_nl_init(int protocol);\n-int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,\n-\t\t\t uint32_t index);\n-int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,\n-\t\t\t    uint32_t index);\n-void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev);\n-void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev);\n-int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable);\n-int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable);\n-unsigned int mlx5_nl_portnum(int nl, const char *name);\n-unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex);\n-int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev,\n-\t\t\t       struct rte_ether_addr *mac, int vf_index);\n-int mlx5_nl_switch_info(int nl, unsigned int ifindex,\n-\t\t\tstruct mlx5_switch_info *info);\n-\n-struct mlx5_vlan_vmwa_context *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,\n-\t\t\t\t\t\t   uint32_t ifindex);\n-void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *ctx);\n-void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,\n-\t\t\t    struct mlx5_vf_vlan *vf_vlan);\n-void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,\n-\t\t\t    struct mlx5_vf_vlan *vf_vlan);\n-\n /* mlx5_flow_meter.c */\n \n int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);\ndiff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c\nindex e7ba034..3fe4b6f 100644\n--- a/drivers/net/mlx5/mlx5_nl.c\n+++ b/drivers/net/mlx5/mlx5_nl.c\n@@ -5,7 +5,6 @@\n \n #include <errno.h>\n #include <linux/if_link.h>\n-#include <linux/netlink.h>\n #include <linux/rtnetlink.h>\n #include <net/if.h>\n #include <rdma/rdma_netlink.h>\n@@ -18,8 +17,6 @@\n #include <unistd.h>\n \n #include <rte_errno.h>\n-#include <rte_malloc.h>\n-#include <rte_hypervisor.h>\n \n #include \"mlx5.h\"\n #include \"mlx5_utils.h\"\n@@ -1072,7 +1069,8 @@ struct mlx5_nl_ifindex_data {\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n int\n-mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info)\n+mlx5_nl_switch_info(int nl, unsigned int ifindex,\n+\t\t    struct mlx5_switch_info *info)\n {\n \tuint32_t seq = random();\n \tstruct {\n@@ -1116,12 +1114,12 @@ struct mlx5_nl_ifindex_data {\n  * Delete VLAN network device by ifindex.\n  *\n  * @param[in] tcf\n- *   Context object initialized by mlx5_vlan_vmwa_init().\n+ *   Context object initialized by mlx5_nl_vlan_vmwa_init().\n  * @param[in] ifindex\n  *   Interface index of network device to delete.\n  */\n-static void\n-mlx5_vlan_vmwa_delete(struct mlx5_vlan_vmwa_context *vmwa,\n+void\n+mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa,\n \t\t      uint32_t ifindex)\n {\n \tint ret;\n@@ -1196,14 +1194,14 @@ struct mlx5_nl_ifindex_data {\n  * Create network VLAN device with specified VLAN tag.\n  *\n  * @param[in] tcf\n- *   Context object initialized by mlx5_vlan_vmwa_init().\n+ *   Context object initialized by mlx5_nl_vlan_vmwa_init().\n  * @param[in] ifindex\n  *   Base network interface index.\n  * @param[in] tag\n  *   VLAN tag for VLAN network device to create.\n  */\n-static uint32_t\n-mlx5_vlan_vmwa_create(struct mlx5_vlan_vmwa_context *vmwa,\n+uint32_t\n+mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa,\n \t\t      uint32_t ifindex,\n \t\t      uint16_t tag)\n {\n@@ -1269,134 +1267,3 @@ struct mlx5_nl_ifindex_data {\n \t}\n \treturn ret;\n }\n-\n-/*\n- * Release VLAN network device, created for VM workaround.\n- *\n- * @param[in] dev\n- *   Ethernet device object, Netlink context provider.\n- * @param[in] vlan\n- *   Object representing the network device to release.\n- */\n-void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,\n-\t\t\t    struct mlx5_vf_vlan *vlan)\n-{\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context;\n-\tstruct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];\n-\n-\tassert(vlan->created);\n-\tassert(priv->vmwa_context);\n-\tif (!vlan->created || !vmwa)\n-\t\treturn;\n-\tvlan->created = 0;\n-\tassert(vlan_dev[vlan->tag].refcnt);\n-\tif (--vlan_dev[vlan->tag].refcnt == 0 &&\n-\t    vlan_dev[vlan->tag].ifindex) {\n-\t\tmlx5_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex);\n-\t\tvlan_dev[vlan->tag].ifindex = 0;\n-\t}\n-}\n-\n-/**\n- * Acquire VLAN interface with specified tag for VM workaround.\n- *\n- * @param[in] dev\n- *   Ethernet device object, Netlink context provider.\n- * @param[in] vlan\n- *   Object representing the network device to acquire.\n- */\n-void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,\n-\t\t\t    struct mlx5_vf_vlan *vlan)\n-{\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context;\n-\tstruct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];\n-\n-\tassert(!vlan->created);\n-\tassert(priv->vmwa_context);\n-\tif (vlan->created || !vmwa)\n-\t\treturn;\n-\tif (vlan_dev[vlan->tag].refcnt == 0) {\n-\t\tassert(!vlan_dev[vlan->tag].ifindex);\n-\t\tvlan_dev[vlan->tag].ifindex =\n-\t\t\tmlx5_vlan_vmwa_create(vmwa,\n-\t\t\t\t\t      vmwa->vf_ifindex,\n-\t\t\t\t\t      vlan->tag);\n-\t}\n-\tif (vlan_dev[vlan->tag].ifindex) {\n-\t\tvlan_dev[vlan->tag].refcnt++;\n-\t\tvlan->created = 1;\n-\t}\n-}\n-\n-/*\n- * Create per ethernet device VLAN VM workaround context\n- */\n-struct mlx5_vlan_vmwa_context *\n-mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,\n-\t\t    uint32_t ifindex)\n-{\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_dev_config *config = &priv->config;\n-\tstruct mlx5_vlan_vmwa_context *vmwa;\n-\tenum rte_hypervisor hv_type;\n-\n-\t/* Do not engage workaround over PF. */\n-\tif (!config->vf)\n-\t\treturn NULL;\n-\t/* Check whether there is desired virtual environment */\n-\thv_type = rte_hypervisor_get();\n-\tswitch (hv_type) {\n-\tcase RTE_HYPERVISOR_UNKNOWN:\n-\tcase RTE_HYPERVISOR_VMWARE:\n-\t\t/*\n-\t\t * The \"white list\" of configurations\n-\t\t * to engage the workaround.\n-\t\t */\n-\t\tbreak;\n-\tdefault:\n-\t\t/*\n-\t\t * The configuration is not found in the \"white list\".\n-\t\t * We should not engage the VLAN workaround.\n-\t\t */\n-\t\treturn NULL;\n-\t}\n-\tvmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t));\n-\tif (!vmwa) {\n-\t\tDRV_LOG(WARNING,\n-\t\t\t\"Can not allocate memory\"\n-\t\t\t\" for VLAN workaround context\");\n-\t\treturn NULL;\n-\t}\n-\tvmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE);\n-\tif (vmwa->nl_socket < 0) {\n-\t\tDRV_LOG(WARNING,\n-\t\t\t\"Can not create Netlink socket\"\n-\t\t\t\" for VLAN workaround context\");\n-\t\trte_free(vmwa);\n-\t\treturn NULL;\n-\t}\n-\tvmwa->nl_sn = random();\n-\tvmwa->vf_ifindex = ifindex;\n-\tvmwa->dev = dev;\n-\t/* Cleanup for existing VLAN devices. */\n-\treturn vmwa;\n-}\n-\n-/*\n- * Destroy per ethernet device VLAN VM workaround context\n- */\n-void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *vmwa)\n-{\n-\tunsigned int i;\n-\n-\t/* Delete all remaining VLAN devices. */\n-\tfor (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) {\n-\t\tif (vmwa->vlan_dev[i].ifindex)\n-\t\t\tmlx5_vlan_vmwa_delete(vmwa, vmwa->vlan_dev[i].ifindex);\n-\t}\n-\tif (vmwa->nl_socket >= 0)\n-\t\tclose(vmwa->nl_socket);\n-\trte_free(vmwa);\n-}\ndiff --git a/drivers/net/mlx5/mlx5_nl.h b/drivers/net/mlx5/mlx5_nl.h\nnew file mode 100644\nindex 0000000..7903673\n--- /dev/null\n+++ b/drivers/net/mlx5/mlx5_nl.h\n@@ -0,0 +1,69 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019 Mellanox Technologies, Ltd\n+ */\n+\n+#ifndef RTE_PMD_MLX5_NL_H_\n+#define RTE_PMD_MLX5_NL_H_\n+\n+#include <linux/netlink.h>\n+\n+\n+/* Recognized Infiniband device physical port name types. */\n+enum mlx5_nl_phys_port_name_type {\n+\tMLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */\n+\tMLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */\n+\tMLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */\n+\tMLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */\n+\tMLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */\n+};\n+\n+/** Switch information returned by mlx5_nl_switch_info(). */\n+struct mlx5_switch_info {\n+\tuint32_t master:1; /**< Master device. */\n+\tuint32_t representor:1; /**< Representor device. */\n+\tenum mlx5_nl_phys_port_name_type name_type; /** < Port name type. */\n+\tint32_t pf_num; /**< PF number (valid for pfxvfx format only). */\n+\tint32_t port_name; /**< Representor port name. */\n+\tuint64_t switch_id; /**< Switch identifier. */\n+};\n+\n+/* VLAN netdev for VLAN workaround. */\n+struct mlx5_nl_vlan_dev {\n+\tuint32_t refcnt;\n+\tuint32_t ifindex; /**< Own interface index. */\n+};\n+\n+/*\n+ * Array of VLAN devices created on the base of VF\n+ * used for workaround in virtual environments.\n+ */\n+struct mlx5_nl_vlan_vmwa_context {\n+\tint nl_socket;\n+\tuint32_t nl_sn;\n+\tuint32_t vf_ifindex;\n+\tstruct mlx5_nl_vlan_dev vlan_dev[4096];\n+};\n+\n+\n+int mlx5_nl_init(int protocol);\n+int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,\n+\t\t\t uint32_t index);\n+int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,\n+\t\t\t    uint32_t index);\n+void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev);\n+void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev);\n+int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable);\n+int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable);\n+unsigned int mlx5_nl_portnum(int nl, const char *name);\n+unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex);\n+int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev,\n+\t\t\t       struct rte_ether_addr *mac, int vf_index);\n+int mlx5_nl_switch_info(int nl, unsigned int ifindex,\n+\t\t\tstruct mlx5_switch_info *info);\n+\n+void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa,\n+\t\t\t   uint32_t ifindex);\n+uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa,\n+\t\t\t\t  uint32_t ifindex, uint16_t tag);\n+\n+#endif /* RTE_PMD_MLX5_NL_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c\nindex b0fa31a..fb52d8f 100644\n--- a/drivers/net/mlx5/mlx5_vlan.c\n+++ b/drivers/net/mlx5/mlx5_vlan.c\n@@ -7,6 +7,8 @@\n #include <errno.h>\n #include <assert.h>\n #include <stdint.h>\n+#include <unistd.h>\n+\n \n /*\n  * Not needed by this file; included to work around the lack of off_t\n@@ -26,6 +28,8 @@\n \n #include <rte_ethdev_driver.h>\n #include <rte_common.h>\n+#include <rte_malloc.h>\n+#include <rte_hypervisor.h>\n \n #include <mlx5_glue.h>\n #include <mlx5_devx_cmds.h>\n@@ -33,6 +37,7 @@\n #include \"mlx5.h\"\n #include \"mlx5_autoconf.h\"\n #include \"mlx5_rxtx.h\"\n+#include \"mlx5_nl.h\"\n #include \"mlx5_utils.h\"\n \n /**\n@@ -193,3 +198,132 @@\n \t}\n \treturn 0;\n }\n+\n+/*\n+ * Release VLAN network device, created for VM workaround.\n+ *\n+ * @param[in] dev\n+ *   Ethernet device object, Netlink context provider.\n+ * @param[in] vlan\n+ *   Object representing the network device to release.\n+ */\n+void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,\n+\t\t\t    struct mlx5_vf_vlan *vlan)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context;\n+\tstruct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];\n+\n+\tassert(vlan->created);\n+\tassert(priv->vmwa_context);\n+\tif (!vlan->created || !vmwa)\n+\t\treturn;\n+\tvlan->created = 0;\n+\tassert(vlan_dev[vlan->tag].refcnt);\n+\tif (--vlan_dev[vlan->tag].refcnt == 0 &&\n+\t    vlan_dev[vlan->tag].ifindex) {\n+\t\tmlx5_nl_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex);\n+\t\tvlan_dev[vlan->tag].ifindex = 0;\n+\t}\n+}\n+\n+/**\n+ * Acquire VLAN interface with specified tag for VM workaround.\n+ *\n+ * @param[in] dev\n+ *   Ethernet device object, Netlink context provider.\n+ * @param[in] vlan\n+ *   Object representing the network device to acquire.\n+ */\n+void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,\n+\t\t\t    struct mlx5_vf_vlan *vlan)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context;\n+\tstruct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];\n+\n+\tassert(!vlan->created);\n+\tassert(priv->vmwa_context);\n+\tif (vlan->created || !vmwa)\n+\t\treturn;\n+\tif (vlan_dev[vlan->tag].refcnt == 0) {\n+\t\tassert(!vlan_dev[vlan->tag].ifindex);\n+\t\tvlan_dev[vlan->tag].ifindex =\n+\t\t\tmlx5_nl_vlan_vmwa_create(vmwa, vmwa->vf_ifindex,\n+\t\t\t\t\t\t vlan->tag);\n+\t}\n+\tif (vlan_dev[vlan->tag].ifindex) {\n+\t\tvlan_dev[vlan->tag].refcnt++;\n+\t\tvlan->created = 1;\n+\t}\n+}\n+\n+/*\n+ * Create per ethernet device VLAN VM workaround context\n+ */\n+struct mlx5_nl_vlan_vmwa_context *\n+mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_dev_config *config = &priv->config;\n+\tstruct mlx5_nl_vlan_vmwa_context *vmwa;\n+\tenum rte_hypervisor hv_type;\n+\n+\t/* Do not engage workaround over PF. */\n+\tif (!config->vf)\n+\t\treturn NULL;\n+\t/* Check whether there is desired virtual environment */\n+\thv_type = rte_hypervisor_get();\n+\tswitch (hv_type) {\n+\tcase RTE_HYPERVISOR_UNKNOWN:\n+\tcase RTE_HYPERVISOR_VMWARE:\n+\t\t/*\n+\t\t * The \"white list\" of configurations\n+\t\t * to engage the workaround.\n+\t\t */\n+\t\tbreak;\n+\tdefault:\n+\t\t/*\n+\t\t * The configuration is not found in the \"white list\".\n+\t\t * We should not engage the VLAN workaround.\n+\t\t */\n+\t\treturn NULL;\n+\t}\n+\tvmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t));\n+\tif (!vmwa) {\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"Can not allocate memory\"\n+\t\t\t\" for VLAN workaround context\");\n+\t\treturn NULL;\n+\t}\n+\tvmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE);\n+\tif (vmwa->nl_socket < 0) {\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"Can not create Netlink socket\"\n+\t\t\t\" for VLAN workaround context\");\n+\t\trte_free(vmwa);\n+\t\treturn NULL;\n+\t}\n+\tvmwa->nl_sn = random();\n+\tvmwa->vf_ifindex = ifindex;\n+\t/* Cleanup for existing VLAN devices. */\n+\treturn vmwa;\n+}\n+\n+/*\n+ * Destroy per ethernet device VLAN VM workaround context\n+ */\n+void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *vmwa)\n+{\n+\tunsigned int i;\n+\n+\t/* Delete all remaining VLAN devices. */\n+\tfor (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) {\n+\t\tif (vmwa->vlan_dev[i].ifindex)\n+\t\t\tmlx5_nl_vlan_vmwa_delete(vmwa,\n+\t\t\t\t\t\t vmwa->vlan_dev[i].ifindex);\n+\t}\n+\tif (vmwa->nl_socket >= 0)\n+\t\tclose(vmwa->nl_socket);\n+\trte_free(vmwa);\n+}\n",
    "prefixes": [
        "v1",
        "34/38"
    ]
}