Remove associated lisp-gpe entries when removing lisp local mapping. 70/8370/4
authorAlberto Rodriguez-Natal <natal@cisco.com>
Sat, 9 Sep 2017 21:15:15 +0000 (14:15 -0700)
committerFlorin Coras <florin.coras@gmail.com>
Tue, 19 Sep 2017 06:29:05 +0000 (06:29 +0000)
Change-Id: Ifda4d22c9d1de210165932a0996f75cc8428ae7a
Signed-off-by: Alberto Rodriguez-Natal <natal@cisco.com>
src/vnet/lisp-cp/control.c
src/vnet/lisp-cp/control.h

index c811e78..74597a6 100644 (file)
@@ -265,7 +265,7 @@ dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add)
 }
 
 static void
-dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
+dp_del_fwd_entry (lisp_cp_main_t * lcm, u32 dst_map_index)
 {
   vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
   fwd_entry_t *fe = 0;
@@ -438,8 +438,8 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
   gid_address_t *rmt_eid, *lcl_eid;
   mapping_t *lcl_map, *rmt_map;
-  u32 sw_if_index;
-  uword *feip = 0, *dpid;
+  u32 sw_if_index, **rmts, rmts_idx;
+  uword *feip = 0, *dpid, *rmts_stored_idxp = 0;
   fwd_entry_t *fe;
   u8 type, is_src_dst = 0;
   int rv;
@@ -449,7 +449,7 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   /* remove entry if it already exists */
   feip = hash_get (lcm->fwd_entry_by_mapping_index, dst_map_index);
   if (feip)
-    dp_del_fwd_entry (lcm, src_map_index, dst_map_index);
+    dp_del_fwd_entry (lcm, dst_map_index);
 
   /*
    * Determine local mapping and eid
@@ -557,6 +557,23 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index)
   fe->is_src_dst = is_src_dst;
   hash_set (lcm->fwd_entry_by_mapping_index, dst_map_index,
            fe - lcm->fwd_entry_pool);
+
+  /* Add rmt mapping to the vector of adjacent mappings to lcl mapping */
+  rmts_stored_idxp =
+    hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, src_map_index);
+  if (!rmts_stored_idxp)
+    {
+      pool_get (lcm->lcl_to_rmt_adjacencies, rmts);
+      memset (rmts, 0, sizeof (*rmts));
+      rmts_idx = rmts - lcm->lcl_to_rmt_adjacencies;
+      hash_set (lcm->lcl_to_rmt_adjs_by_lcl_idx, src_map_index, rmts_idx);
+    }
+  else
+    {
+      rmts_idx = (u32) (*rmts_stored_idxp);
+      rmts = pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idx);
+    }
+  vec_add1 (rmts[0], dst_map_index);
 }
 
 typedef struct
@@ -707,6 +724,8 @@ vnet_lisp_map_cache_add_del (vnet_lisp_add_del_mapping_args_t * a,
 {
   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
   u32 mi, *map_indexp, map_index, i;
+  u32 **rmts = 0, *remote_idxp, rmts_itr, remote_idx;
+  uword *rmts_idxp;
   mapping_t *m, *old_map;
   u32 **eid_indexes;
 
@@ -794,6 +813,21 @@ vnet_lisp_map_cache_add_del (vnet_lisp_add_del_mapping_args_t * a,
       m = pool_elt_at_index (lcm->mapping_pool, mi);
       if (m->local)
        {
+         /* Remove adjacencies associated with the local mapping */
+         rmts_idxp = hash_get (lcm->lcl_to_rmt_adjs_by_lcl_idx, mi);
+         if (rmts_idxp)
+           {
+             rmts =
+               pool_elt_at_index (lcm->lcl_to_rmt_adjacencies, rmts_idxp[0]);
+             vec_foreach (remote_idxp, rmts[0])
+             {
+               dp_del_fwd_entry (lcm, remote_idxp[0]);
+             }
+             vec_free (rmts[0]);
+             pool_put (lcm->lcl_to_rmt_adjacencies, rmts);
+             hash_unset (lcm->lcl_to_rmt_adjs_by_lcl_idx, mi);
+           }
+
          u32 k, *lm_indexp;
          for (k = 0; k < vec_len (lcm->local_mappings_indexes); k++)
            {
@@ -803,6 +837,26 @@ vnet_lisp_map_cache_add_del (vnet_lisp_add_del_mapping_args_t * a,
            }
          vec_del1 (lcm->local_mappings_indexes, k);
        }
+      else
+       {
+         /* Remove remote (if present) from the vectors of lcl-to-rmts
+          * TODO: Address this in a more efficient way.
+          */
+         /* *INDENT-OFF* */
+         pool_foreach (rmts, lcm->lcl_to_rmt_adjacencies,
+         ({
+           vec_foreach_index (rmts_itr, rmts[0])
+           {
+             remote_idx = vec_elt (rmts[0], rmts_itr);
+             if (mi == remote_idx)
+               {
+                 vec_del1 (rmts[0], rmts_itr);
+                 break;
+               }
+           }
+         }));
+         /* *INDENT-ON* */
+       }
 
       /* remove mapping from dictionary */
       gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->eid, 0, 0);
@@ -1318,7 +1372,7 @@ vnet_lisp_clear_all_remote_adjacencies (void)
     mapping_t *map = pool_elt_at_index (lcm->mapping_pool, map_indexp[0]);
     if (!map->local)
       {
-       dp_del_fwd_entry (lcm, 0, map_indexp[0]);
+       dp_del_fwd_entry (lcm, map_indexp[0]);
 
        dm_args->is_add = 0;
        gid_address_copy (&dm_args->eid, &map->eid);
@@ -1404,7 +1458,7 @@ vnet_lisp_add_del_adjacency (vnet_lisp_add_del_adjacency_args_t * a)
       dp_add_fwd_entry (lcm, local_mi, remote_mi);
     }
   else
-    dp_del_fwd_entry (lcm, 0, remote_mi);
+    dp_del_fwd_entry (lcm, remote_mi);
 
   return 0;
 }
@@ -2029,7 +2083,7 @@ vnet_lisp_map_register_enable_disable (u8 is_enable)
 clib_error_t *
 vnet_lisp_enable_disable (u8 is_enable)
 {
-  u32 vni, dp_table;
+  u32 vni, dp_table, **rmts;
   clib_error_t *error = 0;
   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
   vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
@@ -2060,6 +2114,15 @@ vnet_lisp_enable_disable (u8 is_enable)
       /* clear interface table */
       hash_free (lcm->fwd_entry_by_mapping_index);
       pool_free (lcm->fwd_entry_pool);
+      /* Clear state tracking rmt-lcl fwd entries */
+      /* *INDENT-OFF* */
+      pool_foreach(rmts, lcm->lcl_to_rmt_adjacencies,
+      {
+        vec_free(rmts[0]);
+      });
+      /* *INDENT-ON* */
+      hash_free (lcm->lcl_to_rmt_adjs_by_lcl_idx);
+      pool_free (lcm->lcl_to_rmt_adjacencies);
     }
 
   /* update global flag */
index a3e2fc2..12bfcb5 100644 (file)
@@ -180,6 +180,12 @@ typedef struct
   /* hash map of forwarding entries by mapping index */
   u32 *fwd_entry_by_mapping_index;
 
+  /* pool of vectors of rmts per lcl mapping in adjacencies */
+  u32 **lcl_to_rmt_adjacencies;
+
+  /* hash of pool positions of vectors of rmts by lcl mapping index */
+  u32 *lcl_to_rmt_adjs_by_lcl_idx;
+
   /* forwarding entries pool */
   fwd_entry_t *fwd_entry_pool;