api: multiple connections per process

Type: feature

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I2272521d6e69edcd385ef684af6dd4eea5eaa953
diff --git a/src/plugins/dhcp/dhcp6_ia_na_client_cp.c b/src/plugins/dhcp/dhcp6_ia_na_client_cp.c
index b87ad21..f9c379c 100644
--- a/src/plugins/dhcp/dhcp6_ia_na_client_cp.c
+++ b/src/plugins/dhcp/dhcp6_ia_na_client_cp.c
@@ -766,7 +766,7 @@
 
   rm->vlib_main = vm;
   rm->vnet_main = vnet_get_main ();
-  rm->api_main = &api_main;
+  rm->api_main = vlibapi_get_main ();
   rm->node_index = dhcp6_client_cp_process_node.index;
 
   return NULL;
diff --git a/src/plugins/dhcp/dhcp6_pd_client_cp.c b/src/plugins/dhcp/dhcp6_pd_client_cp.c
index 14f127d..ec9e5c6 100644
--- a/src/plugins/dhcp/dhcp6_pd_client_cp.c
+++ b/src/plugins/dhcp/dhcp6_pd_client_cp.c
@@ -1394,7 +1394,7 @@
 
   rm->vlib_main = vm;
   rm->vnet_main = vnet_get_main ();
-  rm->api_main = &api_main;
+  rm->api_main = vlibapi_get_main ();
   rm->node_index = dhcp6_pd_client_cp_process_node.index;
 
   return (NULL);
diff --git a/src/plugins/dns/dns.c b/src/plugins/dns/dns.c
index a6dff67..4a07fc0 100644
--- a/src/plugins/dns/dns.c
+++ b/src/plugins/dns/dns.c
@@ -3056,7 +3056,7 @@
   dm->name_cache_size = 1000;
   dm->max_ttl_in_seconds = 86400;
   dm->random_seed = 0xDEADDABE;
-  dm->api_main = &api_main;
+  dm->api_main = vlibapi_get_main ();
 
   /* Ask for a correctly-sized block of API message decode slots */
   dm->msg_id_base = setup_message_id_table ();
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c
index 1285032..35cd608 100644
--- a/src/plugins/hs_apps/echo_client.c
+++ b/src/plugins/hs_apps/echo_client.c
@@ -318,7 +318,7 @@
 static int
 create_api_loopback (echo_client_main_t * ecm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr;
 
   shmem_hdr = am->shmem_hdr;
diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c
index dc15185..0da7bc0 100644
--- a/src/plugins/hs_apps/echo_server.c
+++ b/src/plugins/hs_apps/echo_server.c
@@ -306,7 +306,7 @@
 create_api_loopback (vlib_main_t * vm)
 {
   echo_server_main_t *esm = &echo_server_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr;
 
   shmem_hdr = am->shmem_hdr;
diff --git a/src/plugins/hs_apps/proxy.c b/src/plugins/hs_apps/proxy.c
index 31dbfc5..c4ddd67 100644
--- a/src/plugins/hs_apps/proxy.c
+++ b/src/plugins/hs_apps/proxy.c
@@ -381,7 +381,7 @@
 create_api_loopbacks (vlib_main_t * vm)
 {
   proxy_main_t *pm = &proxy_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr;
 
   shmem_hdr = am->shmem_hdr;
diff --git a/src/plugins/hs_apps/sapi/vpp_echo.c b/src/plugins/hs_apps/sapi/vpp_echo.c
index 18a0280..c94ff9d 100644
--- a/src/plugins/hs_apps/sapi/vpp_echo.c
+++ b/src/plugins/hs_apps/sapi/vpp_echo.c
@@ -88,7 +88,7 @@
 connect_to_vpp (char *name)
 {
   echo_main_t *em = &echo_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (em->use_sock_api)
     {
diff --git a/src/plugins/lacp/lacp_api.c b/src/plugins/lacp/lacp_api.c
index 115dd47..dbeb14b 100644
--- a/src/plugins/lacp/lacp_api.c
+++ b/src/plugins/lacp/lacp_api.c
@@ -119,7 +119,7 @@
 lacp_plugin_api_hookup (vlib_main_t * vm)
 {
   lacp_main_t *lm = &lacp_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /* Ask for a correctly-sized block of API message decode slots */
   lm->msg_id_base = setup_message_id_table ();
diff --git a/src/plugins/mactime/mactime.c b/src/plugins/mactime/mactime.c
index bc0c9ce..9192a26 100644
--- a/src/plugins/mactime/mactime.c
+++ b/src/plugins/mactime/mactime.c
@@ -249,7 +249,7 @@
   u8 *name;
   vl_api_mactime_add_del_range_t *mp;
 
-  am = &api_main;
+  am = vlibapi_get_main ();
   shmem_hdr = am->shmem_hdr;
   mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
   clib_memset (mp, 0, sizeof (*mp));
diff --git a/src/plugins/mactime/mactime_top.c b/src/plugins/mactime/mactime_top.c
index df7c755..48735a2 100644
--- a/src/plugins/mactime/mactime_top.c
+++ b/src/plugins/mactime/mactime_top.c
@@ -120,7 +120,7 @@
 static int
 connect_to_vpp (char *name)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   mt_main_t *mm = &mt_main;
   u8 *msg_base_lookup_name;
 
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index d713368..ee70b0f 100755
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -2309,7 +2309,7 @@
   sm->vnet_main = vnet_get_main ();
   sm->ip4_main = im;
   sm->ip4_lookup_main = lm;
-  sm->api_main = &api_main;
+  sm->api_main = vlibapi_get_main ();
   sm->first_worker_index = 0;
   sm->num_workers = 0;
   sm->num_snat_thread = 1;
diff --git a/src/plugins/nsh/nsh_api.c b/src/plugins/nsh/nsh_api.c
index 02675f9..2f40f31 100644
--- a/src/plugins/nsh/nsh_api.c
+++ b/src/plugins/nsh/nsh_api.c
@@ -713,7 +713,7 @@
   error = nsh_plugin_api_hookup (vm);
 
   /* Add our API messages to the global name_crc hash table */
-  setup_message_id_table (nm, &api_main);
+  setup_message_id_table (nm, vlibapi_get_main ());
 
   vec_free (name);
 
diff --git a/src/svm/svm.c b/src/svm/svm.c
index cc49eb3..cb42194 100644
--- a/src/svm/svm.c
+++ b/src/svm/svm.c
@@ -596,7 +596,7 @@
 
   shm_name = shm_name_from_svm_map_region_args (a);
 
-  if (CLIB_DEBUG > 1)
+  if (1 || CLIB_DEBUG > 1)
     clib_warning ("[%d] map region %s: shm_open (%s)",
 		  getpid (), a->name, shm_name);
 
diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py
index e84732e..a893b3a 100644
--- a/src/tools/vppapigen/vppapigen_c.py
+++ b/src/tools/vppapigen/vppapigen_c.py
@@ -612,7 +612,7 @@
     write(hdr.format(module=module))
     write('static u16\n')
     write('setup_message_id_table (void) {\n')
-    write('   api_main_t *am = &api_main;\n')
+    write('   api_main_t *am = my_api_main;\n')
     write('   u16 msg_id_base = vl_msg_api_get_msg_ids ("{}_{crc:08x}", VL_MSG_FIRST_AVAILABLE);\n'
           .format(module, crc=file_crc))
 
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index e362672..218ae95 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -1100,7 +1100,7 @@
 {
   vat_main_t *vam = &vat_main;
   vat_json_node_t node;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   void *oldheap;
   u8 *reply;
 
@@ -2710,7 +2710,7 @@
   (vl_api_get_node_graph_reply_t * mp)
 {
   vat_main_t *vam = &vat_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   i32 retval = ntohl (mp->retval);
   u8 *pvt_copy, *reply;
   void *oldheap;
@@ -2773,7 +2773,7 @@
   (vl_api_get_node_graph_reply_t * mp)
 {
   vat_main_t *vam = &vat_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   void *oldheap;
   vat_json_node_t node;
   u8 *reply;
@@ -21333,7 +21333,7 @@
 static int
 dump_msg_api_table (vat_main_t * vam)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   name_sort_t *nses = 0, *ns;
   hash_pair_t *hp;
   int i;
diff --git a/src/vat/main.c b/src/vat/main.c
index 893a102..996fb1e 100644
--- a/src/vat/main.c
+++ b/src/vat/main.c
@@ -31,7 +31,7 @@
 connect_to_vpe (char *name)
 {
   vat_main_t *vam = &vat_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
     return -1;
@@ -185,7 +185,7 @@
       if (vam->client_index_invalid)
 	{
 	  vat_main_t *vam = &vat_main;
-	  api_main_t *am = &api_main;
+	  api_main_t *am = vlibapi_get_main ();
 
 	  vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
 	  vam->my_client_index = am->my_client_index;
diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c
index be7ce6b..a98b181 100644
--- a/src/vcl/vcl_bapi.c
+++ b/src/vcl/vcl_bapi.c
@@ -510,7 +510,7 @@
 vppcom_connect_to_vpp (char *app_name)
 {
   vcl_worker_t *wrk = vcl_worker_get_current ();
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
 
   if (vcl_cfg->vpp_api_socket_name)
diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c
index f431396..b14fdee 100644
--- a/src/vcl/vcl_private.c
+++ b/src/vcl/vcl_private.c
@@ -316,7 +316,7 @@
 vcl_cleanup_bapi (void)
 {
   socket_client_main_t *scm = &socket_client_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->my_client_index = ~0;
   am->my_registration = 0;
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index ae08915..3d5c869 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -68,7 +68,7 @@
                                                                         \
 static void __vl_msg_api_add_##tag##_function_##x (void)                \
 {                                                                       \
- api_main_t * am = &api_main;                                           \
+ api_main_t * am = vlibapi_get_main();                                  \
  static _vl_msg_api_function_list_elt_t _vl_msg_api_function;           \
  _vl_msg_api_function.next_init_function                                \
     = am->tag##_function_registrations;                                 \
diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h
index fac4c96..c3ef573 100644
--- a/src/vlibapi/api_common.h
+++ b/src/vlibapi/api_common.h
@@ -369,7 +369,14 @@
 
 } api_main_t;
 
-extern api_main_t api_main;
+extern __thread api_main_t *my_api_main;
+extern api_main_t api_global_main;
+
+always_inline api_main_t *
+vlibapi_get_main (void)
+{
+  return my_api_main;
+}
 
 #endif /* included_api_common_h */
 
diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c
index ba87262..a553a5b 100644
--- a/src/vlibapi/api_shared.c
+++ b/src/vlibapi/api_shared.c
@@ -32,7 +32,7 @@
 #include <vppinfra/elog.h>
 
 /* *INDENT-OFF* */
-api_main_t api_main =
+api_main_t api_global_main =
   {
     .region_name = "/unset",
     .api_uid = -1,
@@ -40,10 +40,20 @@
   };
 /* *INDENT-ON* */
 
+/* Please use vlibapi_get_main() to access my_api_main */
+__thread api_main_t *my_api_main = &api_global_main;
+
+void
+vl_msg_api_set_global_main (void *am_arg)
+{
+  ASSERT (am_arg);
+  my_api_main = (api_main_t *) am_arg;
+}
+
 void
 vl_msg_api_increment_missing_client_counter (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   am->missing_clients++;
 }
 
@@ -644,7 +654,7 @@
 void
 vl_msg_api_handler (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   msg_handler_internal (am, the_msg,
 			(am->rx_trace
@@ -655,7 +665,7 @@
 void
 vl_msg_api_handler_no_free (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   msg_handler_internal (am, the_msg,
 			(am->rx_trace
 			 && am->rx_trace->enabled) /* trace_it */ ,
@@ -665,7 +675,7 @@
 void
 vl_msg_api_handler_no_trace_no_free (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ ,
 			0 /* free_it */ );
 }
@@ -682,7 +692,7 @@
 void
 vl_msg_api_trace_only (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   msg_handler_internal (am, the_msg,
 			(am->rx_trace
@@ -693,7 +703,7 @@
 void
 vl_msg_api_cleanup_handler (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
 
   if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers)))
@@ -713,7 +723,7 @@
 void
 vl_msg_api_replay_handler (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
 
@@ -740,7 +750,7 @@
 void
 vl_msg_api_socket_handler (void *the_msg)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   msg_handler_internal (am, the_msg,
 			(am->rx_trace
@@ -761,7 +771,7 @@
 void
 vl_msg_api_config (vl_msg_api_msg_config_t * c)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /*
    * This happens during the java core tests if the message
@@ -844,7 +854,7 @@
 void
 vl_msg_api_set_cleanup_handler (int msg_id, void *fp)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   ASSERT (msg_id > 0);
 
   vec_validate (am->msg_cleanup_handlers, msg_id);
@@ -891,7 +901,7 @@
 void
 vl_msg_api_post_mortem_dump (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   FILE *fp;
   char filename[64];
   int rv;
@@ -926,7 +936,7 @@
 void
 vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /* Mild idiot proofing */
   if (msg_id_host_byte_order > 10000)
@@ -940,7 +950,7 @@
 int
 vl_msg_api_pd_handler (void *mp, int rv)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int (*fp) (void *, int);
   u16 msg_id;
 
@@ -961,7 +971,7 @@
 void
 vl_msg_api_set_first_available_msg_id (u16 first_avail)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->first_available_msg_id = first_avail;
 }
@@ -969,7 +979,7 @@
 u16
 vl_msg_api_get_msg_ids (const char *name, int n)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u8 *name_copy;
   vl_api_msg_range_t *rp;
   uword *p;
@@ -1041,7 +1051,7 @@
 u32
 vl_msg_api_get_msg_index (u8 * name_and_crc)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   uword *p;
 
   if (am->msg_index_by_name_and_crc)
@@ -1056,7 +1066,7 @@
 void *
 vl_msg_push_heap (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   pthread_mutex_lock (&am->vlib_rp->mutex);
   return svm_push_data_heap (am->vlib_rp);
 }
@@ -1064,7 +1074,7 @@
 void
 vl_msg_pop_heap (void *oldheap)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   svm_pop_heap (oldheap);
   pthread_mutex_unlock (&am->vlib_rp->mutex);
 }
@@ -1122,7 +1132,7 @@
 void
 vl_api_set_elog_main (elog_main_t * m)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   am->elog_main = m;
 }
 
@@ -1130,7 +1140,7 @@
 vl_api_set_elog_trace_api_messages (int enable)
 {
   int rv;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   rv = am->elog_trace_api_messages;
   am->elog_trace_api_messages = enable;
@@ -1140,7 +1150,7 @@
 int
 vl_api_get_elog_trace_api_messages (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   return am->elog_trace_api_messages;
 }
diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c
index b5c97e9..8c633e2 100644
--- a/src/vlibmemory/memory_api.c
+++ b/src/vlibmemory/memory_api.c
@@ -64,7 +64,7 @@
 memclnt_queue_callback (vlib_main_t * vm)
 {
   int i;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (PREDICT_FALSE (vec_len (vl_api_queue_cursizes) !=
 		     1 + vec_len (am->vlib_private_rps)))
@@ -123,7 +123,7 @@
   vl_api_registration_t *regp;
   svm_region_t *svm;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   ASSERT (vlib_get_thread_index () == 0);
   pool_get (am->vl_clients, regpp);
@@ -164,7 +164,7 @@
   svm_queue_t *q;
   int rv = 0;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u8 *msg_table;
 
   /*
@@ -246,7 +246,7 @@
   clib_error_t *error = 0;
   _vl_msg_api_function_list_elt_t *i;
 
-  i = api_main.reaper_function_registrations;
+  i = vlibapi_get_main ()->reaper_function_registrations;
   while (i)
     {
       error = i->f (client_index);
@@ -268,7 +268,7 @@
   vl_api_memclnt_delete_reply_t *rp;
   svm_region_t *svm;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 handle, client_index, epoch;
 
   handle = mp->index;
@@ -411,7 +411,7 @@
   api_main_t *am;
   vl_shmem_hdr_t *shmem_hdr;
 
-  am = &api_main;
+  am = vlibapi_get_main ();
   shmem_hdr = am->shmem_hdr;
 
   rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp));
@@ -439,7 +439,7 @@
 vl_mem_api_init (const char *region_name)
 {
   int rv;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_msg_api_msg_config_t cfg;
   vl_msg_api_msg_config_t *c = &cfg;
   vl_shmem_hdr_t *shm;
@@ -488,7 +488,7 @@
 clib_error_t *
 map_api_segment_init (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int rv;
 
   if ((rv = vl_mem_api_init (am->region_name)) < 0)
@@ -503,8 +503,8 @@
 send_memclnt_keepalive (vl_api_registration_t * regp, f64 now)
 {
   vl_api_memclnt_keepalive_t *mp;
-  api_main_t *am = &api_main;
   svm_queue_t *q;
+  api_main_t *am = vlibapi_get_main ();
 
   q = regp->vl_input_queue;
 
@@ -722,7 +722,7 @@
 int
 vl_mem_api_handle_msg_main (vlib_main_t * vm, vlib_node_runtime_t * node)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   return void_mem_api_handle_msg_i (am, am->vlib_rp, vm, node,
 				    0 /* is_private */ );
 }
@@ -730,7 +730,7 @@
 int
 vl_mem_api_handle_rpc (vlib_main_t * vm, vlib_node_runtime_t * node)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int i;
   uword *tmp, mp;
 
@@ -775,7 +775,7 @@
 vl_mem_api_handle_msg_private (vlib_main_t * vm, vlib_node_runtime_t * node,
 			       u32 reg_index)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   return void_mem_api_handle_msg_i (am, am->vlib_private_rps[reg_index], vm,
 				    node, 1 /* is_private */ );
@@ -786,7 +786,7 @@
 {
   vl_api_registration_t **regpp;
   vl_api_registration_t *regp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr;
   u32 index;
 
@@ -814,7 +814,7 @@
 vl_api_client_index_to_input_queue (u32 index)
 {
   vl_api_registration_t *regp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /* Special case: vlib trying to send itself a message */
   if (index == (u32) ~ 0)
@@ -884,7 +884,7 @@
 {
   int i;
   vl_shmem_hdr_t *shmem_hdr;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /* First, dump the primary region rings.. */
 
@@ -950,7 +950,7 @@
 clib_error_t *
 vlibmemory_init (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   svm_map_region_args_t _a, *a = &_a;
   u8 *remove_path1, *remove_path2;
   void vlibsocket_reference (void);
@@ -999,7 +999,7 @@
 void
 vl_set_memory_region_name (const char *name)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   am->region_name = name;
 }
 
diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c
index bb377f1..f78288e 100644
--- a/src/vlibmemory/memory_client.c
+++ b/src/vlibmemory/memory_client.c
@@ -24,6 +24,7 @@
 #include <vppinfra/serialize.h>
 #include <vppinfra/hash.h>
 #include <vlibmemory/memory_client.h>
+#include <vlibapi/api_common.h>
 
 /* A hack. vl_client_get_first_plugin_msg_id depends on it */
 #include <vlibmemory/socket_client.h>
@@ -45,15 +46,15 @@
 #undef vl_printfun
 
 memory_client_main_t memory_client_main;
+__thread memory_client_main_t *my_memory_client_main = &memory_client_main;
 
 static void *
 rx_thread_fn (void *arg)
 {
   svm_queue_t *q;
-  memory_client_main_t *mm = &memory_client_main;
-  api_main_t *am = &api_main;
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
 
-  q = am->vl_input_queue;
+  q = vlibapi_get_main ()->vl_input_queue;
 
   /* So we can make the rx thread terminate cleanly */
   if (setjmp (mm->rx_thread_jmpbuf) == 0)
@@ -69,7 +70,7 @@
 static void
 vl_api_rx_thread_exit_t_handler (vl_api_rx_thread_exit_t * mp)
 {
-  memory_client_main_t *mm = &memory_client_main;
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
   if (mm->rx_thread_jmpbuf_valid)
     longjmp (mm->rx_thread_jmpbuf, 1);
 }
@@ -77,7 +78,7 @@
 static void
 vl_api_name_and_crc_free (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int i;
   u8 **keys = 0;
   hash_pair_t *hp;
@@ -108,7 +109,7 @@
 vl_api_memclnt_create_reply_t_handler (vl_api_memclnt_create_reply_t * mp)
 {
   serialize_main_t _sm, *sm = &_sm;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u8 *tblv;
   u32 nmsgs;
   int i;
@@ -154,7 +155,7 @@
   vl_shmem_hdr_t *shmem_hdr;
   int rv = 0;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (am->my_registration)
     {
@@ -241,7 +242,7 @@
 vl_api_memclnt_delete_reply_t_handler (vl_api_memclnt_delete_reply_t * mp)
 {
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   pthread_mutex_lock (&am->vlib_rp->mutex);
   oldheap = svm_push_data_heap (am->vlib_rp);
@@ -259,7 +260,7 @@
 {
   vl_api_memclnt_delete_t *mp;
   vl_shmem_hdr_t *shmem_hdr;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   ASSERT (am->vlib_rp);
   shmem_hdr = am->shmem_hdr;
@@ -280,7 +281,7 @@
 {
   vl_api_memclnt_delete_reply_t *rp;
   svm_queue_t *vl_input_queue;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   time_t begin;
 
   vl_input_queue = am->vl_input_queue;
@@ -336,7 +337,7 @@
   api_main_t *am;
   vl_shmem_hdr_t *shmem_hdr;
 
-  am = &api_main;
+  am = vlibapi_get_main ();
   shmem_hdr = am->shmem_hdr;
 
   rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp));
@@ -395,11 +396,11 @@
 connect_to_vlib_internal (const char *svm_name,
 			  const char *client_name,
 			  int rx_queue_size, void *(*thread_fn) (void *),
-			  int do_map)
+			  void *thread_fn_arg, int do_map)
 {
   int rv = 0;
-  memory_client_main_t *mm = &memory_client_main;
-  api_main_t *am = &api_main;
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
+  api_main_t *am = vlibapi_get_main ();
 
   if (do_map && (rv = vl_client_api_map (svm_name)))
     {
@@ -419,7 +420,7 @@
   if (thread_fn)
     {
       rv = pthread_create (&mm->rx_thread_handle,
-			   NULL /*attr */ , thread_fn, 0);
+			   NULL /*attr */ , thread_fn, thread_fn_arg);
       if (rv)
 	{
 	  clib_warning ("pthread_create returned %d", rv);
@@ -440,7 +441,8 @@
 			   const char *client_name, int rx_queue_size)
 {
   return connect_to_vlib_internal (svm_name, client_name, rx_queue_size,
-				   rx_thread_fn, 1 /* do map */ );
+				   rx_thread_fn, 0 /* thread fn arg */ ,
+				   1 /* do map */ );
 }
 
 int
@@ -450,6 +452,7 @@
 {
   return connect_to_vlib_internal (svm_name, client_name, rx_queue_size,
 				   0 /* no rx_thread_fn */ ,
+				   0 /* no thread fn arg */ ,
 				   1 /* do map */ );
 }
 
@@ -458,7 +461,8 @@
 				  const char *client_name, int rx_queue_size)
 {
   return connect_to_vlib_internal (svm_name, client_name, rx_queue_size,
-				   rx_thread_fn, 0 /* dont map */ );
+				   rx_thread_fn, 0 /* no thread fn arg */ ,
+				   0 /* dont map */ );
 }
 
 int
@@ -467,7 +471,8 @@
 						int rx_queue_size)
 {
   return connect_to_vlib_internal (svm_name, client_name, rx_queue_size,
-				   0 /* want pthread */ ,
+				   0 /* no thread_fn */ ,
+				   0 /* no thread fn arg */ ,
 				   0 /* dont map */ );
 }
 
@@ -475,18 +480,18 @@
 vl_client_connect_to_vlib_thread_fn (const char *svm_name,
 				     const char *client_name,
 				     int rx_queue_size,
-				     void *(*thread_fn) (void *))
+				     void *(*thread_fn) (void *), void *arg)
 {
   return connect_to_vlib_internal (svm_name, client_name, rx_queue_size,
-				   thread_fn, 1 /* do map */ );
+				   thread_fn, arg, 1 /* do map */ );
 }
 
 
 static void
 disconnect_from_vlib_internal (u8 do_unmap)
 {
-  memory_client_main_t *mm = &memory_client_main;
-  api_main_t *am = &api_main;
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
+  api_main_t *am = vlibapi_get_main ();
   uword junk;
 
   if (mm->rx_thread_jmpbuf_valid)
@@ -521,7 +526,7 @@
 static void vl_api_get_first_msg_id_reply_t_handler
   (vl_api_get_first_msg_id_reply_t * mp)
 {
-  memory_client_main_t *mm = &memory_client_main;
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
   i32 retval = ntohl (mp->retval);
 
   mm->first_msg_id_reply = (retval >= 0) ? ntohs (mp->first_msg_id) : ~0;
@@ -532,8 +537,8 @@
 vl_client_get_first_plugin_msg_id (const char *plugin_name)
 {
   vl_api_get_first_msg_id_t *mp;
-  api_main_t *am = &api_main;
-  memory_client_main_t *mm = &memory_client_main;
+  api_main_t *am = vlibapi_get_main ();
+  memory_client_main_t *mm = vlibapi_get_memory_client_main ();
   f64 timeout;
   void *old_handler;
   clib_time_t clib_time;
diff --git a/src/vlibmemory/memory_client.h b/src/vlibmemory/memory_client.h
index 7ec7253..4d79478 100644
--- a/src/vlibmemory/memory_client.h
+++ b/src/vlibmemory/memory_client.h
@@ -36,6 +36,7 @@
 } memory_client_main_t;
 
 extern memory_client_main_t memory_client_main;
+extern __thread memory_client_main_t *my_memory_client_main;
 
 int vl_client_connect (const char *name, int ctx_quota, int input_queue_size);
 void vl_client_send_disconnect (u8 do_cleanup);
@@ -49,7 +50,7 @@
 int vl_client_connect_to_vlib_thread_fn (const char *svm_name,
 					 const char *client_name,
 					 int rx_queue_size,
-					 void *(*)(void *));
+					 void *(*)(void *), void *);
 int vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name,
 					     const char *client_name,
 					     int rx_queue_size);
@@ -62,6 +63,13 @@
 void vl_client_install_client_message_handlers (void);
 u8 vl_mem_client_is_connected (void);
 
+always_inline memory_client_main_t *
+vlibapi_get_memory_client_main (void)
+{
+  ASSERT (my_memory_client_main);
+  return my_memory_client_main;
+}
+
 #endif /* SRC_VLIBMEMORY_MEMORY_CLIENT_H_ */
 
 /*
diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c
index b927f95..0b232ad 100644
--- a/src/vlibmemory/memory_shared.c
+++ b/src/vlibmemory/memory_shared.c
@@ -35,6 +35,7 @@
 #include <vlib/unix/unix.h>
 #include <vlibmemory/memory_api.h>
 #include <vlibmemory/vl_memory_msg_enum.h>
+#include <vlibapi/api_common.h>
 
 #define vl_typedefs
 #include <vlibmemory/vl_memory_api_h.h>
@@ -52,7 +53,7 @@
   svm_queue_t *q;
   void *oldheap;
   vl_shmem_hdr_t *shmem_hdr;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   shmem_hdr = (void *) vlib_rp->user_ctx;
 
@@ -121,9 +122,9 @@
 			 q->head);
 		      msg_idp = (u16 *) (rv->data);
 		      msg_id = clib_net_to_host_u16 (*msg_idp);
-		      if (msg_id < vec_len (api_main.msg_names))
+		      if (msg_id < vec_len (vlibapi_get_main ()->msg_names))
 			clib_warning ("msg id %d name %s", (u32) msg_id,
-				      api_main.msg_names[msg_id]);
+				      vlibapi_get_main ()->msg_names[msg_id]);
 		    }
 		  shmem_hdr->garbage_collects++;
 		  goto collected;
@@ -201,7 +202,7 @@
 vl_msg_api_alloc (int nbytes)
 {
   int pool;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
 
   /*
@@ -226,7 +227,7 @@
 vl_msg_api_alloc_or_null (int nbytes)
 {
   int pool;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
 
   pool = (am->our_pid == shmem_hdr->vl_pid);
@@ -237,7 +238,8 @@
 void *
 vl_msg_api_alloc_as_if_client (int nbytes)
 {
-  return vl_msg_api_alloc_internal (api_main.vlib_rp, nbytes, 0,
+  api_main_t *am = vlibapi_get_main ();
+  return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, 0,
 				    0 /* may_return_null */ );
 }
 
@@ -254,7 +256,8 @@
 void *
 vl_msg_api_alloc_as_if_client_or_null (int nbytes)
 {
-  return vl_msg_api_alloc_internal (api_main.vlib_rp, nbytes, 0,
+  api_main_t *am = vlibapi_get_main ();
+  return vl_msg_api_alloc_internal (am->vlib_rp, nbytes, 0,
 				    1 /* may_return_null */ );
 }
 
@@ -312,7 +315,8 @@
 void
 vl_msg_api_free (void *a)
 {
-  vl_msg_api_free_w_region (api_main.vlib_rp, a);
+  api_main_t *am = vlibapi_get_main ();
+  vl_msg_api_free_w_region (am->vlib_rp, a);
 }
 
 static void
@@ -320,7 +324,7 @@
 {
   msgbuf_t *rv;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   rv = (msgbuf_t *) (((u8 *) a) - offsetof (msgbuf_t, data));
   /*
@@ -343,7 +347,7 @@
 void
 vl_set_memory_root_path (const char *name)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->root_path = name;
 }
@@ -351,7 +355,7 @@
 void
 vl_set_memory_uid (int uid)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->api_uid = uid;
 }
@@ -359,7 +363,7 @@
 void
 vl_set_memory_gid (int gid)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->api_gid = gid;
 }
@@ -367,7 +371,7 @@
 void
 vl_set_global_memory_baseva (u64 baseva)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->global_baseva = baseva;
 }
@@ -375,7 +379,7 @@
 void
 vl_set_global_memory_size (u64 size)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->global_size = size;
 }
@@ -383,7 +387,7 @@
 void
 vl_set_api_memory_size (u64 size)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->api_size = size;
 }
@@ -391,7 +395,7 @@
 void
 vl_set_global_pvt_heap_size (u64 size)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->global_pvt_heap_size = size;
 }
@@ -399,7 +403,7 @@
 void
 vl_set_api_pvt_heap_size (u64 size)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   am->api_pvt_heap_size = size;
 }
@@ -407,7 +411,7 @@
 static void
 vl_api_default_mem_config (vl_shmem_hdr_t * shmem_hdr)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 vlib_input_queue_length;
 
   /* vlib main input queue */
@@ -493,7 +497,7 @@
 vl_init_shmem (svm_region_t * vlib_rp, vl_api_shm_elem_config_t * config,
 	       int is_vlib, int is_private_region)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr = 0;
   void *oldheap;
   ASSERT (vlib_rp);
@@ -536,7 +540,7 @@
 {
   svm_map_region_args_t _a, *a = &_a;
   svm_region_t *vlib_rp, *root_rp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int i;
   struct timespec ts, tsrem;
   char *vpe_api_region_suffix = "-vpe-api";
@@ -706,7 +710,7 @@
 void
 vl_register_mapped_shmem_region (svm_region_t * rp)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   vec_add1 (am->mapped_shmem_regions, rp);
 }
@@ -716,7 +720,7 @@
 {
   svm_region_t *rp;
   int i;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (!svm_get_root_rp ())
     return;
@@ -753,7 +757,7 @@
 void
 vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   void *msg = (void *) *(uword *) elem;
 
   if (am->tx_trace && am->tx_trace->enabled)
@@ -800,7 +804,7 @@
 void
 vl_msg_api_send_shmem_nolock (svm_queue_t * q, u8 * elem)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   void *msg = (void *) *(uword *) elem;
 
   if (am->tx_trace && am->tx_trace->enabled)
diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c
index 32d1e70..eb0466d 100644
--- a/src/vlibmemory/socket_api.c
+++ b/src/vlibmemory/socket_api.c
@@ -118,7 +118,7 @@
 #endif
   socket_main_t *sm = &socket_main;
   u16 msg_id = ntohs (*(u16 *) elem);
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   msgbuf_t *mb = (msgbuf_t *) (elem - offsetof (msgbuf_t, data));
   vl_api_registration_t *sock_rp;
   clib_file_main_t *fm = &file_main;
@@ -445,7 +445,7 @@
 {
   vl_api_registration_t *regp;
   vl_api_sockclnt_create_reply_t *rp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   hash_pair_t *hp;
   int rv = 0;
   u32 nmsg = hash_elts (am->msg_index_by_name_and_crc);
@@ -606,7 +606,7 @@
   ssvm_private_t _memfd_private, *memfd = &_memfd_private;
   svm_map_region_args_t _args, *a = &_args;
   vl_api_registration_t *regp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   svm_region_t *vlib_rp;
   clib_file_t *cf;
   vl_api_shm_elem_config_t *config = 0;
diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c
index 0c4e11e..5483110 100644
--- a/src/vlibmemory/socket_client.c
+++ b/src/vlibmemory/socket_client.c
@@ -330,7 +330,7 @@
   socket_client_main_t *scm = socket_client_ctx;
   ssvm_private_t *memfd = &scm->memfd_segment;
   i32 retval = ntohl (mp->retval);
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   clib_error_t *error;
   int my_fd = -1;
   u8 *new_name;
diff --git a/src/vlibmemory/vlib_api.c b/src/vlibmemory/vlib_api.c
index 5494da3..297ac37 100644
--- a/src/vlibmemory/vlib_api.c
+++ b/src/vlibmemory/vlib_api.c
@@ -74,7 +74,7 @@
   vl_api_get_first_msg_id_reply_t *rmp;
   vl_api_registration_t *regp;
   uword *p;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_msg_range_t *rp;
   u8 name[64];
   u16 first_msg_id = ~0;
@@ -108,7 +108,7 @@
 void
 vl_api_api_versions_t_handler (vl_api_api_versions_t * mp)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_api_versions_reply_t *rmp;
   vl_api_registration_t *reg;
   u32 nmsg = vec_len (am->api_version_list);
@@ -185,7 +185,7 @@
 send_one_plugin_msg_ids_msg (u8 * name, u16 first_msg_id, u16 last_msg_id)
 {
   vl_api_trace_plugin_msg_ids_t *mp;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
   svm_queue_t *q;
 
@@ -207,7 +207,7 @@
 vl_api_save_msg_table (void)
 {
   u8 *serialized_message_table;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u8 *chroot_file;
   int fd, rv;
 
@@ -257,7 +257,7 @@
   vl_shmem_hdr_t *shm;
   svm_queue_t *q;
   clib_error_t *e;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   f64 dead_client_scan_time;
   f64 sleep_time, start_time;
   f64 vector_rate;
@@ -624,7 +624,7 @@
 static void
 vl_api_trace_plugin_msg_ids_t_handler (vl_api_trace_plugin_msg_ids_t * mp)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_msg_range_t *rp;
   uword *p;
 
@@ -677,7 +677,7 @@
 static clib_error_t *
 rpc_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                            vl_api_##n##_t_handler,              \
diff --git a/src/vlibmemory/vlib_api_cli.c b/src/vlibmemory/vlib_api_cli.c
index 08db458..3f8e1c9 100755
--- a/src/vlibmemory/vlib_api_cli.c
+++ b/src/vlibmemory/vlib_api_cli.c
@@ -101,7 +101,7 @@
   vl_api_registration_t **regpp, *regp;
   svm_queue_t *q;
   char *health;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 *confused_indices = 0;
 
   if (!pool_elts (am->vl_clients))
@@ -161,7 +161,7 @@
 vl_api_status_command (vlib_main_t * vm,
 		       unformat_input_t * input, vlib_cli_command_t * cli_cmd)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   /* check if rx_trace and tx_trace are not null pointers */
   if (am->rx_trace == 0)
@@ -228,7 +228,7 @@
 			      unformat_input_t * input,
 			      vlib_cli_command_t * cli_cmd)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   int i;
   int verbose = 0;
 
@@ -304,7 +304,7 @@
 			    unformat_input_t * input,
 			    vlib_cli_command_t * cli_cmd)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_msg_range_t *rp = 0;
   int i;
 
@@ -402,7 +402,7 @@
   struct stat statb;
   size_t file_size;
   u8 *msg;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u8 *tmpbuf = 0;
   u32 nitems, nitems_msgtbl;
   void **saved_print_handlers = 0;
@@ -668,7 +668,7 @@
 		      unformat_input_t * input, vlib_cli_command_t * cmd)
 {
   u32 nitems = 256 << 10;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_trace_which_t which = VL_API_TRACE_RX;
   u8 *filename = 0;
   u8 *chroot_filename = 0;
@@ -804,7 +804,7 @@
 {
   u32 nitems = 1024;
   vl_api_trace_which_t which = VL_API_TRACE_RX;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -881,7 +881,7 @@
 {
   u32 nitems = 256 << 10;
   vl_api_trace_which_t which = VL_API_TRACE_RX;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -914,7 +914,7 @@
 static clib_error_t *
 api_queue_config_fn (vlib_main_t * vm, unformat_input_t * input)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 nitems;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1004,7 +1004,7 @@
 				vlib_cli_command_t * cmd)
 {
   u8 *filename = 0;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   serialize_main_t _sm, *sm = &_sm;
   clib_error_t *error;
   u32 nmsgs;
diff --git a/src/vnet/bfd/bfd_api.c b/src/vnet/bfd/bfd_api.c
index 0671a5d..50be675 100644
--- a/src/vnet/bfd/bfd_api.c
+++ b/src/vnet/bfd/bfd_api.c
@@ -415,7 +415,7 @@
 static clib_error_t *
 bfd_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N, n)                                                    \
   vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
diff --git a/src/vnet/bier/bier_api.c b/src/vnet/bier/bier_api.c
index 66f6b42..e06a53e 100644
--- a/src/vnet/bier/bier_api.c
+++ b/src/vnet/bier/bier_api.c
@@ -688,7 +688,7 @@
 static clib_error_t *
 bier_api_hookup (vlib_main_t * vm)
 {
-    api_main_t *am = &api_main;
+    api_main_t *am = vlibapi_get_main();
 
 #define _(N,n)                                          \
     vl_msg_api_set_handlers(VL_API_##N, #n,             \
diff --git a/src/vnet/bonding/bond_api.c b/src/vnet/bonding/bond_api.c
index ebbb80e..525f058 100644
--- a/src/vnet/bonding/bond_api.c
+++ b/src/vnet/bonding/bond_api.c
@@ -269,7 +269,7 @@
 static clib_error_t *
 bond_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/classify/classify_api.c b/src/vnet/classify/classify_api.c
index 24f2887..03d0429 100644
--- a/src/vnet/classify/classify_api.c
+++ b/src/vnet/classify/classify_api.c
@@ -678,7 +678,7 @@
 static clib_error_t *
 classify_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/cop/cop_api.c b/src/vnet/cop/cop_api.c
index 0b8a5a2..1415bf0 100644
--- a/src/vnet/cop/cop_api.c
+++ b/src/vnet/cop/cop_api.c
@@ -110,7 +110,7 @@
 static clib_error_t *
 cop_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/af_packet/af_packet_api.c b/src/vnet/devices/af_packet/af_packet_api.c
index dd9697a..58d45be 100644
--- a/src/vnet/devices/af_packet/af_packet_api.c
+++ b/src/vnet/devices/af_packet/af_packet_api.c
@@ -170,7 +170,7 @@
 static clib_error_t *
 af_packet_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/netmap/netmap_api.c b/src/vnet/devices/netmap/netmap_api.c
index 3959615..ee05ec2 100644
--- a/src/vnet/devices/netmap/netmap_api.c
+++ b/src/vnet/devices/netmap/netmap_api.c
@@ -106,7 +106,7 @@
 static clib_error_t *
 netmap_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/pipe/pipe_api.c b/src/vnet/devices/pipe/pipe_api.c
index 1466681..35efb87 100644
--- a/src/vnet/devices/pipe/pipe_api.c
+++ b/src/vnet/devices/pipe/pipe_api.c
@@ -146,7 +146,7 @@
 static clib_error_t *
 pipe_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c
index a1acacf..af3c276 100644
--- a/src/vnet/devices/tap/tapv2_api.c
+++ b/src/vnet/devices/tap/tapv2_api.c
@@ -254,7 +254,7 @@
 static clib_error_t *
 tapv2_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/virtio/vhost_user_api.c b/src/vnet/devices/virtio/vhost_user_api.c
index 7899fa2..c8c9b59 100644
--- a/src/vnet/devices/virtio/vhost_user_api.c
+++ b/src/vnet/devices/virtio/vhost_user_api.c
@@ -226,7 +226,7 @@
 static clib_error_t *
 vhost_user_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/devices/virtio/virtio_api.c b/src/vnet/devices/virtio/virtio_api.c
index e354958..9d009f3 100644
--- a/src/vnet/devices/virtio/virtio_api.c
+++ b/src/vnet/devices/virtio/virtio_api.c
@@ -187,7 +187,7 @@
 static clib_error_t *
 virtio_pci_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/ethernet/p2p_ethernet_api.c b/src/vnet/ethernet/p2p_ethernet_api.c
index 3f53716..3bbda6e 100644
--- a/src/vnet/ethernet/p2p_ethernet_api.c
+++ b/src/vnet/ethernet/p2p_ethernet_api.c
@@ -106,7 +106,7 @@
 static clib_error_t *
 p2p_ethernet_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/feature/feature_api.c b/src/vnet/feature/feature_api.c
index a2c0ced..75399ec 100644
--- a/src/vnet/feature/feature_api.c
+++ b/src/vnet/feature/feature_api.c
@@ -102,7 +102,7 @@
 static clib_error_t *
 feature_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/geneve/geneve_api.c b/src/vnet/geneve/geneve_api.c
index 2a4f5aa..996a7a0 100644
--- a/src/vnet/geneve/geneve_api.c
+++ b/src/vnet/geneve/geneve_api.c
@@ -199,7 +199,7 @@
 static clib_error_t *
 geneve_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/gre/gre_api.c b/src/vnet/gre/gre_api.c
index 9ee9f19..be91f75 100644
--- a/src/vnet/gre/gre_api.c
+++ b/src/vnet/gre/gre_api.c
@@ -252,7 +252,7 @@
 static clib_error_t *
 gre_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/gso/gso_api.c b/src/vnet/gso/gso_api.c
index 9991c5f..d342614 100644
--- a/src/vnet/gso/gso_api.c
+++ b/src/vnet/gso/gso_api.c
@@ -75,7 +75,7 @@
 static clib_error_t *
 feature_gso_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index 387ef32..fe3426c 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -1391,7 +1391,7 @@
 static clib_error_t *
 interface_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 3440c65..6da6ac3 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -2925,7 +2925,7 @@
 static clib_error_t *
 ip_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/ip/punt_api.c b/src/vnet/ip/punt_api.c
index 8bb0f7f..6ed62a1 100644
--- a/src/vnet/ip/punt_api.c
+++ b/src/vnet/ip/punt_api.c
@@ -389,7 +389,7 @@
 static clib_error_t *
 punt_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/ip/rd_cp.c b/src/vnet/ip/rd_cp.c
index f6cb674..c9c387e 100644
--- a/src/vnet/ip/rd_cp.c
+++ b/src/vnet/ip/rd_cp.c
@@ -662,7 +662,7 @@
 rd_cp_init (vlib_main_t * vm)
 {
   rd_cp_main_t *rm = &rd_cp_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   rm->vlib_main = vm;
   rm->vnet_main = vnet_get_main ();
diff --git a/src/vnet/ipfix-export/flow_api.c b/src/vnet/ipfix-export/flow_api.c
index ead6024..84babe7 100644
--- a/src/vnet/ipfix-export/flow_api.c
+++ b/src/vnet/ipfix-export/flow_api.c
@@ -409,7 +409,7 @@
 static clib_error_t *
 flow_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index ed79193..4252acd 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -978,7 +978,7 @@
 static clib_error_t *
 ipsec_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/l2/l2_api.c b/src/vnet/l2/l2_api.c
index 255e91b..e8b103a 100644
--- a/src/vnet/l2/l2_api.c
+++ b/src/vnet/l2/l2_api.c
@@ -1067,7 +1067,7 @@
 static clib_error_t *
 l2_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/l2tp/l2tp_api.c b/src/vnet/l2tp/l2tp_api.c
index ba1f7c6..3a31372 100644
--- a/src/vnet/l2tp/l2tp_api.c
+++ b/src/vnet/l2tp/l2tp_api.c
@@ -242,7 +242,7 @@
 static clib_error_t *
 l2tp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/lisp-cp/lisp_api.c b/src/vnet/lisp-cp/lisp_api.c
index 3f18a5d..4ef4d18 100644
--- a/src/vnet/lisp-cp/lisp_api.c
+++ b/src/vnet/lisp-cp/lisp_api.c
@@ -1283,7 +1283,7 @@
 static clib_error_t *
 lisp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c
index 17d4afc..d1117ee 100644
--- a/src/vnet/lisp-cp/one_api.c
+++ b/src/vnet/lisp-cp/one_api.c
@@ -1817,7 +1817,7 @@
 static clib_error_t *
 one_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/lisp-gpe/lisp_gpe_api.c b/src/vnet/lisp-gpe/lisp_gpe_api.c
index 16c1128..59a3fd1 100644
--- a/src/vnet/lisp-gpe/lisp_gpe_api.c
+++ b/src/vnet/lisp-gpe/lisp_gpe_api.c
@@ -566,7 +566,7 @@
 static clib_error_t *
 gpe_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/lldp/lldp_api.c b/src/vnet/lldp/lldp_api.c
index 00b71f9..b28d1b1 100644
--- a/src/vnet/lldp/lldp_api.c
+++ b/src/vnet/lldp/lldp_api.c
@@ -142,7 +142,7 @@
 static clib_error_t *
 lldp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c
index 56911c8..0185e37 100644
--- a/src/vnet/mpls/mpls_api.c
+++ b/src/vnet/mpls/mpls_api.c
@@ -550,7 +550,7 @@
 static clib_error_t *
 mpls_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/pg/pg_api.c b/src/vnet/pg/pg_api.c
index f4b9604..5b64a77 100644
--- a/src/vnet/pg/pg_api.c
+++ b/src/vnet/pg/pg_api.c
@@ -153,7 +153,7 @@
 static clib_error_t *
 pg_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/policer/policer_api.c b/src/vnet/policer/policer_api.c
index 96ee781..ae57a93 100644
--- a/src/vnet/policer/policer_api.c
+++ b/src/vnet/policer/policer_api.c
@@ -204,7 +204,7 @@
 static clib_error_t *
 policer_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/qos/qos_api.c b/src/vnet/qos/qos_api.c
index cb92c85..af0a700 100644
--- a/src/vnet/qos/qos_api.c
+++ b/src/vnet/qos/qos_api.c
@@ -367,7 +367,7 @@
 static clib_error_t *
 qos_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 4eb4f4a..3369106 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -1333,7 +1333,7 @@
 {
   u32 evt_q_length = 2048, evt_size = sizeof (session_event_t);
   ssvm_private_t *eqs = &smm->evt_qs_segment;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   uword eqs_size = 64 << 20;
   pid_t vpp_pid = getpid ();
   void *oldheap;
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 6cff9ec..0846e57 100644
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -1531,7 +1531,7 @@
 static clib_error_t *
 session_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/span/span_api.c b/src/vnet/span/span_api.c
index 9566941..6ed58cd 100644
--- a/src/vnet/span/span_api.c
+++ b/src/vnet/span/span_api.c
@@ -129,7 +129,7 @@
 static clib_error_t *
 span_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/srmpls/sr_mpls_api.c b/src/vnet/srmpls/sr_mpls_api.c
index f3bfc27..f17c8b4 100644
--- a/src/vnet/srmpls/sr_mpls_api.c
+++ b/src/vnet/srmpls/sr_mpls_api.c
@@ -179,7 +179,7 @@
 static clib_error_t *
 sr_mpls_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/srv6/sr_api.c b/src/vnet/srv6/sr_api.c
index 5a7d8c5..ffd0c4d 100644
--- a/src/vnet/srv6/sr_api.c
+++ b/src/vnet/srv6/sr_api.c
@@ -396,7 +396,7 @@
 static clib_error_t *
 sr_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/syslog/syslog_api.c b/src/vnet/syslog/syslog_api.c
index 9fc8e55..626a2ac 100644
--- a/src/vnet/syslog/syslog_api.c
+++ b/src/vnet/syslog/syslog_api.c
@@ -212,7 +212,7 @@
 static clib_error_t *
 syslog_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/tcp/tcp_api.c b/src/vnet/tcp/tcp_api.c
index 7f57463..db488e1 100644
--- a/src/vnet/tcp/tcp_api.c
+++ b/src/vnet/tcp/tcp_api.c
@@ -83,7 +83,7 @@
 static clib_error_t *
 tcp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/udp/udp_api.c b/src/vnet/udp/udp_api.c
index 5f4081c..522b0a8 100644
--- a/src/vnet/udp/udp_api.c
+++ b/src/vnet/udp/udp_api.c
@@ -177,7 +177,7 @@
 static clib_error_t *
 udp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/vxlan-gbp/vxlan_gbp_api.c b/src/vnet/vxlan-gbp/vxlan_gbp_api.c
index 08e2a7c..17a1984 100644
--- a/src/vnet/vxlan-gbp/vxlan_gbp_api.c
+++ b/src/vnet/vxlan-gbp/vxlan_gbp_api.c
@@ -229,7 +229,7 @@
 static clib_error_t *
 vxlan_gbp_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/vxlan-gpe/vxlan_gpe_api.c b/src/vnet/vxlan-gpe/vxlan_gpe_api.c
index 22a28a7..480441d 100644
--- a/src/vnet/vxlan-gpe/vxlan_gpe_api.c
+++ b/src/vnet/vxlan-gpe/vxlan_gpe_api.c
@@ -236,7 +236,7 @@
 static clib_error_t *
 vxlan_gpe_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vnet/vxlan/vxlan_api.c b/src/vnet/vxlan/vxlan_api.c
index 2cec93c..8efd1e6 100644
--- a/src/vnet/vxlan/vxlan_api.c
+++ b/src/vnet/vxlan/vxlan_api.c
@@ -263,7 +263,7 @@
 static clib_error_t *
 vxlan_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vpp-api/client/client.c b/src/vpp-api/client/client.c
index fa83696..0579095 100644
--- a/src/vpp-api/client/client.c
+++ b/src/vpp-api/client/client.c
@@ -177,7 +177,7 @@
   vl_api_memclnt_keepalive_t *mp;
   vl_api_memclnt_keepalive_reply_t *rmp;
   vac_main_t *pm = &vac_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   vl_shmem_hdr_t *shmem_hdr;
   uword msg;
 
@@ -237,7 +237,7 @@
 {
   vl_api_memclnt_read_timeout_t *ep;
   vac_main_t *pm = &vac_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   struct timespec ts;
   struct timeval tv;
   int rv;
@@ -272,7 +272,7 @@
 void
 vac_rx_suspend (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   vac_main_t *pm = &vac_main;
   vl_api_memclnt_rx_thread_suspend_t *ep;
 
@@ -306,14 +306,14 @@
 static uword *
 vac_msg_table_get_hash (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   return (am->msg_index_by_name_and_crc);
 }
 
 int
 vac_msg_table_size(void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   return hash_elts(am->msg_index_by_name_and_crc);
 }
 
@@ -390,7 +390,7 @@
 int
 vac_disconnect (void)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   vac_main_t *pm = &vac_main;
   uword junk;
   int rv = 0;
@@ -442,7 +442,7 @@
 vac_read (char **p, int *l, u16 timeout)
 {
   svm_queue_t *q;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   vac_main_t *pm = &vac_main;
   vl_api_memclnt_keepalive_t *mp;
   vl_api_memclnt_keepalive_reply_t *rmp;
@@ -489,7 +489,7 @@
       shmem_hdr = am->shmem_hdr;
       vl_msg_api_send_shmem(shmem_hdr->vl_input_queue, (u8 *)&rmp);
       vl_msg_api_free((void *) msg);
-      /* 
+      /*
        * Python code is blissfully unaware of these pings, so
        * act as if it never happened...
        */
@@ -535,14 +535,14 @@
 static u32
 vac_client_index (void)
 {
-  return (api_main.my_client_index);
+  return (vlibapi_get_main()->my_client_index);
 }
 
 int
 vac_write (char *p, int l)
 {
   int rv = -1;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main();
   vl_api_header_t *mp = vl_msg_api_alloc(l);
   svm_queue_t *q;
   vac_main_t *pm = &vac_main;
diff --git a/src/vpp-api/client/test.c b/src/vpp-api/client/test.c
index da2211b..308492d 100644
--- a/src/vpp-api/client/test.c
+++ b/src/vpp-api/client/test.c
@@ -87,7 +87,7 @@
 static void
 test_messages (void)
 {
-  api_main_t * am = &api_main;
+  api_main_t * am = vlibapi_get_main();
   vl_api_show_version_t message;
   vl_api_show_version_t *mp;
   int async = 1;
diff --git a/src/vpp-api/vapi/vapi.c b/src/vpp-api/vapi/vapi.c
index 859a811..8a9c8e3 100644
--- a/src/vpp-api/vapi/vapi.c
+++ b/src/vpp-api/vapi/vapi.c
@@ -447,7 +447,7 @@
       goto out;
     }
   int tmp;
-  svm_queue_t *q = api_main.shmem_hdr->vl_input_queue;
+  svm_queue_t *q = vlibapi_get_main ()->shmem_hdr->vl_input_queue;
 #if VAPI_DEBUG
   unsigned msgid = be16toh (*(u16 *) msg);
   if (msgid <= ctx->vl_msg_id_max)
@@ -490,7 +490,7 @@
       rv = VAPI_EINVAL;
       goto out;
     }
-  svm_queue_t *q = api_main.shmem_hdr->vl_input_queue;
+  svm_queue_t *q = vlibapi_get_main ()->shmem_hdr->vl_input_queue;
 #if VAPI_DEBUG
   unsigned msgid1 = be16toh (*(u16 *) msg1);
   unsigned msgid2 = be16toh (*(u16 *) msg2);
@@ -536,7 +536,7 @@
       return VAPI_EINVAL;
     }
   vapi_error_e rv = VAPI_OK;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   uword data;
 
   if (am->our_pid == 0)
@@ -860,7 +860,7 @@
 int
 vapi_get_client_index (vapi_ctx_t ctx)
 {
-  return api_main.my_client_index;
+  return vlibapi_get_main ()->my_client_index;
 }
 
 bool
diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c
index 51d1edb..c62e7d0 100644
--- a/src/vpp/api/api.c
+++ b/src/vpp/api/api.c
@@ -143,7 +143,7 @@
   u8 **shmem_vecp = (u8 **) arg;
   u8 *shmem_vec;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 offset;
 
   shmem_vec = *shmem_vecp;
@@ -170,7 +170,7 @@
   vl_api_cli_reply_t *rp;
   vl_api_registration_t *reg;
   vlib_main_t *vm = vlib_get_main ();
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   unformat_input_t input;
   u8 *shmem_vec = 0;
   void *oldheap;
@@ -439,7 +439,7 @@
 {
   int rv = 0;
   u8 *vector = 0;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vlib_main_t *vm = vlib_get_main ();
   void *oldheap;
   vl_api_get_node_graph_reply_t *rmp;
@@ -625,7 +625,7 @@
 static clib_error_t *
 vpe_api_hookup (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
diff --git a/src/vpp/api/api_main.c b/src/vpp/api/api_main.c
index af31307..7fcbe70 100644
--- a/src/vpp/api/api_main.c
+++ b/src/vpp/api/api_main.c
@@ -78,7 +78,7 @@
   vl_api_registration_t *regp;
   svm_region_t *svm;
   void *oldheap;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   if (vam->my_client_index != ~0)
     return;
@@ -260,7 +260,7 @@
 u16
 vl_client_get_first_plugin_msg_id (const char *plugin_name)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   vl_api_msg_range_t *rp;
   uword *p;
 
diff --git a/src/vpp/api/gmon.c b/src/vpp/api/gmon.c
index f665a09..044410f 100644
--- a/src/vpp/api/gmon.c
+++ b/src/vpp/api/gmon.c
@@ -158,7 +158,7 @@
 gmon_init (vlib_main_t * vm)
 {
   gmon_main_t *gm = &gmon_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   pid_t *swp = 0;
   f64 *v = 0;
   clib_error_t *error;
diff --git a/src/vpp/api/test_client.c b/src/vpp/api/test_client.c
index 14f98cd..f207bb0 100644
--- a/src/vpp/api/test_client.c
+++ b/src/vpp/api/test_client.c
@@ -1288,7 +1288,7 @@
 int
 main (int argc, char **argv)
 {
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   test_main_t *tm = &test_main;
   int ch;
 
diff --git a/src/vpp/api/test_ha.c b/src/vpp/api/test_ha.c
index b9fc428..e05361b 100644
--- a/src/vpp/api/test_ha.c
+++ b/src/vpp/api/test_ha.c
@@ -131,7 +131,7 @@
 {
   int rv = 0;
   test_main_t *tm = &test_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
 
   rv = vl_client_connect_to_vlib ("/vpe-api", name, 32);
   if (rv < 0)
@@ -174,7 +174,7 @@
 main (int argc, char **argv)
 {
   test_main_t *tm = &test_main;
-  api_main_t *am = &api_main;
+  api_main_t *am = vlibapi_get_main ();
   u32 swt_pid = 0;
   int connected = 0;