From: Andrej Kozemcak Date: Thu, 31 Mar 2016 11:51:42 +0000 (+0200) Subject: Add LISP API X-Git-Tag: v16.06-rc1~153 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=b92feb6bd3f58c44be32eadfd683a1b2caac5607;p=vpp.git Add LISP API SET API: lisp_add_del_locator_set lisp_add_del_locator lisp_add_del_local_eid lisp_gpe_add_del_fwd_entry lisp_add_del_map_resolver lisp_gpe_add_del_iface SHOW API: lisp_locator_set_dump lisp_local_eid_table_dump lisp_gpe_tunnel_dump lisp_map_resolver_dump Change-Id: Ie7f521e7e64ad2736b8417852b38454bfdef3728 Signed-off-by: Andrej Kozemcak --- 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; diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c index be36cb1da1e..704237be225 100644 --- a/vpp-api-test/vat/api_format.c +++ b/vpp-api-test/vat/api_format.c @@ -1863,6 +1863,218 @@ static void vl_api_get_node_graph_reply_t_handler_json vam->result_ready = 1; } +static void +vl_api_lisp_locator_set_details_t_handler ( + vl_api_lisp_locator_set_details_t *mp) +{ + vat_main_t *vam = &vat_main; + + fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n", + mp->locator_set_name, + ntohl(mp->sw_if_index), + mp->priority, + mp->weight); +} + +static void +vl_api_lisp_locator_set_details_t_handler_json ( + vl_api_lisp_locator_set_details_t *mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t *node = NULL; + + if (VAT_JSON_ARRAY != vam->json_tree.type) { + ASSERT(VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array(&vam->json_tree); + } + node = vat_json_array_add(&vam->json_tree); + + vat_json_init_object(node); + vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name); + vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index)); + vat_json_object_add_uint(node, "priority", mp->priority); + vat_json_object_add_uint(node, "weight", mp->weight); +} + +static void +vl_api_lisp_local_eid_table_details_t_handler ( + vl_api_lisp_local_eid_table_details_t *mp) +{ + vat_main_t *vam = &vat_main; + u8 *prefix; + + prefix = format(0, "%U/%d", + mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address, + mp->eid_ip_address, + mp->eid_prefix_len); + + fformat(vam->ofp, "%=20s%=30s\n", + mp->locator_set_name, prefix); + + vec_free(prefix); +} + +static void +vl_api_lisp_local_eid_table_details_t_handler_json ( + vl_api_lisp_local_eid_table_details_t *mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t *node = NULL; + struct in6_addr ip6; + struct in_addr ip4; + + if (VAT_JSON_ARRAY != vam->json_tree.type) { + ASSERT(VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array(&vam->json_tree); + } + node = vat_json_array_add(&vam->json_tree); + + vat_json_init_object(node); + vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name); + if (mp->eid_is_ipv6) { + memcpy(&ip6, mp->eid_ip_address, sizeof(ip6)); + vat_json_object_add_ip6(node, "eid address", ip6); + } else { + memcpy(&ip4, mp->eid_ip_address, sizeof(ip4)); + vat_json_object_add_ip4(node, "eid address", ip4); + } + vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len); +} + +static u8 * +format_decap_next (u8 * s, va_list * args) +{ + u32 next_index = va_arg (*args, u32); + + switch (next_index) + { + case LISP_GPE_INPUT_NEXT_DROP: + return format (s, "drop"); + case LISP_GPE_INPUT_NEXT_IP4_INPUT: + return format (s, "ip4"); + case LISP_GPE_INPUT_NEXT_IP6_INPUT: + return format (s, "ip6"); + case LISP_GPE_INPUT_NEXT_LISP_GPE_ENCAP: + return format (s, "nsh-lisp-gpe"); + default: + return format (s, "unknown %d", next_index); + } + return s; +} + +static void +vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp) +{ + vat_main_t *vam = &vat_main; + u8 *iid_str; + u8 *flag_str = NULL; + + iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid)); + +#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n); + foreach_lisp_gpe_flag_bit; +#undef _ + + fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U" + "%=16d%=16d%=16sd=16d%=16s%=16s\n", + mp->tunnels, + mp->is_ipv6 ? format_ip6_address : format_ip4_address, + mp->source_ip, + mp->is_ipv6 ? format_ip6_address : format_ip4_address, + mp->destination_ip, + ntohl(mp->encap_fib_id), + ntohl(mp->decap_fib_id), + format_decap_next, ntohl(mp->dcap_next), + mp->ver_res >> 6, + flag_str, + mp->next_protocol, + mp->ver_res, + mp->res, + iid_str); + + vec_free(iid_str); +} + +static void +vl_api_lisp_gpe_tunnel_details_t_handler_json ( + vl_api_lisp_gpe_tunnel_details_t *mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t *node = NULL; + struct in6_addr ip6; + struct in_addr ip4; + u8 *next_decap_str; + + next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next)); + + if (VAT_JSON_ARRAY != vam->json_tree.type) { + ASSERT(VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array(&vam->json_tree); + } + node = vat_json_array_add(&vam->json_tree); + + vat_json_init_object(node); + vat_json_object_add_uint(node, "tunel", mp->tunnels); + if (mp->is_ipv6) { + memcpy(&ip6, mp->source_ip, sizeof(ip6)); + vat_json_object_add_ip6(node, "source address", ip6); + memcpy(&ip6, mp->destination_ip, sizeof(ip6)); + vat_json_object_add_ip6(node, "destination address", ip6); + } else { + memcpy(&ip4, mp->source_ip, sizeof(ip4)); + vat_json_object_add_ip4(node, "source address", ip4); + memcpy(&ip4, mp->destination_ip, sizeof(ip4)); + vat_json_object_add_ip4(node, "destination address", ip4); + } + vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id)); + vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id)); + vat_json_object_add_string_copy(node, "decap next", next_decap_str); + vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6); + vat_json_object_add_uint(node, "flags", mp->flags); + vat_json_object_add_uint(node, "next protocol", mp->next_protocol); + vat_json_object_add_uint(node, "ver_res", mp->ver_res); + vat_json_object_add_uint(node, "res", mp->res); + vat_json_object_add_uint(node, "iid", ntohl(mp->iid)); + + vec_free(next_decap_str); +} + +static void +vl_api_lisp_map_resolver_details_t_handler ( + vl_api_lisp_map_resolver_details_t *mp) +{ + vat_main_t *vam = &vat_main; + + fformat(vam->ofp, "%=20U\n", + mp->is_ipv6 ? format_ip6_address : format_ip4_address, + mp->ip_address); +} + +static void +vl_api_lisp_map_resolver_details_t_handler_json ( + vl_api_lisp_map_resolver_details_t *mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t *node = NULL; + struct in6_addr ip6; + struct in_addr ip4; + + if (VAT_JSON_ARRAY != vam->json_tree.type) { + ASSERT(VAT_JSON_NONE == vam->json_tree.type); + vat_json_init_array(&vam->json_tree); + } + node = vat_json_array_add(&vam->json_tree); + + vat_json_init_object(node); + if (mp->is_ipv6) { + memcpy(&ip6, mp->ip_address, sizeof(ip6)); + vat_json_object_add_ip6(node, "map resolver", ip6); + } else { + memcpy(&ip4, mp->ip_address, sizeof(ip4)); + vat_json_object_add_ip4(node, "map resolver", ip4); + } +} + #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler @@ -1943,7 +2155,13 @@ _(cop_whitelist_enable_disable_reply) \ _(sw_interface_clear_stats_reply) \ _(trace_profile_add_reply) \ _(trace_profile_apply_reply) \ -_(trace_profile_del_reply) +_(trace_profile_del_reply) \ +_(lisp_add_del_locator_set_reply) \ +_(lisp_add_del_locator_reply) \ +_(lisp_add_del_local_eid_reply) \ +_(lisp_gpe_add_del_fwd_entry_reply) \ +_(lisp_add_del_map_resolver_reply) \ +_(lisp_gpe_add_del_iface_reply) #define _(n) \ static void vl_api_##n##_t_handler \ @@ -2105,7 +2323,17 @@ _(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \ _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \ _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \ _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \ -_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) +_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \ +_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \ +_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \ +_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \ +_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \ +_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \ +_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \ +_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \ +_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \ +_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \ +_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) /* M: construct, but don't yet send a message */ @@ -9128,6 +9356,553 @@ static int api_get_node_graph (vat_main_t * vam) W; } +static int +api_lisp_add_del_locator_set(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_add_del_locator_set_t *mp; + f64 timeout = ~0; + u8 is_add = 1; + u8 *locator_set_name = NULL; + u8 locator_set_name_set = 0; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "del")) { + is_add = 0; + } else if (unformat(input, "locator-set %s", &locator_set_name)) { + locator_set_name_set = 1; + } else + break; + } + + if (locator_set_name_set == 0) { + errmsg ("missing locator-set name"); + return -99; + } + + if (vec_len(locator_set_name) > 64) { + errmsg ("locator-set name too long\n"); + vec_free(locator_set_name); + return -99; + } + vec_add1(locator_set_name, 0); + + /* Construct the API message */ + M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set); + + mp->is_add = is_add; + memcpy(mp->locator_set_name, locator_set_name, + vec_len(locator_set_name)); + vec_free(locator_set_name); + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_add_del_locator(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_add_del_locator_t *mp; + f64 timeout = ~0; + u32 tmp_if_index = ~0; + u32 sw_if_index = ~0; + u8 sw_if_index_set = 0; + u8 sw_if_index_if_name_set = 0; + u8 priority = ~0; + u8 priority_set = 0; + u8 weight = ~0; + u8 weight_set = 0; + u8 is_add = 1; + u8 *locator_set_name = NULL; + u8 locator_set_name_set = 0; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "del")) { + is_add = 0; + } else if (unformat(input, "locator-set %s", &locator_set_name)) { + locator_set_name_set = 1; + } else if (unformat(input, "iface %U", unformat_sw_if_index, vam, + &tmp_if_index)) { + sw_if_index_if_name_set = 1; + sw_if_index = tmp_if_index; + } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) { + sw_if_index_set = 1; + sw_if_index = tmp_if_index; + } else if (unformat(input, "p %d", &priority)) { + priority_set = 1; + } else if (unformat(input, "w %d", &weight)) { + weight_set = 1; + } else + break; + } + + if (locator_set_name_set == 0) { + errmsg ("missing locator-set name"); + return -99; + } + + if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) { + errmsg ("missing sw_if_index"); + vec_free(locator_set_name); + return -99; + } + + if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) { + errmsg ("cannot use both params interface name and sw_if_index"); + vec_free(locator_set_name); + return -99; + } + + if (priority_set == 0) { + errmsg ("missing locator-set priority\n"); + vec_free(locator_set_name); + return -99; + } + + if (weight_set == 0) { + errmsg ("missing locator-set weight\n"); + vec_free(locator_set_name); + return -99; + } + + if (vec_len(locator_set_name) > 64) { + errmsg ("locator-set name too long\n"); + vec_free(locator_set_name); + return -99; + } + vec_add1(locator_set_name, 0); + + /* Construct the API message */ + M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator); + + mp->is_add = is_add; + mp->sw_if_index = ntohl(sw_if_index); + mp->priority = priority; + mp->weight = weight; + memcpy(mp->locator_set_name, locator_set_name, + vec_len(locator_set_name)); + vec_free(locator_set_name); + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_add_del_local_eid(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_add_del_local_eid_t *mp; + f64 timeout = ~0; + u8 is_add = 1; + u8 eidv4_set = 0; + u8 eidv6_set = 0; + ip4_address_t eidv4; + ip6_address_t eidv6; + u8 tmp_eid_lenght = ~0; + u8 eid_lenght = ~0; + u8 *locator_set_name = NULL; + u8 locator_set_name_set = 0; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "del")) { + is_add = 0; + } else if (unformat(input, "eid %U/%d", unformat_ip4_address, + &eidv4, &tmp_eid_lenght)) { + eid_lenght = tmp_eid_lenght; + eidv4_set = 1; + } else if (unformat(input, "eid %U/%d", unformat_ip6_address, + &eidv6, &tmp_eid_lenght)) { + eid_lenght = tmp_eid_lenght; + eidv6_set = 1; + } else if (unformat(input, "locator-set %s", &locator_set_name)) { + locator_set_name_set = 1; + } else + break; + } + + if (locator_set_name_set == 0) { + errmsg ("missing locator-set name\n"); + return -99; + } + + if (vec_len(locator_set_name) > 64) { + errmsg ("locator-set name too long\n"); + vec_free(locator_set_name); + return -99; + } + vec_add1(locator_set_name, 0); + + if (eidv4_set && eidv6_set) { + errmsg ("both eid v4 and v6 addresses set\n"); + vec_free(locator_set_name); + return -99; + } + + if (!eidv4_set && !eidv6_set) { + errmsg ("eid addresses not set\n"); + vec_free(locator_set_name); + return -99; + } + + /* Construct the API message */ + M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid); + + mp->is_add = is_add; + if (eidv6_set) { + mp->is_ipv6 = 1; + memcpy(mp->ip_address, &eidv6, sizeof(eidv6)); + } else { + mp->is_ipv6 = 0; + memcpy(mp->ip_address, &eidv4, sizeof(eidv4)); + } + mp->prefix_len = eid_lenght; + memcpy(mp->locator_set_name, locator_set_name, + vec_len(locator_set_name)); + vec_free(locator_set_name); + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_gpe_add_del_fwd_entry_t *mp; + f64 timeout = ~0; + u8 is_add = 1; + u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0; + u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0; + ip4_address_t eidv4, slocv4, dlocv4; + ip6_address_t eidv6, slocv6, dlocv6; + u8 tmp_eid_lenght = ~0; + u8 eid_lenght = ~0; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "del")) { + is_add = 0; + } else if (unformat(input, "eid %U/%d", unformat_ip4_address, + &eidv4, &tmp_eid_lenght)) { + eid_lenght = tmp_eid_lenght; + eidv4_set = 1; + } else if (unformat(input, "eid %U/%d", unformat_ip6_address, + &eidv6, &tmp_eid_lenght)) { + eid_lenght = tmp_eid_lenght; + eidv6_set = 1; + } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) { + slocv4_set = 1; + } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) { + slocv6_set = 1; + } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) { + dlocv4_set = 1; + } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) { + dlocv6_set = 1; + } else + break; + } + + if (eidv4_set && eidv6_set) { + errmsg ("both eid v4 and v6 addresses set\n"); + return -99; + } + + if (!eidv4_set && !eidv6_set) { + errmsg ("eid addresses not set\n"); + return -99; + } + + if (slocv4_set && slocv6_set) { + errmsg ("both source v4 and v6 addresses set\n"); + return -99; + } + + if (!slocv4_set && !slocv6_set) { + errmsg ("source addresses not set\n"); + return -99; + } + + if (dlocv4_set && dlocv6_set) { + errmsg ("both destination v4 and v6 addresses set\n"); + return -99; + } + + if (dlocv4_set && dlocv6_set) { + errmsg ("destination addresses not set\n"); + return -99; + } + + if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) { + errmsg ("mixing type of source and destination address\n"); + return -99; + } + + /* Construct the API message */ + M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry); + + mp->is_add = is_add; + if (eidv6_set) { + mp->eid_is_ipv6 = 1; + memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6)); + } else { + mp->eid_is_ipv6 = 0; + memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4)); + } + mp->eid_prefix_len = eid_lenght; + if (slocv6_set) { + mp->address_is_ipv6 = 1; + memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6)); + memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6)); + } else { + mp->address_is_ipv6 = 0; + memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4)); + memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4)); + } + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_add_del_map_resolver(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_add_del_map_resolver_t *mp; + f64 timeout = ~0; + u8 is_add = 1; + u8 ipv4_set = 0; + u8 ipv6_set = 0; + ip4_address_t ipv4; + ip6_address_t ipv6; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "del")) { + is_add = 0; + } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) { + ipv4_set = 1; + } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) { + ipv6_set = 1; + } else + break; + } + + if (ipv4_set && ipv6_set) { + errmsg ("both eid v4 and v6 addresses set\n"); + return -99; + } + + if (!ipv4_set && !ipv6_set) { + errmsg ("eid addresses not set\n"); + return -99; + } + + /* Construct the API message */ + M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver); + + mp->is_add = is_add; + if (ipv6_set) { + mp->is_ipv6 = 1; + memcpy(mp->ip_address, &ipv6, sizeof(ipv6)); + } else { + mp->is_ipv6 = 0; + memcpy(mp->ip_address, &ipv4, sizeof(ipv4)); + } + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_gpe_add_del_iface(vat_main_t * vam) +{ + unformat_input_t * input = vam->input; + vl_api_lisp_gpe_add_del_iface_t *mp; + f64 timeout = ~0; + u8 is_set = 0; + u8 is_add = 1; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { + if (unformat(input, "up")) { + is_set = 1; + is_add = 1; + } else if (unformat(input, "down")) { + is_set = 1; + is_add = 0; + } else + break; + } + + if (is_set == 0) { + errmsg("Value not set\n"); + return -99; + } + + /* Construct the API message */ + M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface); + + mp->is_add = is_add; + + /* send it... */ + S; + + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_locator_set_dump(vat_main_t *vam) +{ + vl_api_lisp_locator_set_dump_t *mp; + f64 timeout = ~0; + + if (!vam->json_output) { + fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n", + "Locator-set", "Locator", "Priority", "Weight"); + } + + M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump); + /* send it... */ + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t * mp; + M(CONTROL_PING, control_ping); + S; + } + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_local_eid_table_dump(vat_main_t *vam) +{ + vl_api_lisp_local_eid_table_dump_t *mp; + f64 timeout = ~0; + + if (!vam->json_output) { + fformat(vam->ofp, "%=20s%=30s\n", + "Locator-set", "Eid"); + } + + M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump); + /* send it... */ + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t * mp; + M(CONTROL_PING, control_ping); + S; + } + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_gpe_tunnel_dump(vat_main_t *vam) +{ + vl_api_lisp_gpe_tunnel_dump_t *mp; + f64 timeout = ~0; + + if (!vam->json_output) { + fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s" + "%=16s%=16s%=16s%=16s%=16s\n", + "Tunel", "Source", "Destination", "Fib encap", "Fib decap", + "Decap next", "Lisp version", "Flags", "Next protocol", + "ver_res", "res", "iid"); + } + + M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump); + /* send it... */ + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t * mp; + M(CONTROL_PING, control_ping); + S; + } + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + +static int +api_lisp_map_resolver_dump(vat_main_t *vam) +{ + vl_api_lisp_map_resolver_dump_t *mp; + f64 timeout = ~0; + + if (!vam->json_output) { + fformat(vam->ofp, "%=20s\n", + "Map resolver"); + } + + M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump); + /* send it... */ + S; + + /* Use a control ping for synchronization */ + { + vl_api_control_ping_t * mp; + M(CONTROL_PING, control_ping); + S; + } + /* Wait for a reply... */ + W; + + /* NOTREACHED */ + return 0; +} + static int q_or_quit (vat_main_t * vam) { longjmp (vam->jump_buf, 1); @@ -9597,7 +10372,21 @@ _(trace_profile_add, "id trace-type <0x1f|0x3|0x9|0x11|0x19> " \ "app-data [pow] [ppc ]") \ _(trace_profile_apply, "id /" \ " vrf_id add | pop | none") \ -_(trace_profile_del, "") +_(trace_profile_del, "") \ +_(lisp_add_del_locator_set, "locator-set [del]") \ +_(lisp_add_del_locator, "locator-set " \ + "iface | sw_if_index " \ + "p w [del]") \ +_(lisp_add_del_local_eid, "/ " \ + "locator-set [del]") \ +_(lisp_gpe_add_del_fwd_entry, "eid / " \ + "sloc dloc [del]") \ +_(lisp_add_del_map_resolver, " [del]") \ +_(lisp_gpe_add_del_iface, "up|down") \ +_(lisp_locator_set_dump, "") \ +_(lisp_local_eid_table_dump, "") \ +_(lisp_gpe_tunnel_dump, "") \ +_(lisp_map_resolver_dump, "") /* List of command functions, CLI names map directly to functions */ #define foreach_cli_function \ diff --git a/vpp/api/api.c b/vpp/api/api.c index f9e69024ae0..32be34f7c01 100644 --- a/vpp/api/api.c +++ b/vpp/api/api.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -322,7 +323,17 @@ _(GET_NODE_GRAPH, get_node_graph) \ _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \ _(TRACE_PROFILE_ADD, trace_profile_add) \ _(TRACE_PROFILE_APPLY, trace_profile_apply) \ -_(TRACE_PROFILE_DEL, trace_profile_del) +_(TRACE_PROFILE_DEL, trace_profile_del) \ +_(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \ +_(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \ +_(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \ +_(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \ +_(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \ +_(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \ +_(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \ +_(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump) \ +_(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \ +_(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -4477,6 +4488,442 @@ out: })); } +static void +vl_api_lisp_add_del_locator_set_t_handler(vl_api_lisp_add_del_locator_set_t *mp) +{ + vl_api_lisp_add_del_locator_set_reply_t *rmp; + int rv = 0; + vnet_lisp_add_del_locator_set_args_t _a, *a = &_a; + u32 ls_index = ~0; + u8 *locator_name = NULL; + + memset(a, 0, sizeof(a[0])); + + locator_name = format(0, "%s", mp->locator_set_name); + + a->name = locator_name; + a->locators = NULL; + a->is_add = mp->is_add; + a->local = 1; + + rv = vnet_lisp_add_del_locator_set_name(a, &ls_index); + + vec_free(locator_name); + + REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY); +} + +static void +vl_api_lisp_add_del_locator_t_handler( + vl_api_lisp_add_del_locator_t *mp) +{ + vl_api_lisp_add_del_locator_reply_t *rmp; + int rv = 0; + locator_t locator, *locators = NULL; + vnet_lisp_add_del_locator_set_args_t _a, *a = &_a; + u32 ls_index = ~0; + u8 *locator_name = NULL; + + memset(&locator, 0, sizeof(locator)); + memset(a, 0, sizeof(a[0])); + + locator.sw_if_index = ntohl(mp->sw_if_index); + locator.priority = mp->priority; + locator.weight = mp->weight; + locator.local = 1; + vec_add1(locators, locator); + + locator_name = format(0, "%s", mp->locator_set_name); + + a->name = locator_name; + a->locators = locators; + a->is_add = mp->is_add; + a->local = 1; + + rv = vnet_lisp_add_del_locator(a, &ls_index); + + vec_free(locators); + vec_free(locator_name); + + REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_REPLY); +} + +static void +vl_api_lisp_add_del_local_eid_t_handler( + vl_api_lisp_add_del_local_eid_t *mp) +{ + vl_api_lisp_add_del_local_eid_reply_t *rmp; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + int rv = 0; + ip_prefix_t *prefp = NULL; + ip_address_t *ip_eid = NULL; + gid_address_t eid; + uword * p = NULL; + u32 locator_set_index = ~0, map_index = ~0; + vnet_lisp_add_del_mapping_args_t _a, *a = &_a; + u8 *name = NULL; + + prefp = &gid_address_ippref(&eid); + ip_eid = &ip_prefix_addr(prefp); + gid_address_type (&eid) = IP_PREFIX; + + if (mp->is_ipv6) { + memcpy(&ip_addr_v6(ip_eid), mp->ip_address, + sizeof(ip_addr_v6(ip_eid))); + ip_addr_version(ip_eid) = IP6; + } else { + memcpy(&ip_addr_v4(ip_eid), mp->ip_address, + sizeof(ip_addr_v4(ip_eid))); + ip_addr_version(ip_eid) = IP4; + } + ip_prefix_len(prefp) = mp->prefix_len; + + name = format(0, "%s", mp->locator_set_name); + p = hash_get_mem(lcm->locator_set_index_by_name, name); + if (!p) { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + locator_set_index = p[0]; + + /* XXX treat batch configuration */ + a->is_add = mp->is_add; + a->deid = eid; + a->locator_set_index = locator_set_index; + a->local = 1; + + rv = vnet_lisp_add_del_mapping(a, &map_index); + +out: + vec_free(name); + + REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY); +} + +static void +lisp_gpe_add_del_fwd_entry_set_address( + vl_api_lisp_gpe_add_del_fwd_entry_t *mp, + ip_address_t *slocator, + ip_address_t *dlocator, + gid_address_t *eid) +{ + ip_address_t *ip_eid = NULL; + ip_prefix_t *prefp = NULL; + + prefp = &gid_address_ippref(eid); + ip_eid = &ip_prefix_addr(prefp); + + if (mp->eid_is_ipv6) { + memcpy(&ip_addr_v6(ip_eid), mp->eid_ip_address, + sizeof(ip_addr_v6(ip_eid))); + ip_addr_version(ip_eid) = IP6; + } else { + memcpy(&ip_addr_v4(ip_eid), mp->eid_ip_address, + sizeof(ip_addr_v4(ip_eid))); + ip_addr_version(ip_eid) = IP4; + } + ip_prefix_len(prefp) = mp->eid_prefix_len; + + if (mp->address_is_ipv6) { + memcpy(&ip_addr_v6(slocator), mp->source_ip_address, + sizeof(ip_addr_v6(slocator))); + ip_addr_version(slocator) = IP6; + memcpy(&ip_addr_v6(dlocator), mp->destination_ip_address, + sizeof(ip_addr_v6(dlocator))); + ip_addr_version(dlocator) = IP6; + } else { + memcpy(&ip_addr_v4(slocator), mp->source_ip_address, + sizeof(ip_addr_v4(slocator))); + ip_addr_version(slocator) = IP4; + memcpy(&ip_addr_v4(dlocator), mp->destination_ip_address, + sizeof(ip_addr_v4(dlocator))); + ip_addr_version(dlocator) = IP4; + } +} + +static void +vl_api_lisp_gpe_add_del_fwd_entry_t_handler( + vl_api_lisp_gpe_add_del_fwd_entry_t *mp) +{ + vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp; + int rv = 0; + ip_address_t slocator, dlocator; + ip_prefix_t * prefp = NULL; + gid_address_t eid; + vnet_lisp_gpe_add_del_fwd_entry_args_t a; + + lisp_gpe_add_del_fwd_entry_set_address(mp, &slocator, &dlocator, &eid); + + memset (&a, 0, sizeof(a)); + + a.is_add = mp->is_add; + a.deid = eid; + a.slocator = slocator; + a.dlocator = dlocator; + prefp = &gid_address_ippref(&a.deid); + a.decap_next_index = (ip_prefix_version(prefp) == IP4) ? + LISP_GPE_INPUT_NEXT_IP4_INPUT : LISP_GPE_INPUT_NEXT_IP6_INPUT; + rv = vnet_lisp_gpe_add_del_fwd_entry (&a, 0); + + REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY); +} + +static void +vl_api_lisp_add_del_map_resolver_t_handler( + vl_api_lisp_add_del_map_resolver_t *mp) +{ + vl_api_lisp_add_del_map_resolver_reply_t *rmp; + int rv = 0; + ip_address_t *ip_addr = NULL; + vnet_lisp_add_del_map_resolver_args_t _a, * a = &_a; + + a->is_add = mp->is_add; + ip_addr = &a->address; + + if (mp->is_ipv6) { + memcpy(&ip_addr_v6(ip_addr), mp->ip_address, + sizeof(ip_addr_v6(ip_addr))); + ip_addr_version(ip_addr) = IP6; + } else { + memcpy(&ip_addr_v4(ip_addr), mp->ip_address, + sizeof(ip_addr_v4(ip_addr))); + ip_addr_version(ip_addr) = IP4; + } + + rv = vnet_lisp_add_del_map_resolver (a); + + REPLY_MACRO(VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY); +} + +static void +vl_api_lisp_gpe_add_del_iface_t_handler( + vl_api_lisp_gpe_add_del_iface_t *mp) +{ + vl_api_lisp_gpe_add_del_iface_reply_t *rmp; + int rv = 0; + vnet_lisp_gpe_add_del_iface_args_t _a, * a = &_a; + + a->is_add = mp->is_add; + vnet_lisp_gpe_add_del_iface (a, 0); + + REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY); +} + +static void +send_lisp_locator_set_details (lisp_cp_main_t *lcm, + locator_set_t *lsit, + unix_shared_memory_queue_t *q) +{ + vl_api_lisp_locator_set_details_t *rmp; + locator_t *loc = NULL; + u32 * locit = NULL; + + vec_foreach (locit, lsit->locator_indices) { + loc = pool_elt_at_index (lcm->locator_pool, locit[0]); + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_SET_DETAILS); + strncpy((char *) rmp->locator_set_name, + (char *) lsit->name, ARRAY_LEN(rmp->locator_set_name) - 1); + rmp->sw_if_index = htonl(loc->sw_if_index); + rmp->priority = loc->priority; + rmp->weight = loc->weight; + + vl_msg_api_send_shmem (q, (u8 *)&rmp); + } +} + +static void +vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t *mp) +{ + unix_shared_memory_queue_t * q = NULL; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + locator_set_t * lsit = NULL; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) { + return; + } + + pool_foreach (lsit, lcm->locator_set_pool, + ({ + send_lisp_locator_set_details(lcm, lsit, q); + })); +} + +static void +send_lisp_local_eid_table_details (mapping_t *mapit, + unix_shared_memory_queue_t *q) +{ + vl_api_lisp_local_eid_table_details_t *rmp = NULL; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + locator_set_t *ls = NULL; + gid_address_t *gid = NULL; + ip_prefix_t *ip_prefix = NULL; + u8 type = ~0; + + ls = pool_elt_at_index (lcm->locator_set_pool, + mapit->locator_set_index); + + gid = &mapit->eid; + type = gid_address_type(gid); + + if (type != IP_PREFIX) { + return; + } + + ip_prefix = &gid_address_ippref(gid); + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCAL_EID_TABLE_DETAILS); + strncpy((char *) rmp->locator_set_name, + (char *) ls->name, ARRAY_LEN(rmp->locator_set_name) - 1); + + switch (ip_prefix_version(ip_prefix)) { + case IP4: + rmp->eid_is_ipv6 = 0; + memcpy(rmp->eid_ip_address, &ip_prefix_v4(ip_prefix), + sizeof(ip_prefix_v4(ip_prefix))); + break; + + case IP6: + rmp->eid_is_ipv6 = 1; + memcpy(rmp->eid_ip_address, &ip_prefix_v6(ip_prefix), + sizeof(ip_prefix_v6(ip_prefix))); + break; + + default: + ASSERT(0); + } + rmp->eid_prefix_len = ip_prefix_len(ip_prefix); + + vl_msg_api_send_shmem (q, (u8 *)&rmp); +} + +static void +vl_api_lisp_local_eid_table_dump_t_handler ( + vl_api_lisp_local_eid_table_dump_t *mp) +{ + unix_shared_memory_queue_t * q = NULL; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + mapping_t * mapit = NULL; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) { + return; + } + + pool_foreach (mapit, lcm->mapping_pool, + ({ + send_lisp_local_eid_table_details(mapit, q); + })); +} + +static void +send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t *tunnel, + unix_shared_memory_queue_t *q) +{ + vl_api_lisp_gpe_tunnel_details_t *rmp; + lisp_gpe_main_t * lgm = &lisp_gpe_main; + ip4_address_t *ip4 = NULL; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_LISP_GPE_TUNNEL_DETAILS); + + rmp->tunnels = tunnel - lgm->tunnels; + + /*list_gpe_tunnel now support only IPv4*/ + rmp->is_ipv6 = 0; + ip4 = &tunnel->src; + memcpy(rmp->source_ip, ip4, sizeof(*ip4)); + ip4 = &tunnel->dst; + memcpy(rmp->destination_ip, ip4, sizeof(*ip4)); + + rmp->encap_fib_id = htonl(tunnel->encap_fib_index); + rmp->decap_fib_id = htonl(tunnel->decap_fib_index); + rmp->dcap_next = htonl(tunnel->decap_next_index); + rmp->lisp_ver = tunnel->ver_res; + rmp->next_protocol = tunnel->next_protocol; + rmp->flags = tunnel->flags; + rmp->ver_res = tunnel->ver_res; + rmp->res = tunnel->res; + rmp->iid = htonl(tunnel->iid); + + vl_msg_api_send_shmem (q, (u8 *)&rmp); +} + +static void +vl_api_lisp_gpe_tunnel_dump_t_handler ( + vl_api_lisp_local_eid_table_dump_t *mp) +{ + unix_shared_memory_queue_t * q = NULL; + lisp_gpe_main_t * lgm = &lisp_gpe_main; + lisp_gpe_tunnel_t * tunnel = NULL; + + if (pool_elts(lgm->tunnels) == 0) { + return; + } + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) { + return; + } + + pool_foreach(tunnel, lgm->tunnels, + ({ + send_lisp_gpe_tunnel_details(tunnel, q); + })); +} + +static void +send_lisp_map_resolver_details (ip_address_t *ip, + unix_shared_memory_queue_t *q) +{ + vl_api_lisp_map_resolver_details_t *rmp = NULL; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs(VL_API_LISP_MAP_RESOLVER_DETAILS); + + switch (ip_addr_version(ip)) { + case IP4: + rmp->is_ipv6 = 0; + memcpy(rmp->ip_address, &ip_addr_v4(ip), sizeof(ip_addr_v4(ip))); + break; + + case IP6: + rmp->is_ipv6 = 1; + memcpy(rmp->ip_address, &ip_addr_v6(ip), sizeof(ip_addr_v6(ip))); + break; + + default: + ASSERT(0); + } + + vl_msg_api_send_shmem (q, (u8 *)&rmp); +} + +static void +vl_api_lisp_map_resolver_dump_t_handler ( + vl_api_lisp_local_eid_table_dump_t *mp) +{ + unix_shared_memory_queue_t * q = NULL; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); + ip_address_t *ip = NULL; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) { + return; + } + + vec_foreach(ip, lcm->map_resolvers) { + send_lisp_map_resolver_details(ip, q); + } + +} + static void vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *mp) { diff --git a/vpp/api/vpe.api b/vpp/api/vpe.api index d9e62e2ab12..4414a7f7ade 100644 --- a/vpp/api/vpe.api +++ b/vpp/api/vpe.api @@ -2184,6 +2184,252 @@ define lisp_gpe_add_del_tunnel_reply { u32 sw_if_index; }; +/** \brief add or delete locator_set + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete + @param locator_set_name - locator name +*/ +define lisp_add_del_locator_set { + u32 client_index; + u32 context; + u8 is_add; + u8 locator_set_name[64]; +}; + +/** \brief Reply for locator_set add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_add_del_locator_set_reply { + u32 context; + i32 retval; +}; + +/** \brief add or delete locator for locator_set + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete + @param locator_set_name - name of locator_set to add/del locator + @param sw_if_index - index of the interface + @param priority - priority of the lisp locator + @param weight - weight of the lisp locator +*/ +define lisp_add_del_locator { + u32 client_index; + u32 context; + u8 is_add; + u8 locator_set_name[64]; + u32 sw_if_index; + u8 priority; + u8 weight; +}; + +/** \brief Reply for locator add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_add_del_locator_reply { + u32 context; + i32 retval; +}; + +/** \brief add or delete lisp eid-table + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete + @param is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param ip_address - array of address bytes + @param prefix_len - prefix len + @param locator_set_name - name of locator_set to add/del eid-table +*/ +define lisp_add_del_local_eid { + u32 client_index; + u32 context; + u8 is_add; + u8 is_ipv6; + u8 ip_address[16]; + u8 prefix_len; + u8 locator_set_name[64]; +}; + +/** \brief Reply for local_eid add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_add_del_local_eid_reply { + u32 context; + i32 retval; +}; + +/** \brief add or delete lisp gpe maptunel + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete + @param eid_is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param eid_ip_address - array of address bytes + @param eid_prefix_len - prefix len + @param address_is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param source_ip_address - array of address bytes + @param destination_ip_address - array of address bytes +*/ +define lisp_gpe_add_del_fwd_entry { + u32 client_index; + u32 context; + u8 is_add; + u8 eid_is_ipv6; + u8 eid_ip_address[16]; + u8 eid_prefix_len; + u8 address_is_ipv6; + u8 source_ip_address[16]; + u8 destination_ip_address[16]; +}; + +/** \brief Reply for gpe_fwd_entry add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_gpe_add_del_fwd_entry_reply { + u32 context; + i32 retval; +}; + +/** \brief add or delete map-resolver + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete + @param is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param ip_address - array of address bytes +*/ +define lisp_add_del_map_resolver { + u32 client_index; + u32 context; + u8 is_add; + u8 is_ipv6; + u8 ip_address[16]; +}; + +/** \brief Reply for map_resolver add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_add_del_map_resolver_reply { + u32 context; + i32 retval; +}; + +/** \brief add or delete gpe_iface + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add address if non-zero, else delete +*/ +define lisp_gpe_add_del_iface { + u32 client_index; + u32 context; + u8 is_add; +}; + +/** \brief Reply for gpe_iface add/del + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define lisp_gpe_add_del_iface_reply { + u32 context; + i32 retval; +}; + +/** \brief LISP locator_set status + @param locator_set_name - name of the locator_set + @param sw_if_index - sw_if_index of the locator + @param priority - locator priority + @param weight - locator weight + */ +manual_java define lisp_locator_set_details { + u32 context; + u8 locator_set_name[64]; + u32 sw_if_index; + u8 priority; + u8 weight; +}; + +/** \brief Request for locator_set summary status + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define lisp_locator_set_dump { + u32 client_index; + u32 context; +}; + +/** \brief LISP local eid table status + @param locator_set_name - name of the locator_set + @param eid_is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param eid_ip_address - array of address bytes + @param eid_prefix_len - prefix len + */ +manual_java define lisp_local_eid_table_details { + u32 context; + u8 locator_set_name[64]; + u8 eid_is_ipv6; + u8 eid_ip_address[16]; + u8 eid_prefix_len; +}; + +/** \brief Request for local eid table summary status + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define lisp_local_eid_table_dump { + u32 client_index; + u32 context; +}; + +manual_java define lisp_gpe_tunnel_details { + u32 context; + u32 tunnels; + u8 is_ipv6; + u8 source_ip[16]; + u8 destination_ip[16]; + u32 encap_fib_id; + u32 decap_fib_id; + u32 dcap_next; + u8 lisp_ver; + u8 next_protocol; + u8 flags; + u8 ver_res; + u8 res; + u32 iid; +}; + +/** \brief Request for gpe tunnel summary status + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define lisp_gpe_tunnel_dump { + u32 client_index; + u32 context; +}; + +/** \brief LISP map resolver status + @param locator_set_name - name of the locator_set + @param is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param ip_address - array of address bytes + */ +manual_java define lisp_map_resolver_details { + u32 context; + u8 is_ipv6; + u8 ip_address[16]; +}; + +/** \brief Request for map resolver summary status + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + */ +define lisp_map_resolver_dump { + u32 client_index; + u32 context; +}; + /* Gross kludge, DGMS */ define interface_name_renumber { u32 client_index;