2 * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
36 DEFINE_MTYPE_STATIC(LIB
, MODULE_LOADNAME
, "Module loading name")
37 DEFINE_MTYPE_STATIC(LIB
, MODULE_LOADARGS
, "Module loading arguments")
39 static struct frrmod_info frrmod_default_info
= {
41 .version
= FRR_VERSION
,
42 .description
= "libfrr core module",
44 union _frrmod_runtime_u frrmod_default
= {
46 .info
= &frrmod_default_info
,
47 .finished_loading
= 1,
51 // if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE)
52 // union _frrmod_runtime_u _frrmod_this_module
53 // __attribute__((weak, alias("frrmod_default")));
54 // elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA)
55 #pragma weak _frrmod_this_module = frrmod_default
57 // error need weak symbol support
60 struct frrmod_runtime
*frrmod_list
= &frrmod_default
.r
;
61 static struct frrmod_runtime
**frrmod_last
= &frrmod_default
.r
.next
;
62 static const char *execname
= NULL
;
64 void frrmod_init(struct frrmod_runtime
*modinfo
)
66 modinfo
->finished_loading
= 1;
67 *frrmod_last
= modinfo
;
68 frrmod_last
= &modinfo
->next
;
70 execname
= modinfo
->info
->name
;
73 struct frrmod_runtime
*frrmod_load(const char *spec
, const char *dir
, char *err
,
77 char name
[PATH_MAX
], fullpath
[PATH_MAX
], *args
;
78 struct frrmod_runtime
*rtinfo
, **rtinfop
;
79 const struct frrmod_info
*info
;
81 snprintf(name
, sizeof(name
), "%s", spec
);
82 args
= strchr(name
, ':');
86 if (!strchr(name
, '/')) {
87 if (!handle
&& execname
) {
88 snprintf(fullpath
, sizeof(fullpath
), "%s/%s_%s.so", dir
,
90 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
93 snprintf(fullpath
, sizeof(fullpath
), "%s/%s.so", dir
,
95 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
99 snprintf(fullpath
, sizeof(fullpath
), "%s", name
);
100 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
104 snprintf(err
, err_len
,
105 "loading module \"%s\" failed: %s", name
,
110 rtinfop
= dlsym(handle
, "frr_module");
114 snprintf(err
, err_len
,
115 "\"%s\" is not an FRR module: %s", name
,
120 rtinfo
->load_name
= XSTRDUP(MTYPE_MODULE_LOADNAME
, name
);
121 rtinfo
->dl_handle
= handle
;
123 rtinfo
->load_args
= XSTRDUP(MTYPE_MODULE_LOADARGS
, args
);
126 if (rtinfo
->finished_loading
) {
129 snprintf(err
, err_len
, "module \"%s\" already loaded",
134 if (info
->init
&& info
->init()) {
137 snprintf(err
, err_len
,
138 "module \"%s\" initialisation failed", name
);
142 rtinfo
->finished_loading
= 1;
144 *frrmod_last
= rtinfo
;
145 frrmod_last
= &rtinfo
->next
;
149 if (rtinfo
->load_args
)
150 XFREE(MTYPE_MODULE_LOADARGS
, rtinfo
->load_args
);
151 XFREE(MTYPE_MODULE_LOADNAME
, rtinfo
->load_name
);
156 void frrmod_unload(struct frrmod_runtime
*module
)