25 #define PLUGIN_LOG_DBG(...) \ 26 do {vlib_log_debug (vlib_plugin_main.logger, __VA_ARGS__);} while(0) 27 #define PLUGIN_LOG_ERR(...) \ 28 do {vlib_log_err (vlib_plugin_main.logger, __VA_ARGS__);} while(0) 29 #define PLUGIN_LOG_NOTICE(...) \ 30 do {vlib_log_notice (vlib_plugin_main.logger, __VA_ARGS__);} while(0) 32 char *vlib_plugin_path __attribute__ ((weak));
33 char *vlib_plugin_path =
"";
48 return dlsym (pi->
handle, symbol_name);
62 while (c && ++n < len);
92 vlib_plugin_registration_t * reg)
96 uword data_segment_offset;
111 data_segment_offset = *((
uword *) data);
114 #define _(a) r2->a.data_segment_offset -= data_segment_offset; 130 memcpy ((
void *) reg->version_required,
142 reg->early_init = (
void *) ei;
151 reg->description = (
void *) desc;
167 char *version_required;
168 vlib_plugin_registration_t *reg;
183 memset (reg, 0,
sizeof (*reg));
193 reg->default_disabled = 1;
207 reg = (vlib_plugin_registration_t *) data;
209 if (
vec_len (data) !=
sizeof (*reg))
211 PLUGIN_LOG_ERR (
"vlib_plugin_registration size mismatch in plugin %s\n",
217 reg->default_disabled = 1;
229 if (reg->default_disabled && pc->
is_enabled == 0)
235 else if (reg->default_disabled)
242 sizeof (reg->version_required));
244 if ((strlen (version_required) > 0) &&
245 (strncmp (vlib_plugin_app_version, version_required,
246 strlen (version_required))))
249 pi->
name, vlib_plugin_app_version,
250 reg->version_required);
262 if (reg->overrides[0])
264 const char *overrides = reg->overrides;
265 u8 *override_name_copy, *overridden_by_name_copy;
269 sp = ep = (
u8 *) overrides;
274 || (sp >= (
u8 *) overrides +
ARRAY_LEN (reg->overrides)))
276 if (*sp ==
' ' || *sp ==
',')
282 while (*ep && *ep !=
' ' && *ep !=
',' &&
283 ep < (
u8 *) overrides +
ARRAY_LEN (reg->overrides))
285 if (*ep ==
' ' || *ep ==
',')
288 override_name_copy =
extract (sp, ep);
298 overridden_by_name_copy =
format (0,
"%s%c", pi->
name, 0);
300 override_name_copy, overridden_by_name_copy);
302 sp = *ep ? ep + 1 : ep;
307 handle = dlopen ((
char *) pi->
filename, RTLD_LAZY);
319 reg = dlsym (pi->
handle,
"vlib_plugin_registration");
323 sizeof (reg->version));
330 h = dlsym (pi->
handle, reg->early_init);
347 PLUGIN_LOG_ERR (
"Plugin %s: early init function %s set but not found",
348 (
char *) pi->
name, reg->early_init);
351 if (reg->description)
399 return strcmp ((
char *) p1->
name, (
char *) p2->
name);
419 struct dirent *entry;
424 uword *not_loaded_indices = 0;
429 for (i = 0; i <
vec_len (plugin_path); i++)
431 dp = opendir ((
char *) plugin_path[i]);
436 while ((entry = readdir (dp)))
449 filename =
format (0,
"%s/%s%c", plugin_path[i], entry->d_name, 0);
452 char *ext = strrchr ((
const char *) filename,
'.');
454 if (!ext || (strcmp (ext,
".so") != 0) ||
455 stat ((
char *) filename, &statb) < 0)
463 if (!S_ISREG (statb.st_mode))
466 plugin_name =
format (0,
"%s%c", entry->d_name, 0);
473 pi->
name = plugin_name;
542 for (i = 0; i <
vec_len (not_loaded_indices); i++)
544 if (i < vec_len (not_loaded_indices) - 1)
546 if (not_loaded_indices[i + 1] == not_loaded_indices[i])
555 if (vec_len (not_loaded_indices) > 0)
557 for (i = vec_len (not_loaded_indices) - 1; i >= 0; i--)
633 s =
format (s,
" %-41s%-33s%s\n",
"Plugin",
"Version",
"Description");
640 pi = vec_elt_at_index (pm->plugin_info, value);
641 s = format (s,
"%3d. %-40s %-32s %s\n", index, key, pi->version,
642 (pi->reg && pi->reg->description) ?
643 pi->reg->description :
"");
657 .path =
"show plugins",
658 .short_help =
"show loaded plugins",
672 int skip_version_check = 0;
689 else if (
unformat (input,
"disable"))
691 else if (
unformat (input,
"skip-version-check"))
692 skip_version_check = 1;
701 if (is_enable && is_disable)
704 " for plugin '%s'", name);
731 if (
unformat (input,
"%s %v", &s, &v))
733 if (strncmp ((
const char *) s,
"plugins", 8) == 0)
756 if (
unformat (input,
"path %s", &s))
758 else if (
unformat (input,
"name-filter %s", &s))
760 else if (
unformat (input,
"vat-path %s", &s))
762 else if (
unformat (input,
"vat-name-filter %s", &s))
764 else if (
unformat (input,
"plugin default %U",
768 unformat (&sub_input,
"disable") ? 1 : 0;
771 else if (
unformat (input,
"plugin %s %U", &s,
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u8 * vlib_get_vat_plugin_name_filter(void)
static void elf_main_free(elf_main_t *em)
static clib_error_t * plugins_config(vlib_main_t *vm, unformat_input_t *input)
uword * plugin_overrides_by_name_hash
u8 * vat_plugin_name_filter
static int plugin_name_sort_cmp(void *a1, void *a2)
#define PLUGIN_LOG_ERR(...)
#define foreach_r2_string_field
u8 * vlib_get_vat_plugin_path(void)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
clib_error_t * vlib_plugin_config(vlib_main_t *vm, unformat_input_t *input)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
#define hash_set_mem(h, key, value)
uword * config_index_by_name
static clib_error_t * r2_to_reg(elf_main_t *em, vlib_plugin_r2_t *r2, vlib_plugin_registration_t *reg)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
vlib_r2_string_t early_init
#define PLUGIN_LOG_DBG(...)
static int load_one_plugin(plugin_main_t *pm, plugin_info_t *pi, int from_early_init)
vlib_plugin_registration_t * reg
description fragment has unexpected format
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
vlib_log_class_t vlib_log_register_class_rate_limit(char *class, char *subclass, u32 limit)
int vlib_plugin_early_init(vlib_main_t *vm)
#define hash_create_string(elts, value_bytes)
#define hash_unset_mem(h, key)
#define VLIB_CONFIG_FUNCTION(x, n,...)
plugin_info_t * plugin_info
#define hash_foreach_mem(key_var, value_var, h, body)
__clib_export clib_error_t * elf_read_file(elf_main_t *em, char *file_name)
static int index_cmp(void *a1, void *a2)
__clib_export clib_error_t * elf_get_section_by_name(elf_main_t *em, char *section_name, elf_section_t **result)
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
char * vlib_plugin_app_version
static clib_error_t * config_one_plugin(vlib_main_t *vm, char *name, unformat_input_t *input)
vlib_r2_string_t description
vlib_r2_string_t version_required
#define VLIB_CLI_COMMAND(x,...)
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
vlib_r2_string_t overrides
#define vec_delete(V, N, M)
Delete N elements starting at element M.
static void * elf_get_section_contents(elf_main_t *em, uword section_index, uword elt_size)
#define PLUGIN_LOG_NOTICE(...)
int vlib_load_new_plugins(plugin_main_t *pm, int from_early_init)
void * vlib_get_plugin_symbol(char *plugin_name, char *symbol_name)
static void * clib_mem_alloc(uword size)
static u8 ** split_plugin_path(plugin_main_t *pm)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
uword data_segment_offset
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
#define clib_error_free(e)
#define hash_get_mem(h, key)
plugin_config_t * configs
static u8 * extract(u8 *sp, u8 *ep)
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
static char * str_array_to_vec(char *array, int len)
plugin_main_t vlib_plugin_main
uword * plugin_by_name_hash
u8 plugins_default_disable
static clib_error_t * vlib_plugins_show_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)