diff options
Diffstat (limited to 'src/vnet/lisp-cp/control.c')
-rw-r--r-- | src/vnet/lisp-cp/control.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c index c811e789af9..74597a6b36a 100644 --- a/src/vnet/lisp-cp/control.c +++ b/src/vnet/lisp-cp/control.c @@ -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 */ |