LISP statistics
Change-Id: I399cac46d279e020ba33459ef759d9d29d3ac716
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c
index 5c90c03..47badeb 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -19,6 +19,7 @@
#include <vnet/lisp-cp/lisp_msg_serdes.h>
#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
+#include <vnet/lisp-gpe/lisp_gpe_tunnel.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
@@ -284,6 +285,7 @@
if (fe->is_src_dst)
gid_address_copy (&a->lcl_eid, &fe->leid);
+ vnet_lisp_del_fwd_stats (a, feip[0]);
vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
/* delete entry in fwd table */
@@ -1228,9 +1230,6 @@
if (a->is_add)
{
- /* TODO 1) check if src/dst 2) once we have src/dst working, use it in
- * delete*/
-
/* check if source eid has an associated mapping. If pitr mode is on,
* just use the pitr's mapping */
local_mi = lcm->lisp_pitr ? lcm->pitr_map_index :
@@ -2654,16 +2653,15 @@
return vni;
}
-always_inline void
+void
get_src_and_dst_eids_from_buffer (lisp_cp_main_t * lcm, vlib_buffer_t * b,
- gid_address_t * src, gid_address_t * dst)
+ gid_address_t * src, gid_address_t * dst,
+ u16 type)
{
u32 vni = 0;
- u16 type;
memset (src, 0, sizeof (*src));
memset (dst, 0, sizeof (*dst));
- type = vnet_buffer (b)->lisp.overlay_afi;
if (LISP_AFI_IP == type || LISP_AFI_IP6 == type)
{
@@ -2742,10 +2740,9 @@
b0 = vlib_get_buffer (vm, pi0);
b0->error = node->errors[LISP_CP_LOOKUP_ERROR_DROP];
- vnet_buffer (b0)->lisp.overlay_afi = overlay;
/* src/dst eid pair */
- get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst);
+ get_src_and_dst_eids_from_buffer (lcm, b0, &src, &dst, overlay);
/* if we have remote mapping for destination already in map-chache
add forwarding tunnel directly. If not send a map-request */
@@ -3605,6 +3602,55 @@
return 0;
}
+static int
+lisp_stats_api_fill (lisp_cp_main_t * lcm, lisp_gpe_main_t * lgm,
+ lisp_api_stats_t * stat, lisp_stats_key_t * key,
+ u32 stats_index)
+{
+ lisp_stats_t *s;
+ lisp_gpe_fwd_entry_key_t fwd_key;
+ const lisp_gpe_tunnel_t *lgt;
+ fwd_entry_t *fe;
+
+ memset (stat, 0, sizeof (*stat));
+ memset (&fwd_key, 0, sizeof (fwd_key));
+
+ fe = pool_elt_at_index (lcm->fwd_entry_pool, key->fwd_entry_index);
+ ASSERT (fe != 0);
+
+ gid_to_dp_address (&fe->reid, &stat->deid);
+ gid_to_dp_address (&fe->leid, &stat->seid);
+ stat->vni = gid_address_vni (&fe->reid);
+
+ lgt = lisp_gpe_tunnel_get (key->tunnel_index);
+ stat->loc_rloc = lgt->key->lcl;
+ stat->rmt_rloc = lgt->key->rmt;
+
+ s = pool_elt_at_index (lgm->lisp_stats_pool, stats_index);
+ stat->stats = *s;
+ return 1;
+}
+
+lisp_api_stats_t *
+vnet_lisp_get_stats (void)
+{
+ lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+ lisp_api_stats_t *stats = 0, stat;
+ lisp_stats_key_t *key;
+ u32 index;
+
+ /* *INDENT-OFF* */
+ hash_foreach_mem (key, index, lgm->lisp_stats_index_by_key,
+ {
+ if (lisp_stats_api_fill (lcm, lgm, &stat, key, index))
+ vec_add1 (stats, stat);
+ });
+ /* *INDENT-ON* */
+
+ return stats;
+}
+
static void *
send_map_request_thread_fn (void *arg)
{
@@ -3810,7 +3856,11 @@
if (vnet_lisp_enable_disable_status () == 0)
return VNET_API_ERROR_LISP_DISABLED;
- lcm->stats_enabled = enable;
+ if (enable)
+ lcm->flags |= LISP_FLAG_STATS_ENABLED;
+ else
+ lcm->flags &= ~LISP_FLAG_STATS_ENABLED;
+
return 0;
}
@@ -3822,7 +3872,7 @@
if (vnet_lisp_enable_disable_status () == 0)
return VNET_API_ERROR_LISP_DISABLED;
- return lcm->stats_enabled;
+ return lcm->flags & LISP_FLAG_STATS_ENABLED;
}
/* *INDENT-OFF* */
diff --git a/src/vnet/lisp-cp/control.h b/src/vnet/lisp-cp/control.h
index 933b34b..eae8a18 100644
--- a/src/vnet/lisp-cp/control.h
+++ b/src/vnet/lisp-cp/control.h
@@ -95,7 +95,8 @@
} map_request_mode_t;
#define foreach_lisp_flag_bit \
- _(USE_PETR, "Use Proxy-ETR")
+ _(USE_PETR, "Use Proxy-ETR") \
+ _(STATS_ENABLED, "Statistics enabled")
typedef enum lisp_flag_bits
{
@@ -210,9 +211,6 @@
/* timing wheel for mappping timeouts */
timing_wheel_t wheel;
- /* statistics */
- u8 stats_enabled;
-
/* commodity */
ip4_main_t *im4;
ip6_main_t *im6;
@@ -235,6 +233,11 @@
return &lisp_control_main;
}
+void
+get_src_and_dst_eids_from_buffer (lisp_cp_main_t * lcm, vlib_buffer_t * b,
+ gid_address_t * src, gid_address_t * dst,
+ u16 type);
+
typedef struct
{
u8 is_add;
@@ -335,9 +338,6 @@
return pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
}
-u8 vnet_lisp_stats_enable_disable_state (void);
-vnet_api_error_t vnet_lisp_stats_enable_disable (u8 enable);
-
#endif /* VNET_CONTROL_H_ */
/*
diff --git a/src/vnet/lisp-cp/lisp_types.c b/src/vnet/lisp-cp/lisp_types.c
index b646668..ad3a4bd 100644
--- a/src/vnet/lisp-cp/lisp_types.c
+++ b/src/vnet/lisp-cp/lisp_types.c
@@ -573,6 +573,44 @@
return (sizeof (u16) + size);
}
+void
+gid_to_dp_address (gid_address_t * g, dp_address_t * d)
+{
+ switch (gid_address_type (g))
+ {
+ case GID_ADDR_SRC_DST:
+ switch (gid_address_sd_dst_type (g))
+ {
+ case FID_ADDR_IP_PREF:
+ ip_prefix_copy (&d->ippref, &gid_address_sd_dst_ippref (g));
+ d->type = FID_ADDR_IP_PREF;
+ break;
+ case FID_ADDR_MAC:
+ mac_copy (&d->mac, &gid_address_sd_dst_mac (g));
+ d->type = FID_ADDR_MAC;
+ break;
+ default:
+ clib_warning ("Source/Dest address type %d not supported!",
+ gid_address_sd_dst_type (g));
+ break;
+ }
+ break;
+ case GID_ADDR_IP_PREFIX:
+ ip_prefix_copy (&d->ippref, &gid_address_ippref (g));
+ d->type = FID_ADDR_IP_PREF;
+ break;
+ case GID_ADDR_MAC:
+ mac_copy (&d->mac, &gid_address_mac (g));
+ d->type = FID_ADDR_MAC;
+ break;
+ case GID_ADDR_NSH:
+ default:
+ d->nsh = gid_address_nsh (g).spi << 8 | gid_address_nsh (g).si;
+ d->type = FID_ADDR_NSH;
+ break;
+ }
+}
+
u32
lcaf_hdr_parse (void *offset, lcaf_t * lcaf)
{
diff --git a/src/vnet/lisp-cp/lisp_types.h b/src/vnet/lisp-cp/lisp_types.h
index 672835b..a65a479 100644
--- a/src/vnet/lisp-cp/lisp_types.h
+++ b/src/vnet/lisp-cp/lisp_types.h
@@ -126,6 +126,8 @@
typedef fid_address_t dp_address_t;
#define fid_addr_ippref(_a) (_a)->ippref
+#define fid_addr_prefix_length(_a) ip_prefix_len(&fid_addr_ippref(_a))
+#define fid_addr_ip_version(_a) ip_prefix_version(&fid_addr_ippref(_a))
#define fid_addr_mac(_a) (_a)->mac
#define fid_addr_nsh(_a) (_a)->nsh
#define fid_addr_type(_a) (_a)->type
@@ -359,6 +361,7 @@
build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst);
void gid_address_from_ip (gid_address_t * g, ip_address_t * ip);
+void gid_to_dp_address (gid_address_t * g, dp_address_t * d);
#endif /* VNET_LISP_GPE_LISP_TYPES_H_ */
diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c
index 4faf624..ab9e7a6 100644
--- a/src/vnet/lisp-cp/one_api.c
+++ b/src/vnet/lisp-cp/one_api.c
@@ -58,6 +58,21 @@
#include <vlibapi/api_helper_macros.h>
+#define REPLY_DETAILS(t, body) \
+do { \
+ unix_shared_memory_queue_t * q; \
+ rv = vl_msg_api_pd_handler (mp, rv); \
+ q = vl_api_client_index_to_input_queue (mp->client_index); \
+ if (!q) \
+ return; \
+ \
+ rmp = vl_msg_api_alloc (sizeof (*rmp)); \
+ rmp->_vl_msg_id = ntohs((t)); \
+ rmp->context = mp->context; \
+ do {body;} while (0); \
+ vl_msg_api_send_shmem (q, (u8 *)&rmp); \
+} while(0);
+
#define foreach_vpe_api_msg \
_(ONE_ADD_DEL_LOCATOR_SET, one_add_del_locator_set) \
_(ONE_ADD_DEL_LOCATOR, one_add_del_locator) \
@@ -1301,9 +1316,61 @@
}
static void
+lisp_fid_addr_to_api (fid_address_t * fid, u8 * dst, u8 * api_eid_type,
+ u8 * prefix_length)
+{
+ switch (fid_addr_type (fid))
+ {
+ case FID_ADDR_IP_PREF:
+ *prefix_length = fid_addr_prefix_length (fid);
+ if (fid_addr_ip_version (fid) == IP4)
+ {
+ *api_eid_type = 0; /* ipv4 type */
+ clib_memcpy (dst, &fid_addr_ippref (fid), 4);
+ }
+ else
+ {
+ *api_eid_type = 1; /* ipv6 type */
+ clib_memcpy (dst, &fid_addr_ippref (fid), 16);
+ }
+ break;
+ case FID_ADDR_MAC:
+ *api_eid_type = 2; /* l2 mac type */
+ mac_copy (dst, fid_addr_mac (fid));
+ break;
+ default:
+ ASSERT (0);
+ }
+}
+
+static void
vl_api_one_stats_dump_t_handler (vl_api_one_stats_dump_t * mp)
{
+ vl_api_one_stats_details_t *rmp;
+ lisp_api_stats_t *stats, *stat;
+ u8 rv = 0;
+ stats = vnet_lisp_get_stats ();
+ vec_foreach (stat, stats)
+ {
+ /* *INDENT-OFF* */
+ REPLY_DETAILS (VL_API_ONE_STATS_DETAILS,
+ ({
+ lisp_fid_addr_to_api (&stat->deid, rmp->deid, &rmp->eid_type,
+ &rmp->deid_pref_len);
+ lisp_fid_addr_to_api (&stat->seid, rmp->seid, &rmp->eid_type,
+ &rmp->seid_pref_len);
+ rmp->vni = clib_host_to_net_u32 (stat->vni);
+
+ rmp->is_ip4 = ip_addr_version (&stat->rmt_rloc) == IP4 ? 1 : 0;
+ ip_address_copy_addr (rmp->rloc, &stat->rmt_rloc);
+ ip_address_copy_addr (rmp->lloc, &stat->loc_rloc);
+
+ rmp->pkt_count = clib_host_to_net_u32 (stat->stats.pkt_count);
+ rmp->bytes = clib_host_to_net_u32 (stat->stats.bytes);
+ }));
+ /* *INDENT-ON* */
+ }
}
/*
diff --git a/src/vnet/lisp-cp/one_cli.c b/src/vnet/lisp-cp/one_cli.c
index 2ceeaf4..b5bc529 100644
--- a/src/vnet/lisp-cp/one_cli.c
+++ b/src/vnet/lisp-cp/one_cli.c
@@ -352,7 +352,7 @@
}
}
- if (!eid_set)
+ if (!del_all && !eid_set)
{
clib_warning ("missing eid!");
goto done;
@@ -372,8 +372,6 @@
goto done;
}
- /* TODO build src/dst with seid */
-
/* if it's a delete, clean forwarding */
if (!is_add)
{
@@ -1654,13 +1652,47 @@
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (one_show_stats_command) = {
- .path = "show one stats",
- .short_help = "show ONE statistics",
+ .path = "show one statistics status",
+ .short_help = "show ONE statistics enable/disable status",
.function = lisp_show_stats_command_fn,
};
/* *INDENT-ON* */
static clib_error_t *
+lisp_show_stats_details_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ lisp_api_stats_t *stat, *stats = vnet_lisp_get_stats ();
+
+ if (vec_len (stats) > 0)
+ vlib_cli_output (vm,
+ "[src-EID, dst-EID] [loc-rloc, rmt-rloc] count bytes\n");
+ else
+ vlib_cli_output (vm, "No statistics found.\n");
+
+ vec_foreach (stat, stats)
+ {
+ vlib_cli_output (vm, "[%U, %U] [%U, %U] %7u %7u\n",
+ format_fid_address, &stat->seid,
+ format_fid_address, &stat->deid,
+ format_ip_address, &stat->loc_rloc,
+ format_ip_address, &stat->rmt_rloc,
+ stat->stats.pkt_count, stat->stats.bytes);
+ }
+ vec_free (stats);
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (one_show_stats_details_command) = {
+ .path = "show one statistics details",
+ .short_help = "show ONE statistics",
+ .function = lisp_show_stats_details_command_fn,
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
lisp_stats_enable_disable_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
@@ -1692,12 +1724,29 @@
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (one_stats_enable_disable_command) = {
- .path = "one stats",
+ .path = "one statistics",
.short_help = "enable/disable ONE statistics collecting",
.function = lisp_stats_enable_disable_command_fn,
};
/* *INDENT-ON* */
+static clib_error_t *
+lisp_stats_flush_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ vnet_lisp_flush_stats ();
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (one_stats_flush_command) = {
+ .path = "one statistics flush",
+ .short_help = "Flush ONE statistics",
+ .function = lisp_stats_flush_command_fn,
+};
+/* *INDENT-ON* */
+
/*
* fd.io coding-style-patch-verification: ON
*