aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/hicn_api.c
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-11-17 12:50:48 +0100
committerAlberto Compagno <acompagn+fdio@cisco.com>2019-11-18 11:16:44 +0100
commitfb81ea88640de69820f2b2d24e29e5743e4f301b (patch)
tree51b929825d7d68b4105ac63ea0cea32dd48ae269 /hicn-plugin/src/hicn_api.c
parent547acf3eed92d3564139cccf205c852178bcc310 (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.c314
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);