LISP: make statistics thread safe

Change-Id: I056dc6246f79d887d69ad459a6b8b3092a099baa
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 5c901f3..ebbd1be 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -285,7 +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_del_fwd_counters (a, feip[0]);
   vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
 
   /* delete entry in fwd table */
@@ -532,10 +532,18 @@
       a->action = rmt_map->action;
     }
 
-  vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
+  rv = vnet_lisp_gpe_add_del_fwd_entry (a, &sw_if_index);
+  if (rv)
+    {
+      if (a->locator_pairs)
+	vec_free (a->locator_pairs);
+      return;
+    }
 
-  /* add tunnel to fwd entry table XXX check return value from DP insertion */
+  /* add tunnel to fwd entry table */
   pool_get (lcm->fwd_entry_pool, fe);
+  vnet_lisp_gpe_add_fwd_counters (a, fe - lcm->fwd_entry_pool);
+
   fe->locator_pairs = a->locator_pairs;
   gid_address_copy (&fe->reid, &a->rmt_eid);
 
@@ -3608,7 +3616,8 @@
 		     lisp_api_stats_t * stat, lisp_stats_key_t * key,
 		     u32 stats_index)
 {
-  lisp_stats_t *s;
+  vlib_counter_t v;
+  vlib_combined_counter_main_t *cm = &lgm->counters;
   lisp_gpe_fwd_entry_key_t fwd_key;
   const lisp_gpe_tunnel_t *lgt;
   fwd_entry_t *fe;
@@ -3627,8 +3636,8 @@
   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;
+  vlib_get_combined_counter (cm, stats_index, &v);
+  stat->counters = v;
   return 1;
 }
 
diff --git a/src/vnet/lisp-cp/one.api b/src/vnet/lisp-cp/one.api
index 7cc9068..ca82f69 100644
--- a/src/vnet/lisp-cp/one.api
+++ b/src/vnet/lisp-cp/one.api
@@ -901,6 +901,18 @@
   u32 bytes;
 };
 
+define one_stats_flush
+{
+  u32 client_index;
+  u32 context;
+};
+
+define one_stats_flush_reply
+{
+  u32 context;
+  i32 retval;
+};
+
 define one_stats_enable_disable
 {
   u32 client_index;
diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c
index 2892409..23549af 100644
--- a/src/vnet/lisp-cp/one_api.c
+++ b/src/vnet/lisp-cp/one_api.c
@@ -108,6 +108,7 @@
 _(SHOW_ONE_STATS_ENABLE_DISABLE, show_one_stats_enable_disable)         \
 _(ONE_STATS_ENABLE_DISABLE, one_stats_enable_disable)                   \
 _(ONE_STATS_DUMP, one_stats_dump)                                       \
+_(ONE_STATS_FLUSH, one_stats_flush)                                     \
 
 
 static locator_t *
@@ -1347,6 +1348,16 @@
 }
 
 static void
+vl_api_one_stats_flush_t_handler (vl_api_one_stats_flush_t * mp)
+{
+  vl_api_one_stats_flush_reply_t *rmp;
+  u8 rv;
+
+  rv = vnet_lisp_flush_stats ();
+  REPLY_MACRO (VL_API_ONE_STATS_FLUSH_REPLY);
+}
+
+static void
 vl_api_one_stats_dump_t_handler (vl_api_one_stats_dump_t * mp)
 {
   vl_api_one_stats_details_t *rmp;
@@ -1369,8 +1380,8 @@
         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);
+        rmp->pkt_count = clib_host_to_net_u32 (stat->counters.packets);
+        rmp->bytes = clib_host_to_net_u32 (stat->counters.bytes);
       }));
       /* *INDENT-ON* */
   }
diff --git a/src/vnet/lisp-cp/one_cli.c b/src/vnet/lisp-cp/one_cli.c
index 4b1a1cc..109aca2 100644
--- a/src/vnet/lisp-cp/one_cli.c
+++ b/src/vnet/lisp-cp/one_cli.c
@@ -1682,7 +1682,7 @@
 		     format_fid_address, &stat->deid,
 		     format_ip_address, &stat->loc_rloc,
 		     format_ip_address, &stat->rmt_rloc,
-		     stat->stats.pkt_count, stat->stats.bytes);
+		     stat->counters.packets, stat->counters.bytes);
   }
   vec_free (stats);
   return 0;