2 * Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
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.
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.
30 DEFINE_MTYPE_STATIC(LIB
, MODULE_LOADNAME
, "Module loading name")
31 DEFINE_MTYPE_STATIC(LIB
, MODULE_LOADARGS
, "Module loading arguments")
33 static struct frrmod_info frrmod_default_info
= {
35 .version
= FRR_VERSION
,
36 .description
= "libfrr core module",
38 union _frrmod_runtime_u frrmod_default
= {
41 .info
= &frrmod_default_info
,
42 .finished_loading
= 1,
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
52 // error need weak symbol support
55 struct frrmod_runtime
*frrmod_list
= &frrmod_default
.r
;
56 static struct frrmod_runtime
**frrmod_last
= &frrmod_default
.r
.next
;
57 static const char *execname
= NULL
;
59 void frrmod_init(struct frrmod_runtime
*modinfo
)
61 modinfo
->finished_loading
= 1;
62 *frrmod_last
= modinfo
;
63 frrmod_last
= &modinfo
->next
;
65 execname
= modinfo
->info
->name
;
68 struct frrmod_runtime
*frrmod_load(const char *spec
, const char *dir
, char *err
,
72 char name
[PATH_MAX
], fullpath
[PATH_MAX
* 2], *args
;
73 struct frrmod_runtime
*rtinfo
, **rtinfop
;
74 const struct frrmod_info
*info
;
76 snprintf(name
, sizeof(name
), "%s", spec
);
77 args
= strchr(name
, ':');
81 if (!strchr(name
, '/')) {
83 snprintf(fullpath
, sizeof(fullpath
), "%s/%s_%s.so", dir
,
85 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
88 snprintf(fullpath
, sizeof(fullpath
), "%s/%s.so", dir
,
90 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
94 snprintf(fullpath
, sizeof(fullpath
), "%s", name
);
95 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
99 snprintf(err
, err_len
,
100 "loading module \"%s\" failed: %s", name
,
105 rtinfop
= dlsym(handle
, "frr_module");
109 snprintf(err
, err_len
,
110 "\"%s\" is not an FRR module: %s", name
,
115 rtinfo
->load_name
= XSTRDUP(MTYPE_MODULE_LOADNAME
, name
);
116 rtinfo
->dl_handle
= handle
;
118 rtinfo
->load_args
= XSTRDUP(MTYPE_MODULE_LOADARGS
, args
);
121 if (rtinfo
->finished_loading
) {
124 snprintf(err
, err_len
, "module \"%s\" already loaded",
129 if (info
->init
&& info
->init()) {
132 snprintf(err
, err_len
,
133 "module \"%s\" initialisation failed", name
);
137 rtinfo
->finished_loading
= 1;
139 *frrmod_last
= rtinfo
;
140 frrmod_last
= &rtinfo
->next
;
144 XFREE(MTYPE_MODULE_LOADARGS
, rtinfo
->load_args
);
145 XFREE(MTYPE_MODULE_LOADNAME
, rtinfo
->load_name
);
150 void frrmod_unload(struct frrmod_runtime
*module
)