]> git.proxmox.com Git - mirror_frr.git/blame - lib/module.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / module.c
CommitLineData
30771d65
DL
1/*
2 * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
3 *
bbfeedb5
DL
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
30771d65 7 *
bbfeedb5
DL
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30771d65
DL
15 */
16
17#include "config.h"
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <unistd.h>
23#include <limits.h>
24#include <dlfcn.h>
25
26#include "module.h"
27#include "memory.h"
28#include "version.h"
29
30DEFINE_MTYPE_STATIC(LIB, MODULE_LOADNAME, "Module loading name")
31DEFINE_MTYPE_STATIC(LIB, MODULE_LOADARGS, "Module loading arguments")
32
33static struct frrmod_info frrmod_default_info = {
34 .name = "libfrr",
35 .version = FRR_VERSION,
36 .description = "libfrr core module",
37};
38union _frrmod_runtime_u frrmod_default = {
996c9314
LB
39 .r =
40 {
41 .info = &frrmod_default_info,
42 .finished_loading = 1,
43 },
30771d65
DL
44};
45
46// if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE)
47// union _frrmod_runtime_u _frrmod_this_module
48// __attribute__((weak, alias("frrmod_default")));
49// elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA)
50#pragma weak _frrmod_this_module = frrmod_default
51// else
52// error need weak symbol support
53// endif
54
55struct frrmod_runtime *frrmod_list = &frrmod_default.r;
56static struct frrmod_runtime **frrmod_last = &frrmod_default.r.next;
57static const char *execname = NULL;
58
59void frrmod_init(struct frrmod_runtime *modinfo)
60{
61 modinfo->finished_loading = 1;
62 *frrmod_last = modinfo;
63 frrmod_last = &modinfo->next;
64
65 execname = modinfo->info->name;
66}
67
d62a17ae 68struct frrmod_runtime *frrmod_load(const char *spec, const char *dir, char *err,
69 size_t err_len)
30771d65
DL
70{
71 void *handle = NULL;
ff44f570 72 char name[PATH_MAX], fullpath[PATH_MAX * 2], *args;
30771d65
DL
73 struct frrmod_runtime *rtinfo, **rtinfop;
74 const struct frrmod_info *info;
75
76 snprintf(name, sizeof(name), "%s", spec);
77 args = strchr(name, ':');
78 if (args)
79 *args++ = '\0';
80
81 if (!strchr(name, '/')) {
2e1cc436 82 if (execname) {
d62a17ae 83 snprintf(fullpath, sizeof(fullpath), "%s/%s_%s.so", dir,
84 execname, name);
30771d65
DL
85 handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
86 }
87 if (!handle) {
d62a17ae 88 snprintf(fullpath, sizeof(fullpath), "%s/%s.so", dir,
89 name);
30771d65
DL
90 handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
91 }
92 }
93 if (!handle) {
94 snprintf(fullpath, sizeof(fullpath), "%s", name);
95 handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
96 }
97 if (!handle) {
98 if (err)
99 snprintf(err, err_len,
d62a17ae 100 "loading module \"%s\" failed: %s", name,
101 dlerror());
30771d65
DL
102 return NULL;
103 }
104
105 rtinfop = dlsym(handle, "frr_module");
106 if (!rtinfop) {
107 dlclose(handle);
108 if (err)
109 snprintf(err, err_len,
d62a17ae 110 "\"%s\" is not an FRR module: %s", name,
111 dlerror());
30771d65
DL
112 return NULL;
113 }
114 rtinfo = *rtinfop;
115 rtinfo->load_name = XSTRDUP(MTYPE_MODULE_LOADNAME, name);
116 rtinfo->dl_handle = handle;
117 if (args)
118 rtinfo->load_args = XSTRDUP(MTYPE_MODULE_LOADARGS, args);
119 info = rtinfo->info;
120
121 if (rtinfo->finished_loading) {
122 dlclose(handle);
123 if (err)
d62a17ae 124 snprintf(err, err_len, "module \"%s\" already loaded",
125 name);
30771d65
DL
126 goto out_fail;
127 }
128
129 if (info->init && info->init()) {
130 dlclose(handle);
131 if (err)
132 snprintf(err, err_len,
d62a17ae 133 "module \"%s\" initialisation failed", name);
30771d65
DL
134 goto out_fail;
135 }
136
137 rtinfo->finished_loading = 1;
138
139 *frrmod_last = rtinfo;
140 frrmod_last = &rtinfo->next;
141 return rtinfo;
142
143out_fail:
144 if (rtinfo->load_args)
145 XFREE(MTYPE_MODULE_LOADARGS, rtinfo->load_args);
146 XFREE(MTYPE_MODULE_LOADNAME, rtinfo->load_name);
147 return NULL;
148}
149
150#if 0
151void frrmod_unload(struct frrmod_runtime *module)
152{
153}
154#endif