diff options
Diffstat (limited to 'vnet')
-rw-r--r-- | vnet/vnet/api_errno.h | 3 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/control.c | 246 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/control.h | 7 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.h | 2 |
4 files changed, 240 insertions, 18 deletions
diff --git a/vnet/vnet/api_errno.h b/vnet/vnet/api_errno.h index e59efd70c4e..77c14a4a4fa 100644 --- a/vnet/vnet/api_errno.h +++ b/vnet/vnet/api_errno.h @@ -70,7 +70,8 @@ _(INVALID_DECAP_NEXT, -76, "Invalid decap-next") \ _(RESPONSE_NOT_READY, -77, "Response not ready") \ _(NOT_CONNECTED, -78, "Not connected to the data plane") \ _(IF_ALREADY_EXISTS, -79, "Interface already exists") \ -_(BOND_SLAVE_NOT_ALLOWED, -80, "Operation not allowed on slave of BondEthernet") +_(BOND_SLAVE_NOT_ALLOWED, -80, "Operation not allowed on slave of BondEthernet") \ +_(VALUE_EXIST, -81, "Value already exists") typedef enum { #define _(a,b,c) VNET_API_ERROR_##a = (b), diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c index c1873972517..f60405e7519 100644 --- a/vnet/vnet/lisp-cp/control.c +++ b/vnet/vnet/lisp-cp/control.c @@ -35,7 +35,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, if (mi != GID_LOOKUP_MISS) { clib_warning("eid %U found in the eid-table", format_ip_address, &a->deid); - return -1; + return VNET_API_ERROR_VALUE_EXIST; } pool_get(lcm->mapping_pool, m); @@ -52,7 +52,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, { clib_warning("Locator set with index %d doesn't exist", a->locator_set_index); - return -1; + return VNET_API_ERROR_INVALID_VALUE; } /* add eid to list of eids supported by locator-set */ @@ -72,10 +72,10 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, } else { - if (mi != ~0) { + if (mi == GID_LOOKUP_MISS) { clib_warning("eid %U not found in the eid-table", format_ip_address, &a->deid); - return -1; + return VNET_API_ERROR_INVALID_VALUE; } /* clear locator-set to eids binding */ @@ -236,19 +236,6 @@ clean_locator_to_locator_set (lisp_cp_main_t * lcm, u32 lsi) /* delete locator if it's part of no locator-set */ if (vec_len (ls_indexes[0]) == 0) pool_put_index(lcm->locator_pool, loc_indexp[0]); - - /* remove from local locator-set vector */ - if (ls->local) - { - u32 k, *llocp; - for (k = 0; k < vec_len(lcm->local_locator_set_indexes); k++) - { - llocp = vec_elt_at_index(lcm->local_locator_set_indexes, k); - if (llocp[0] == lsi) - break; - } - vec_del1(lcm->local_locator_set_indexes, k); - } } } int @@ -260,6 +247,7 @@ vnet_lisp_add_del_locator_set (vnet_lisp_add_del_locator_set_args_t * a, locator_t * loc, * itloc; uword _p = (u32)~0, * p = &_p; u32 loc_index, ls_index, ** ls_indexes; + u32 **eid_indexes; if (a->is_add) { @@ -358,6 +346,151 @@ vnet_lisp_add_del_locator_set (vnet_lisp_add_del_locator_set_args_t * a, // return -1; // } + if (vec_len(lcm->locator_set_to_eids) != 0) + { + eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids, p[0]); + if (vec_len(eid_indexes[0]) != 0) + { + clib_warning ("Can't delete a locator that supports a mapping!"); + return -1; + } + } + + /* clean locator to locator-sets data */ + clean_locator_to_locator_set (lcm, p[0]); + + if (ls->local) + { + u32 it, lsi; + + vec_foreach_index(it, lcm->local_locator_set_indexes) + { + lsi = vec_elt(lcm->local_locator_set_indexes, it); + if (lsi == p[0]) + { + vec_del1(lcm->local_locator_set_indexes, it); + break; + } + } + hash_unset_mem(lcm->locator_set_index_by_name, ls->name); + vec_free(ls->name); + } + pool_put(lcm->locator_set_pool, ls); + } + return 0; +} + +static inline +uword *vnet_lisp_get_locator(vnet_lisp_add_del_locator_set_args_t * a, + uword *p) +{ + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + + ASSERT(a != NULL); + ASSERT(p != NULL); + + /* find locator-set */ + if (a->local) + { + p = hash_get_mem(lcm->locator_set_index_by_name, a->name); + } + else + { + *p = a->index; + } + + return p; +} + +int +vnet_lisp_add_del_locator_set_name (vnet_lisp_add_del_locator_set_args_t * a, + u32 * ls_result) +{ + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + locator_set_t * ls; + uword _p = (u32)~0, * p = &_p; + u32 ls_index = ~0; + u32 **eid_indexes = NULL; + + ASSERT(a != NULL); + ASSERT(ls_result != NULL); + + p = vnet_lisp_get_locator(a, p); + + if (a->is_add) + { + /* overwrite */ + if (p && p[0] != (u32)~0) + { + ls = pool_elt_at_index(lcm->locator_set_pool, p[0]); + if (!ls) + { + clib_warning("locator-set %d to be overwritten doesn't exist!", + p[0]); + return VNET_API_ERROR_UNSPECIFIED; + } + + /* clean locator to locator-set vectors and remove locators if + * they're not part of another locator-set */ + clean_locator_to_locator_set (lcm, p[0]); + + /* remove locator indices from locator set */ + vec_free(ls->locator_indices); + + ls_index = p[0]; + + if (ls_result) + ls_result[0] = p[0]; + } + /* new locator-set */ + else + { + pool_get(lcm->locator_set_pool, ls); + ls_index = ls - lcm->locator_set_pool; + + if (a->local) + { + ls->name = vec_dup(a->name); + + if (!lcm->locator_set_index_by_name) + lcm->locator_set_index_by_name = hash_create_vec( + /* size */0, sizeof(ls->name[0]), sizeof(uword)); + hash_set_mem(lcm->locator_set_index_by_name, ls->name, ls_index); + + /* mark as local locator-set */ + vec_add1(lcm->local_locator_set_indexes, ls_index); + } + ls->local = a->local; + ls->locator_indices = NULL; + if (ls_result) + ls_result[0] = ls_index; + } + } + else + { + if (!p) + { + clib_warning("locator-set %v doesn't exists", a->name); + return VNET_API_ERROR_INVALID_ARGUMENT; + } + + ls = pool_elt_at_index(lcm->locator_set_pool, p[0]); + if (!ls) + { + clib_warning("locator-set with index %d doesn't exists", p[0]); + return VNET_API_ERROR_INVALID_ARGUMENT; + } + + if (vec_len(lcm->locator_set_to_eids) != 0) + { + eid_indexes = vec_elt_at_index(lcm->locator_set_to_eids, p[0]); + if (vec_len(eid_indexes[0]) != 0) + { + clib_warning ("Can't delete a locator that supports a mapping!"); + return -1; + } + } + /* clean locator to locator-sets data */ clean_locator_to_locator_set (lcm, p[0]); @@ -382,6 +515,85 @@ vnet_lisp_add_del_locator_set (vnet_lisp_add_del_locator_set_args_t * a, return 0; } +int +vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t *a, + u32 *ls_result) +{ + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + locator_set_t *ls = NULL; + locator_t *loc = NULL, *itloc = NULL; + uword _p = (u32)~0, * p = &_p; + u32 loc_index = ~0, ls_index = ~0, *locit = NULL, **ls_indexes = NULL; + u32 i = ~0; + + ASSERT(a != NULL); + ASSERT(ls_result != NULL); + + p = vnet_lisp_get_locator(a, p); + if (!p) { + clib_warning("locator-set %v doesn't exists", a->name); + return VNET_API_ERROR_INVALID_ARGUMENT; + } + + ls_index = p[0]; + + if (a->is_add) + { + ls = pool_elt_at_index(lcm->locator_set_pool, p[0]); + if (!ls) + { + clib_warning("locator-set %d to be overwritten doesn't exist!", + p[0]); + return VNET_API_ERROR_INVALID_ARGUMENT; + } + + if (ls_result) + ls_result[0] = p[0]; + + /* allocate locators */ + itloc = a->locators; + pool_get(lcm->locator_pool, loc); + loc[0] = itloc[0]; + loc_index = loc - lcm->locator_pool; + + vec_add1(ls->locator_indices, loc_index); + + vec_validate (lcm->locator_to_locator_sets, loc_index); + ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets, + loc_index); + vec_add1(ls_indexes[0], ls_index); + } + else + { + ls = pool_elt_at_index(lcm->locator_set_pool, p[0]); + if (!ls) + { + clib_warning("locator-set with index %d doesn't exists", p[0]); + return VNET_API_ERROR_INVALID_ARGUMENT; + } + + if (ls->local) + { + itloc = a->locators; + i = 0; + vec_foreach (locit, ls->locator_indices) + { + loc = pool_elt_at_index(lcm->locator_pool, locit[0]); + if (loc->local && loc->sw_if_index == itloc->sw_if_index) + { + ls_indexes = vec_elt_at_index(lcm->locator_to_locator_sets, + locit[0]); + pool_put_index(lcm->locator_pool, locit[0]); + vec_del1(ls->locator_indices, i); + vec_del1(ls_indexes[0], ls_index); + } + i++; + } + } + } + return 0; +} + static clib_error_t * lisp_add_del_locator_set_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) diff --git a/vnet/vnet/lisp-cp/control.h b/vnet/vnet/lisp-cp/control.h index 713dce6a5b8..53d90fca8e5 100644 --- a/vnet/vnet/lisp-cp/control.h +++ b/vnet/vnet/lisp-cp/control.h @@ -123,6 +123,13 @@ int vnet_lisp_add_del_locator_set (vnet_lisp_add_del_locator_set_args_t * a, u32 * ls_index); +int +vnet_lisp_add_del_locator_set_name (vnet_lisp_add_del_locator_set_args_t * a, + u32 * ls_index); +int +vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t * a, + u32 * ls_index); + typedef struct { u8 is_add; diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h index 63adaa0e9a3..0e8b38ec71e 100644 --- a/vnet/vnet/lisp-cp/lisp_types.h +++ b/vnet/vnet/lisp-cp/lisp_types.h @@ -35,6 +35,8 @@ typedef struct ip_address_type_t version; } ip_address_t; +int ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2); + typedef struct { ip_address_t addr; |