Plugin infrastructure improvements

This patch replaces requirement for vlib_plugin_register function
in the plugin so file and introduces new macro:

VLIB_PLUGIN_REGISTER () = {
  .version = "version string",
  .version_required = "requred version",
  .default_disabled = 1,
  .early_init = "early_init_function_name",
};

Plugin will nor be loaded if .default_disabled is set to 1
unless explicitely enabled in startup.conf.

If .verstion_required is set, plugin will not be loaded if there
is version mismatch between plugin and vpp. This can be bypassed
by setting "skip-version-check" for specific plugin.

If .early-init string is present, plugin loader will try to resolve
this specific symbol in the plugin namespace and make a function call.

Following startup.conf configuration is added:

plugins {
  path /path/to/plugin/directory
  plugin ila_plugin.so { enable skip-version-check }
  plugin acl_plugin.so { disable }
}

Change-Id: I706c691dd34d94ffe9e02b59831af8859a95f061
Signed-off-by: Damjan Marion <damarion@cisco.com>
This commit is contained in:
Damjan Marion
2017-01-23 21:13:45 +01:00
committed by Dave Wallace
parent 2ae991e27a
commit 3b46cba8f4
16 changed files with 367 additions and 210 deletions

View File

@@ -22,6 +22,7 @@
#include <vnet/l2/l2_classify.h>
#include <vnet/classify/input_acl.h>
#include <vpp/app/version.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
@@ -128,29 +129,11 @@ _(MACIP_ACL_INTERFACE_ADD_DEL, macip_acl_interface_add_del) \
_(MACIP_ACL_DUMP, macip_acl_dump) \
_(MACIP_ACL_INTERFACE_GET, macip_acl_interface_get)
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
acl_main_t *am = &acl_main;
clib_error_t *error = 0;
am->vlib_main = vm;
am->vnet_main = h->vnet_main;
am->ethernet_main = h->ethernet_main;
l2sess_vlib_plugin_register(vm, h, from_early_init);
return error;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
static void
vl_api_acl_plugin_get_version_t_handler (vl_api_acl_plugin_get_version_t * mp)

View File

@@ -17,7 +17,6 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/l2/l2_output.h>
@@ -139,7 +138,6 @@ typedef struct {
/* convenience */
vlib_main_t * vlib_main;
vnet_main_t * vnet_main;
ethernet_main_t * ethernet_main;
} acl_main_t;
extern acl_main_t acl_main;

View File

@@ -30,19 +30,6 @@
#include <vnet/l2/l2_output.h>
#include <vnet/l2/l2_input.h>
void
l2sess_vlib_plugin_register (vlib_main_t * vm, void* hh,
int from_early_init)
{
l2sess_main_t *sm = &l2sess_main;
vnet_plugin_handoff_t * h = hh;
memset (sm, 0, sizeof (*sm));
sm->vlib_main = vm;
sm->vnet_main = h->vnet_main;
sm->ethernet_main = h->ethernet_main;
}
void
l2sess_init_next_features_input (vlib_main_t * vm, l2sess_main_t * sm)
{

View File

@@ -132,7 +132,6 @@ foreach_l2sess_node
/* convenience */
vlib_main_t * vlib_main;
vnet_main_t * vnet_main;
ethernet_main_t * ethernet_main;
/* Counter(s) */
u64 counter_attempted_delete_free_session;

View File

@@ -24,6 +24,7 @@
*/
#include <vnet/vnet.h>
#include <vpp/app/version.h>
#include <vnet/plugin/plugin.h>
#include <flowperpkt/flowperpkt.h>
@@ -479,30 +480,11 @@ static void *vl_api_flowperpkt_tx_interface_add_del_t_print
#define foreach_flowperpkt_plugin_api_msg \
_(FLOWPERPKT_TX_INTERFACE_ADD_DEL, flowperpkt_tx_interface_add_del)
/**
* @brief plugin-api required function
* @param vm vlib_main_t * vlib main data structure pointer
* @param h vlib_plugin_handoff_t * handoff structure
* @param from_early_init int notused
*
* <em>Notes:</em>
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
flowperpkt_main_t *fm = &flowperpkt_main;
clib_error_t *error = 0;
fm->vlib_main = vm;
fm->vnet_main = h->vnet_main;
return error;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
static clib_error_t *
flowperpkt_tx_interface_add_del_feature_command_fn (vlib_main_t * vm,
@@ -627,6 +609,8 @@ flowperpkt_init (vlib_main_t * vm)
u32 num_threads;
u8 *name;
fm->vnet_main = vnet_get_main ();
/* Construct the API name */
name = format (0, "flowperpkt_%08x%c", api_version, 0);

View File

@@ -18,6 +18,7 @@
#include <vnet/ip/lookup.h>
#include <vnet/dpo/dpo.h>
#include <vnet/fib/fib_table.h>
#include <vpp/app/version.h>
static ila_main_t ila_main;
@@ -821,14 +822,11 @@ ila_interface (u32 sw_if_index, u8 disable)
return 0;
}
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
clib_error_t *error = 0;
return error;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
u8 *format_ila_dpo (u8 * s, va_list * va)
{

View File

@@ -16,6 +16,7 @@
#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vppinfra/error.h>
#include <vpp/app/version.h>
#include <vnet/ip/ip6.h>
#include <vnet/ip/ip6_hop_by_hop.h>
@@ -349,18 +350,11 @@ VLIB_CLI_COMMAND (ip6_show_ioam_trace_cmd, static) = {
};
/* *INDENT-ON* */
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
return 0;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
static clib_error_t *
ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm)

View File

@@ -15,6 +15,7 @@
#include <lb/lb.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <vnet/api_errno.h>
//GC runs at most once every so many seconds
@@ -730,15 +731,11 @@ int lb_vip_del(u32 vip_index)
return 0;
}
clib_error_t *
vlib_plugin_register (vlib_main_t * vm,
vnet_plugin_handoff_t * h,
int from_early_init)
{
clib_error_t *error = 0;
return error;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
u8 *format_lb_dpo (u8 * s, va_list * va)
{

View File

@@ -19,6 +19,7 @@
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip6_fib.h>
#include <vnet/adj/adj.h>
#include <vpp/app/version.h>
/*
* This code supports the following sixrd modes:
@@ -340,27 +341,19 @@ VLIB_CLI_COMMAND(show_sixrd_stats_command, static) = {
.function = show_sixrd_stats_command_fn,
};
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
static clib_error_t * sixrd_init (vlib_main_t * vm)
{
clib_error_t * error = 0;
sixrd_main_t *mm = &sixrd_main;
mm->vnet_main = vnet_get_main();
mm->vlib_main = vm;
return error;
}
static clib_error_t * sixrd_init (vlib_main_t * vm)
{
sixrd_dpo_module_init ();
return (NULL);

View File

@@ -28,6 +28,7 @@
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vlibsocket/api.h>
#include <vpp/app/version.h>
snat_main_t snat_main;
@@ -129,27 +130,11 @@ VNET_FEATURE_INIT (ip4_snat_out2in_fast, static) = {
.runs_before = VNET_FEATURES ("ip4-lookup"),
};
/*
* This routine exists to convince the vlib plugin framework that
* we haven't accidentally copied a random .dll into the plugin directory.
*
* Also collects global variable pointers passed from the vpp engine
*/
clib_error_t *
vlib_plugin_register (vlib_main_t * vm, vnet_plugin_handoff_t * h,
int from_early_init)
{
snat_main_t * sm = &snat_main;
clib_error_t * error = 0;
sm->vlib_main = vm;
sm->vnet_main = h->vnet_main;
sm->ethernet_main = h->ethernet_main;
return error;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
};
/* *INDENT-ON* */
/*$$$$$ move to an installed header file */
#if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */

View File

@@ -233,7 +233,6 @@ typedef struct {
vnet_main_t * vnet_main;
ip4_main_t * ip4_main;
ip_lookup_main_t * ip4_lookup_main;
ethernet_main_t * ethernet_main;
api_main_t * api_main;
} snat_main_t;

View File

@@ -503,6 +503,14 @@ vlib_unix_main (int argc, char *argv[])
vm->heap_base = clib_mem_get_heap ();
ASSERT (vm->heap_base);
unformat_init_command_line (&input, (char **) vm->argv);
if ((e = vlib_plugin_config (vm, &input)))
{
clib_error_report (e);
return 1;
}
unformat_free (&input);
i = vlib_plugin_early_init (vm);
if (i)
return i;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,14 @@
* vlib_load_new_plugins().
*/
/* *INDENT-OFF* */
typedef CLIB_PACKED(struct {
u8 default_disabled;
const char version[32];
const char version_required[32];
const char *early_init;
}) vlib_plugin_registration_t;
/* *INDENT-ON* */
typedef struct
{
@@ -64,8 +71,20 @@ typedef struct
u8 *filename;
struct stat file_info;
void *handle;
/* plugin registration */
vlib_plugin_registration_t *reg;
char *version;
} plugin_info_t;
typedef struct
{
char *name;
u8 is_disabled;
u8 is_enabled;
u8 skip_version_check;
} plugin_config_t;
typedef struct
{
/* loaded plugin info */
@@ -76,8 +95,9 @@ typedef struct
u8 *plugin_path;
u8 *plugin_name_filter;
/* handoff structure get callback */
void *handoff_structure_get_cb;
/* plugin configs and hash by name */
plugin_config_t *configs;
uword *config_index_by_name;
/* usual */
vlib_main_t *vlib_main;
@@ -85,10 +105,15 @@ typedef struct
extern plugin_main_t vlib_plugin_main;
clib_error_t *vlib_plugin_config (vlib_main_t * vm, unformat_input_t * input);
int vlib_plugin_early_init (vlib_main_t * vm);
int vlib_load_new_plugins (plugin_main_t * pm, int from_early_init);
void *vlib_get_plugin_symbol (char *plugin_name, char *symbol_name);
#define VLIB_PLUGIN_REGISTER() \
vlib_plugin_registration_t vlib_plugin_registration \
__attribute__((__section__(".vlib_plugin_registration")))
#endif /* __included_plugin_h__ */
/*

View File

@@ -20,13 +20,6 @@
#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vppinfra/error.h>
/* Pointers to Genuine Vnet data structures handed to plugin .dll's */
typedef struct {
vnet_main_t * vnet_main;
ethernet_main_t * ethernet_main;
} vnet_plugin_handoff_t;
void * vnet_get_handoff_structure (void);
#include <vlib/unix/plugin.h>
#endif /* included_vnet_plugin_h */

View File

@@ -18,7 +18,7 @@
#include <vlib/unix/unix.h>
#include <vnet/plugin/plugin.h>
#include <vnet/ethernet/ethernet.h>
#include <vpp/app/version.h>
#include <vpp/api/vpe_msg_enum.h>
@@ -39,16 +39,7 @@ vpe_main_init (vlib_main_t * vm)
* Load plugins from /usr/lib/vpp_plugins by default
*/
char *vlib_plugin_path = "/usr/lib/vpp_plugins";
void *
vnet_get_handoff_structure (void)
{
static vnet_plugin_handoff_t _rv, *rv = &_rv;
rv->vnet_main = vnet_get_main ();
rv->ethernet_main = &ethernet_main;
return (void *) rv;
}
char *vlib_plugin_app_version = VPP_BUILD_VER;
int
main (int argc, char *argv[])
@@ -59,7 +50,6 @@ main (int argc, char *argv[])
uword main_heap_size = (1ULL << 30);
u8 *sizep;
u32 size;
void vlib_set_get_handoff_structure_cb (void *cb);
#if __x86_64__
CLIB_UNUSED (const char *msg)
@@ -206,7 +196,6 @@ defaulted:
#if DPDK == 0
unix_physmem_init (vm, 0 /* fail_if_physical_memory_not_present */ );
#endif
vlib_set_get_handoff_structure_cb (&vnet_get_handoff_structure);
return vlib_unix_main (argc, argv);
}
else