LISP: re-fetch mapping before it expires

Change-Id: I0581a1bddad55d8d573c546ec84b0b2760abab3d
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c
index ac04814..d7d3cb8 100644
--- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c
+++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c
@@ -193,12 +193,15 @@
  * @param[in]   src_fib_index   The index/ID of the SRC FIB
  * @param[in]   src_prefix      Source IP prefix.
  * @param[in]   src_dpo         The DPO the route will link to.
+ *
+ * @return fib index of the inserted prefix
  */
-static void
+static fib_node_index_t
 ip_src_fib_add_route_w_dpo (u32 src_fib_index,
 			    const ip_prefix_t * src_prefix,
 			    const dpo_id_t * src_dpo)
 {
+  fib_node_index_t fei = ~0;
   fib_prefix_t src_fib_prefix;
 
   ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix);
@@ -213,11 +216,13 @@
   if (FIB_NODE_INDEX_INVALID == src_fei ||
       !fib_entry_is_sourced (src_fei, FIB_SOURCE_LISP))
     {
-      fib_table_entry_special_dpo_add (src_fib_index,
-				       &src_fib_prefix,
-				       FIB_SOURCE_LISP,
-				       FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo);
+      fei = fib_table_entry_special_dpo_add (src_fib_index,
+					     &src_fib_prefix,
+					     FIB_SOURCE_LISP,
+					     FIB_ENTRY_FLAG_EXCLUSIVE,
+					     src_dpo);
     }
+  return fei;
 }
 
 static fib_route_path_t *
@@ -262,7 +267,7 @@
  * @param[in]   paths           The paths from which to construct the
  *                              load balance
  */
-static void
+static fib_node_index_t
 ip_src_fib_add_route (u32 src_fib_index,
 		      const ip_prefix_t * src_prefix,
 		      const lisp_fwd_path_t * paths)
@@ -274,10 +279,11 @@
 
   rpaths = lisp_gpe_mk_fib_paths (paths);
 
-  fib_table_entry_update (src_fib_index,
-			  &src_fib_prefix,
-			  FIB_SOURCE_LISP, FIB_ENTRY_FLAG_NONE, rpaths);
+  fib_node_index_t fib_entry_index =
+    fib_table_entry_update (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP,
+			    FIB_ENTRY_FLAG_NONE, rpaths);
   vec_free (rpaths);
+  return fib_entry_index;
 }
 
 static void
@@ -311,9 +317,11 @@
     }
 }
 
-static void
+static index_t
 create_fib_entries (lisp_gpe_fwd_entry_t * lfe)
 {
+  fib_node_index_t fi;
+  fib_entry_t *fe;
   lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
   dpo_proto_t dproto;
   ip_prefix_t ippref;
@@ -361,13 +369,15 @@
 	  dpo_copy (&dpo, drop_dpo_get (dproto));
 	  break;
 	}
-      ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo);
+      fi = ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo);
       dpo_reset (&dpo);
     }
   else
     {
-      ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths);
+      fi = ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths);
     }
+  fe = fib_entry_get (fi);
+  return fe->fe_lb.dpoi_index;
 }
 
 static void
@@ -546,7 +556,7 @@
       lfe->action = a->action;
     }
 
-  create_fib_entries (lfe);
+  lfe->dpoi_index = create_fib_entries (lfe);
   return (0);
 }
 
@@ -793,6 +803,7 @@
   lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index,
 			     fid_addr_mac (&lfe->key->lcl),
 			     fid_addr_mac (&lfe->key->rmt), &dpo, 1);
+  lfe->dpoi_index = dpo.dpoi_index;
 
   dpo_reset (&dpo);
 }
@@ -1538,6 +1549,29 @@
   return entries;
 }
 
+int
+vnet_lisp_gpe_get_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+			     vlib_counter_t * c)
+{
+  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
+  lisp_gpe_fwd_entry_t *lfe;
+  lisp_gpe_fwd_entry_key_t unused;
+
+  lfe = find_fwd_entry (lgm, a, &unused);
+  if (NULL == lfe)
+    return -1;
+
+  if (LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE == lfe->type)
+    return -1;
+
+  if (~0 == lfe->dpoi_index)
+    return -1;
+
+  vlib_get_combined_counter (&load_balance_main.lbm_to_counters,
+			     lfe->dpoi_index, c);
+  return 0;
+}
+
 VLIB_INIT_FUNCTION (lisp_gpe_fwd_entry_init);
 
 /*
diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h
index 1580351..dfdb8b9 100644
--- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h
+++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h
@@ -198,6 +198,12 @@
      */
     negative_fwd_actions_e action;
   };
+
+  /**
+   * used for getting load balance statistics
+   */
+  index_t dpoi_index;
+
 } lisp_gpe_fwd_entry_t;
 
 extern int
@@ -219,6 +225,10 @@
 				u32 fwd_entry_index);
 extern u32 *vnet_lisp_gpe_get_fwd_entry_vnis (void);
 
+int
+vnet_lisp_gpe_get_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a,
+			     vlib_counter_t * c);
+
 #endif
 
 /*
diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c
index 7146b38..b234d9d 100644
--- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c
+++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c
@@ -192,7 +192,7 @@
       lisp_gpe_sub_interface_unset_table (l3s->sw_if_index,
 					  l3s->eid_table_id);
 
-      lisp_gpe_tenant_l3_iface_unlock (clib_net_to_host_u32 (l3s->key->vni));
+      lisp_gpe_tenant_l3_iface_unlock (l3s->key->vni);
       vnet_sw_interface_set_flags (vnet_get_main (), l3s->sw_if_index, 0);
       vnet_delete_sub_interface (l3s->sw_if_index);