Repair vlib API socket server

- Teach vpp_api_test to send/receive API messages over sockets
- Add memfd-based shared memory
- Add api messages to create memfd-based shared memory segments
- vpp_api_test supports both socket and shared memory segment connections
- vpp_api_test pivot from socket to shared memory API messaging
- add socket client support to libvlibclient.so
- dead client reaper sends ping messages, container-friendly
- dead client reaper falls back to kill (<pid>, 0) live checking
  if e.g. a python app goes silent for tens of seconds
- handle ping messages in python client support code
- teach show api ring about pairwise shared-memory segments
- fix ip probing of already resolved destinations (VPP-998)

We'll need this work to implement proper host-stack client isolation

Change-Id: Ic23b65f75c854d0393d9a2e9d6b122a9551be769
Signed-off-by: Dave Barach <dave@barachs.net>
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 120a276..52b13e0 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -615,7 +615,7 @@
        */
       if (0 == memcmp (e->ethernet_address,
 		       a->ethernet, sizeof (e->ethernet_address)))
-	return -1;
+	goto check_customers;
 
       /* Update time stamp and ethernet address. */
       clib_memcpy (e->ethernet_address, a->ethernet,
@@ -630,6 +630,7 @@
 
   adj_nbr_walk_nh4 (sw_if_index, &e->ip4_address, arp_mk_complete_walk, e);
 
+check_customers:
   /* Customer(s) waiting for this address to be resolved? */
   p = hash_get (am->pending_resolutions_by_address, a->ip4.as_u32);
   if (p)
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index ba1e272..627e5cb 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -846,7 +846,8 @@
 	 * removing an etry that does not exist.
 	 * i'll allow it, but i won't like it.
 	 */
-	clib_warning("%U not in FIB", format_fib_prefix, prefix);
+        if (0)
+            clib_warning("%U not in FIB", format_fib_prefix, prefix);
     }
     else
     {
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index 93551e4..45b472e 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -138,7 +138,7 @@
 
 static void
 send_sw_interface_details (vpe_api_main_t * am,
-			   unix_shared_memory_queue_t * q,
+			   vl_api_registration_t * rp,
 			   vnet_sw_interface_t * swif,
 			   u8 * interface_name, u32 context)
 {
@@ -233,7 +233,7 @@
   if (tag)
     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
 
-  vl_msg_api_send_shmem (q, (u8 *) & mp);
+  vl_msg_api_send (rp, (u8 *) mp);
 }
 
 static void
@@ -242,11 +242,15 @@
   vpe_api_main_t *am = &vpe_api_main;
   vnet_sw_interface_t *swif;
   vnet_interface_main_t *im = &am->vnet_main->interface_main;
+  vl_api_registration_t *rp;
 
-  unix_shared_memory_queue_t *q =
-    vl_api_client_index_to_input_queue (mp->client_index);
-  if (q == 0)
-    return;
+  rp = vl_api_client_index_to_registration (mp->client_index);
+
+  if (rp == 0)
+    {
+      clib_warning ("Client %d AWOL", mp->client_index);
+      return;
+    }
 
   u8 *filter = 0, *name = 0;
   if (mp->name_filter_valid)
@@ -268,7 +272,7 @@
     if (filter && !strcasestr((char *) name, (char *) filter))
 	continue;
 
-    send_sw_interface_details (am, q, swif, name, mp->context);
+    send_sw_interface_details (am, rp, swif, name, mp->context);
   }));
   /* *INDENT-ON* */
 
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 0a34497..58cfd18 100755
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2257,14 +2257,6 @@
 	 sw_if_index);
     }
 
-  ip46_address_t nh = {
-    .ip4 = *dst,
-  };
-
-  ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
-			    VNET_LINK_IP4, &nh, sw_if_index);
-  adj = adj_get (ai);
-
   h = vlib_packet_template_get_packet (vm,
 				       &im->ip4_arp_request_packet_template,
 				       &bi);
@@ -2288,6 +2280,22 @@
   vnet_buffer (b)->sw_if_index[VLIB_RX] =
     vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
 
+  ip46_address_t nh = {
+    .ip4 = *dst,
+  };
+
+  ai = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
+			    VNET_LINK_IP4, &nh, sw_if_index);
+  adj = adj_get (ai);
+
+  /* Peer has been previously resolved, retrieve glean adj instead */
+  if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE)
+    {
+      adj_unlock (ai);
+      ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP4, sw_if_index, &nh);
+      adj = adj_get (ai);
+    }
+
   /* Add encapsulation string for software interface (e.g. ethernet header). */
   vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t));
   vlib_buffer_advance (b, -adj->rewrite_header.data_bytes);
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index bb4893a..54582d3 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -2041,6 +2041,14 @@
 			    VNET_LINK_IP6, &nh, sw_if_index);
   adj = adj_get (ai);
 
+  /* Peer has been previously resolved, retrieve glean adj instead */
+  if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE)
+    {
+      adj_unlock (ai);
+      ai = adj_glean_add_or_lock (FIB_PROTOCOL_IP6, sw_if_index, &nh);
+      adj = adj_get (ai);
+    }
+
   vnet_rewrite_one_header (adj[0], h, sizeof (ethernet_header_t));
   vlib_buffer_advance (b, -adj->rewrite_header.data_bytes);
 
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index 1908a67..d549ac3 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -723,7 +723,7 @@
        */
       if (0 == memcmp (n->link_layer_address,
 		       link_layer_address, n_bytes_link_layer_address))
-	return -1;
+	goto check_customers;
 
       clib_memcpy (n->link_layer_address,
 		   link_layer_address, n_bytes_link_layer_address);
@@ -739,6 +739,7 @@
   adj_nbr_walk_nh6 (sw_if_index,
 		    &n->key.ip6_address, ip6_nd_mk_complete_walk, n);
 
+check_customers:
   /* Customer(s) waiting for this address to be resolved? */
   p = mhash_get (&nm->pending_resolutions_by_address, a);
   if (p)
diff --git a/src/vnet/l2/l2_fib.c b/src/vnet/l2/l2_fib.c
index 64b3275..0ad56f3 100644
--- a/src/vnet/l2/l2_fib.c
+++ b/src/vnet/l2/l2_fib.c
@@ -1036,9 +1036,10 @@
 			}
 		      else
 			{
-			  clib_warning ("MAC event to pid %d queue stuffed!"
-					" %d MAC entries lost", client,
-					evt_idx);
+			  if (q)
+			    clib_warning ("MAC event to pid %d queue stuffed!"
+					  " %d MAC entries lost", client,
+					  evt_idx);
 			}
 		      evt_idx = 0;
 		    }
@@ -1119,8 +1120,9 @@
 	    }
 	  else
 	    {
-	      clib_warning ("MAC event to pid %d queue stuffed!"
-			    " %d MAC entries lost", client, evt_idx);
+	      if (q)
+		clib_warning ("MAC event to pid %d queue stuffed!"
+			      " %d MAC entries lost", client, evt_idx);
 	      vl_msg_api_free (mp);
 	    }
 	}
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c
index 0d6d453..d09be40 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -1380,6 +1380,7 @@
   mapping_t *old_map;
   u32 mi;
 
+  memset (ls_args, 0, sizeof (ls_args[0]));
   memset (m_args, 0, sizeof (m_args[0]));
   if (res_map_index)
     res_map_index[0] = ~0;
@@ -1784,6 +1785,7 @@
   /* find locator-set */
   if (a->local)
     {
+      ASSERT (a->name);
       p = hash_get_mem (lcm->locator_set_index_by_name, a->name);
     }
   else
diff --git a/src/vnet/lisp-cp/lisp_api.c b/src/vnet/lisp-cp/lisp_api.c
index f7c4197..3053611 100644
--- a/src/vnet/lisp-cp/lisp_api.c
+++ b/src/vnet/lisp-cp/lisp_api.c
@@ -128,6 +128,7 @@
 
   memset (a, 0, sizeof (a[0]));
 
+  mp->locator_set_name[63] = 0;
   locator_name = format (0, "%s", mp->locator_set_name);
 
   a->name = locator_name;
@@ -182,6 +183,7 @@
   locator.local = 1;
   vec_add1 (locators, locator);
 
+  mp->locator_set_name[63] = 0;
   locator_name = format (0, "%s", mp->locator_set_name);
 
   a->name = locator_name;
@@ -248,6 +250,7 @@
   if (rv)
     goto out;
 
+  mp->locator_set_name[63] = 0;
   name = format (0, "%s", mp->locator_set_name);
   p = hash_get_mem (lcm->locator_set_index_by_name, name);
   if (!p)
@@ -476,6 +479,7 @@
   u8 *locator_set_name = NULL;
   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
 
+  mp->locator_set_name[63] = 0;
   locator_set_name = format (0, "%s", mp->locator_set_name);
 
   a->is_add = mp->is_add;
@@ -510,6 +514,7 @@
   if (!mp->is_add)
     {
       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
+      memset (a, 0, sizeof (*a));
       gid_address_copy (&a->reid, eid);
       a->is_add = 0;
       rv = vnet_lisp_add_del_adjacency (a);
@@ -533,7 +538,9 @@
       rv = vnet_lisp_add_mapping (m_args, rlocs, NULL, NULL);
     }
   else
-    rv = vnet_lisp_del_mapping (eid, NULL);
+    {
+      rv = vnet_lisp_del_mapping (eid, NULL);
+    }
 
   if (mp->del_all)
     vnet_lisp_clear_all_remote_adjacencies ();
diff --git a/src/vnet/tcp/builtin_client.c b/src/vnet/tcp/builtin_client.c
index 527b328..b48422c 100644
--- a/src/vnet/tcp/builtin_client.c
+++ b/src/vnet/tcp/builtin_client.c
@@ -21,7 +21,6 @@
 
 #include <vlibapi/api.h>
 #include <vlibmemory/api.h>
-#include <vlibsocket/api.h>
 #include <vpp/app/version.h>
 
 #define TCP_BUILTIN_CLIENT_DBG (0)