diff options
author | Alberto Compagno <acompagn+fdio@cisco.com> | 2019-11-17 12:50:48 +0100 |
---|---|---|
committer | Alberto Compagno <acompagn+fdio@cisco.com> | 2019-11-18 11:16:44 +0100 |
commit | fb81ea88640de69820f2b2d24e29e5743e4f301b (patch) | |
tree | 51b929825d7d68b4105ac63ea0cea32dd48ae269 /hicn-plugin/src/hicn_api.c | |
parent | 547acf3eed92d3564139cccf205c852178bcc310 (diff) |
[HICN-225] Added generic binary api for handling faces
Supported messages are add, del, get, dump, get.
Each message contains a face id and the expected message has different
fields based on the face type.
The binary api specific for ip faces is still available for compatibility
but deprecated.
Change-Id: I899c6cf31a56abd39ad287ea3128993857997fcb
Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
Diffstat (limited to 'hicn-plugin/src/hicn_api.c')
-rw-r--r-- | hicn-plugin/src/hicn_api.c | 314 |
1 files changed, 284 insertions, 30 deletions
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c index 5f195b6da..b1e6bccb9 100644 --- a/hicn-plugin/src/hicn_api.c +++ b/hicn-plugin/src/hicn_api.c @@ -26,6 +26,7 @@ #include "hicn.h" #include "faces/ip/face_ip.h" +#include "faces/udp/face_udp.h" #include "infra.h" #include "parser.h" #include "mgmt.h" @@ -70,6 +71,10 @@ _(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_FACE_ADD, hicn_api_face_add) \ + _(HICN_API_FACE_DEL, hicn_api_face_del) \ + _(HICN_API_FACES_DUMP, hicn_api_faces_dump) \ + _(HICN_API_FACE_GET, hicn_api_face_get) \ _(HICN_API_FACE_STATS_DUMP, hicn_api_face_stats_dump) \ _(HICN_API_ROUTE_GET, hicn_api_route_get) \ _(HICN_API_ROUTES_DUMP, hicn_api_routes_dump) \ @@ -175,21 +180,17 @@ vl_api_hicn_api_node_stats_get_t_handler (vl_api_hicn_api_node_stats_get_t * /****** FACE *******/ - -static void -vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp) +static hicn_error_t +hicn_api_face_ip_add (vl_api_hicn_face_ip_t * mp, hicn_face_id_t * face_id) { - vl_api_hicn_api_face_ip_add_reply_t *rmp; hicn_error_t rv = HICN_ERROR_NONE; - hicn_main_t *sm = &hicn_main; vnet_main_t *vnm = vnet_get_main (); - hicn_face_id_t faceid = HICN_FACE_NULL; ip46_address_t local_addr; ip46_address_t remote_addr; - ip_address_decode(&mp->local_addr, &local_addr); - ip_address_decode(&mp->remote_addr, &remote_addr); + ip_address_decode (&mp->local_addr, &local_addr); + ip_address_decode (&mp->remote_addr, &remote_addr); u32 sw_if = clib_net_to_host_u32 (mp->swif); @@ -244,14 +245,25 @@ vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp) } if (rv == HICN_ERROR_NONE) - rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid, 0); - else - faceid = HICN_FACE_NULL; + rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, face_id, 0); + + return rv; +} + +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; + hicn_error_t rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + hicn_face_id_t face_id = HICN_FACE_NULL; + rv = hicn_api_face_ip_add (&(mp->face), &face_id); /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_ADD_REPLY /* , rmp, mp, rv */ ,( { - rmp->faceid = clib_host_to_net_u32 ((u32) faceid); + rmp->faceid = clib_host_to_net_u32 ((u32) face_id); rmp->retval = rv; })); /* *INDENT-ON* */ @@ -261,12 +273,15 @@ 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; + int rv = HICN_ERROR_FACE_NOT_FOUND; hicn_main_t *sm = &hicn_main; hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); - rv = hicn_face_ip_del (faceid); + if (hicn_dpoi_idx_is_valid (faceid)) + { + rv = hicn_face_ip_del (faceid); + } REPLY_MACRO (VL_API_HICN_API_FACE_IP_DEL_REPLY /* , rmp, mp, rv */ ); @@ -292,6 +307,242 @@ static void /* *INDENT-ON* */ } +static hicn_error_t +hicn_api_face_udp_add (vl_api_hicn_face_udp_t * mp, hicn_face_id_t * face_id) +{ + hicn_error_t rv = HICN_ERROR_NONE; + + ip46_address_t local_addr = ip46_address_initializer; + ip46_address_t remote_addr = ip46_address_initializer; + u16 lport; + u16 rport; + u32 sw_if; + ip_address_decode (&mp->local_addr, &local_addr); + ip_address_decode (&mp->remote_addr, &remote_addr); + //Do not byteswap. We store ports in network order + lport = mp->lport; + rport = mp->rport; + sw_if = clib_net_to_host_u32 (mp->swif); + + int input_is_ok = !ip46_address_is_zero (&local_addr) + && !ip46_address_is_zero (&remote_addr) + && + ((ip46_address_is_ip4 (&local_addr) && ip46_address_is_ip4 (&remote_addr)) + || (!ip46_address_is_ip4 (&local_addr) + && !ip46_address_is_ip4 (&remote_addr))) && lport != 0 && rport != 0; + + if (!input_is_ok) + { + rv = HICN_ERROR_UNSPECIFIED; + } + else + { + rv = hicn_face_udp_add (&local_addr, + &remote_addr, lport, rport, sw_if, face_id); + } + return rv; +} + +static void +vl_api_hicn_api_face_add_t_handler (vl_api_hicn_api_face_add_t * mp) +{ + vl_api_hicn_api_face_add_reply_t *rmp; + hicn_error_t rv = HICN_ERROR_NONE; + + hicn_main_t *sm = &hicn_main; + hicn_face_id_t face_id; + vl_api_face_type_t face_type = mp->type; + + switch (face_type) + { + case IP_FACE: + rv = hicn_api_face_ip_add (&(mp->face.ip), &face_id); + break; + case UDP_FACE: + rv = hicn_api_face_udp_add (&(mp->face.udp), &face_id); + break; + default: + rv = HICN_ERROR_UNSPECIFIED; + break; + } + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_FACE_ADD_REPLY /* , rmp, mp, rv */ ,( + { + rmp->faceid = clib_host_to_net_u32 ((u32) face_id); + rmp->retval = rv; + })); + /* *INDENT-ON* */ +} + +static void +vl_api_hicn_api_face_del_t_handler (vl_api_hicn_api_face_del_t * mp) +{ + vl_api_hicn_api_face_del_reply_t *rmp; + int rv = HICN_ERROR_FACE_NOT_FOUND; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); + if (hicn_dpoi_idx_is_valid (faceid)) + { + hicn_face_t *face = hicn_dpoi_get_from_idx (faceid); + hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type); + rv = vft->hicn_face_del (faceid); + } + + REPLY_MACRO (VL_API_HICN_API_FACE_DEL_REPLY /* , rmp, mp, rv */ ); + +} + +static void +send_face_ip_details (hicn_face_t * face, vl_api_hicn_face_ip_t * mp) +{ + vnet_main_t *vnm = vnet_get_main (); + + hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data; + ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY, &mp->local_addr); + ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY, &mp->remote_addr); + mp->flags = clib_host_to_net_u32 (face->shared.flags); + mp->swif = clib_net_to_host_u32 (face->shared.sw_if); + vnet_sw_interface_t *sw_interface = + vnet_get_sw_interface_or_null (vnm, face->shared.sw_if); + u8 *sbuf = 0; + if (sw_interface != NULL) + { + sbuf = + format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface); + strcpy ((char *) (mp->if_name), (char *) sbuf); + } +} + +static void +send_face_udp_details (hicn_face_t * face, vl_api_hicn_face_udp_t * mp) +{ + vnet_main_t *vnm = vnet_get_main (); + hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data; + if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == 0x45) + { + ip46_address_t src_addr = { 0 }; + ip46_address_t dst_addr = { 0 }; + ip46_address_set_ip4 (&src_addr, &(face_udp->hdrs.ip4.ip.src_address)); + ip46_address_set_ip4 (&dst_addr, &(face_udp->hdrs.ip4.ip.dst_address)); + + ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr)); + ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr)); + //Do not swap, they are already in network order + mp->lport = face_udp->hdrs.ip4.udp.src_port; + mp->rport = face_udp->hdrs.ip4.udp.dst_port; + } + else + { + ip46_address_t src_addr = { 0 }; + ip46_address_t dst_addr = { 0 }; + ip46_address_set_ip6 (&src_addr, &(face_udp->hdrs.ip6.ip.src_address)); + ip46_address_set_ip6 (&dst_addr, &(face_udp->hdrs.ip6.ip.dst_address)); + + ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr)); + ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr)); + //Do not swap, they are already in network order + mp->lport = face_udp->hdrs.ip6.udp.src_port; + mp->rport = face_udp->hdrs.ip6.udp.dst_port; + } + mp->flags = clib_host_to_net_u32 (face->shared.flags); + mp->swif = clib_net_to_host_u32 (face->shared.sw_if); + vnet_sw_interface_t *sw_interface = + vnet_get_sw_interface_or_null (vnm, face->shared.sw_if); + u8 *sbuf = 0; + if (sw_interface != NULL) + { + sbuf = + format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface); + strcpy ((char *) (mp->if_name), (char *) sbuf); + } +} + +static void +send_faces_details (vl_api_registration_t * reg, + hicn_face_t * face, u32 context) +{ + vl_api_hicn_api_faces_details_t *mp; + hicn_main_t *hm = &hicn_main; + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->faceid = clib_host_to_net_u32 (hicn_dpoi_get_index (face)); + mp->_vl_msg_id = htons (VL_API_HICN_API_FACES_DETAILS + hm->msg_id_base); + mp->context = context; + + if (face->shared.face_type == hicn_face_ip_type) + { + mp->type = IP_FACE; + send_face_ip_details (face, &(mp->face.ip)); + } + else if (face->shared.face_type == hicn_face_udp_type) + { + mp->type = UDP_FACE; + send_face_udp_details (face, &(mp->face.udp)); + } + + + vl_api_send_msg (reg, (u8 *) mp); +} + +static void + vl_api_hicn_api_faces_dump_t_handler (vl_api_hicn_api_faces_dump_t * mp) +{ + hicn_face_t *face; + vl_api_registration_t *reg; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + /* *INDENT-OFF* */ + pool_foreach (face, hicn_dpoi_face_pool, + ({ + send_faces_details (reg, face, mp->context); + })); + /* *INDENT-ON* */ +} + +static void + vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp) +{ + vl_api_hicn_api_face_get_reply_t *rmp; + int rv = 0; + + hicn_main_t *sm = &hicn_main; + + hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_HICN_API_FACE_GET_REPLY, ( + { + rv = hicn_dpoi_idx_is_valid(faceid); + if (rv) + { + hicn_face_t * face = hicn_dpoi_get_from_idx(faceid); + if (face->shared.face_type == hicn_face_ip_type) + { + rmp->type = IP_FACE; + send_face_ip_details(face, &(rmp->face.ip)); + } + else if (face->shared.face_type == hicn_face_udp_type) + { + rmp->type = UDP_FACE; + send_face_udp_details(face, &(rmp->face.udp)); + } + rv = HICN_ERROR_NONE; + } + else + { + rv = HICN_ERROR_FACE_NOT_FOUND; + } + rmp->retval = clib_host_to_net_u32(rv); + })); + /* *INDENT-ON* */ +} + static void send_face_stats_details (vl_api_registration_t * reg, hicn_face_t * face, u32 context) @@ -367,7 +618,7 @@ vl_api_hicn_api_route_nhops_add_t_handler (vl_api_hicn_api_route_nhops_add_t hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); u8 n_faces = mp->n_faces; @@ -402,7 +653,7 @@ static void vl_api_hicn_api_route_del_t_handler hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); rv = hicn_route_del (&prefix); @@ -418,7 +669,7 @@ static void vl_api_hicn_api_route_nhop_del_t_handler hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid); @@ -436,7 +687,7 @@ static void vl_api_hicn_api_route_get_t_handler hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); const dpo_id_t *hicn_dpo_id; const hicn_dpo_vft_t *hicn_dpo_vft; hicn_dpo_ctx_t *hicn_dpo_ctx; @@ -482,8 +733,7 @@ send_route_details (vl_api_registration_t * reg, hicn_dpo_ctx_t *hicn_dpo_ctx; u32 fib_index; - int rv = - hicn_route_get_dpo (pfx, &hicn_dpo_id, &fib_index); + int rv = hicn_route_get_dpo (pfx, &hicn_dpo_id, &fib_index); if (rv == HICN_ERROR_NONE) { @@ -494,8 +744,9 @@ send_route_details (vl_api_registration_t * reg, if (dpo_id_is_valid (&hicn_dpo_ctx->next_hops[i])) { mp->faceids[i] = - clib_host_to_net_u32 (((dpo_id_t *) & hicn_dpo_ctx-> - next_hops[i])->dpoi_index); + clib_host_to_net_u32 (((dpo_id_t *) & + hicn_dpo_ctx->next_hops[i])-> + dpoi_index); mp->nfaces++; } } @@ -566,7 +817,8 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP4, vl_api_hicn_api_route_dump_walk, - &ctx);} + &ctx); + } )); pool_foreach (fib_table, im6->fibs, ( @@ -574,7 +826,8 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP6, vl_api_hicn_api_route_dump_walk, - &ctx);} + &ctx); + } )); vec_foreach (lfeip, ctx.feis) @@ -647,11 +900,10 @@ static void vl_api_hicn_api_punting_add_t_handler hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); u32 swif = clib_net_to_host_u32 (mp->swif); - rv = - hicn_punt_interest_data_for_ip (vm, &prefix, swif, 0, NO_L2); + rv = hicn_punt_interest_data_for_ip (vm, &prefix, swif, 0, NO_L2); REPLY_MACRO (VL_API_HICN_API_PUNTING_ADD_REPLY /* , rmp, mp, rv */ ); } @@ -680,7 +932,7 @@ static void vl_api_hicn_api_register_prod_app_t_handler hicn_main_t *sm = &hicn_main; fib_prefix_t prefix; - ip_prefix_decode(&mp->prefix, &prefix); + ip_prefix_decode (&mp->prefix, &prefix); u32 swif = clib_net_to_host_u32 (mp->swif); u32 cs_reserved = clib_net_to_host_u32 (mp->cs_reserved); u32 faceid; @@ -797,8 +1049,10 @@ hicn_face_api_entry_params_serialize (hicn_face_id_t faceid, if (face != NULL && face->shared.face_type == hicn_face_ip_type) { hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data; - ip_address_encode(&face_ip->local_addr, IP46_TYPE_ANY, &reply->local_addr); - ip_address_encode(&face_ip->remote_addr, IP46_TYPE_ANY, &reply->remote_addr); + ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY, + &reply->local_addr); + ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY, + &reply->remote_addr); reply->swif = clib_host_to_net_u32 (face->shared.sw_if); reply->flags = clib_host_to_net_u32 (face->shared.flags); reply->faceid = clib_host_to_net_u32 (faceid); |