FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
plugin.c
Go to the documentation of this file.
1 /*
2  * plugin.c: plugin handling
3  *
4  * Copyright (c) 2011 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/unix/plugin.h>
19 #include <vppinfra/elf.h>
20 #include <dlfcn.h>
21 #include <dirent.h>
22 
24 
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)
31 
32 char *vlib_plugin_path __attribute__ ((weak));
33 char *vlib_plugin_path = "";
34 char *vlib_plugin_app_version __attribute__ ((weak));
35 char *vlib_plugin_app_version = "";
36 
37 void *
38 vlib_get_plugin_symbol (char *plugin_name, char *symbol_name)
39 {
41  uword *p;
42  plugin_info_t *pi;
43 
44  if ((p = hash_get_mem (pm->plugin_by_name_hash, plugin_name)) == 0)
45  return 0;
46 
47  pi = vec_elt_at_index (pm->plugin_info, p[0]);
48  return dlsym (pi->handle, symbol_name);
49 }
50 
51 static char *
52 str_array_to_vec (char *array, int len)
53 {
54  char c, *r = 0;
55  int n = 0;
56 
57  do
58  {
59  c = array[n];
60  vec_add1 (r, c);
61  }
62  while (c && ++n < len);
63 
64  if (c)
65  vec_add1 (r, 0);
66 
67  return r;
68 }
69 
70 static u8 *
71 extract (u8 * sp, u8 * ep)
72 {
73  u8 *rv = 0;
74 
75  while (sp <= ep)
76  {
77  vec_add1 (rv, *sp);
78  sp++;
79  }
80  vec_add1 (rv, 0);
81  return rv;
82 }
83 
84 /*
85  * If a plugin .so contains a ".vlib_plugin_r2" section,
86  * this function converts the vlib_plugin_r2_t to
87  * a vlib_plugin_registration_t.
88  */
89 
90 static clib_error_t *
92  vlib_plugin_registration_t * reg)
93 {
95  elf_section_t *section;
96  uword data_segment_offset;
97  u8 *data;
98 
99  /* It turns out that the strings land in the ".data" section */
100  error = elf_get_section_by_name (em, ".data", &section);
101  if (error)
102  return error;
103  data = elf_get_section_contents (em, section->index, 1);
104 
105  /*
106  * Offsets in the ".vlib_plugin_r2" section
107  * need to have the data section base subtracted from them.
108  * The offset is in the first 8 bytes of the ".data" section
109  */
110 
111  data_segment_offset = *((uword *) data);
112 
113  /* Relocate pointers, subtract data_segment_offset */
114 #define _(a) r2->a.data_segment_offset -= data_segment_offset;
116 #undef _
117 
118  if (r2->version.length >= ARRAY_LEN (reg->version) - 1)
119  return clib_error_return (0, "Version string too long");
120 
121  if (r2->version_required.length >= ARRAY_LEN (reg->version_required) - 1)
122  return clib_error_return (0, "Version-required string too long");
123 
124  if (r2->overrides.length >= ARRAY_LEN (reg->overrides) - 1)
125  return clib_error_return (0, "Override string too long");
126 
127  /* Compatibility with C-initializer */
128  memcpy ((void *) reg->version, data + r2->version.data_segment_offset,
129  r2->version.length);
130  memcpy ((void *) reg->version_required,
133  memcpy ((void *) reg->overrides, data + r2->overrides.data_segment_offset,
134  r2->overrides.length);
135 
136  if (r2->early_init.length > 0)
137  {
138  u8 *ei = 0;
139  vec_validate (ei, r2->early_init.length + 1);
140  memcpy (ei, data + r2->early_init.data_segment_offset,
141  r2->early_init.length);
142  reg->early_init = (void *) ei;
143  }
144 
145  if (r2->description.length > 0)
146  {
147  u8 *desc = 0;
148  vec_validate (desc, r2->description.length + 1);
149  memcpy (desc, data + r2->description.data_segment_offset,
150  r2->description.length);
151  reg->description = (void *) desc;
152  }
153  vec_free (data);
154  return 0;
155 }
156 
157 
158 static int
159 load_one_plugin (plugin_main_t * pm, plugin_info_t * pi, int from_early_init)
160 {
161  void *handle;
162  int reread_reg = 1;
164  elf_main_t em = { 0 };
165  elf_section_t *section;
166  u8 *data;
167  char *version_required;
168  vlib_plugin_registration_t *reg;
169  vlib_plugin_r2_t *r2;
170  plugin_config_t *pc = 0;
171  uword *p;
172 
173  if (elf_read_file (&em, (char *) pi->filename))
174  return -1;
175 
176  /* New / improved (well, not really) registration structure? */
177  error = elf_get_section_by_name (&em, ".vlib_plugin_r2", &section);
178  if (error == 0)
179  {
180  data = elf_get_section_contents (&em, section->index, 1);
181  r2 = (vlib_plugin_r2_t *) data;
182  reg = clib_mem_alloc (sizeof (*reg));
183  memset (reg, 0, sizeof (*reg));
184 
185  reg->default_disabled = r2->default_disabled != 0;
186  error = r2_to_reg (&em, r2, reg);
187  if (error)
188  {
189  PLUGIN_LOG_ERR ("Bad r2 registration: %s\n", (char *) pi->name);
190  return -1;
191  }
192  if (pm->plugins_default_disable)
193  reg->default_disabled = 1;
194  reread_reg = 0;
195  goto process_reg;
196  }
197 
198  error = elf_get_section_by_name (&em, ".vlib_plugin_registration",
199  &section);
200  if (error)
201  {
202  PLUGIN_LOG_ERR ("Not a plugin: %s\n", (char *) pi->name);
203  return -1;
204  }
205 
206  data = elf_get_section_contents (&em, section->index, 1);
207  reg = (vlib_plugin_registration_t *) data;
208 
209  if (vec_len (data) != sizeof (*reg))
210  {
211  PLUGIN_LOG_ERR ("vlib_plugin_registration size mismatch in plugin %s\n",
212  (char *) pi->name);
213  goto error;
214  }
215 
216  if (pm->plugins_default_disable)
217  reg->default_disabled = 1;
218 
219 process_reg:
220  p = hash_get_mem (pm->config_index_by_name, pi->name);
221  if (p)
222  {
223  pc = vec_elt_at_index (pm->configs, p[0]);
224  if (pc->is_disabled)
225  {
226  PLUGIN_LOG_NOTICE ("Plugin disabled: %s", pi->name);
227  goto error;
228  }
229  if (reg->default_disabled && pc->is_enabled == 0)
230  {
231  PLUGIN_LOG_NOTICE ("Plugin disabled (default): %s", pi->name);
232  goto error;
233  }
234  }
235  else if (reg->default_disabled)
236  {
237  PLUGIN_LOG_NOTICE ("Plugin disabled (default): %s", pi->name);
238  goto error;
239  }
240 
241  version_required = str_array_to_vec ((char *) &reg->version_required,
242  sizeof (reg->version_required));
243 
244  if ((strlen (version_required) > 0) &&
245  (strncmp (vlib_plugin_app_version, version_required,
246  strlen (version_required))))
247  {
248  PLUGIN_LOG_ERR ("Plugin %s version mismatch: %s != %s",
250  reg->version_required);
251  if (!(pc && pc->skip_version_check == 1))
252  {
253  vec_free (version_required);
254  goto error;
255  }
256  }
257 
258  /*
259  * Collect names of plugins overridden (disabled) by the
260  * current plugin.
261  */
262  if (reg->overrides[0])
263  {
264  const char *overrides = reg->overrides;
265  u8 *override_name_copy, *overridden_by_name_copy;
266  u8 *sp, *ep;
267  uword *p;
268 
269  sp = ep = (u8 *) overrides;
270 
271  while (1)
272  {
273  if (*sp == 0
274  || (sp >= (u8 *) overrides + ARRAY_LEN (reg->overrides)))
275  break;
276  if (*sp == ' ' || *sp == ',')
277  {
278  sp++;
279  continue;
280  }
281  ep = sp;
282  while (*ep && *ep != ' ' && *ep != ',' &&
283  ep < (u8 *) overrides + ARRAY_LEN (reg->overrides))
284  ep++;
285  if (*ep == ' ' || *ep == ',')
286  ep--;
287 
288  override_name_copy = extract (sp, ep);
289 
290 
292  override_name_copy);
293  /* Already overridden... */
294  if (p)
295  vec_free (override_name_copy);
296  else
297  {
298  overridden_by_name_copy = format (0, "%s%c", pi->name, 0);
300  override_name_copy, overridden_by_name_copy);
301  }
302  sp = *ep ? ep + 1 : ep;
303  }
304  }
305  vec_free (version_required);
306 
307  handle = dlopen ((char *) pi->filename,
308  RTLD_LAZY | (reg->deep_bind ? RTLD_DEEPBIND : 0));
309 
310  if (handle == 0)
311  {
312  PLUGIN_LOG_ERR ("%s", dlerror ());
313  PLUGIN_LOG_ERR ("Failed to load plugin '%s'", pi->name);
314  goto error;
315  }
316 
317  pi->handle = handle;
318 
319  if (reread_reg)
320  reg = dlsym (pi->handle, "vlib_plugin_registration");
321 
322  pi->reg = reg;
323  pi->version = str_array_to_vec ((char *) &reg->version,
324  sizeof (reg->version));
325 
326  if (reg->early_init)
327  {
328  clib_error_t *(*ei) (vlib_main_t *);
329  void *h;
330 
331  h = dlsym (pi->handle, reg->early_init);
332  if (h)
333  {
334  ei = h;
335  error = (*ei) (pm->vlib_main);
336  if (error)
337  {
338  u8 *err = format (0, "%s: %U%c", pi->name,
340  PLUGIN_LOG_ERR ((char *) err);
342  dlclose (pi->handle);
343  pi->handle = 0;
344  goto error;
345  }
346  }
347  else
348  PLUGIN_LOG_ERR ("Plugin %s: early init function %s set but not found",
349  (char *) pi->name, reg->early_init);
350  }
351 
352  if (reg->description)
353  PLUGIN_LOG_NOTICE ("Loaded plugin: %s (%s)", pi->name, reg->description);
354  else
355  PLUGIN_LOG_NOTICE ("Loaded plugin: %s", pi->name);
356 
357  vec_free (data);
358  elf_main_free (&em);
359  return 0;
360 
361 error:
362  vec_free (data);
363  elf_main_free (&em);
364  return -1;
365 }
366 
367 static u8 **
369 {
370  int i;
371  u8 **rv = 0;
372  u8 *path = pm->plugin_path;
373  u8 *this = 0;
374 
375  for (i = 0; i < vec_len (pm->plugin_path); i++)
376  {
377  if (path[i] != ':')
378  {
379  vec_add1 (this, path[i]);
380  continue;
381  }
382  vec_add1 (this, 0);
383  vec_add1 (rv, this);
384  this = 0;
385  }
386  if (this)
387  {
388  vec_add1 (this, 0);
389  vec_add1 (rv, this);
390  }
391  return rv;
392 }
393 
394 static int
395 plugin_name_sort_cmp (void *a1, void *a2)
396 {
397  plugin_info_t *p1 = a1;
398  plugin_info_t *p2 = a2;
399 
400  return strcmp ((char *) p1->name, (char *) p2->name);
401 }
402 
403 static int
404 index_cmp (void *a1, void *a2)
405 {
406  uword *i1 = (uword *) a1, *i2 = (uword *) a2;
407 
408  if (*i1 < *i2)
409  return -1;
410  else if (*i1 > *i2)
411  return 1;
412  else
413  return 0;
414 }
415 
416 int
417 vlib_load_new_plugins (plugin_main_t * pm, int from_early_init)
418 {
419  DIR *dp;
420  struct dirent *entry;
421  struct stat statb;
422  uword *p;
423  plugin_info_t *pi;
424  u8 **plugin_path;
425  uword *not_loaded_indices = 0;
426  int i;
427 
428  plugin_path = split_plugin_path (pm);
429 
430  for (i = 0; i < vec_len (plugin_path); i++)
431  {
432  dp = opendir ((char *) plugin_path[i]);
433 
434  if (dp == 0)
435  continue;
436 
437  while ((entry = readdir (dp)))
438  {
439  u8 *plugin_name;
440  u8 *filename;
441 
442  if (pm->plugin_name_filter)
443  {
444  int j;
445  for (j = 0; j < vec_len (pm->plugin_name_filter); j++)
446  if (entry->d_name[j] != pm->plugin_name_filter[j])
447  goto next;
448  }
449 
450  filename = format (0, "%s/%s%c", plugin_path[i], entry->d_name, 0);
451 
452  /* Only accept .so */
453  char *ext = strrchr ((const char *) filename, '.');
454  /* unreadable */
455  if (!ext || (strcmp (ext, ".so") != 0) ||
456  stat ((char *) filename, &statb) < 0)
457  {
458  ignore:
459  vec_free (filename);
460  continue;
461  }
462 
463  /* a dir or other things which aren't plugins */
464  if (!S_ISREG (statb.st_mode))
465  goto ignore;
466 
467  plugin_name = format (0, "%s%c", entry->d_name, 0);
468  /* Have we seen this plugin already? */
469  p = hash_get_mem (pm->plugin_by_name_hash, plugin_name);
470  if (p == 0)
471  {
472  /* No, add it to the plugin vector */
473  vec_add2 (pm->plugin_info, pi, 1);
474  pi->name = plugin_name;
475  pi->filename = filename;
476  pi->file_info = statb;
477  pi->handle = 0;
478  hash_set_mem (pm->plugin_by_name_hash, plugin_name,
479  pi - pm->plugin_info);
480  }
481  next:
482  ;
483  }
484  closedir (dp);
485  vec_free (plugin_path[i]);
486  }
487  vec_free (plugin_path);
488 
489 
490  /*
491  * Sort the plugins by name. This is important.
492  * API traces contain absolute message numbers.
493  * Loading plugins in directory (vs. alphabetical) order
494  * makes trace replay incredibly fragile.
495  */
497 
498  /*
499  * Attempt to load the plugins
500  */
501  for (i = 0; i < vec_len (pm->plugin_info); i++)
502  {
503  pi = vec_elt_at_index (pm->plugin_info, i);
504 
505  if (load_one_plugin (pm, pi, from_early_init))
506  {
507  /* Make a note of any which fail to load */
508  vec_add1 (not_loaded_indices, i);
509  }
510  }
511 
512  /*
513  * Honor override list
514  */
515  for (i = 0; i < vec_len (pm->plugin_info); i++)
516  {
517  uword *p;
518 
519  pi = vec_elt_at_index (pm->plugin_info, i);
520 
522 
523  /* Plugin overridden? */
524  if (p)
525  {
526  PLUGIN_LOG_NOTICE ("Plugin '%s' overridden by '%s'", pi->name,
527  p[0]);
528  vec_add1 (not_loaded_indices, i);
529  }
530  }
531 
532  /*
533  * Sort the vector of indices to delete to avoid screwing up
534  * the indices as we delete them.
535  */
536  vec_sort_with_function (not_loaded_indices, index_cmp);
537 
538  /*
539  * Remove duplicates, which can happen if a plugin is
540  * disabled from the command line and disabled by
541  * a plugin which is loaded.
542  */
543  for (i = 0; i < vec_len (not_loaded_indices); i++)
544  {
545  if (i < vec_len (not_loaded_indices) - 1)
546  {
547  if (not_loaded_indices[i + 1] == not_loaded_indices[i])
548  {
549  vec_delete (not_loaded_indices, 1, i);
550  i--;
551  }
552  }
553  }
554 
555  /* Remove plugin info vector elements corresponding to load failures */
556  if (vec_len (not_loaded_indices) > 0)
557  {
558  for (i = vec_len (not_loaded_indices) - 1; i >= 0; i--)
559  {
560  pi = vec_elt_at_index (pm->plugin_info, not_loaded_indices[i]);
562  if (pi->handle)
563  {
564  dlclose (pi->handle);
565  PLUGIN_LOG_NOTICE ("Unloaded plugin: %s", pi->name);
566  }
567  vec_free (pi->name);
568  vec_free (pi->filename);
569  vec_delete (pm->plugin_info, 1, not_loaded_indices[i]);
570  }
571  vec_free (not_loaded_indices);
572  }
573 
574  /* Recreate the plugin name hash */
576  pm->plugin_by_name_hash = hash_create_string (0, sizeof (uword));
577 
578  for (i = 0; i < vec_len (pm->plugin_info); i++)
579  {
580  pi = vec_elt_at_index (pm->plugin_info, i);
581  hash_set_mem (pm->plugin_by_name_hash, pi->name, pi - pm->plugin_info);
582  }
583 
584  return 0;
585 }
586 
587 int
589 {
591 
592  pm->logger =
593  vlib_log_register_class_rate_limit ("plugin", "load",
594  0x7FFFFFFF /* aka no rate limit */ );
595 
596  if (pm->plugin_path == 0)
597  pm->plugin_path = format (0, "%s%c", vlib_plugin_path, 0);
598 
599  PLUGIN_LOG_DBG ("plugin path %s", pm->plugin_path);
600 
601  pm->plugin_by_name_hash = hash_create_string (0, sizeof (uword));
603  pm->vlib_main = vm;
604 
605  return vlib_load_new_plugins (pm, 1 /* from_early_init */ );
606 }
607 
608 u8 *
610 {
612  return (pm->vat_plugin_path);
613 }
614 
615 u8 *
617 {
619  return (pm->vat_plugin_name_filter);
620 }
621 
622 static clib_error_t *
624  unformat_input_t * input, vlib_cli_command_t * cmd)
625 {
627  u8 *s = 0;
628  u8 *key = 0;
629  uword value = 0;
630  int index = 1;
631  plugin_info_t *pi;
632 
633  s = format (s, " Plugin path is: %s\n\n", pm->plugin_path);
634  s = format (s, " %-41s%-33s%s\n", "Plugin", "Version", "Description");
635 
636  /* *INDENT-OFF* */
638  {
639  if (key != 0)
640  {
641  pi = vec_elt_at_index (pm->plugin_info, value);
642  s = format (s, "%3d. %-40s %-32s %s\n", index, key, pi->version,
643  (pi->reg && pi->reg->description) ?
644  pi->reg->description : "");
645  index++;
646  }
647  });
648  /* *INDENT-ON* */
649 
650  vlib_cli_output (vm, "%v", s);
651  vec_free (s);
652  return 0;
653 }
654 
655 /* *INDENT-OFF* */
657 {
658  .path = "show plugins",
659  .short_help = "show loaded plugins",
660  .function = vlib_plugins_show_cmd_fn,
661 };
662 /* *INDENT-ON* */
663 
664 static clib_error_t *
666 {
668  plugin_config_t *pc;
669  clib_error_t *error = 0;
670  uword *p;
671  int is_enable = 0;
672  int is_disable = 0;
673  int skip_version_check = 0;
674 
675  if (pm->config_index_by_name == 0)
676  pm->config_index_by_name = hash_create_string (0, sizeof (uword));
677 
679 
680  if (p)
681  {
682  error = clib_error_return (0, "plugin '%s' already configured", name);
683  goto done;
684  }
685 
687  {
688  if (unformat (input, "enable"))
689  is_enable = 1;
690  else if (unformat (input, "disable"))
691  is_disable = 1;
692  else if (unformat (input, "skip-version-check"))
693  skip_version_check = 1;
694  else
695  {
696  error = clib_error_return (0, "unknown input '%U'",
697  format_unformat_error, input);
698  goto done;
699  }
700  }
701 
702  if (is_enable && is_disable)
703  {
704  error = clib_error_return (0, "please specify either enable or disable"
705  " for plugin '%s'", name);
706  goto done;
707  }
708 
709  vec_add2 (pm->configs, pc, 1);
711  pc->is_enabled = is_enable;
712  pc->is_disabled = is_disable;
713  pc->skip_version_check = skip_version_check;
714  pc->name = name;
715 
716 done:
717  return error;
718 }
719 
720 clib_error_t *
722 {
724  clib_error_t *error = 0;
725  unformat_input_t in;
726 
727  unformat_init (&in, 0, 0);
728 
730  {
731  u8 *s, *v;
732  if (unformat (input, "%s %v", &s, &v))
733  {
734  if (strncmp ((const char *) s, "plugins", 8) == 0)
735  {
736  if (vec_len (in.buffer) > 0)
737  vec_add1 (in.buffer, ' ');
738  vec_add (in.buffer, v, vec_len (v));
739  }
740  }
741  else
742  {
743  error = clib_error_return (0, "unknown input '%U'",
744  format_unformat_error, input);
745  goto done;
746  }
747 
748  vec_free (v);
749  vec_free (s);
750  }
751 done:
752  input = &in;
754  {
755  unformat_input_t sub_input;
756  u8 *s = 0;
757  if (unformat (input, "path %s", &s))
758  pm->plugin_path = s;
759  else if (unformat (input, "name-filter %s", &s))
760  pm->plugin_name_filter = s;
761  else if (unformat (input, "vat-path %s", &s))
762  pm->vat_plugin_path = s;
763  else if (unformat (input, "vat-name-filter %s", &s))
764  pm->vat_plugin_name_filter = s;
765  else if (unformat (input, "plugin default %U",
766  unformat_vlib_cli_sub_input, &sub_input))
767  {
769  unformat (&sub_input, "disable") ? 1 : 0;
770  unformat_free (&sub_input);
771  }
772  else if (unformat (input, "plugin %s %U", &s,
773  unformat_vlib_cli_sub_input, &sub_input))
774  {
775  error = config_one_plugin (vm, (char *) s, &sub_input);
776  unformat_free (&sub_input);
777  if (error)
778  goto done2;
779  }
780  else
781  {
782  error = clib_error_return (0, "unknown input '%U'",
783  format_unformat_error, input);
784  {
785  vec_free (s);
786  goto done2;
787  }
788  }
789  }
790 
791 done2:
792  unformat_free (&in);
793  return error;
794 }
795 
796 /* discard whole 'plugins' section, as it is already consumed prior to
797  plugin load */
798 static clib_error_t *
800 {
801  u8 *junk;
802 
804  {
805  if (unformat (input, "%s", &junk))
806  {
807  vec_free (junk);
808  return 0;
809  }
810  else
811  return clib_error_return (0, "unknown input '%U'",
812  format_unformat_error, input);
813  }
814  return 0;
815 }
816 
818 
819 /*
820  * fd.io coding-style-patch-verification: ON
821  *
822  * Local Variables:
823  * eval: (c-set-style "gnu")
824  * End:
825  */
plugin_info_t::filename
u8 * filename
Definition: plugin.h:100
plugin_main_t::logger
vlib_log_class_t logger
Definition: plugin.h:136
extract
static u8 * extract(u8 *sp, u8 *ep)
Definition: plugin.c:71
plugin_main_t::vat_plugin_path
u8 * vat_plugin_path
Definition: plugin.h:127
vec_add
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:688
plugin_info_t::reg
vlib_plugin_registration_t * reg
Definition: plugin.h:105
PLUGIN_LOG_NOTICE
#define PLUGIN_LOG_NOTICE(...)
Definition: plugin.c:29
PLUGIN_LOG_DBG
#define PLUGIN_LOG_DBG(...)
Definition: plugin.c:25
plugin_info_t::handle
void * handle
Definition: plugin.h:102
hash_free
#define hash_free(h)
Definition: hash.h:310
plugin_info_t::name
u8 * name
Definition: plugin.h:99
split_plugin_path
static u8 ** split_plugin_path(plugin_main_t *pm)
Definition: plugin.c:368
name
string name[64]
Definition: fib.api:25
vlib_plugin_main
plugin_main_t vlib_plugin_main
Definition: plugin.c:23
elf_get_section_contents
static void * elf_get_section_contents(elf_main_t *em, uword section_index, uword elt_size)
Definition: elf.h:957
load_one_plugin
static int load_one_plugin(plugin_main_t *pm, plugin_info_t *pi, int from_early_init)
Definition: plugin.c:159
plugin_main_t::plugin_info
plugin_info_t * plugin_info
Definition: plugin.h:120
plugin_main_t
Definition: plugin.h:117
elf_main_free
static void elf_main_free(elf_main_t *em)
Definition: elf.h:925
next
u16 * next
Definition: nat44_ei_out2in.c:718
path
vl_api_fib_path_t path
Definition: mfib_types.api:44
vlib_plugin_r2_t::early_init
vlib_r2_string_t early_init
Definition: plugin.h:86
hash_create_string
#define hash_create_string(elts, value_bytes)
Definition: hash.h:689
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
index_cmp
static int index_cmp(void *a1, void *a2)
Definition: plugin.c:404
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
vlib_plugin_r2_t
Definition: plugin.h:80
plugin_main_t::plugin_by_name_hash
uword * plugin_by_name_hash
Definition: plugin.h:121
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vec_delete
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:875
vlib_plugin_r2_t::description
vlib_r2_string_t description
Definition: plugin.h:87
plugins_show_cmd
static vlib_cli_command_t plugins_show_cmd
(constructor) VLIB_CLI_COMMAND (plugins_show_cmd)
Definition: plugin.c:656
plugin.h
unformat_input_t
struct _unformat_input_t unformat_input_t
vlib_load_new_plugins
int vlib_load_new_plugins(plugin_main_t *pm, int from_early_init)
Definition: plugin.c:417
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1089
plugin_main_t::vlib_main
vlib_main_t * vlib_main
Definition: plugin.h:139
config_one_plugin
static clib_error_t * config_one_plugin(vlib_main_t *vm, char *name, unformat_input_t *input)
Definition: plugin.c:665
h
h
Definition: flowhash_template.h:372
plugin_main_t::plugin_path
u8 * plugin_path
Definition: plugin.h:125
error
Definition: cJSON.c:88
key
typedef key
Definition: ipsec_types.api:91
format_clib_error
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
elf_section_t::index
u32 index
Definition: elf.h:856
plugin_main_t::plugin_name_filter
u8 * plugin_name_filter
Definition: plugin.h:126
plugin_main_t::plugins_default_disable
u8 plugins_default_disable
Definition: plugin.h:129
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ignore
description IKE_SA_INIT ignore(IKE SA already auth)"
plugin_main_t::vat_plugin_name_filter
u8 * vat_plugin_name_filter
Definition: plugin.h:128
plugin_config_t::is_enabled
u8 is_enabled
Definition: plugin.h:113
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
len
u8 len
Definition: ip_types.api:103
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
plugin_config_t::skip_version_check
u8 skip_version_check
Definition: plugin.h:114
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
PLUGIN_LOG_ERR
#define PLUGIN_LOG_ERR(...)
Definition: plugin.c:27
vlib_plugins_show_cmd_fn
static clib_error_t * vlib_plugins_show_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: plugin.c:623
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_log_register_class_rate_limit
vlib_log_class_t vlib_log_register_class_rate_limit(char *class, char *subclass, u32 limit)
Definition: log.c:346
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
vlib_r2_string_t::data_segment_offset
uword data_segment_offset
Definition: plugin.h:76
elf.h
uword
u64 uword
Definition: types.h:112
plugins_config
static clib_error_t * plugins_config(vlib_main_t *vm, unformat_input_t *input)
Definition: plugin.c:799
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
plugin_config_t::name
char * name
Definition: plugin.h:111
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
vlib_plugin_early_init
int vlib_plugin_early_init(vlib_main_t *vm)
Definition: plugin.c:588
vlib_get_vat_plugin_name_filter
u8 * vlib_get_vat_plugin_name_filter(void)
Definition: plugin.c:616
plugin_info_t::file_info
struct stat file_info
Definition: plugin.h:101
unformat_vlib_cli_sub_input
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:163
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
data
u8 data[128]
Definition: ipsec_types.api:95
vlib_get_vat_plugin_path
u8 * vlib_get_vat_plugin_path(void)
Definition: plugin.c:609
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
index
u32 index
Definition: flow_types.api:221
plugin_main_t::configs
plugin_config_t * configs
Definition: plugin.h:132
elf_read_file
__clib_export clib_error_t * elf_read_file(elf_main_t *em, char *file_name)
Definition: elf.c:1329
plugin_config_t
Definition: plugin.h:109
format
description fragment has unexpected format
Definition: map.api:433
vlib_plugin_app_version
char * vlib_plugin_app_version
Definition: plugin.c:34
elf_section_t
Definition: elf.h:852
str_array_to_vec
static char * str_array_to_vec(char *array, int len)
Definition: plugin.c:52
plugin_main_t::plugin_overrides_by_name_hash
uword * plugin_overrides_by_name_hash
Definition: plugin.h:122
plugin_config_t::is_disabled
u8 is_disabled
Definition: plugin.h:112
vlib_plugin_r2_t::version_required
vlib_r2_string_t version_required
Definition: plugin.h:84
vlib_r2_string_t::length
uword length
Definition: plugin.h:77
value
u8 value
Definition: qos.api:54
vlib_plugin_r2_t::overrides
vlib_r2_string_t overrides
Definition: plugin.h:85
vlib_plugin_r2_t::version
vlib_r2_string_t version
Definition: plugin.h:83
vec_sort_with_function
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1097
plugin_name_sort_cmp
static int plugin_name_sort_cmp(void *a1, void *a2)
Definition: plugin.c:395
foreach_r2_string_field
#define foreach_r2_string_field
Definition: plugin.h:90
vlib_main_t
Definition: main.h:102
r2_to_reg
static clib_error_t * r2_to_reg(elf_main_t *em, vlib_plugin_r2_t *r2, vlib_plugin_registration_t *reg)
Definition: plugin.c:91
plugin_info_t::version
char * version
Definition: plugin.h:106
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_plugin_path
char * vlib_plugin_path
Definition: plugin.c:32
i
int i
Definition: flowhash_template.h:376
clib_error_free
#define clib_error_free(e)
Definition: error.h:86
rv
int __clib_unused rv
Definition: application.c:491
vlib_plugin_config
clib_error_t * vlib_plugin_config(vlib_main_t *vm, unformat_input_t *input)
Definition: plugin.c:721
vlib_cli_command_t
Definition: cli.h:92
vlib_plugin_r2_t::default_disabled
int default_disabled
Definition: plugin.h:82
hash_foreach_mem
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:460
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
plugin_info_t
Definition: plugin.h:97
unformat_init
static void unformat_init(unformat_input_t *i, uword(*fill_buffer)(unformat_input_t *), void *fill_buffer_arg)
Definition: format.h:145
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
plugin_main_t::config_index_by_name
uword * config_index_by_name
Definition: plugin.h:133
vlib_get_plugin_symbol
void * vlib_get_plugin_symbol(char *plugin_name, char *symbol_name)
Definition: plugin.c:38
elf_get_section_by_name
__clib_export clib_error_t * elf_get_section_by_name(elf_main_t *em, char *section_name, elf_section_t **result)
Definition: elf.c:47
elf_main_t
Definition: elf.h:882