/*
 * plugin.h: plugin handling
 *
 * Copyright (c) 2011 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_plugin_h__
#define __included_plugin_h__

#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/*
 * vlib plugin scheme
 *
 * Almost anything which can be made to work in a vlib unix
 * application will also work in a vlib plugin.
 *
 * The elf-section magic which registers static objects
 * works so long as plugins are preset when the vlib unix process
 * starts. But wait: there's more...
 *
 * If an application calls vlib_load_new_plugins() -- possibly after
 * changing vlib_plugin_main.plugin_path / vlib_plugin_main.plugin_name_filter,
 * -- new plugins will be loaded. That, in turn, allows considerable
 * flexibility in terms of adding feature code or fixing bugs without
 * requiring the data-plane process to restart.
 *
 * When the plugin mechanism loads a plugin, it uses dlsym to locate
 * and call the plugin's function vlib_plugin_register() if it exists.
 * A plugin which expects to be loaded after the vlib application
 * starts uses this callback to modify the application. If vlib_plugin_register
 * returns non-zero, the plugin mechanism dlclose()'s the plugin.
 *
 * Applications control the plugin search path and name filter by
 * declaring the variables vlib_plugin_path and vlib_plugin_name_filter.
 * libvlib.la supplies weak references for these symbols which
 * effectively disable the scheme. In order for the elf-section magic to
 * work, static plugins must be loaded at the earliest possible moment.
 *
 * An application can change these parameters at any time and call
 * vlib_load_new_plugins().
 */

typedef struct
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
  u8 default_disabled : 1;
  u8 deep_bind : 1;
  const char version[64];
  const char version_required[64];
  const char overrides[256];
  const char *early_init;
  const char *description;
} vlib_plugin_registration_t;

/*
 * Plugins may also use this registration format, which is
 * easy enough to emit from e.g. a golang compiler.
 */
typedef struct
{
  uword data_segment_offset;
  uword length;
} vlib_r2_string_t;

typedef struct
{
  int default_disabled;
  vlib_r2_string_t version;
  vlib_r2_string_t version_required;
  vlib_r2_string_t overrides;
  vlib_r2_string_t early_init;
  vlib_r2_string_t description;
} vlib_plugin_r2_t;

#define foreach_r2_string_field                 \
_(version)                                      \
_(version_required)                             \
_(overrides)                                    \
_(early_init)                                   \
_(description)

typedef struct
{
  u8 *name;
  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 */
  plugin_info_t *plugin_info;
  uword *plugin_by_name_hash;
  uword *plugin_overrides_by_name_hash;

  /* paths and name filters */
  u8 *plugin_path;
  u8 *plugin_path_add;
  u8 *plugin_name_filter;
  u8 *vat_plugin_path;
  u8 *vat_plugin_name_filter;
  u8 plugins_default_disable;

  /* plugin configs and hash by name */
  plugin_config_t *configs;
  uword *config_index_by_name;

  /* Plugin log, avoid filling syslog w/ junk */
  vlib_log_class_t logger;

  /* usual */
  vlib_main_t *vlib_main;
} plugin_main_t;

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 (const char *plugin_name,
			      const char *symbol_name);
u8 *vlib_get_vat_plugin_path (void);

#define VLIB_PLUGIN_REGISTER() \
  vlib_plugin_registration_t vlib_plugin_registration \
  __clib_export __clib_section(".vlib_plugin_registration")

/* Call a plugin init function: used for init function dependencies. */
#define vlib_call_plugin_init_function(vm,p,x)                  \
({                                                              \
  clib_error_t *(*_f)(vlib_main_t *);                           \
  uword *_fptr = 0;                                             \
  clib_error_t * _error = 0;                                    \
  _fptr= vlib_get_plugin_symbol                                 \
    (p, CLIB_STRING_MACRO(_vlib_init_function_##x));            \
  if (_fptr == 0)                                               \
    {                                                           \
      _error = clib_error_return                                \
        (0, "Plugin %s and/or symbol %s not found.",            \
         p, CLIB_STRING_MACRO(_vlib_init_function_##x));        \
    }                                                           \
  else                                                          \
    {                                                           \
      _f = (void *)(_fptr[0]);                                  \
    }                                                           \
  if (_fptr && ! hash_get (vm->init_functions_called, _f))      \
    {                                                           \
      hash_set1 (vm->init_functions_called, _f);                \
      _error = _f (vm);                                         \
    }                                                           \
  _error;                                                       \
 })

#endif /* __included_plugin_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
