vat: unload unused vat plugins

If the corresponding vpp plugin is absent, return a non-zero
clib_error_t * from vat_plugin_register ("xxx plugin not loaded"). The
vat plugin calls dlclose on the vat plugin, and it disappears.

Depending on the plugin configuration, this can reduce the vpp virtual
size by several gigabytes.

Added a VAT_PLUGIN(<plugin-name>) macro to vat_helper_macros, clean up
boilerplate vat_plugin_register() implementations. Fixed a number of
non-standard vat_plugin_register methods.

Type: refactor

Change-Id: Iac908e5af7d5497c78d6aa9c3c51cdae08374045
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/src/examples/sample-plugin/sample/sample_test.c b/src/examples/sample-plugin/sample/sample_test.c
index 51c2c87..6f645f7 100644
--- a/src/examples/sample-plugin/sample/sample_test.c
+++ b/src/examples/sample-plugin/sample/sample_test.c
@@ -33,19 +33,19 @@
 
 /* define message structures */
 #define vl_typedefs
-#include <sample/sample_all_api_h.h> 
+#include <sample/sample_all_api_h.h>
 #undef vl_typedefs
 
 /* declare message handlers for each api */
 
 #define vl_endianfun             /* define message structures */
-#include <sample/sample_all_api_h.h> 
+#include <sample/sample_all_api_h.h>
 #undef vl_endianfun
 
 /* instantiate all the print functions we know about */
 #define vl_print(handle, ...)
 #define vl_printfun
-#include <sample/sample_all_api_h.h> 
+#include <sample/sample_all_api_h.h>
 #undef vl_printfun
 
 /* Get the API version number. */
@@ -81,7 +81,7 @@
 foreach_standard_reply_retval_handler;
 #undef _
 
-/* 
+/*
  * Table of message reply handlers, must include boilerplate handlers
  * we just generated
  */
@@ -108,12 +108,12 @@
         else
             break;
     }
-    
+
     if (sw_if_index == ~0) {
         errmsg ("missing interface name / explicit sw_if_index number \n");
         return -99;
     }
-    
+
     /* Construct the API message */
     M(SAMPLE_MACSWAP_ENABLE_DISABLE, mp);
     mp->sw_if_index = ntohl (sw_if_index);
@@ -127,7 +127,7 @@
     return ret;
 }
 
-/* 
+/*
  * List of messages that the api test plugin sends,
  * and that the data plane plugin processes
  */
@@ -145,35 +145,19 @@
                            vl_noop_handler,                     \
                            vl_api_##n##_t_endian,               \
                            vl_api_##n##_t_print,                \
-                           sizeof(vl_api_##n##_t), 1); 
+                           sizeof(vl_api_##n##_t), 1);
     foreach_vpe_api_reply_msg;
 #undef _
 
     /* API messages we can send */
 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
     foreach_vpe_api_msg;
-#undef _    
-    
+#undef _
+
     /* Help strings */
 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
     foreach_vpe_api_msg;
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  sample_test_main_t * sm = &sample_test_main;
-  u8 * name;
-
-  sm->vat_main = vam;
-
-  name = format (0, "sample_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~0)
-    sample_api_hookup (vam);
-  
-  vec_free(name);
-  
-  return 0;
-}
+VAT_PLUGIN_REGISTER(sample);
diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c
index 19a6f91..9185cc1 100644
--- a/src/plugins/acl/acl_test.c
+++ b/src/plugins/acl/acl_test.c
@@ -1489,7 +1489,7 @@
 
 
 static
-void acl_vat_api_hookup (vat_main_t *vam)
+void acl_api_hookup (vat_main_t *vam)
 {
     acl_test_main_t * sm = &acl_test_main;
     /* Hook up handlers for replies from the data plane plug-in */
@@ -1515,20 +1515,4 @@
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  acl_test_main_t * sm = &acl_test_main;
-  u8 * name;
-
-  sm->vat_main = vam;
-
-  name = format (0, "acl_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~0)
-    acl_vat_api_hookup (vam);
-
-  vec_free(name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER(acl);
diff --git a/src/plugins/avf/avf_test.c b/src/plugins/avf/avf_test.c
index 368d503..17f4308 100644
--- a/src/plugins/avf/avf_test.c
+++ b/src/plugins/avf/avf_test.c
@@ -202,7 +202,7 @@
 _(avf_delete, "<sw_if_index>")
 
 static void
-avf_vat_api_hookup (vat_main_t * vam)
+avf_api_hookup (vat_main_t * vam)
 {
   avf_test_main_t *avm __attribute__ ((unused)) = &avf_test_main;
 #define _(N,n)                                                  \
@@ -226,24 +226,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  avf_test_main_t *avm = &avf_test_main;
-  u8 *name;
-
-  avm->vat_main = vam;
-
-  name = format (0, "avf_%08x%c", api_version, 0);
-  avm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (avm->msg_id_base != (u16) ~ 0)
-    avf_vat_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (avf);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/cdp/cdp_test.c b/src/plugins/cdp/cdp_test.c
index 33b5449..2e24ddc 100644
--- a/src/plugins/cdp/cdp_test.c
+++ b/src/plugins/cdp/cdp_test.c
@@ -150,25 +150,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  cdp_test_main_t *sm = &cdp_test_main;
-  u8 *name;
-
-  sm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "cdp_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~ 0)
-    cdp_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (cdp);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/ct6/ct6_test.c b/src/plugins/ct6/ct6_test.c
index 507620e..2f985a6 100644
--- a/src/plugins/ct6/ct6_test.c
+++ b/src/plugins/ct6/ct6_test.c
@@ -173,25 +173,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  ct6_test_main_t *ctmp = &ct6_test_main;
-  u8 *name;
-
-  ctmp->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "ct6_%08x%c", api_version, 0);
-  ctmp->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (ctmp->msg_id_base != (u16) ~ 0)
-    ct6_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (ct6);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/dpdk/api/dpdk_test.c b/src/plugins/dpdk/api/dpdk_test.c
index 637b401..4594a9d 100644
--- a/src/plugins/dpdk/api/dpdk_test.c
+++ b/src/plugins/dpdk/api/dpdk_test.c
@@ -77,7 +77,7 @@
 foreach_standard_reply_retval_handler;
 #undef _
 
-/* 
+/*
  * Table of message reply handlers, must include boilerplate handlers
  * we just generated
  */
@@ -336,7 +336,7 @@
   return 0;
 }
 
-/* 
+/*
  * List of messages that the api test plugin sends,
  * and that the data plane plugin processes
  */
@@ -361,36 +361,19 @@
                           vl_noop_handler,                      \
                           vl_api_##n##_t_endian,                \
                           vl_api_##n##_t_print,                 \
-                          sizeof(vl_api_##n##_t), 1); 
+                          sizeof(vl_api_##n##_t), 1);
   foreach_vpe_api_reply_msg;
 #undef _
 
   /* API messages we can send */
 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
   foreach_vpe_api_msg;
-#undef _    
-    
+#undef _
+
   /* Help strings */
 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
   foreach_vpe_api_msg;
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  dpdk_test_main_t * dm = &dpdk_test_main;
-  u8 * name;
-
-  dm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "dpdk_%08x%c", api_version, 0);
-  dm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (dm->msg_id_base != (u16) ~0)
-    dpdk_api_hookup (vam);
-  
-  vec_free(name);
-  
-  return 0;
-}
+VAT_PLUGIN_REGISTER(dpdk);
diff --git a/src/plugins/flowprobe/flowprobe_test.c b/src/plugins/flowprobe/flowprobe_test.c
index 19b7a73..53fdb23 100644
--- a/src/plugins/flowprobe/flowprobe_test.c
+++ b/src/plugins/flowprobe/flowprobe_test.c
@@ -206,7 +206,7 @@
 _(flowprobe_params, "record <[l2] [l3] [l4]> [active <timer> passive <timer>]")
 
 static void
-flowprobe_vat_api_hookup (vat_main_t * vam)
+flowprobe_api_hookup (vat_main_t * vam)
 {
   flowprobe_test_main_t *sm = &flowprobe_test_main;
   /* Hook up handlers for replies from the data plane plug-in */
@@ -232,26 +232,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  flowprobe_test_main_t *sm = &flowprobe_test_main;
-  u8 *name;
-
-  sm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "flowprobe_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  /* Don't attempt to hook up API messages if the data plane plugin is AWOL */
-  if (sm->msg_id_base != (u16) ~ 0)
-    flowprobe_vat_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (flowprobe);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/gtpu/gtpu_test.c b/src/plugins/gtpu/gtpu_test.c
index f9812c6..5e9afa2 100644
--- a/src/plugins/gtpu/gtpu_test.c
+++ b/src/plugins/gtpu/gtpu_test.c
@@ -450,7 +450,7 @@
 _(gtpu_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
 
 static void
-gtpu_vat_api_hookup (vat_main_t *vam)
+gtpu_api_hookup (vat_main_t *vam)
 {
   gtpu_test_main_t * gtm = &gtpu_test_main;
   /* Hook up handlers for replies from the data plane plug-in */
@@ -476,22 +476,4 @@
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  gtpu_test_main_t * gtm = &gtpu_test_main;
-
-  u8 * name;
-
-  gtm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "gtpu_%08x%c", api_version, 0);
-  gtm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (gtm->msg_id_base != (u16) ~0)
-    gtpu_vat_api_hookup (vam);
-
-  vec_free(name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER(gtpu);
diff --git a/src/plugins/http_static/http_static_test.c b/src/plugins/http_static/http_static_test.c
index 0720463..545980b 100644
--- a/src/plugins/http_static/http_static_test.c
+++ b/src/plugins/http_static/http_static_test.c
@@ -208,25 +208,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  http_static_test_main_t *htmp = &http_static_test_main;
-  u8 *name;
-
-  htmp->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "http_static_%08x%c", api_version, 0);
-  htmp->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (htmp->msg_id_base != (u16) ~ 0)
-    http_static_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (http_static);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/ikev2/ikev2_test.c b/src/plugins/ikev2/ikev2_test.c
index 68c5068..57724b8 100644
--- a/src/plugins/ikev2/ikev2_test.c
+++ b/src/plugins/ikev2/ikev2_test.c
@@ -807,7 +807,7 @@
 _(ikev2_initiate_rekey_child_sa, "<ispi>")
 
 static void
-ikev2_vat_api_hookup (vat_main_t * vam)
+ikev2_api_hookup (vat_main_t * vam)
 {
   ikev2_test_main_t *sm = &ikev2_test_main;
   /* Hook up handlers for replies from the data plane plug-in */
@@ -833,24 +833,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  ikev2_test_main_t *sm = &ikev2_test_main;
-  u8 *name;
-
-  sm->vat_main = vam;
-
-  name = format (0, "ikev2_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~ 0)
-    ikev2_vat_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (ikev2);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/ioam/lib-pot/pot_test.c b/src/plugins/ioam/lib-pot/pot_test.c
index e02640b..d0cf49e 100644
--- a/src/plugins/ioam/lib-pot/pot_test.c
+++ b/src/plugins/ioam/lib-pot/pot_test.c
@@ -111,7 +111,7 @@
 foreach_custom_reply_retval_handler;
 #undef _
 
-/* 
+/*
  * Table of message reply handlers, must include boilerplate handlers
  * we just generated
  */
@@ -167,7 +167,7 @@
         rv = -99;
         goto OUT;
       }
-    
+
     M2(POT_PROFILE_ADD, mp, vec_len(name));
 
     mp->list_name_len = vec_len(name);
@@ -187,11 +187,11 @@
       }
     mp->id = id;
     mp->max_bits = bits;
-      
+
     S(mp);
     W (ret);
     return ret;
-  
+
 OUT:
     vec_free(name);
     return(rv);
@@ -206,7 +206,7 @@
     u8 id = 0;
     int rv = 0;
     int ret;
-    
+
     while (unformat_check_input(input) != UNFORMAT_END_OF_INPUT)
       {
         if (unformat(input, "name %s", &name))
@@ -223,17 +223,17 @@
         rv = -99;
         goto OUT;
       }
-    
+
     M2(POT_PROFILE_ACTIVATE, mp, vec_len(name));
 
     mp->list_name_len = vec_len(name);
     clib_memcpy(mp->list_name, name, mp->list_name_len);
     mp->id = id;
-      
+
     S(mp);
     W (ret);
     return ret;
-  
+
 OUT:
     vec_free(name);
     return(rv);
@@ -244,7 +244,7 @@
 {
     vl_api_pot_profile_del_t *mp;
     int ret;
-   
+
     M(POT_PROFILE_DEL, mp);
     mp->list_name_len = 0;
     S(mp);
@@ -274,7 +274,7 @@
     return ret;
 }
 
-/* 
+/*
  * List of messages that the api test plugin sends,
  * and that the data plane plugin processes
  */
@@ -287,7 +287,7 @@
 _(pot_profile_del, "[id <nn>]")                                         \
 _(pot_profile_show_config_dump, "id [0-1]")
 
-static void 
+static void
 pot_vat_api_hookup (vat_main_t *vam)
 {
     pot_test_main_t * sm = &pot_test_main;
@@ -299,21 +299,22 @@
                            vl_noop_handler,                     \
                            vl_api_##n##_t_endian,               \
                            vl_api_##n##_t_print,                \
-                           sizeof(vl_api_##n##_t), 1); 
+                           sizeof(vl_api_##n##_t), 1);
     foreach_vpe_api_reply_msg;
 #undef _
 
     /* API messages we can send */
 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
     foreach_vpe_api_msg;
-#undef _    
-    
+#undef _
+
     /* Help strings */
 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
     foreach_vpe_api_msg;
 #undef _
 }
 
+
 clib_error_t *
 pot_vat_plugin_register (vat_main_t *vam)
 {
@@ -324,11 +325,12 @@
 
   name = format (0, "ioam_pot_%08x%c", api_version, 0);
   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free(name);
 
   if (sm->msg_id_base != (u16) ~0)
     pot_vat_api_hookup (vam);
-  
-  vec_free(name);
-  
+  else
+    return clib_error_return (0, "ioam_pot plugin not loaded...");
+
   return 0;
 }
diff --git a/src/plugins/lacp/lacp_test.c b/src/plugins/lacp/lacp_test.c
index 0a8631d..4e28a6d 100644
--- a/src/plugins/lacp/lacp_test.c
+++ b/src/plugins/lacp/lacp_test.c
@@ -206,6 +206,10 @@
   /* Ask the vpp engine for the first assigned message-id */
   name = format (0, "lacp_%08x%c", api_version, 0);
   lm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free (name);
+
+  if (lm->msg_id_base == (u16) ~ 0)
+    return clib_error_return (0, "lacp plugin not loaded...");
 
   /* Get the control ping ID */
 #define _(id,n,crc) \
@@ -217,8 +221,6 @@
   if (lm->msg_id_base != (u16) ~ 0)
     lacp_vat_api_hookup (vam);
 
-  vec_free (name);
-
   return 0;
 }
 
diff --git a/src/plugins/lb/lb_test.c b/src/plugins/lb/lb_test.c
index 00ad673..4ac306b 100644
--- a/src/plugins/lb/lb_test.c
+++ b/src/plugins/lb/lb_test.c
@@ -349,8 +349,8 @@
 _(lb_add_del_as, "<vip-prefix> [protocol (tcp|udp) port <n>] "  \
                  "[<address>] [del] [flush]")
 
-static void 
-lb_vat_api_hookup (vat_main_t *vam)
+static void
+lb_api_hookup (vat_main_t *vam)
 {
   lb_test_main_t * lbtm = &lb_test_main;
   /* Hook up handlers for replies from the data plane plug-in */
@@ -376,22 +376,4 @@
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  lb_test_main_t * lbtm = &lb_test_main;
-
-  u8 * name;
-
-  lbtm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "lb_%08x%c", api_version, 0);
-  lbtm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (lbtm->msg_id_base != (u16) ~0)
-    lb_vat_api_hookup (vam);
-
-  vec_free(name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER(lb);
diff --git a/src/plugins/mactime/mactime_test.c b/src/plugins/mactime/mactime_test.c
index 4557e57..c9c1a47 100644
--- a/src/plugins/mactime/mactime_test.c
+++ b/src/plugins/mactime/mactime_test.c
@@ -300,25 +300,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  mactime_test_main_t *sm = &mactime_test_main;
-  u8 *name;
-
-  sm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "mactime_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~ 0)
-    mactime_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (mactime);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/memif/memif_test.c b/src/plugins/memif/memif_test.c
index 510462e..e26094b 100644
--- a/src/plugins/memif/memif_test.c
+++ b/src/plugins/memif/memif_test.c
@@ -482,6 +482,10 @@
   /* Ask the vpp engine for the first assigned message-id */
   name = format (0, "memif_%08x%c", api_version, 0);
   mm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free (name);
+
+  if (mm->msg_id_base == (u16) ~ 0)
+    return clib_error_return (0, "memif plugin not loaded...");
 
   /* Get the control ping ID */
 #define _(id,n,crc) \
@@ -493,8 +497,6 @@
   if (mm->msg_id_base != (u16) ~ 0)
     memif_vat_api_hookup (vam);
 
-  vec_free (name);
-
   return 0;
 }
 
diff --git a/src/plugins/nat/nat_test.c b/src/plugins/nat/nat_test.c
index 0371ec4..1dd25b3 100644
--- a/src/plugins/nat/nat_test.c
+++ b/src/plugins/nat/nat_test.c
@@ -1171,11 +1171,12 @@
   /* Ask the vpp engine for the first assigned message-id */
   name = format (0, "nat_%08x%c", api_version, 0);
   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free(name);
 
   if (sm->msg_id_base != (u16) ~0)
     snat_vat_api_hookup (vam);
-
-  vec_free(name);
+  else
+    return clib_error_return (0, "nat plugin not loaded...");
 
   return 0;
 }
diff --git a/src/plugins/nsh/nsh_test.c b/src/plugins/nsh/nsh_test.c
index 0852956..091ad97 100644
--- a/src/plugins/nsh/nsh_test.c
+++ b/src/plugins/nsh/nsh_test.c
@@ -402,11 +402,12 @@
   /* Ask the vpp engine for the first assigned message-id */
   name = format (0, "nsh_%08x%c", api_version, 0);
   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free(name);
 
   if (sm->msg_id_base != (u16) ~0)
     nsh_vat_api_hookup (vam);
-
-  vec_free(name);
+  else
+    return clib_error_return (0, "nsh plugin not loaded...");
 
   return 0;
 }
diff --git a/src/plugins/nsim/nsim_test.c b/src/plugins/nsim/nsim_test.c
index e3c95c7..3e38bd0 100644
--- a/src/plugins/nsim/nsim_test.c
+++ b/src/plugins/nsim/nsim_test.c
@@ -306,25 +306,7 @@
 #undef _
 }
 
-clib_error_t *
-vat_plugin_register (vat_main_t * vam)
-{
-  nsim_test_main_t *sm = &nsim_test_main;
-  u8 *name;
-
-  sm->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "nsim_%08x%c", api_version, 0);
-  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (sm->msg_id_base != (u16) ~ 0)
-    nsim_api_hookup (vam);
-
-  vec_free (name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER (nsim);
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/pppoe/pppoe_test.c b/src/plugins/pppoe/pppoe_test.c
index 0d085ed..d8ad19d 100644
--- a/src/plugins/pppoe/pppoe_test.c
+++ b/src/plugins/pppoe/pppoe_test.c
@@ -283,7 +283,7 @@
 _(pppoe_session_dump, "[<intfc> | sw_if_index <nn>]")                    \
 
 static void
-pppoe_vat_api_hookup (vat_main_t *vam)
+pppoe_api_hookup (vat_main_t *vam)
 {
   pppoe_test_main_t * pem = &pppoe_test_main;
   /* Hook up handlers for replies from the data plane plug-in */
@@ -309,22 +309,4 @@
 #undef _
 }
 
-clib_error_t * vat_plugin_register (vat_main_t *vam)
-{
-  pppoe_test_main_t * pem = &pppoe_test_main;
-
-  u8 * name;
-
-  pem->vat_main = vam;
-
-  /* Ask the vpp engine for the first assigned message-id */
-  name = format (0, "pppoe_%08x%c", api_version, 0);
-  pem->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
-
-  if (pem->msg_id_base != (u16) ~0)
-    pppoe_vat_api_hookup (vam);
-
-  vec_free(name);
-
-  return 0;
-}
+VAT_PLUGIN_REGISTER(pppoe);
diff --git a/src/plugins/stn/stn_test.c b/src/plugins/stn/stn_test.c
index 8fdbeb9..40ebd77 100644
--- a/src/plugins/stn/stn_test.c
+++ b/src/plugins/stn/stn_test.c
@@ -154,6 +154,10 @@
 
   name = format (0, "stn_%08x%c", api_version, 0);
   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free (name);
+
+  if (sm->msg_id_base == (u16) ~ 0)
+    return clib_error_return (0, "stn plugin not loaded...");
 
   /* Get the control ping ID */
 #define _(id,n,crc) \
@@ -165,8 +169,6 @@
   if (sm->msg_id_base != (u16) ~ 0)
     stn_vat_api_hookup (vam);
 
-  vec_free (name);
-
   return 0;
 }
 
diff --git a/src/plugins/vmxnet3/vmxnet3_test.c b/src/plugins/vmxnet3/vmxnet3_test.c
index d32bcee..7a70f61 100644
--- a/src/plugins/vmxnet3/vmxnet3_test.c
+++ b/src/plugins/vmxnet3/vmxnet3_test.c
@@ -330,6 +330,10 @@
 
   name = format (0, "vmxnet3_%08x%c", api_version, 0);
   vxm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
+  vec_free (name);
+
+  if (vxm->msg_id_base == (u16) ~ 0)
+    return clib_error_return (0, "vmxnet3 plugin not loaded...");
 
   /* Get the control ping ID */
 #define _(id,n,crc) \
@@ -338,10 +342,7 @@
 #undef _
   vxm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
 
-  if (vxm->msg_id_base != (u16) ~ 0)
-    vmxnet3_vat_api_hookup (vam);
-
-  vec_free (name);
+  vmxnet3_vat_api_hookup (vam);
 
   return 0;
 }
diff --git a/src/vlibapi/vat_helper_macros.h b/src/vlibapi/vat_helper_macros.h
index 5bc6772..0abfa73 100644
--- a/src/vlibapi/vat_helper_macros.h
+++ b/src/vlibapi/vat_helper_macros.h
@@ -109,5 +109,26 @@
     }                                                           \
 } while(0);
 
+#define VAT_PLUGIN_REGISTER(plug)                               \
+clib_error_t * vat_plugin_register (vat_main_t *vam)            \
+{                                                               \
+  plug##_test_main_t * mp = &plug##_test_main;                  \
+  u8 * name;                                                    \
+                                                                \
+  mp->vat_main = vam;                                           \
+                                                                \
+  /* Ask the vpp engine for the first assigned message-id */    \
+  name = format (0, #plug "_%08x%c", api_version, 0);           \
+  mp->msg_id_base =                                             \
+      vl_client_get_first_plugin_msg_id ((char *) name);        \
+  vec_free(name);                                               \
+                                                                \
+  if (mp->msg_id_base != (u16) ~0)                              \
+    plug##_api_hookup (vam);                                    \
+  else                                                          \
+    return clib_error_return (0, #plug " plugin not loaded...");\
+  return 0;                                                     \
+}
+
 
 #endif /* __vat_helper_macros_h__ */