summaryrefslogtreecommitdiffstats
path: root/hicn-plugin
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-08-14 15:31:31 +0200
committerAlberto Compagno <acompagn+fdio@cisco.com>2019-09-24 10:34:49 +0800
commitf1eb650af8c73a983653d982f96ebf360dbaa9f3 (patch)
tree293fd8ba4ed4f50fc432e9e3b6c2e98c7a28d5d1 /hicn-plugin
parentaf6944a35b97a971139d93da49e09e023005f633 (diff)
[HICN-260] Added a dump binary api for hicn routes
Change-Id: Ic2f7b1edeb35603f6d1fa5f40f7fff441aa43203 Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
Diffstat (limited to 'hicn-plugin')
-rw-r--r--hicn-plugin/src/hicn.api44
-rw-r--r--hicn-plugin/src/hicn_api.c129
-rw-r--r--hicn-plugin/src/hicn_api_test.c63
3 files changed, 232 insertions, 4 deletions
diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api
index 0debf25c5..d344061ba 100644
--- a/hicn-plugin/src/hicn.api
+++ b/hicn-plugin/src/hicn.api
@@ -272,6 +272,9 @@ define hicn_api_face_ip_params_get_reply
/* Return value, zero means all OK */
i32 retval;
+ /* The face required */
+ u32 faceid;
+
/* IP local address */
u64 local_addr[2];
@@ -390,7 +393,37 @@ define hicn_api_route_get_reply
u32 context;
/* List of faces pointing to the next hops */
- u32 faceids[1000];
+ u32 faceids[5];
+
+ /* Number of valid faceids */
+ u8 nfaces;
+
+ /* Strategy */
+ u32 strategy_id;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+};
+
+define hicn_api_routes_details
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Route prefix */
+ u64 prefix[2];
+
+ /* Prefix len */
+ u8 len;
+
+ /* List of faces pointing to the next hops */
+ u32 faceids[5];
+
+ /* Number of valid faceids */
+ u8 nfaces;
/* Strategy */
u32 strategy_id;
@@ -399,6 +432,15 @@ define hicn_api_route_get_reply
i32 retval;
};
+define hicn_api_routes_dump
+{
+/* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+};
+
define hicn_api_strategies_get
{
/* Client identifier, set from api_main.my_client_index */
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index fe7a4e9da..7db6cca79 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -21,6 +21,7 @@
#include <vnet/ip/ip6.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
+#include <vnet/dpo/load_balance.h>
#include "hicn.h"
#include "faces/ip/face_ip.h"
@@ -70,6 +71,7 @@
_(HICN_API_FACE_IP_PARAMS_GET, hicn_api_face_ip_params_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) \
_(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) \
@@ -474,7 +476,7 @@ static void vl_api_hicn_api_route_get_t_handler
{
if (rv == HICN_ERROR_NONE)
{
- hicn_dpo_vft = hicn_dpo_get_vft(hicn_dpo_id->dpoi_index);
+ hicn_dpo_vft = hicn_dpo_get_vft(hicn_dpo_id->dpoi_type);
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++)
{
@@ -487,6 +489,130 @@ static void vl_api_hicn_api_route_get_t_handler
/* *INDENT-ON* */
}
+static void
+send_route_details (vl_api_registration_t * reg,
+ const fib_prefix_t *pfx, u32 context)
+{
+ vl_api_hicn_api_routes_details_t *mp;
+ hicn_main_t *hm = &hicn_main;
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+
+ mp->_vl_msg_id =
+ htons (VL_API_HICN_API_ROUTES_DETAILS + hm->msg_id_base);
+ mp->context = context;
+
+ clib_memcpy(&mp->prefix, &pfx->fp_addr, sizeof(ip46_address_t));
+ mp->len = pfx->fp_len;
+ mp->nfaces = 0;
+
+ 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;
+
+ int rv = hicn_route_get_dpo (&pfx->fp_addr, pfx->fp_len, &hicn_dpo_id, &fib_index);
+
+ if (rv == HICN_ERROR_NONE)
+ {
+ hicn_dpo_vft = hicn_dpo_get_vft(hicn_dpo_id->dpoi_type);
+ 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]))
+ {
+ mp->faceids[i] = clib_host_to_net_u32(((dpo_id_t *) &hicn_dpo_ctx->next_hops[i])->dpoi_index);
+ mp->nfaces++;
+ }
+ }
+ mp->strategy_id = clib_host_to_net_u32(hicn_dpo_get_vft_id(hicn_dpo_id));
+ }
+
+ vl_api_send_msg (reg, (u8 *) mp);
+}
+
+typedef struct vl_api_hicn_api_route_dump_walk_ctx_t_
+{
+ fib_node_index_t *feis;
+} vl_api_hicn_api_route_dump_walk_ctx_t;
+
+static fib_table_walk_rc_t
+vl_api_hicn_api_route_dump_walk(fib_node_index_t fei, void *arg)
+{
+ vl_api_hicn_api_route_dump_walk_ctx_t *ctx = arg;
+ int found = 0;
+ const dpo_id_t *former_dpo_id;
+
+ /* Route already existing. We need to update the dpo. */
+ const dpo_id_t * load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fei);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type == DPO_LOAD_BALANCE)
+ {
+ /* former_dpo_id is a load_balance dpo */
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
+
+ /* FIB entry exists but there is no hicn dpo. */
+ for (int i = 0; i < lb->lb_n_buckets && !found; i++)
+ {
+ former_dpo_id = load_balance_get_bucket_i (lb, i);
+
+ if (dpo_is_hicn (former_dpo_id))
+ {
+ vec_add1 (ctx->feis, fei);
+ }
+ }
+ }
+
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+static void
+vl_api_hicn_api_routes_dump_t_handler
+(vl_api_hicn_api_face_stats_dump_t * mp)
+{
+ vl_api_registration_t *reg;
+ fib_table_t *fib_table;
+ ip4_main_t *im = &ip4_main;
+ ip6_main_t *im6 = &ip6_main;
+ fib_node_index_t *lfeip;
+ const fib_prefix_t *pfx;
+ vl_api_hicn_api_route_dump_walk_ctx_t ctx = {
+ .feis = NULL,
+ };
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ pool_foreach (fib_table, im->fibs,
+ ({
+ fib_table_walk(fib_table->ft_index,
+ FIB_PROTOCOL_IP4,
+ vl_api_hicn_api_route_dump_walk,
+ &ctx);
+ }));
+
+ pool_foreach (fib_table, im6->fibs,
+ ({
+ fib_table_walk(fib_table->ft_index,
+ FIB_PROTOCOL_IP6,
+ vl_api_hicn_api_route_dump_walk,
+ &ctx);
+ }));
+
+ vec_foreach (lfeip, ctx.feis)
+ {
+ pfx = fib_entry_get_prefix (*lfeip);
+ send_route_details (reg, pfx, mp->context);
+ }
+
+ vec_free (ctx.feis);
+
+}
+
static void vl_api_hicn_api_strategies_get_t_handler
(vl_api_hicn_api_strategies_get_t * mp)
{
@@ -716,6 +842,7 @@ hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
clib_host_to_net_u64 (face_ip->remote_addr.as_u64[1]);
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);
}
else
rv = HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c
index d69c20770..e73538814 100644
--- a/hicn-plugin/src/hicn_api_test.c
+++ b/hicn-plugin/src/hicn_api_test.c
@@ -135,6 +135,7 @@ _(HICN_API_FACE_STATS_DETAILS, hicn_api_face_stats_details) \
_(HICN_API_ROUTE_NHOPS_ADD_REPLY, hicn_api_route_nhops_add_reply) \
_(HICN_API_FACE_IP_PARAMS_GET_REPLY, hicn_api_face_ip_params_get_reply) \
_(HICN_API_ROUTE_GET_REPLY, hicn_api_route_get_reply) \
+_(HICN_API_ROUTES_DETAILS, hicn_api_routes_details) \
_(HICN_API_ROUTE_DEL_REPLY, hicn_api_route_del_reply) \
_(HICN_API_ROUTE_NHOP_DEL_REPLY, hicn_api_route_nhop_del_reply) \
_(HICN_API_STRATEGIES_GET_REPLY, hicn_api_strategies_get_reply) \
@@ -554,7 +555,7 @@ api_hicn_api_face_stats_dump (vat_main_t * vam)
return ret;
}
-/* memif-details message handler */
+/* face_stats-details message handler */
static void
vl_api_hicn_api_face_stats_details_t_handler
(vl_api_hicn_api_face_stats_details_t * mp)
@@ -625,6 +626,38 @@ api_hicn_api_route_get (vat_main_t * vam)
return ret;
}
+static int
+api_hicn_api_routes_dump (vat_main_t *vam)
+{
+
+ hicn_test_main_t *hm = &hicn_test_main;
+ vl_api_hicn_api_route_get_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ int ret;
+
+ if (vam->json_output)
+ {
+ clib_warning ("JSON output not supported for routes_dump");
+ return -99;
+ }
+
+ M (HICN_API_ROUTES_DUMP, mp);
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
+ mp_ping->_vl_msg_id = htons (hm->ping_id);
+ mp_ping->client_index = vam->my_client_index;
+
+ fformat (vam->ofp, "Sending ping id=%d\n", hm->ping_id);
+
+ vam->result_ready = 0;
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
static void
vl_api_hicn_api_route_get_reply_t_handler (vl_api_hicn_api_route_get_reply_t *
rmp)
@@ -669,10 +702,35 @@ vl_api_hicn_api_route_get_reply_t_handler (vl_api_hicn_api_route_get_reply_t *
}
}
- fformat (vam->ofp, "%s\n Strategy: %d",
+ fformat (vam->ofp, "%s\n Strategy: %d\n",
sbuf, clib_net_to_host_u32 (rmp->strategy_id));
}
+/* face_stats-details message handler */
+static void
+vl_api_hicn_api_routes_details_t_handler
+(vl_api_hicn_api_routes_details_t * mp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+
+ u32 faceid;
+ u8 *sbuf = 0;
+ vec_reset_length (sbuf);
+
+ sbuf = format (sbuf, "Prefix: %U/%u\n", format_ip46_address, &mp->prefix, 0, mp->len);
+
+ sbuf = format (sbuf, "Faces: \n");
+ for( int i = 0; i < mp->nfaces; i++)
+ {
+ faceid = clib_net_to_host_u32 (mp->faceids[i]);
+ sbuf =
+ format (sbuf, " faceid %d\n", faceid);
+ }
+
+ fformat (vam->ofp, "%sStrategy: %d\n",
+ sbuf, clib_net_to_host_u32 (mp->strategy_id));
+}
+
static int
api_hicn_api_route_nhops_add (vat_main_t * vam)
{
@@ -1074,6 +1132,7 @@ _(hicn_api_face_stats_dump, "") \
_(hicn_api_route_nhops_add, "add prefix <IP4/IP6>/<subnet> face <faceID> weight <weight>") \
_(hicn_api_face_ip_params_get, "face <faceID>") \
_(hicn_api_route_get, "prefix <IP4/IP6>/<subnet>") \
+_(hicn_api_routes_dump, "") \
_(hicn_api_route_del, "prefix <IP4/IP6>/<subnet>") \
_(hicn_api_route_nhop_del, "del prefix <IP4/IP6>/<subnet> face <faceID>") \
_(hicn_api_strategies_get, "") \