From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 59841A052F; Wed, 29 Jan 2020 13:43:09 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8D8A41C0CD; Wed, 29 Jan 2020 13:39:55 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 924DF1C030 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:32 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1u018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:47 +0000 Message-Id: <1580301530-6643-23-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 22/25] net/mlx5: separate Netlink command interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.h | 72 +++------------------ drivers/net/mlx5/mlx5_nl.c | 149 +++---------------------------------------- drivers/net/mlx5/mlx5_nl.h | 69 ++++++++++++++++++++ drivers/net/mlx5/mlx5_vlan.c | 134 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 204 deletions(-) create mode 100644 drivers/net/mlx5/mlx5_nl.h diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 3daf0db..01d0051 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -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_hairpin_cap_get(struct rte_eth_dev *dev, 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 @@ int mlx5_mp_req_queue_state_modify(struct rte_eth_dev *dev, 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); diff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c index e7ba034..3fe4b6f 100644 --- a/drivers/net/mlx5/mlx5_nl.c +++ b/drivers/net/mlx5/mlx5_nl.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -18,8 +17,6 @@ #include #include -#include -#include #include "mlx5.h" #include "mlx5_utils.h" @@ -1072,7 +1069,8 @@ struct mlx5_nl_ifindex_data { * 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 @@ struct mlx5_nl_ifindex_data { * 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 @@ struct mlx5_nl_ifindex_data { * 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 @@ struct mlx5_nl_ifindex_data { } 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 index 0000000..7903673 --- /dev/null +++ b/drivers/net/mlx5/mlx5_nl.h @@ -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 + + +/* 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_ */ diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index b0fa31a..fb52d8f 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -7,6 +7,8 @@ #include #include #include +#include + /* * Not needed by this file; included to work around the lack of off_t @@ -26,6 +28,8 @@ #include #include +#include +#include #include #include @@ -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 @@ } 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); +} -- 1.8.3.1