net/mlx5: separate Netlink command interface
authorMatan Azrad <matan@mellanox.com>
Wed, 29 Jan 2020 12:38:47 +0000 (12:38 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 5 Feb 2020 08:51:20 +0000 (09:51 +0100)
The Netlink commands interfaces is included in the mlx5.h file with a
lot of other PMD interfaces.

As an arrangement to make the Netlink commands shared with different
PMDs, this patch moves the Netlink interface to a new file called
mlx5_nl.h.

Move non Netlink pure vlan commands from mlx5_nl.c to the
mlx5_vlan.c.

Rename Netlink commands and structures to use prefix mlx5_nl.

Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_nl.c
drivers/net/mlx5/mlx5_nl.h [new file with mode: 0644]
drivers/net/mlx5/mlx5_vlan.c

index 3daf0db..01d0051 100644 (file)
@@ -39,6 +39,7 @@
 #include "mlx5_defs.h"
 #include "mlx5_utils.h"
 #include "mlx5_mr.h"
+#include "mlx5_nl.h"
 #include "mlx5_autoconf.h"
 
 /* Request types for IPC. */
@@ -75,24 +76,6 @@ struct mlx5_mp_param {
 /** Key string for IPC. */
 #define MLX5_MP_NAME "net_mlx5_mp"
 
-/* Recognized Infiniband device physical port name types. */
-enum mlx5_phys_port_name_type {
-       MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */
-       MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */
-       MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */
-       MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */
-       MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */
-};
-
-/** Switch information returned by mlx5_nl_switch_info(). */
-struct mlx5_switch_info {
-       uint32_t master:1; /**< Master device. */
-       uint32_t representor:1; /**< Representor device. */
-       enum mlx5_phys_port_name_type name_type; /** < Port name type. */
-       int32_t pf_num; /**< PF number (valid for pfxvfx format only). */
-       int32_t port_name; /**< Representor port name. */
-       uint64_t switch_id; /**< Switch identifier. */
-};
 
 LIST_HEAD(mlx5_dev_list, mlx5_ibv_shared);
 
@@ -226,30 +209,12 @@ enum mlx5_verbs_alloc_type {
        MLX5_VERBS_ALLOC_TYPE_RX_QUEUE,
 };
 
-/* VLAN netdev for VLAN workaround. */
-struct mlx5_vlan_dev {
-       uint32_t refcnt;
-       uint32_t ifindex; /**< Own interface index. */
-};
-
 /* Structure for VF VLAN workaround. */
 struct mlx5_vf_vlan {
        uint32_t tag:12;
        uint32_t created:1;
 };
 
-/*
- * Array of VLAN devices created on the base of VF
- * used for workaround in virtual environments.
- */
-struct mlx5_vlan_vmwa_context {
-       int nl_socket;
-       uint32_t nl_sn;
-       uint32_t vf_ifindex;
-       struct rte_eth_dev *dev;
-       struct mlx5_vlan_dev vlan_dev[4096];
-};
-
 /**
  * Verbs allocator needs a context to know in the callback which kind of
  * resources it is allocating.
@@ -576,7 +541,7 @@ struct mlx5_priv {
        int nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */
        uint32_t nl_sn; /* Netlink message sequence number. */
        LIST_HEAD(dbrpage, mlx5_devx_dbr_page) dbrpgs; /* Door-bell pages. */
-       struct mlx5_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */
+       struct mlx5_nl_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */
        struct mlx5_flow_id_pool *qrss_id_pool;
        struct mlx5_hlist *mreg_cp_tbl;
        /* Hash table of Rx metadata register copy table. */
@@ -672,6 +637,8 @@ int mlx5_get_mac(struct rte_eth_dev *dev, uint8_t (*mac)[RTE_ETHER_ADDR_LEN]);
 void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
                      uint32_t index, uint32_t vmdq);
+struct mlx5_nl_vlan_vmwa_context *mlx5_vlan_vmwa_init
+                                   (struct rte_eth_dev *dev, uint32_t ifindex);
 int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr);
 int mlx5_set_mc_addr_list(struct rte_eth_dev *dev,
                        struct rte_ether_addr *mc_addr_set,
@@ -715,6 +682,11 @@ int mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
 int mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
 void mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on);
 int mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *ctx);
+void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,
+                           struct mlx5_vf_vlan *vf_vlan);
+void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,
+                           struct mlx5_vf_vlan *vf_vlan);
 
 /* mlx5_trigger.c */
 
@@ -796,32 +768,6 @@ void mlx5_mp_uninit_secondary(void);
 int mlx5_pmd_socket_init(void);
 void mlx5_pmd_socket_uninit(void);
 
-/* mlx5_nl.c */
-
-int mlx5_nl_init(int protocol);
-int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
-                        uint32_t index);
-int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
-                           uint32_t index);
-void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev);
-void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev);
-int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable);
-int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable);
-unsigned int mlx5_nl_portnum(int nl, const char *name);
-unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex);
-int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev,
-                              struct rte_ether_addr *mac, int vf_index);
-int mlx5_nl_switch_info(int nl, unsigned int ifindex,
-                       struct mlx5_switch_info *info);
-
-struct mlx5_vlan_vmwa_context *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,
-                                                  uint32_t ifindex);
-void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *ctx);
-void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,
-                           struct mlx5_vf_vlan *vf_vlan);
-void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,
-                           struct mlx5_vf_vlan *vf_vlan);
-
 /* mlx5_flow_meter.c */
 
 int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);
index e7ba034..3fe4b6f 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <errno.h>
 #include <linux/if_link.h>
-#include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <net/if.h>
 #include <rdma/rdma_netlink.h>
@@ -18,8 +17,6 @@
 #include <unistd.h>
 
 #include <rte_errno.h>
-#include <rte_malloc.h>
-#include <rte_hypervisor.h>
 
 #include "mlx5.h"
 #include "mlx5_utils.h"
@@ -1072,7 +1069,8 @@ error:
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info)
+mlx5_nl_switch_info(int nl, unsigned int ifindex,
+                   struct mlx5_switch_info *info)
 {
        uint32_t seq = random();
        struct {
@@ -1116,12 +1114,12 @@ mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info)
  * Delete VLAN network device by ifindex.
  *
  * @param[in] tcf
- *   Context object initialized by mlx5_vlan_vmwa_init().
+ *   Context object initialized by mlx5_nl_vlan_vmwa_init().
  * @param[in] ifindex
  *   Interface index of network device to delete.
  */
-static void
-mlx5_vlan_vmwa_delete(struct mlx5_vlan_vmwa_context *vmwa,
+void
+mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa,
                      uint32_t ifindex)
 {
        int ret;
@@ -1196,14 +1194,14 @@ nl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *nest)
  * Create network VLAN device with specified VLAN tag.
  *
  * @param[in] tcf
- *   Context object initialized by mlx5_vlan_vmwa_init().
+ *   Context object initialized by mlx5_nl_vlan_vmwa_init().
  * @param[in] ifindex
  *   Base network interface index.
  * @param[in] tag
  *   VLAN tag for VLAN network device to create.
  */
-static uint32_t
-mlx5_vlan_vmwa_create(struct mlx5_vlan_vmwa_context *vmwa,
+uint32_t
+mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa,
                      uint32_t ifindex,
                      uint16_t tag)
 {
@@ -1269,134 +1267,3 @@ mlx5_vlan_vmwa_create(struct mlx5_vlan_vmwa_context *vmwa,
        }
        return ret;
 }
-
-/*
- * Release VLAN network device, created for VM workaround.
- *
- * @param[in] dev
- *   Ethernet device object, Netlink context provider.
- * @param[in] vlan
- *   Object representing the network device to release.
- */
-void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,
-                           struct mlx5_vf_vlan *vlan)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       struct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context;
-       struct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];
-
-       assert(vlan->created);
-       assert(priv->vmwa_context);
-       if (!vlan->created || !vmwa)
-               return;
-       vlan->created = 0;
-       assert(vlan_dev[vlan->tag].refcnt);
-       if (--vlan_dev[vlan->tag].refcnt == 0 &&
-           vlan_dev[vlan->tag].ifindex) {
-               mlx5_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex);
-               vlan_dev[vlan->tag].ifindex = 0;
-       }
-}
-
-/**
- * Acquire VLAN interface with specified tag for VM workaround.
- *
- * @param[in] dev
- *   Ethernet device object, Netlink context provider.
- * @param[in] vlan
- *   Object representing the network device to acquire.
- */
-void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,
-                           struct mlx5_vf_vlan *vlan)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       struct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context;
-       struct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];
-
-       assert(!vlan->created);
-       assert(priv->vmwa_context);
-       if (vlan->created || !vmwa)
-               return;
-       if (vlan_dev[vlan->tag].refcnt == 0) {
-               assert(!vlan_dev[vlan->tag].ifindex);
-               vlan_dev[vlan->tag].ifindex =
-                       mlx5_vlan_vmwa_create(vmwa,
-                                             vmwa->vf_ifindex,
-                                             vlan->tag);
-       }
-       if (vlan_dev[vlan->tag].ifindex) {
-               vlan_dev[vlan->tag].refcnt++;
-               vlan->created = 1;
-       }
-}
-
-/*
- * Create per ethernet device VLAN VM workaround context
- */
-struct mlx5_vlan_vmwa_context *
-mlx5_vlan_vmwa_init(struct rte_eth_dev *dev,
-                   uint32_t ifindex)
-{
-       struct mlx5_priv *priv = dev->data->dev_private;
-       struct mlx5_dev_config *config = &priv->config;
-       struct mlx5_vlan_vmwa_context *vmwa;
-       enum rte_hypervisor hv_type;
-
-       /* Do not engage workaround over PF. */
-       if (!config->vf)
-               return NULL;
-       /* Check whether there is desired virtual environment */
-       hv_type = rte_hypervisor_get();
-       switch (hv_type) {
-       case RTE_HYPERVISOR_UNKNOWN:
-       case RTE_HYPERVISOR_VMWARE:
-               /*
-                * The "white list" of configurations
-                * to engage the workaround.
-                */
-               break;
-       default:
-               /*
-                * The configuration is not found in the "white list".
-                * We should not engage the VLAN workaround.
-                */
-               return NULL;
-       }
-       vmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t));
-       if (!vmwa) {
-               DRV_LOG(WARNING,
-                       "Can not allocate memory"
-                       " for VLAN workaround context");
-               return NULL;
-       }
-       vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE);
-       if (vmwa->nl_socket < 0) {
-               DRV_LOG(WARNING,
-                       "Can not create Netlink socket"
-                       " for VLAN workaround context");
-               rte_free(vmwa);
-               return NULL;
-       }
-       vmwa->nl_sn = random();
-       vmwa->vf_ifindex = ifindex;
-       vmwa->dev = dev;
-       /* Cleanup for existing VLAN devices. */
-       return vmwa;
-}
-
-/*
- * Destroy per ethernet device VLAN VM workaround context
- */
-void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *vmwa)
-{
-       unsigned int i;
-
-       /* Delete all remaining VLAN devices. */
-       for (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) {
-               if (vmwa->vlan_dev[i].ifindex)
-                       mlx5_vlan_vmwa_delete(vmwa, vmwa->vlan_dev[i].ifindex);
-       }
-       if (vmwa->nl_socket >= 0)
-               close(vmwa->nl_socket);
-       rte_free(vmwa);
-}
diff --git a/drivers/net/mlx5/mlx5_nl.h b/drivers/net/mlx5/mlx5_nl.h
new file mode 100644 (file)
index 0000000..7903673
--- /dev/null
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2019 Mellanox Technologies, Ltd
+ */
+
+#ifndef RTE_PMD_MLX5_NL_H_
+#define RTE_PMD_MLX5_NL_H_
+
+#include <linux/netlink.h>
+
+
+/* Recognized Infiniband device physical port name types. */
+enum mlx5_nl_phys_port_name_type {
+       MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */
+       MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */
+       MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */
+       MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */
+       MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */
+};
+
+/** Switch information returned by mlx5_nl_switch_info(). */
+struct mlx5_switch_info {
+       uint32_t master:1; /**< Master device. */
+       uint32_t representor:1; /**< Representor device. */
+       enum mlx5_nl_phys_port_name_type name_type; /** < Port name type. */
+       int32_t pf_num; /**< PF number (valid for pfxvfx format only). */
+       int32_t port_name; /**< Representor port name. */
+       uint64_t switch_id; /**< Switch identifier. */
+};
+
+/* VLAN netdev for VLAN workaround. */
+struct mlx5_nl_vlan_dev {
+       uint32_t refcnt;
+       uint32_t ifindex; /**< Own interface index. */
+};
+
+/*
+ * Array of VLAN devices created on the base of VF
+ * used for workaround in virtual environments.
+ */
+struct mlx5_nl_vlan_vmwa_context {
+       int nl_socket;
+       uint32_t nl_sn;
+       uint32_t vf_ifindex;
+       struct mlx5_nl_vlan_dev vlan_dev[4096];
+};
+
+
+int mlx5_nl_init(int protocol);
+int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
+                        uint32_t index);
+int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
+                           uint32_t index);
+void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev);
+void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev);
+int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable);
+int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable);
+unsigned int mlx5_nl_portnum(int nl, const char *name);
+unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex);
+int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev,
+                              struct rte_ether_addr *mac, int vf_index);
+int mlx5_nl_switch_info(int nl, unsigned int ifindex,
+                       struct mlx5_switch_info *info);
+
+void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa,
+                          uint32_t ifindex);
+uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa,
+                                 uint32_t ifindex, uint16_t tag);
+
+#endif /* RTE_PMD_MLX5_NL_H_ */
index b0fa31a..fb52d8f 100644 (file)
@@ -7,6 +7,8 @@
 #include <errno.h>
 #include <assert.h>
 #include <stdint.h>
+#include <unistd.h>
+
 
 /*
  * Not needed by this file; included to work around the lack of off_t
@@ -26,6 +28,8 @@
 
 #include <rte_ethdev_driver.h>
 #include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_hypervisor.h>
 
 #include <mlx5_glue.h>
 #include <mlx5_devx_cmds.h>
@@ -33,6 +37,7 @@
 #include "mlx5.h"
 #include "mlx5_autoconf.h"
 #include "mlx5_rxtx.h"
+#include "mlx5_nl.h"
 #include "mlx5_utils.h"
 
 /**
@@ -193,3 +198,132 @@ mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        }
        return 0;
 }
+
+/*
+ * Release VLAN network device, created for VM workaround.
+ *
+ * @param[in] dev
+ *   Ethernet device object, Netlink context provider.
+ * @param[in] vlan
+ *   Object representing the network device to release.
+ */
+void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev,
+                           struct mlx5_vf_vlan *vlan)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context;
+       struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];
+
+       assert(vlan->created);
+       assert(priv->vmwa_context);
+       if (!vlan->created || !vmwa)
+               return;
+       vlan->created = 0;
+       assert(vlan_dev[vlan->tag].refcnt);
+       if (--vlan_dev[vlan->tag].refcnt == 0 &&
+           vlan_dev[vlan->tag].ifindex) {
+               mlx5_nl_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex);
+               vlan_dev[vlan->tag].ifindex = 0;
+       }
+}
+
+/**
+ * Acquire VLAN interface with specified tag for VM workaround.
+ *
+ * @param[in] dev
+ *   Ethernet device object, Netlink context provider.
+ * @param[in] vlan
+ *   Object representing the network device to acquire.
+ */
+void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev,
+                           struct mlx5_vf_vlan *vlan)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context;
+       struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0];
+
+       assert(!vlan->created);
+       assert(priv->vmwa_context);
+       if (vlan->created || !vmwa)
+               return;
+       if (vlan_dev[vlan->tag].refcnt == 0) {
+               assert(!vlan_dev[vlan->tag].ifindex);
+               vlan_dev[vlan->tag].ifindex =
+                       mlx5_nl_vlan_vmwa_create(vmwa, vmwa->vf_ifindex,
+                                                vlan->tag);
+       }
+       if (vlan_dev[vlan->tag].ifindex) {
+               vlan_dev[vlan->tag].refcnt++;
+               vlan->created = 1;
+       }
+}
+
+/*
+ * Create per ethernet device VLAN VM workaround context
+ */
+struct mlx5_nl_vlan_vmwa_context *
+mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_dev_config *config = &priv->config;
+       struct mlx5_nl_vlan_vmwa_context *vmwa;
+       enum rte_hypervisor hv_type;
+
+       /* Do not engage workaround over PF. */
+       if (!config->vf)
+               return NULL;
+       /* Check whether there is desired virtual environment */
+       hv_type = rte_hypervisor_get();
+       switch (hv_type) {
+       case RTE_HYPERVISOR_UNKNOWN:
+       case RTE_HYPERVISOR_VMWARE:
+               /*
+                * The "white list" of configurations
+                * to engage the workaround.
+                */
+               break;
+       default:
+               /*
+                * The configuration is not found in the "white list".
+                * We should not engage the VLAN workaround.
+                */
+               return NULL;
+       }
+       vmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t));
+       if (!vmwa) {
+               DRV_LOG(WARNING,
+                       "Can not allocate memory"
+                       " for VLAN workaround context");
+               return NULL;
+       }
+       vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE);
+       if (vmwa->nl_socket < 0) {
+               DRV_LOG(WARNING,
+                       "Can not create Netlink socket"
+                       " for VLAN workaround context");
+               rte_free(vmwa);
+               return NULL;
+       }
+       vmwa->nl_sn = random();
+       vmwa->vf_ifindex = ifindex;
+       /* Cleanup for existing VLAN devices. */
+       return vmwa;
+}
+
+/*
+ * Destroy per ethernet device VLAN VM workaround context
+ */
+void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *vmwa)
+{
+       unsigned int i;
+
+       /* Delete all remaining VLAN devices. */
+       for (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) {
+               if (vmwa->vlan_dev[i].ifindex)
+                       mlx5_nl_vlan_vmwa_delete(vmwa,
+                                                vmwa->vlan_dev[i].ifindex);
+       }
+       if (vmwa->nl_socket >= 0)
+               close(vmwa->nl_socket);
+       rte_free(vmwa);
+}