diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-01-17 13:47:57 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-01-17 16:32:51 +0100 |
commit | bac3da61644515f05663789b122554dc77549286 (patch) | |
tree | 898210bc8e70371d77de7d446a26c5dd4fd1165a /hicn-plugin/src/hicn_api.c | |
parent | d5165246787301d0f13b646fda5e8a8567aef5ac (diff) |
This is the first commit of the hicn projectv19.01
Change-Id: I6f2544ad9b9f8891c88cc4bcce3cf19bd3cc863f
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'hicn-plugin/src/hicn_api.c')
-rwxr-xr-x | hicn-plugin/src/hicn_api.c | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c new file mode 100755 index 000000000..8becde12c --- /dev/null +++ b/hicn-plugin/src/hicn_api.c @@ -0,0 +1,570 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <vlib/vlib.h> +#include <vnet/vnet.h> +#include <vppinfra/error.h> +#include <vnet/ip/format.h> +#include <vnet/ip/ip4.h> +#include <vnet/ip/ip6.h> +#include <vlibapi/api.h> +#include <vlibmemory/api.h> + +#include "hicn.h" +#include "faces/ip/face_ip.h" +#include "infra.h" +#include "parser.h" +#include "mgmt.h" +#include "strategy_dpo_manager.h" +#include "strategy_dpo_ctx.h" +#include "strategy.h" +#include "pg.h" +#include "error.h" +#include "punt.h" +#include "faces/app/face_prod.h" +#include "faces/app/face_cons.h" +#include "route.h" + +/* define message IDs */ +#include <hicn/hicn_msg_enum.h> + +/* define generated endian-swappers */ +#define vl_endianfun +#include <hicn/hicn_all_api_h.h> +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include <hicn/hicn_all_api_h.h> +#undef vl_printfun + +/* Get the API version number */ +#define vl_api_version(n, v) static u32 api_version=(v); +#include <hicn/hicn_all_api_h.h> +#undef vl_api_version + +#define REPLY_MSG_ID_BASE sm->msg_id_base +#include <vlibapi/api_helper_macros.h> + +/****** List of message types that this plugin understands ******/ + +#define foreach_hicn_plugin_api_msg \ + _(HICN_API_NODE_PARAMS_SET, hicn_api_node_params_set) \ + _(HICN_API_NODE_PARAMS_GET, hicn_api_node_params_get) \ + _(HICN_API_NODE_STATS_GET, hicn_api_node_stats_get) \ + _(HICN_API_FACE_IP_ADD, hicn_api_face_ip_add) \ + _(HICN_API_FACE_IP_DEL, hicn_api_face_ip_del) \ + _(HICN_API_FACE_IP_PARAMS_GET, hicn_api_face_ip_params_get) \ + _(HICN_API_ROUTE_GET, hicn_api_route_get) \ + _(HICN_API_ROUTE_NHOPS_ADD, hicn_api_route_nhops_add) \ + _(HICN_API_ROUTE_DEL, hicn_api_route_del) \ + _(HICN_API_ROUTE_NHOP_DEL, hicn_api_route_nhop_del) \ + _(HICN_API_STRATEGIES_GET, hicn_api_strategies_get) \ + _(HICN_API_STRATEGY_GET, hicn_api_strategy_get) \ + _(HICN_API_PUNTING_ADD, hicn_api_punting_add) \ + _(HICN_API_PUNTING_DEL, hicn_api_punting_del) \ + _(HICN_API_REGISTER_PROD_APP, hicn_api_register_prod_app) \ + _(HICN_API_REGISTER_CONS_APP, hicn_api_register_cons_app) + + +/****** SUPPORTING FUNCTION DECLARATIONS ******/ + +/* + * Convert a unix return code to a vnet_api return code. Currently stubby: + * should have more cases. + */ +always_inline vnet_api_error_t +hicn_face_api_entry_params_serialize (hicn_face_id_t faceid, + vl_api_hicn_api_face_ip_params_get_reply_t + * reply); + + +/****************** API MESSAGE HANDLERS ******************/ + +/****** NODE ******/ + +static void +vl_api_hicn_api_node_params_set_t_handler (vl_api_hicn_api_node_params_set_t * + mp) +{ + vl_api_hicn_api_node_params_set_reply_t *rmp; + int rv; + + hicn_main_t *sm = &hicn_main; + + int pit_max_size = clib_net_to_host_i32 (mp->pit_max_size); + f64 pit_dflt_lifetime_sec = mp->pit_dflt_lifetime_sec; + f64 pit_min_lifetime_sec = mp->pit_min_lifetime_sec; + f64 pit_max_lifetime_sec = mp->pit_max_lifetime_sec; + int cs_max_size = clib_net_to_host_i32 (mp->cs_max_size); + int cs_reserved_app = clib_net_to_host_i32 (mp->cs_reserved_app); + + cs_reserved_app = cs_reserved_app >= 0 + && cs_reserved_app < 100 ? cs_reserved_app : HICN_PARAM_CS_RESERVED_APP; + + rv = hicn_infra_plugin_enable_disable ((int) (mp->enable_disable), + pit_max_size, + pit_dflt_lifetime_sec, + pit_min_lifetime_sec, + pit_max_lifetime_sec, + cs_max_size, cs_reserved_app); + + REPLY_MACRO (VL_API_HICN_API_NODE_PARAMS_SET_REPLY /* , rmp, mp, rv */ ); +} + +static void +vl_api_hicn_api_node_params_get_t_handler (vl_api_hicn_api_node_params_get_t * + mp) +{ + vl_api_hicn_api_node_params_get_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_NODE_PARAMS_GET_REPLY, ( + { + rmp->is_enabled = sm->is_enabled; + rmp->feature_cs = HICN_FEATURE_CS; + rmp->pit_max_size = clib_host_to_net_u32 (hicn_infra_pit_size); + rmp->pit_dflt_lifetime_sec = ((f64) sm->pit_lifetime_dflt_ms) / SEC_MS; + rmp->pit_min_lifetime_sec = ((f64) sm->pit_lifetime_min_ms) / SEC_MS; + rmp->pit_max_lifetime_sec = ((f64) sm->pit_lifetime_max_ms) / SEC_MS; + rmp->cs_max_size = clib_host_to_net_u32 (hicn_infra_cs_size); + rmp->retval = clib_host_to_net_i32 (rv); + })); + /* *INDENT-ON* */ +} + +static void +vl_api_hicn_api_node_stats_get_t_handler (vl_api_hicn_api_node_stats_get_t * + mp) +{ + vl_api_hicn_api_node_stats_get_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_NODE_STATS_GET_REPLY, ( + { + rv = hicn_mgmt_node_stats_get (rmp); + rmp->retval =clib_host_to_net_i32 (rv); + })); + /* *INDENT-ON* */ +} + + +/****** FACE *******/ + +static void +vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp) +{ + vl_api_hicn_api_face_ip_add_reply_t *rmp; + int rv; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = HICN_FACE_NULL; + ip46_address_t nh_addr; + nh_addr.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->nh_addr))[0]); + nh_addr.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->nh_addr))[1]); + + u32 swif = clib_net_to_host_u32 (mp->swif); + rv = hicn_face_ip_add (&nh_addr, NULL, swif, &faceid); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_ADD_REPLY /* , rmp, mp, rv */ ,( + { + rmp->faceid = clib_host_to_net_u16 ((u16) faceid); + })); + /* *INDENT-ON* */ +} + +static void +vl_api_hicn_api_face_ip_del_t_handler (vl_api_hicn_api_face_ip_del_t * mp) +{ + vl_api_hicn_api_face_ip_del_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u16 (mp->faceid); + rv = hicn_face_del (faceid); + + REPLY_MACRO (VL_API_HICN_API_FACE_IP_DEL_REPLY /* , rmp, mp, rv */ ); + +} + +static void + vl_api_hicn_api_face_ip_params_get_t_handler + (vl_api_hicn_api_face_ip_params_get_t * mp) +{ + vl_api_hicn_api_face_ip_params_get_reply_t *rmp; + int rv = 0; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u16 (mp->faceid); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_PARAMS_GET_REPLY, ( + { + rv = hicn_face_api_entry_params_serialize(faceid, rmp); + rmp->retval = clib_host_to_net_u32(rv); + })); + /* *INDENT-ON* */ +} + +/****** ROUTE *******/ + +static void +vl_api_hicn_api_route_nhops_add_t_handler (vl_api_hicn_api_route_nhops_add_t + * mp) +{ + vl_api_hicn_api_route_nhops_add_reply_t *rmp; + int rv = HICN_ERROR_NONE; + hicn_face_id_t face_ids[HICN_PARAM_FIB_ENTRY_NHOPS_MAX]; + + hicn_main_t *sm = &hicn_main; + + ip46_address_t prefix; + prefix.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + + u8 len = mp->len; + u8 n_faces = mp->n_faces; + + for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) + { + face_ids[i] = clib_net_to_host_u16 (mp->face_ids[i]); + } + + if ((face_ids == NULL) || (n_faces > HICN_PARAM_FIB_ENTRY_NHOPS_MAX)) + { + rv = VNET_API_ERROR_INVALID_ARGUMENT; + } + if (rv == HICN_ERROR_NONE) + { + rv = hicn_route_add (face_ids, n_faces, &prefix, len); + + if (rv == HICN_ERROR_ROUTE_ALREADY_EXISTS) + { + rv = hicn_route_add_nhops (face_ids, n_faces, &prefix, len); + } + } + REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOPS_ADD_REPLY /* , rmp, mp, rv */ ); +} + + +static void vl_api_hicn_api_route_del_t_handler + (vl_api_hicn_api_route_del_t * mp) +{ + vl_api_hicn_api_route_del_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + ip46_address_t prefix; + prefix.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + u8 len = mp->len; + + rv = hicn_route_del (&prefix, len); + + REPLY_MACRO (VL_API_HICN_API_ROUTE_DEL_REPLY /* , rmp, mp, rv */ ); +} + +static void vl_api_hicn_api_route_nhop_del_t_handler + (vl_api_hicn_api_route_nhop_del_t * mp) +{ + vl_api_hicn_api_route_nhop_del_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + ip46_address_t prefix; + prefix.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + u8 len = mp->len; + hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); + + + rv = hicn_route_del_nhop (&prefix, len, faceid); + + REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOP_DEL_REPLY /* , rmp, mp, rv */ ); +} + +static void vl_api_hicn_api_route_get_t_handler + (vl_api_hicn_api_route_get_t * mp) +{ + vl_api_hicn_api_route_get_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + ip46_address_t prefix; + prefix.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + u8 len = mp->len; + const dpo_id_t *hicn_dpo_id; + const hicn_dpo_vft_t *hicn_dpo_vft; + hicn_dpo_ctx_t *hicn_dpo_ctx; + u32 fib_index; + + rv = hicn_route_get_dpo (&prefix, len, &hicn_dpo_id, &fib_index); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_ROUTE_GET_REPLY, ( + { + if (rv == HICN_ERROR_NONE) + { + hicn_dpo_vft = hicn_dpo_get_vft(hicn_dpo_id->dpoi_index); + hicn_dpo_ctx = hicn_dpo_vft->hicn_dpo_get_ctx(hicn_dpo_id->dpoi_index); + for (int i = 0; i < hicn_dpo_ctx->entry_count; i++) + { + if (dpo_id_is_valid(&hicn_dpo_ctx->next_hops[i])) + { + rmp->faceids[i] =((dpo_id_t *) &hicn_dpo_ctx->next_hops[i])->dpoi_index;} + } + rmp->strategy_id = clib_host_to_net_u32(hicn_dpo_get_vft_id(hicn_dpo_id));} + })); + /* *INDENT-ON* */ +} + +static void vl_api_hicn_api_strategies_get_t_handler + (vl_api_hicn_api_strategies_get_t * mp) +{ + vl_api_hicn_api_strategies_get_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + int n_strategies = hicn_strategy_get_all_available (); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_STRATEGIES_GET_REPLY/* , rmp, mp, rv */ ,( + { + int j = 0; + for (u32 i = 0; i < (u32) n_strategies; i++) + { + if (hicn_dpo_strategy_id_is_valid (i) == HICN_ERROR_NONE) + { + rmp->strategy_id[j] = clib_host_to_net_u32 (i); j++;} + } + rmp->n_strategies = n_strategies; + })); + /* *INDENT-ON* */ +} + +static void vl_api_hicn_api_strategy_get_t_handler + (vl_api_hicn_api_strategy_get_t * mp) +{ + vl_api_hicn_api_strategy_get_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + u32 strategy_id = clib_net_to_host_u32 (mp->strategy_id); + rv = hicn_dpo_strategy_id_is_valid (strategy_id); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_STRATEGY_GET_REPLY /* , rmp, mp, rv */ ,( + { + if (rv == HICN_ERROR_NONE) + { + const hicn_dpo_vft_t * hicn_dpo_vft = + hicn_dpo_get_vft (strategy_id); + hicn_dpo_vft->format_hicn_dpo (rmp->description, 0);} + })); + /* *INDENT-ON* */ +} + +/****** PUNTING *******/ + +static void vl_api_hicn_api_punting_add_t_handler + (vl_api_hicn_api_punting_add_t * mp) +{ + vl_api_hicn_api_punting_add_reply_t *rmp; + int rv = HICN_ERROR_NONE; + vlib_main_t *vm = vlib_get_main (); + + hicn_main_t *sm = &hicn_main; + + ip46_address_t prefix; + prefix.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + u8 subnet_mask = mp->len; + u32 swif = clib_net_to_host_u32 (mp->swif); + + rv = + hicn_punt_interest_data_for_ethernet (vm, &prefix, subnet_mask, swif, 0); + + REPLY_MACRO (VL_API_HICN_API_PUNTING_ADD_REPLY /* , rmp, mp, rv */ ); +} + +static void vl_api_hicn_api_punting_del_t_handler + (vl_api_hicn_api_punting_del_t * mp) +{ + vl_api_hicn_api_punting_del_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + rv = HICN_ERROR_NONE; + + REPLY_MACRO (VL_API_HICN_API_ROUTE_DEL_REPLY /* , rmp, mp, rv */ ); +} + +/************* APP FACE ****************/ + +static void vl_api_hicn_api_register_prod_app_t_handler + (vl_api_hicn_api_register_prod_app_t * mp) +{ + vl_api_hicn_api_register_prod_app_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + + hicn_prefix_t prefix; + prefix.name.as_u64[0] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[0]); + prefix.name.as_u64[1] = clib_net_to_host_u64 (((u64 *) (&mp->prefix))[1]); + prefix.len = mp->len; + u32 swif = clib_net_to_host_u32 (mp->swif); + u32 cs_reserved = clib_net_to_host_u32 (mp->cs_reserved); + u32 faceid; + + ip46_address_t prod_addr; + ip46_address_reset (&prod_addr); + rv = hicn_face_prod_add (&prefix, swif, &cs_reserved, &prod_addr, &faceid); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_REGISTER_PROD_APP_REPLY, ( + { + rmp->prod_addr[0] = prod_addr.as_u64[0]; + rmp->prod_addr[1] = prod_addr.as_u64[1]; + rmp->cs_reserved = clib_net_to_host_u32(cs_reserved); + rmp->faceid = clib_net_to_host_u32(faceid); + })); + /* *INDENT-ON* */ +} + +static void vl_api_hicn_api_register_cons_app_t_handler + (vl_api_hicn_api_register_cons_app_t * mp) +{ + vl_api_hicn_api_register_cons_app_reply_t *rmp; + int rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + ip4_address_t src_addr4; + ip6_address_t src_addr6; + src_addr4.as_u32 = (u32) 0; + src_addr6.as_u64[0] = (u64) 0; + src_addr6.as_u64[1] = (u64) 1; + + u32 swif = clib_net_to_host_u32 (mp->swif); + u32 faceid; + + rv = hicn_face_cons_add (&src_addr4, &src_addr6, swif, &faceid); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_REGISTER_CONS_APP_REPLY, ( + { + rmp->src_addr4 = clib_net_to_host_u32(src_addr4.as_u32); + rmp->src_addr6[0] = clib_net_to_host_u64(src_addr6.as_u64[0]); + rmp->src_addr6[1] = clib_net_to_host_u64(src_addr6.as_u64[1]); + rmp->faceid = clib_net_to_host_u32(faceid); + })); + /* *INDENT-ON* */ +} + +/************************************************************************************/ + +/* Set up the API message handling tables */ +clib_error_t * +hicn_api_plugin_hookup (vlib_main_t * vm) +{ + hicn_main_t *sm = &hicn_main; + + /* Get a correctly-sized block of API message decode slots */ + u8 *name = format (0, "hicn_%08x%c", api_version, 0); + sm->msg_id_base = vl_msg_api_get_msg_ids ((char *) name, + VL_MSG_FIRST_AVAILABLE); + vec_free (name); + +#define _(N, n) \ + vl_msg_api_set_handlers(sm->msg_id_base + VL_API_##N, \ + #n, \ + vl_api_##n##_t_handler, \ + vl_noop_handler, \ + vl_api_##n##_t_endian, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 1); + foreach_hicn_plugin_api_msg; +#undef _ + + return 0; +} + + + + + + + +/******************* SUPPORTING FUNCTIONS *******************/ + +/* + * Binary serialization for get face configuration API. for the moment + * assuming only ip faces here. To be completed with othet types of faces + */ +vnet_api_error_t +hicn_face_api_entry_params_serialize (hicn_face_id_t faceid, + vl_api_hicn_api_face_ip_params_get_reply_t + * reply) +{ + int rv = HICN_ERROR_NONE; + + if (!reply) + { + rv = VNET_API_ERROR_INVALID_ARGUMENT; + goto done; + } + hicn_face_t *face = hicn_dpoi_get_from_idx (faceid); + + ip_adjacency_t *ip_adj = adj_get (face->shared.adj); + + if (ip_adj != NULL) + { + reply->nh_addr[0] = + clib_host_to_net_u64 (ip_adj->sub_type.nbr.next_hop.as_u64[0]); + reply->nh_addr[1] = + clib_host_to_net_u64 (ip_adj->sub_type.nbr.next_hop.as_u64[1]); + reply->swif = clib_host_to_net_u32 (face->shared.sw_if); + reply->flags = clib_host_to_net_u32 (face->shared.flags); + } + else + rv = HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; + +done: + return (rv); +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: eval: (c-set-style "gnu") End: + */ |