Sub-Interface deletion not cleanup hash's properly (VPP-1136) 68/10168/2
authorJohn Lo <loj@cisco.com>
Thu, 18 Jan 2018 17:44:50 +0000 (12:44 -0500)
committerDave Wallace <dwallacelf@gmail.com>
Fri, 19 Jan 2018 16:46:03 +0000 (16:46 +0000)
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>
(cherry picked from commit 7f5bec647c9dc743c015d461d040e63a77fd0a08)

src/vnet/ethernet/interface.c
src/vnet/interface.c
src/vppinfra/hash.h

index 3e78a49..801c99f 100644 (file)
@@ -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;
 }
 
index 82eccc1..3ae2a8d 100644 (file)
@@ -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;
 
index 6206dd2..21986ea 100644 (file)
@@ -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 */