summaryrefslogtreecommitdiff
path: root/lib/libfrr.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-05-31 19:25:46 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2017-03-24 13:02:05 +0100
commit30771d65b23e4ef15a8298357b70fc083c699750 (patch)
tree3916bace6127d166780fdd187b4908f2f7e12e7b /lib/libfrr.c
parent4c0a782d477d527fb795640225c5f22767105f32 (diff)
lib: dynamic module loading
This adds a "-M" option to each daemon, to load dynamic modules at startup. Modules are by default located in /usr/lib/frr/modules (lib64 if appropriate). Unloading or loading at runtime is not supported at this point to keep things simple. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/libfrr.c')
-rw-r--r--lib/libfrr.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/libfrr.c b/lib/libfrr.c
index b7ce0679c3..5c047040ae 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -28,6 +28,7 @@
#include "memory_vty.h"
#include "zclient.h"
#include "log_int.h"
+#include "module.h"
const char frr_sysconfdir[] = SYSCONFDIR;
const char frr_vtydir[] = DAEMON_VTY_DIR;
@@ -64,14 +65,16 @@ static const struct option lo_always[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "daemon", no_argument, NULL, 'd' },
+ { "module", no_argument, NULL, 'M' },
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ NULL }
};
static const struct optspec os_always = {
- "hvdi:",
+ "hvdM:",
" -h, --help Display this help and exit\n"
" -v, --version Print program version\n"
" -d, --daemon Runs in daemon mode\n"
+ " -M, --module Load specified module\n"
" --vty_socket Override vty socket path\n",
lo_always
};
@@ -184,12 +187,18 @@ void frr_help_exit(int status)
exit(status);
}
+struct option_chain {
+ struct option_chain *next;
+ const char *arg;
+};
+static struct option_chain *modules = NULL, **modnext = &modules;
static int errors = 0;
static int frr_opt(int opt)
{
static int vty_port_set = 0;
static int vty_addr_set = 0;
+ struct option_chain *oc;
char *err;
switch (opt) {
@@ -203,6 +212,13 @@ static int frr_opt(int opt)
case 'd':
di->daemon_mode = 1;
break;
+ case 'M':
+ oc = XMALLOC(MTYPE_TMP, sizeof(*oc));
+ oc->arg = optarg;
+ oc->next = NULL;
+ *modnext = oc;
+ modnext = &oc->next;
+ break;
case 'i':
if (di->flags & FRR_NO_CFG_PID_DRY)
return 1;
@@ -298,6 +314,9 @@ int frr_getopt(int argc, char * const argv[], int *longindex)
struct thread_master *frr_init(void)
{
struct thread_master *master;
+ struct option_chain *oc;
+ struct frrmod_runtime *module;
+ char moderr[256];
srandom(time(NULL));
@@ -307,6 +326,17 @@ struct thread_master *frr_init(void)
zlog_set_level (ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
#endif
+ frrmod_init(di->module);
+ while (modules) {
+ modules = (oc = modules)->next;
+ module = frrmod_load(oc->arg, moderr, sizeof(moderr));
+ if (!module) {
+ fprintf(stderr, "%s\n", moderr);
+ exit(1);
+ }
+ XFREE(MTYPE_TMP, oc);
+ }
+
zprivs_init(di->privs);
master = thread_master_create();