diff options
author | John Lo <loj@cisco.com> | 2018-01-18 12:44:50 -0500 |
---|---|---|
committer | John Lo <loj@cisco.com> | 2018-01-18 18:52:46 -0500 |
commit | 7f5bec647c9dc743c015d461d040e63a77fd0a08 (patch) | |
tree | 5feb7e1555be7c93d2d1c1ca1ad9fdfda77e7759 | |
parent | ec941ecb86bbce237b1c3d6c20ab17b4471d7cff (diff) |
Sub-Interface deletion not cleanup hash's properly (VPP-1136)
On deleting sub-interfaces, functions vnet_delete_sub_interface()
and vnet_delete_hw_interface() are not cleaning up sub-interface
related hash tables and memory properly.
Change-Id: I17c7c4b2078c062c77bfe48889beb677610035ca
Signed-off-by: John Lo <loj@cisco.com>
-rw-r--r-- | src/vnet/ethernet/interface.c | 17 | ||||
-rw-r--r-- | src/vnet/interface.c | 15 | ||||
-rw-r--r-- | src/vppinfra/hash.h | 10 |
3 files changed, 24 insertions, 18 deletions
diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c index 3e78a49d62b..801c99f824d 100644 --- a/src/vnet/ethernet/interface.c +++ b/src/vnet/ethernet/interface.c @@ -737,29 +737,26 @@ int vnet_delete_sub_interface (u32 sw_if_index) { vnet_main_t *vnm = vnet_get_main (); + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); int rv = 0; if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - vnet_interface_main_t *im = &vnm->interface_main; - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); - if (si->type == VNET_SW_INTERFACE_TYPE_SUB || si->type == VNET_SW_INTERFACE_TYPE_P2P) { - vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + vnet_interface_main_t *im = &vnm->interface_main; + vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); u64 sup_and_sub_key = ((u64) (si->sup_sw_if_index) << 32) | (u64) si->sub.id; - - hash_unset_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key); + hash_unset_mem_free (&im->sw_if_index_by_sup_and_sub, &sup_and_sub_key); + hash_unset (hi->sub_interface_sw_if_index_by_id, si->sub.id); vnet_delete_sw_interface (vnm, sw_if_index); } else - { - rv = VNET_API_ERROR_INVALID_SUB_SW_IF_INDEX; - } + rv = VNET_API_ERROR_INVALID_SUB_SW_IF_INDEX; + return rv; } diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 82eccc12436..3ae2a8d8bf2 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -704,6 +704,7 @@ vnet_register_interface (vnet_main_t * vnm, char *tx_node_name, *output_node_name; pool_get (im->hw_interfaces, hw); + memset (hw, 0, sizeof (*hw)); hw_index = hw - im->hw_interfaces; hw->hw_if_index = hw_index; @@ -904,19 +905,25 @@ vnet_delete_hw_interface (vnet_main_t * vnm, u32 hw_if_index) /* Call delete callbacks. */ call_hw_interface_add_del_callbacks (vnm, hw_if_index, /* is_create */ 0); - /* Delete software interface corresponding to hardware interface. */ - vnet_delete_sw_interface (vnm, hw->sw_if_index); - /* Delete any sub-interfaces. */ { u32 id, sw_if_index; /* *INDENT-OFF* */ - hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id, ({ + hash_foreach (id, sw_if_index, hw->sub_interface_sw_if_index_by_id, + ({ + vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index); + u64 sup_and_sub_key = + ((u64) (si->sup_sw_if_index) << 32) | (u64) si->sub.id; + hash_unset_mem_free (&im->sw_if_index_by_sup_and_sub, &sup_and_sub_key); vnet_delete_sw_interface (vnm, sw_if_index); })); + hash_free (hw->sub_interface_sw_if_index_by_id); /* *INDENT-ON* */ } + /* Delete software interface corresponding to hardware interface. */ + vnet_delete_sw_interface (vnm, hw->sw_if_index); + { vnet_hw_interface_nodes_t *dn; diff --git a/src/vppinfra/hash.h b/src/vppinfra/hash.h index 6206dd2a486..21986ea774c 100644 --- a/src/vppinfra/hash.h +++ b/src/vppinfra/hash.h @@ -294,10 +294,12 @@ always_inline void hash_unset_mem_free (uword ** h, void *key) { hash_pair_t *hp = hash_get_pair_mem (*h, key); - ASSERT (hp); - key = uword_to_pointer (hp->key, void *); - hash_unset_mem (*h, key); - clib_mem_free (key); + if (PREDICT_TRUE (hp != NULL)) + { + key = uword_to_pointer (hp->key, void *); + hash_unset_mem (*h, key); + clib_mem_free (key); + } } /* internal routine to free a hash table */ |