Refactor API message handling code

This is preparation for new C API. Moving common stuff to separate
headers reduces dependency issues.

Change-Id: Ie7adb23398de72448e5eba6c1c1da4e1bc678725
Signed-off-by: Klement Sekera <ksekera@cisco.com>
diff --git a/src/svm.am b/src/svm.am
index 442eba8..7116eb3 100644
--- a/src/svm.am
+++ b/src/svm.am
@@ -13,7 +13,7 @@
 
 bin_PROGRAMS += svmtool svmdbtool
 
-nobase_include_HEADERS += svm/svm.h svm/ssvm.h svm/svmdb.h \
+nobase_include_HEADERS += svm/svm.h svm/svm_common.h svm/ssvm.h svm/svmdb.h \
 	svm/svm_fifo.h svm/svm_fifo_segment.h
 
 lib_LTLIBRARIES += libsvm.la libsvmdb.la
diff --git a/src/svm/svm.h b/src/svm/svm.h
index 06797fa..894c3d9 100644
--- a/src/svm/svm.h
+++ b/src/svm/svm.h
@@ -24,106 +24,10 @@
 #include <pthread.h>
 #include <vppinfra/clib.h>
 #include <vppinfra/mem.h>
+#include <svm/svm_common.h>
 
 #define MMAP_PAGESIZE (clib_mem_get_page_size())
 
-#define SVM_VERSION ((1<<16) | 1)	/* set to declare region ready. */
-
-#define SVM_FLAGS_MHEAP (1<<0)	/* region contains an mheap */
-#define SVM_FLAGS_FILE  (1<<1)	/* region backed by one or more files */
-#define SVM_FLAGS_NODATA (1<<2)	/* region will be further subdivided */
-#define SVM_FLAGS_NEED_DATA_INIT (1<<3)
-
-#define SVM_PVT_MHEAP_SIZE (128<<10)	/* region's private mheap (128k) */
-
-typedef struct svm_region_
-{
-  volatile uword version;
-  pthread_mutex_t mutex;
-  pthread_cond_t condvar;
-  int mutex_owner_pid;		/* in case of trouble */
-  int mutex_owner_tag;
-  uword flags;
-  uword virtual_base;		/* base of the region object */
-  uword virtual_size;
-  void *region_heap;
-  void *data_base;		/* data portion base address */
-  void *data_heap;		/* data heap, if any */
-  volatile void *user_ctx;	/* user context pointer */
-  /* stuff allocated in the region's heap */
-  uword bitmap_size;		/* nbits in virtual alloc bitmap */
-  uword *bitmap;		/* the bitmap */
-  char *region_name;
-  char *backing_file;
-  char **filenames;
-  uword *client_pids;
-  /* pad */
-
-  /* next page:
-   * (64K) clib heap for the region itself
-   *
-   * data_base -> whatever is in this region
-   */
-
-} svm_region_t;
-
-typedef struct svm_map_region_args_
-{
-  const char *root_path;	/* NULL means use the truly global arena */
-  const char *name;
-  u64 baseva;
-  u64 size;
-  u64 pvt_heap_size;
-  uword flags;
-  char *backing_file;
-  uword backing_mmap_size;
-  /* uid, gid to own the svm region(s) */
-  int uid;
-  int gid;
-} svm_map_region_args_t;
-
-
-/*
- * Memory shared across all router instances. Packet buffers, etc
- * Base should be "out of the way," and size should be big enough to
- * cover everything we plan to put here.
- */
-#define SVM_GLOBAL_REGION_BASEVA  0x30000000
-#define SVM_GLOBAL_REGION_SIZE    (64<<20)
-#define SVM_GLOBAL_REGION_NAME "/global_vm"
-
-/*
- * Memory shared across individual router instances.
- */
-#define SVM_OVERLAY_REGION_BASEVA \
-               (SVM_GLOBAL_REGION_BASEVA + SVM_GLOBAL_REGION_SIZE)
-#define SVM_OVERLAY_REGION_SIZE   (1<<20)
-#define SVM_OVERLAY_REGION_BASENAME "/overlay_vm"
-
-typedef struct
-{
-  u8 *subregion_name;
-} svm_subregion_t;
-
-typedef struct
-{
-  svm_subregion_t *subregions;	/* subregion pool */
-  uword *name_hash;
-  u8 *root_path;
-} svm_main_region_t;
-
-
-void *svm_region_find_or_create (svm_map_region_args_t * a);
-void svm_region_init (void);
-void svm_region_init_chroot (const char *root_path);
-void svm_region_init_chroot_uid_gid (const char *root_path, int uid, int gid);
-void svm_region_init_args (svm_map_region_args_t * a);
-void svm_region_exit (void);
-void svm_region_unmap (void *rp_arg);
-void svm_client_scan (const char *root_path);
-void svm_client_scan_this_region_nolock (svm_region_t * rp);
-u8 *shm_name_from_svm_map_region_args (svm_map_region_args_t * a);
-
 static inline void *
 svm_mem_alloc (svm_region_t * rp, uword size)
 {
@@ -192,10 +96,6 @@
   clib_mem_set_heap (oldheap);
 }
 
-u8 *format_svm_region (u8 * s, va_list * args);
-
-svm_region_t *svm_get_root_rp (void);
-
 #endif /* __included_svm_h__ */
 
 /*
diff --git a/src/svm/svm_common.h b/src/svm/svm_common.h
new file mode 100644
index 0000000..1f18443
--- /dev/null
+++ b/src/svm/svm_common.h
@@ -0,0 +1,133 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2009 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __included_svm_common_h__
+#define __included_svm_common_h__
+
+#include <stdarg.h>
+#include <pthread.h>
+#include <vppinfra/types.h>
+
+#define SVM_VERSION ((1<<16) | 1)	/* set to declare region ready. */
+
+#define SVM_FLAGS_MHEAP (1<<0)	/* region contains an mheap */
+#define SVM_FLAGS_FILE  (1<<1)	/* region backed by one or more files */
+#define SVM_FLAGS_NODATA (1<<2)	/* region will be further subdivided */
+#define SVM_FLAGS_NEED_DATA_INIT (1<<3)
+
+#define SVM_PVT_MHEAP_SIZE (128<<10)	/* region's private mheap (128k) */
+
+typedef struct svm_region_
+{
+  volatile uword version;
+  pthread_mutex_t mutex;
+  pthread_cond_t condvar;
+  int mutex_owner_pid;		/* in case of trouble */
+  int mutex_owner_tag;
+  uword flags;
+  uword virtual_base;		/* base of the region object */
+  uword virtual_size;
+  void *region_heap;
+  void *data_base;		/* data portion base address */
+  void *data_heap;		/* data heap, if any */
+  volatile void *user_ctx;	/* user context pointer */
+  /* stuff allocated in the region's heap */
+  uword bitmap_size;		/* nbits in virtual alloc bitmap */
+  uword *bitmap;		/* the bitmap */
+  char *region_name;
+  char *backing_file;
+  char **filenames;
+  uword *client_pids;
+  /* pad */
+
+  /* next page:
+   * (64K) clib heap for the region itself
+   *
+   * data_base -> whatever is in this region
+   */
+
+} svm_region_t;
+
+typedef struct svm_map_region_args_
+{
+  const char *root_path;	/* NULL means use the truly global arena */
+  const char *name;
+  u64 baseva;
+  u64 size;
+  u64 pvt_heap_size;
+  uword flags;
+  char *backing_file;
+  uword backing_mmap_size;
+  /* uid, gid to own the svm region(s) */
+  int uid;
+  int gid;
+} svm_map_region_args_t;
+
+
+/*
+ * Memory shared across all router instances. Packet buffers, etc
+ * Base should be "out of the way," and size should be big enough to
+ * cover everything we plan to put here.
+ */
+#define SVM_GLOBAL_REGION_BASEVA  0x30000000
+#define SVM_GLOBAL_REGION_SIZE    (64<<20)
+#define SVM_GLOBAL_REGION_NAME "/global_vm"
+
+/*
+ * Memory shared across individual router instances.
+ */
+#define SVM_OVERLAY_REGION_BASEVA \
+               (SVM_GLOBAL_REGION_BASEVA + SVM_GLOBAL_REGION_SIZE)
+#define SVM_OVERLAY_REGION_SIZE   (1<<20)
+#define SVM_OVERLAY_REGION_BASENAME "/overlay_vm"
+
+typedef struct
+{
+  u8 *subregion_name;
+} svm_subregion_t;
+
+typedef struct
+{
+  svm_subregion_t *subregions;	/* subregion pool */
+  uword *name_hash;
+  u8 *root_path;
+} svm_main_region_t;
+
+
+void *svm_region_find_or_create (svm_map_region_args_t * a);
+void svm_region_init (void);
+void svm_region_init_chroot (const char *root_path);
+void svm_region_init_chroot_uid_gid (const char *root_path, int uid, int gid);
+void svm_region_init_args (svm_map_region_args_t * a);
+void svm_region_exit (void);
+void svm_region_unmap (void *rp_arg);
+void svm_client_scan (const char *root_path);
+void svm_client_scan_this_region_nolock (svm_region_t * rp);
+u8 *shm_name_from_svm_map_region_args (svm_map_region_args_t * a);
+u8 *format_svm_region (u8 * s, va_list * args);
+
+svm_region_t *svm_get_root_rp (void);
+
+#endif /* __included_svm_common_h__ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vlib-api.am b/src/vlib-api.am
index eea5242..677811b 100644
--- a/src/vlib-api.am
+++ b/src/vlib-api.am
@@ -30,7 +30,10 @@
 	vlibmemory/vl_memory_api_h.h		\
 	vlibmemory/vl_memory_msg_enum.h
 
-nobase_include_HEADERS += vlibapi/api.h vlibapi/api_helper_macros.h vlibapi/vat_helper_macros.h
+nobase_include_HEADERS += vlibapi/api.h		\
+	vlibapi/api_common.h			\
+	vlibapi/api_helper_macros.h		\
+	vlibapi/vat_helper_macros.h
 
 libvlibmemoryclient_la_DEPENDENCIES = libvppinfra.la libsvm.la
 libvlibmemoryclient_la_LIBADD = $(libvlibmemoryclient_la_DEPENDENCIES) -lpthread
@@ -49,6 +52,7 @@
 
 nobase_include_HEADERS +=			\
 	vlibmemory/api.h			\
+	vlibmemory/api_common.h			\
 	vlibmemory/vl_memory_api_h.h		\
 	vlibmemory/vl_memory_msg_enum.h		\
 	vlibmemory/unix_shared_memory_queue.h 	\
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index 0e2c210..49f5d5f 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -20,73 +20,13 @@
 #ifndef included_api_h
 #define included_api_h
 
+#include <stddef.h>
 #include <vppinfra/error.h>
 #include <svm/svm.h>
 #include <vlib/vlib.h>
 #include <vlibmemory/unix_shared_memory_queue.h>
 #include <vlib/unix/unix.h>
-#include <stddef.h>
-
-typedef enum
-{
-  REGISTRATION_TYPE_FREE = 0,
-  REGISTRATION_TYPE_SHMEM,
-  REGISTRATION_TYPE_SOCKET_LISTEN,
-  REGISTRATION_TYPE_SOCKET_SERVER,
-  REGISTRATION_TYPE_SOCKET_CLIENT,
-} vl_registration_type_t;
-
-typedef struct vl_api_registration_
-{
-  vl_registration_type_t registration_type;
-
-  /* Index in VLIB's brain (not shared memory). */
-  u32 vl_api_registration_pool_index;
-
-  u8 *name;
-
-  /*
-   * The following groups of data could be unioned, but my fingers are
-   * going to be sore enough.
-   */
-
-  /* shared memory only */
-  unix_shared_memory_queue_t *vl_input_queue;
-
-  /* socket server and client */
-  u32 unix_file_index;
-  i8 *unprocessed_input;
-  u32 unprocessed_msg_length;
-  u8 *output_vector;
-
-  /* socket client only */
-  u32 server_handle;
-  u32 server_index;
-
-} vl_api_registration_t;
-
-
-/* Trace configuration for a single message */
-typedef struct
-{
-  int size;
-  int trace_enable;
-  int replay_enable;
-} trace_cfg_t;
-
-/*
- * API recording
- */
-typedef struct
-{
-  u8 endian;
-  u8 enabled;
-  u8 wrapped;
-  u8 pad;
-  u32 nitems;
-  u32 curindex;
-  u8 **traces;
-} vl_api_trace_t;
+#include <vlibapi/api_common.h>
 
 /* *INDENT-OFF* */
 typedef CLIB_PACKED
@@ -97,200 +37,8 @@
 }) vl_api_trace_file_header_t;
 /* *INDENT-ON* */
 
-typedef enum
-{
-  VL_API_TRACE_TX,
-  VL_API_TRACE_RX,
-} vl_api_trace_which_t;
-
-#define VL_API_LITTLE_ENDIAN 0x00
-#define VL_API_BIG_ENDIAN 0x01
-
-typedef struct
-{
-  u8 *name;
-  u16 first_msg_id;
-  u16 last_msg_id;
-} vl_api_msg_range_t;
-
-typedef clib_error_t *(vl_msg_api_init_function_t) (u32 client_index);
-
-typedef struct _vl_msg_api_init_function_list_elt
-{
-  struct _vl_msg_api_init_function_list_elt *next_init_function;
-  vl_msg_api_init_function_t *f;
-} _vl_msg_api_function_list_elt_t;
-
-typedef struct
-{
-  void (**msg_handlers) (void *);
-  int (**pd_msg_handlers) (void *, int);
-  void (**msg_cleanup_handlers) (void *);
-  void (**msg_endian_handlers) (void *);
-  void (**msg_print_handlers) (void *, void *);
-  const char **msg_names;
-  u8 *message_bounce;
-  u8 *is_mp_safe;
-  struct ring_alloc_ *arings;
-  u32 ring_misses;
-  u32 garbage_collects;
-  u32 missing_clients;
-  vl_api_trace_t *rx_trace;
-  vl_api_trace_t *tx_trace;
-  int msg_print_flag;
-  trace_cfg_t *api_trace_cfg;
-  int our_pid;
-  svm_region_t *vlib_rp;
-  svm_region_t **mapped_shmem_regions;
-  struct vl_shmem_hdr_ *shmem_hdr;
-  vl_api_registration_t **vl_clients;
-
-  u8 *serialized_message_table_in_shmem;
-
-  /* For plugin msg allocator */
-  u16 first_available_msg_id;
-
-  /* message range by name hash */
-  uword *msg_range_by_name;
-
-  /* vector of message ranges */
-  vl_api_msg_range_t *msg_ranges;
-
-  /* uid for the api shared memory region */
-  int api_uid;
-  /* gid for the api shared memory region */
-  int api_gid;
-
-  /* base virtual address for global VM region */
-  u64 global_baseva;
-
-  /* size of the global VM region */
-  u64 global_size;
-
-  /* size of the API region */
-  u64 api_size;
-
-  /* size of the global VM private mheap */
-  u64 global_pvt_heap_size;
-
-  /* size of the api private mheap */
-  u64 api_pvt_heap_size;
-
-  /* Client-only data structures */
-  unix_shared_memory_queue_t *vl_input_queue;
-
-  /*
-   * All VLIB-side message handlers use my_client_index to identify
-   * the queue / client. This works in sim replay.
-   */
-  int my_client_index;
-  /*
-   * This is the (shared VM) address of the registration,
-   * don't use it to id the connection since it can't possibly
-   * work in simulator replay.
-   */
-  vl_api_registration_t *my_registration;
-
-  i32 vlib_signal;
-
-  /* vlib input queue length */
-  u32 vlib_input_queue_length;
-
-  /* client side message index hash table */
-  uword *msg_index_by_name_and_crc;
-
-  const char *region_name;
-  const char *root_path;
-
-  /* Replay in progress? */
-  int replay_in_progress;
-
-  /* List of API client reaper functions */
-  _vl_msg_api_function_list_elt_t *reaper_function_registrations;
-
-} api_main_t;
-
-extern api_main_t api_main;
-
-typedef struct
-{
-  int id;
-  char *name;
-  u32 crc;
-  void *handler;
-  void *cleanup;
-  void *endian;
-  void *print;
-  int size;
-  int traced;
-  int replay;
-  int message_bounce;
-  int is_mp_safe;
-} vl_msg_api_msg_config_t;
-
-typedef struct msgbuf_
-{
-  unix_shared_memory_queue_t *q;
-  u32 data_len;
-  u32 gc_mark_timestamp;
-  u8 data[0];
-} msgbuf_t;
-
-/* api_shared.c prototypes */
-int vl_msg_api_rx_trace_enabled (api_main_t * am);
-int vl_msg_api_tx_trace_enabled (api_main_t * am);
-void vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg);
-int vl_msg_api_trace_onoff (api_main_t * am, vl_api_trace_which_t which,
-			    int onoff);
-int vl_msg_api_trace_free (api_main_t * am, vl_api_trace_which_t which);
 int vl_msg_api_trace_save (api_main_t * am,
 			   vl_api_trace_which_t which, FILE * fp);
-int vl_msg_api_trace_configure (api_main_t * am, vl_api_trace_which_t which,
-				u32 nitems);
-void vl_msg_api_handler_with_vm_node (api_main_t * am,
-				      void *the_msg, vlib_main_t * vm,
-				      vlib_node_runtime_t * node);
-void vl_msg_api_handler (void *the_msg);
-void vl_msg_api_handler_no_free (void *the_msg);
-void vl_msg_api_handler_no_trace_no_free (void *the_msg);
-void vl_msg_api_trace_only (void *the_msg);
-void vl_msg_api_cleanup_handler (void *the_msg);
-void vl_msg_api_replay_handler (void *the_msg);
-void vl_msg_api_socket_handler (void *the_msg);
-void vl_msg_api_set_handlers (int msg_id, char *msg_name,
-			      void *handler,
-			      void *cleanup,
-			      void *endian,
-			      void *print, int msg_size, int traced);
-void vl_msg_api_config (vl_msg_api_msg_config_t *);
-void vl_msg_api_set_cleanup_handler (int msg_id, void *fp);
-void vl_msg_api_queue_handler (unix_shared_memory_queue_t * q);
-vl_api_trace_t *vl_msg_api_trace_get (api_main_t * am,
-				      vl_api_trace_which_t which);
-
-void vl_msg_api_barrier_sync (void) __attribute__ ((weak));
-void vl_msg_api_barrier_release (void) __attribute__ ((weak));
-void vl_msg_api_free (void *);
-void vl_noop_handler (void *mp);
-void vl_msg_api_increment_missing_client_counter (void);
-void vl_msg_api_post_mortem_dump (void);
-void vl_msg_api_post_mortem_dump_enable_disable (int enable);
-void vl_msg_api_register_pd_handler (void *handler,
-				     u16 msg_id_host_byte_order);
-int vl_msg_api_pd_handler (void *mp, int rv);
-
-void vl_msg_api_set_first_available_msg_id (u16 first_avail);
-u16 vl_msg_api_get_msg_ids (const char *name, int n);
-void vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string,
-				  u32 id);
-u32 vl_api_get_msg_index (u8 * name_and_crc);
-u32 vl_msg_api_get_msg_length (void *msg_arg);
-
-/* node_serialize.c prototypes */
-u8 *vlib_node_serialize (vlib_node_main_t * nm, u8 * vector,
-			 u32 max_threads, int include_nexts,
-			 int include_stats);
-vlib_node_t **vlib_node_unserialize (u8 * vector);
 
 #define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)
 
@@ -350,8 +98,30 @@
 
   return clib_net_to_host_u32 (header->data_len);
 }
-#endif /* included_api_h */
 
+int vl_msg_api_rx_trace_enabled (api_main_t * am);
+int vl_msg_api_tx_trace_enabled (api_main_t * am);
+void vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg);
+int vl_msg_api_trace_onoff (api_main_t * am, vl_api_trace_which_t which,
+			    int onoff);
+int vl_msg_api_trace_free (api_main_t * am, vl_api_trace_which_t which);
+int vl_msg_api_trace_configure (api_main_t * am, vl_api_trace_which_t which,
+				u32 nitems);
+void vl_msg_api_handler_with_vm_node (api_main_t * am,
+				      void *the_msg, vlib_main_t * vm,
+				      vlib_node_runtime_t * node);
+vl_api_trace_t *vl_msg_api_trace_get (api_main_t * am,
+				      vl_api_trace_which_t which);
+void vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string,
+				  u32 id);
+/* node_serialize.c prototypes */
+u8 *vlib_node_serialize (vlib_node_main_t * nm, u8 * vector,
+			 u32 max_threads, int include_nexts,
+			 int include_stats);
+vlib_node_t **vlib_node_unserialize (u8 * vector);
+u32 vl_msg_api_get_msg_length (void *msg_arg);
+
+#endif /* included_api_h */
 /*
  * fd.io coding-style-patch-verification: ON
  *
diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h
new file mode 100644
index 0000000..b84d269
--- /dev/null
+++ b/src/vlibapi/api_common.h
@@ -0,0 +1,268 @@
+/*
+ *------------------------------------------------------------------
+ * api_common.h
+ *
+ * Copyright (c) 2009-2015 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#ifndef included_api_common_h
+#define included_api_common_h
+
+#include <vppinfra/clib_error.h>
+#include <svm/svm_common.h>
+#include <vlibmemory/unix_shared_memory_queue.h>
+
+typedef enum
+{
+  REGISTRATION_TYPE_FREE = 0,
+  REGISTRATION_TYPE_SHMEM,
+  REGISTRATION_TYPE_SOCKET_LISTEN,
+  REGISTRATION_TYPE_SOCKET_SERVER,
+  REGISTRATION_TYPE_SOCKET_CLIENT,
+} vl_registration_type_t;
+
+typedef struct vl_api_registration_
+{
+  vl_registration_type_t registration_type;
+
+  /* Index in VLIB's brain (not shared memory). */
+  u32 vl_api_registration_pool_index;
+
+  u8 *name;
+
+  /*
+   * The following groups of data could be unioned, but my fingers are
+   * going to be sore enough.
+   */
+
+  /* shared memory only */
+  unix_shared_memory_queue_t *vl_input_queue;
+
+  /* socket server and client */
+  u32 unix_file_index;
+  i8 *unprocessed_input;
+  u32 unprocessed_msg_length;
+  u8 *output_vector;
+
+  /* socket client only */
+  u32 server_handle;
+  u32 server_index;
+
+} vl_api_registration_t;
+
+
+/* Trace configuration for a single message */
+typedef struct
+{
+  int size;
+  int trace_enable;
+  int replay_enable;
+} trace_cfg_t;
+
+/*
+ * API recording
+ */
+typedef struct
+{
+  u8 endian;
+  u8 enabled;
+  u8 wrapped;
+  u8 pad;
+  u32 nitems;
+  u32 curindex;
+  u8 **traces;
+} vl_api_trace_t;
+
+typedef enum
+{
+  VL_API_TRACE_TX,
+  VL_API_TRACE_RX,
+} vl_api_trace_which_t;
+
+#define VL_API_LITTLE_ENDIAN 0x00
+#define VL_API_BIG_ENDIAN 0x01
+
+typedef struct
+{
+  u8 *name;
+  u16 first_msg_id;
+  u16 last_msg_id;
+} vl_api_msg_range_t;
+
+typedef struct
+{
+  int id;
+  char *name;
+  u32 crc;
+  void *handler;
+  void *cleanup;
+  void *endian;
+  void *print;
+  int size;
+  int traced;
+  int replay;
+  int message_bounce;
+  int is_mp_safe;
+} vl_msg_api_msg_config_t;
+
+typedef struct msgbuf_
+{
+  unix_shared_memory_queue_t *q;
+  u32 data_len;
+  u32 gc_mark_timestamp;
+  u8 data[0];
+} msgbuf_t;
+
+/* api_shared.c prototypes */
+void vl_msg_api_handler (void *the_msg);
+void vl_msg_api_handler_no_free (void *the_msg);
+void vl_msg_api_handler_no_trace_no_free (void *the_msg);
+void vl_msg_api_trace_only (void *the_msg);
+void vl_msg_api_cleanup_handler (void *the_msg);
+void vl_msg_api_replay_handler (void *the_msg);
+void vl_msg_api_socket_handler (void *the_msg);
+void vl_msg_api_set_handlers (int msg_id, char *msg_name,
+			      void *handler,
+			      void *cleanup,
+			      void *endian,
+			      void *print, int msg_size, int traced);
+void vl_msg_api_config (vl_msg_api_msg_config_t *);
+void vl_msg_api_set_cleanup_handler (int msg_id, void *fp);
+void vl_msg_api_queue_handler (unix_shared_memory_queue_t * q);
+
+void vl_msg_api_barrier_sync (void) __attribute__ ((weak));
+void vl_msg_api_barrier_release (void) __attribute__ ((weak));
+void vl_msg_api_free (void *);
+void vl_noop_handler (void *mp);
+void vl_msg_api_increment_missing_client_counter (void);
+void vl_msg_api_post_mortem_dump (void);
+void vl_msg_api_post_mortem_dump_enable_disable (int enable);
+void vl_msg_api_register_pd_handler (void *handler,
+				     u16 msg_id_host_byte_order);
+int vl_msg_api_pd_handler (void *mp, int rv);
+
+void vl_msg_api_set_first_available_msg_id (u16 first_avail);
+u16 vl_msg_api_get_msg_ids (const char *name, int n);
+u32 vl_api_get_msg_index (u8 * name_and_crc);
+
+typedef clib_error_t *(vl_msg_api_init_function_t) (u32 client_index);
+
+typedef struct _vl_msg_api_init_function_list_elt
+{
+  struct _vl_msg_api_init_function_list_elt *next_init_function;
+  vl_msg_api_init_function_t *f;
+} _vl_msg_api_function_list_elt_t;
+
+typedef struct
+{
+  void (**msg_handlers) (void *);
+  int (**pd_msg_handlers) (void *, int);
+  void (**msg_cleanup_handlers) (void *);
+  void (**msg_endian_handlers) (void *);
+  void (**msg_print_handlers) (void *, void *);
+  const char **msg_names;
+  u8 *message_bounce;
+  u8 *is_mp_safe;
+  struct ring_alloc_ *arings;
+  u32 ring_misses;
+  u32 garbage_collects;
+  u32 missing_clients;
+  vl_api_trace_t *rx_trace;
+  vl_api_trace_t *tx_trace;
+  int msg_print_flag;
+  trace_cfg_t *api_trace_cfg;
+  int our_pid;
+  svm_region_t *vlib_rp;
+  svm_region_t **mapped_shmem_regions;
+  struct vl_shmem_hdr_ *shmem_hdr;
+  vl_api_registration_t **vl_clients;
+
+  u8 *serialized_message_table_in_shmem;
+
+  /* For plugin msg allocator */
+  u16 first_available_msg_id;
+
+  /* message range by name hash */
+  uword *msg_range_by_name;
+
+  /* vector of message ranges */
+  vl_api_msg_range_t *msg_ranges;
+
+  /* uid for the api shared memory region */
+  int api_uid;
+  /* gid for the api shared memory region */
+  int api_gid;
+
+  /* base virtual address for global VM region */
+  u64 global_baseva;
+
+  /* size of the global VM region */
+  u64 global_size;
+
+  /* size of the API region */
+  u64 api_size;
+
+  /* size of the global VM private mheap */
+  u64 global_pvt_heap_size;
+
+  /* size of the api private mheap */
+  u64 api_pvt_heap_size;
+
+  /* Client-only data structures */
+  unix_shared_memory_queue_t *vl_input_queue;
+
+  /*
+   * All VLIB-side message handlers use my_client_index to identify
+   * the queue / client. This works in sim replay.
+   */
+  int my_client_index;
+  /*
+   * This is the (shared VM) address of the registration,
+   * don't use it to id the connection since it can't possibly
+   * work in simulator replay.
+   */
+  vl_api_registration_t *my_registration;
+
+  i32 vlib_signal;
+
+  /* vlib input queue length */
+  u32 vlib_input_queue_length;
+
+  /* client side message index hash table */
+  uword *msg_index_by_name_and_crc;
+
+  const char *region_name;
+  const char *root_path;
+
+  /* Replay in progress? */
+  int replay_in_progress;
+
+  /* List of API client reaper functions */
+  _vl_msg_api_function_list_elt_t *reaper_function_registrations;
+
+} api_main_t;
+
+extern api_main_t api_main;
+
+
+#endif /* included_api_common_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vlibmemory/api.h b/src/vlibmemory/api.h
index c195e18..2a1438f 100644
--- a/src/vlibmemory/api.h
+++ b/src/vlibmemory/api.h
@@ -20,81 +20,12 @@
 #ifndef included_vlibmemory_api_h
 #define included_vlibmemory_api_h
 
-#include <vppinfra/error.h>
 #include <svm/svm.h>
 #include <vlib/vlib.h>
 #include <vlibmemory/unix_shared_memory_queue.h>
 #include <vlib/unix/unix.h>
 #include <vlibapi/api.h>
-
-/* Allocated in shared memory */
-
-/*
- * Ring-allocation scheme for client API messages
- *
- * Only one proc/thread has control of a given message buffer.
- * To free a buffer allocated from one of these rings, we clear
- * a field in the buffer (header), and leave.
- *
- * No locks, no hits, no errors...
- */
-typedef struct ring_alloc_
-{
-  unix_shared_memory_queue_t *rp;
-  u16 size;
-  u16 nitems;
-  u32 hits;
-  u32 misses;
-} ring_alloc_t;
-
-/*
- * Initializers for the (shared-memory) rings
- * _(size, n). Note: each msg has an 8 byte header.
- * Might want to change that to an index sometime.
- */
-#define foreach_vl_aring_size                   \
-_(64+8, 1024)                                   \
-_(256+8, 128)                                   \
-_(1024+8, 64)
-
-#define foreach_clnt_aring_size                 \
-_(1024+8, 1024)                                 \
-_(2048+8, 128)                                  \
-_(4096+8, 8)
-
-typedef struct vl_shmem_hdr_
-{
-  int version;
-
-  /* getpid () for the VLIB client process */
-  volatile int vl_pid;
-
-  /* Client sends VLIB msgs here. */
-  unix_shared_memory_queue_t *vl_input_queue;
-
-  /* Vector of rings; one for each size. */
-
-  /* VLIB allocates buffers to send msgs to clients here. */
-  ring_alloc_t *vl_rings;
-
-  /* Clients allocate buffer to send msgs to VLIB here. */
-  ring_alloc_t *client_rings;
-
-  /* Number of detected application restarts */
-  u32 application_restarts;
-
-  /* Number of messages reclaimed during application restart */
-  u32 restart_reclaims;
-
-  /* Number of garbage-collected messages */
-  u32 garbage_collects;
-
-} vl_shmem_hdr_t;
-
-#define VL_SHM_VERSION 2
-
-#define VL_API_EPOCH_MASK 0xFF
-#define VL_API_EPOCH_SHIFT 8
+#include <vlibmemory/api_common.h>
 
 static inline u32
 vl_msg_api_handle_get_epoch (u32 index)
@@ -118,43 +49,7 @@
   return handle;
 }
 
-void *vl_msg_api_alloc (int nbytes);
-void *vl_msg_api_alloc_or_null (int nbytes);
-void *vl_msg_api_alloc_as_if_client (int nbytes);
-void *vl_msg_api_alloc_as_if_client_or_null (int nbytes);
-void vl_msg_api_free (void *a);
-int vl_map_shmem (const char *region_name, int is_vlib);
-void vl_register_mapped_shmem_region (svm_region_t * rp);
-void vl_unmap_shmem (void);
-void vl_msg_api_send_shmem (unix_shared_memory_queue_t * q, u8 * elem);
-void vl_msg_api_send_shmem_nolock (unix_shared_memory_queue_t * q, u8 * elem);
-void vl_msg_api_send (vl_api_registration_t * rp, u8 * elem);
-int vl_client_connect (const char *name, int ctx_quota, int input_queue_size);
-void vl_client_disconnect (void);
-unix_shared_memory_queue_t *vl_api_client_index_to_input_queue (u32 index);
-vl_api_registration_t *vl_api_client_index_to_registration (u32 index);
-int vl_client_api_map (const char *region_name);
-void vl_client_api_unmap (void);
-void vl_set_memory_region_name (const char *name);
-void vl_set_memory_root_path (const char *root_path);
-void vl_set_memory_uid (int uid);
-void vl_set_memory_gid (int gid);
-void vl_set_global_memory_baseva (u64 baseva);
-void vl_set_global_memory_size (u64 size);
-void vl_set_api_memory_size (u64 size);
-void vl_set_global_pvt_heap_size (u64 size);
-void vl_set_api_pvt_heap_size (u64 size);
 void vl_enable_disable_memory_api (vlib_main_t * vm, int yesno);
-void vl_client_disconnect_from_vlib (void);
-int vl_client_connect_to_vlib (const char *svm_name,
-			       const char *client_name, int rx_queue_size);
-int vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name,
-					     const char *client_name,
-					     int rx_queue_size);
-u16 vl_client_get_first_plugin_msg_id (const char *plugin_name);
-
-void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
-
 #endif /* included_vlibmemory_api_h */
 
 /*
diff --git a/src/vlibmemory/api_common.h b/src/vlibmemory/api_common.h
new file mode 100644
index 0000000..53909cc
--- /dev/null
+++ b/src/vlibmemory/api_common.h
@@ -0,0 +1,138 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2009 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#ifndef included_vlibmemory_api_common_h
+#define included_vlibmemory_api_common_h
+
+#include <svm/svm_common.h>
+#include <vlibapi/api_common.h>
+#include <vlibmemory/unix_shared_memory_queue.h>
+
+/* Allocated in shared memory */
+
+/*
+ * Ring-allocation scheme for client API messages
+ *
+ * Only one proc/thread has control of a given message buffer.
+ * To free a buffer allocated from one of these rings, we clear
+ * a field in the buffer (header), and leave.
+ *
+ * No locks, no hits, no errors...
+ */
+typedef struct ring_alloc_
+{
+  unix_shared_memory_queue_t *rp;
+  u16 size;
+  u16 nitems;
+  u32 hits;
+  u32 misses;
+} ring_alloc_t;
+
+/*
+ * Initializers for the (shared-memory) rings
+ * _(size, n). Note: each msg has an 8 byte header.
+ * Might want to change that to an index sometime.
+ */
+#define foreach_vl_aring_size                   \
+_(64+8, 1024)                                   \
+_(256+8, 128)                                   \
+_(1024+8, 64)
+
+#define foreach_clnt_aring_size                 \
+_(1024+8, 1024)                                 \
+_(2048+8, 128)                                  \
+_(4096+8, 8)
+
+typedef struct vl_shmem_hdr_
+{
+  int version;
+
+  /* getpid () for the VLIB client process */
+  volatile int vl_pid;
+
+  /* Client sends VLIB msgs here. */
+  unix_shared_memory_queue_t *vl_input_queue;
+
+  /* Vector of rings; one for each size. */
+
+  /* VLIB allocates buffers to send msgs to clients here. */
+  ring_alloc_t *vl_rings;
+
+  /* Clients allocate buffer to send msgs to VLIB here. */
+  ring_alloc_t *client_rings;
+
+  /* Number of detected application restarts */
+  u32 application_restarts;
+
+  /* Number of messages reclaimed during application restart */
+  u32 restart_reclaims;
+
+  /* Number of garbage-collected messages */
+  u32 garbage_collects;
+
+} vl_shmem_hdr_t;
+
+#define VL_SHM_VERSION 2
+
+#define VL_API_EPOCH_MASK 0xFF
+#define VL_API_EPOCH_SHIFT 8
+
+void *vl_msg_api_alloc (int nbytes);
+void *vl_msg_api_alloc_or_null (int nbytes);
+void *vl_msg_api_alloc_as_if_client (int nbytes);
+void *vl_msg_api_alloc_as_if_client_or_null (int nbytes);
+void vl_msg_api_free (void *a);
+int vl_map_shmem (const char *region_name, int is_vlib);
+void vl_register_mapped_shmem_region (svm_region_t * rp);
+void vl_unmap_shmem (void);
+void vl_msg_api_send_shmem (unix_shared_memory_queue_t * q, u8 * elem);
+void vl_msg_api_send_shmem_nolock (unix_shared_memory_queue_t * q, u8 * elem);
+void vl_msg_api_send (vl_api_registration_t * rp, u8 * elem);
+int vl_client_connect (const char *name, int ctx_quota, int input_queue_size);
+void vl_client_disconnect (void);
+unix_shared_memory_queue_t *vl_api_client_index_to_input_queue (u32 index);
+vl_api_registration_t *vl_api_client_index_to_registration (u32 index);
+int vl_client_api_map (const char *region_name);
+void vl_client_api_unmap (void);
+void vl_set_memory_region_name (const char *name);
+void vl_set_memory_root_path (const char *root_path);
+void vl_set_memory_uid (int uid);
+void vl_set_memory_gid (int gid);
+void vl_set_global_memory_baseva (u64 baseva);
+void vl_set_global_memory_size (u64 size);
+void vl_set_api_memory_size (u64 size);
+void vl_set_global_pvt_heap_size (u64 size);
+void vl_set_api_pvt_heap_size (u64 size);
+void vl_client_disconnect_from_vlib (void);
+int vl_client_connect_to_vlib (const char *svm_name, const char *client_name,
+			       int rx_queue_size);
+int vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name,
+					     const char *client_name,
+					     int rx_queue_size);
+u16 vl_client_get_first_plugin_msg_id (const char *plugin_name);
+
+void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
+
+#endif /* included_vlibmemory_api_common_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vppinfra.am b/src/vppinfra.am
index ff2b8ea..785445a 100644
--- a/src/vppinfra.am
+++ b/src/vppinfra.am
@@ -167,6 +167,7 @@
   vppinfra/byte_order.h \
   vppinfra/cache.h \
   vppinfra/clib.h \
+  vppinfra/clib_error.h \
   vppinfra/cpu.h \
   vppinfra/crc32.h \
   vppinfra/dlist.h \
diff --git a/src/vppinfra/clib_error.h b/src/vppinfra/clib_error.h
new file mode 100644
index 0000000..45f18eb
--- /dev/null
+++ b/src/vppinfra/clib_error.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef included_clib_error_h
+#define included_clib_error_h
+
+#include <vppinfra/types.h>
+
+typedef struct
+{
+  /* Error message. */
+  u8 *what;
+
+  /* Where error occurred (e.g. __FUNCTION__ __LINE__) */
+  const u8 *where;
+
+  uword flags;
+
+  /* Error code (e.g. errno for Unix errors). */
+  any code;
+} clib_error_t;
+
+#endif
diff --git a/src/vppinfra/error.h b/src/vppinfra/error.h
index e51f938..e0e2d47 100644
--- a/src/vppinfra/error.h
+++ b/src/vppinfra/error.h
@@ -72,19 +72,7 @@
 #define clib_panic(format,args...) \
   _clib_error (CLIB_ERROR_ABORT, (char *) clib_error_function, __LINE__, format, ## args)
 
-typedef struct
-{
-  /* Error message. */
-  u8 *what;
-
-  /* Where error occurred (e.g. __FUNCTION__ __LINE__) */
-  const u8 *where;
-
-  uword flags;
-
-  /* Error code (e.g. errno for Unix errors). */
-  any code;
-} clib_error_t;
+#include <vppinfra/clib_error.h>
 
 #define clib_error_get_code(err) ((err) ? (err)->code : 0)
 #define clib_error_set_code(err, c)		\