CLI: hide deleted interfaces

Added a new interface flag - HIDDEN
Indicates that the interface does not appear in CLI/API.
Added three new interface functions:
vnet_sw_interface_is_api_visible - indicates if the sw_if_index should be displayed
vnet_swif_is_api_visible - variant for sw_interface
vnet_sw_interface_is_api_valid - tests if the given if_index exists and is visible
                                 for future use by api functions

Changed the unformat function to only accept visible interfaces
Changed vxlan to add the HIDDEN flag to deleted interfaces

This is the first part in a series to hide deleted interfaces from the API

Change-Id: Ib43cc5cf1c450856560faf4e84126eb3671038e2
Signed-off-by: Eyal Bari <ebari@cisco.com>
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index 7b79175..ef8f911 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -538,6 +538,9 @@
 
 #define VNET_SW_INTERFACE_FLAG_BOND_SLAVE (1 << 4)
 
+/* Interface does not appear in CLI/API */
+#define VNET_SW_INTERFACE_FLAG_HIDDEN (1 << 5)
+
   /* Index for this interface. */
   u32 sw_if_index;
 
diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c
index 7dbee86..bd715e4 100644
--- a/src/vnet/interface_cli.c
+++ b/src/vnet/interface_cli.c
@@ -285,8 +285,9 @@
       _vec_len (sorted_sis) = 0;
       pool_foreach (si, im->sw_interfaces, (
 					     {
-					     vec_add1 (sorted_sis, si[0]);
-					     }
+					     if (vnet_swif_is_api_visible
+						 (si)) vec_add1 (sorted_sis,
+								 si[0]);}
 		    ));
 
       /* Sort by name. */
diff --git a/src/vnet/interface_format.c b/src/vnet/interface_format.c
index b3a3062..b961c77 100644
--- a/src/vnet/interface_format.c
+++ b/src/vnet/interface_format.c
@@ -321,6 +321,7 @@
   u32 *result = va_arg (*args, u32 *);
   vnet_hw_interface_t *hi;
   u32 hw_if_index, id, id_specified;
+  u32 sw_if_index;
   u8 *if_name = 0;
   uword *p, error = 0;
 
@@ -340,14 +341,17 @@
   hi = vnet_get_hw_interface (vnm, hw_if_index);
   if (!id_specified)
     {
-      *result = hi->sw_if_index;
+      sw_if_index = hi->sw_if_index;
     }
   else
     {
       if (!(p = hash_get (hi->sub_interface_sw_if_index_by_id, id)))
-	return 0;
-      *result = p[0];
+	goto done;
+      sw_if_index = p[0];
     }
+  if (!vnet_sw_interface_is_api_visible (vnm, sw_if_index))
+    goto done;
+  *result = sw_if_index;
   error = 1;
 done:
   vec_free (if_name);
diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h
index ab808df..b3aca2f 100644
--- a/src/vnet/interface_funcs.h
+++ b/src/vnet/interface_funcs.h
@@ -183,6 +183,26 @@
 }
 
 always_inline uword
+vnet_swif_is_api_visible (vnet_sw_interface_t * si)
+{
+  return !(si->flags & VNET_SW_INTERFACE_FLAG_HIDDEN);
+}
+
+always_inline uword
+vnet_sw_interface_is_api_visible (vnet_main_t * vnm, u32 sw_if_index)
+{
+  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
+  return vnet_swif_is_api_visible (si);
+}
+
+always_inline uword
+vnet_sw_interface_is_api_valid (vnet_main_t * vnm, u32 sw_if_index)
+{
+  return !pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)
+    && vnet_sw_interface_is_api_visible (vnm, sw_if_index);
+}
+
+always_inline uword
 vnet_hw_interface_get_flags (vnet_main_t * vnm, u32 hw_if_index)
 {
   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
diff --git a/src/vnet/vxlan/vxlan.c b/src/vnet/vxlan/vxlan.c
index f373a28..58c7bec 100644
--- a/src/vnet/vxlan/vxlan.c
+++ b/src/vnet/vxlan/vxlan.c
@@ -18,6 +18,7 @@
 #include <vnet/fib/fib_table.h>
 #include <vnet/mfib/mfib_table.h>
 #include <vnet/adj/adj_mcast.h>
+#include <vnet/interface.h>
 #include <vlib/vlib.h>
 
 /**
@@ -462,8 +463,11 @@
       l2im->configs[sw_if_index].feature_bitmap = L2INPUT_FEAT_DROP;
       l2im->configs[sw_if_index].bd_index = 0;
       
+      vnet_sw_interface_t * si = vnet_get_sw_interface (vnm, sw_if_index);
+      si->flags &= ~VNET_SW_INTERFACE_FLAG_HIDDEN;
       vnet_sw_interface_set_flags (vnm, sw_if_index, 
                                    VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+
       fib_node_init(&t->node, FIB_NODE_TYPE_VXLAN_TUNNEL);
       fib_prefix_t tun_dst_pfx;
       u32 encap_index = !is_ip6 ?
@@ -573,6 +577,9 @@
       t = pool_elt_at_index (vxm->tunnels, p[0]);
 
       vnet_sw_interface_set_flags (vnm, t->sw_if_index, 0 /* down */);
+      vnet_sw_interface_t * si = vnet_get_sw_interface (vnm, t->sw_if_index);
+      si->flags |= VNET_SW_INTERFACE_FLAG_HIDDEN;
+
       /* make sure tunnel is removed from l2 bd or xconnect */
       set_int_l2_mode(vxm->vlib_main, vnm, MODE_L3, t->sw_if_index, 0, 0, 0, 0);
       vec_add1 (vxm->free_vxlan_tunnel_hw_if_indices, t->hw_if_index);