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.
28 #include "lib/version.h"
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,
48 // if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE)
49 // union _frrmod_runtime_u _frrmod_this_module
50 // __attribute__((weak, alias("frrmod_default")));
51 // elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA)
52 #pragma weak _frrmod_this_module = frrmod_default
54 // error need weak symbol support
57 struct frrmod_runtime
*frrmod_list
= &frrmod_default
.r
;
58 static struct frrmod_runtime
**frrmod_last
= &frrmod_default
.r
.next
;
59 static const char *execname
= NULL
;
61 void frrmod_init(struct frrmod_runtime
*modinfo
)
63 modinfo
->finished_loading
= true;
64 *frrmod_last
= modinfo
;
65 frrmod_last
= &modinfo
->next
;
67 execname
= modinfo
->info
->name
;
70 struct frrmod_runtime
*frrmod_load(const char *spec
, const char *dir
, char *err
,
74 char name
[PATH_MAX
], fullpath
[PATH_MAX
* 2], *args
;
75 struct frrmod_runtime
*rtinfo
, **rtinfop
;
76 const struct frrmod_info
*info
;
78 snprintf(name
, sizeof(name
), "%s", spec
);
79 args
= strchr(name
, ':');
83 if (!strchr(name
, '/')) {
85 snprintf(fullpath
, sizeof(fullpath
), "%s/%s_%s.so", dir
,
87 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
90 snprintf(fullpath
, sizeof(fullpath
), "%s/%s.so", dir
,
92 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
96 snprintf(fullpath
, sizeof(fullpath
), "%s", name
);
97 handle
= dlopen(fullpath
, RTLD_NOW
| RTLD_GLOBAL
);
101 snprintf(err
, err_len
,
102 "loading module \"%s\" failed: %s", name
,
107 rtinfop
= dlsym(handle
, "frr_module");
111 snprintf(err
, err_len
,
112 "\"%s\" is not an FRR module: %s", name
,
117 rtinfo
->load_name
= XSTRDUP(MTYPE_MODULE_LOADNAME
, name
);
118 rtinfo
->dl_handle
= handle
;
120 rtinfo
->load_args
= XSTRDUP(MTYPE_MODULE_LOADARGS
, args
);
123 if (rtinfo
->finished_loading
) {
126 snprintf(err
, err_len
, "module \"%s\" already loaded",
131 if (info
->init
&& info
->init()) {
134 snprintf(err
, err_len
,
135 "module \"%s\" initialisation failed", name
);
139 rtinfo
->finished_loading
= true;
141 *frrmod_last
= rtinfo
;
142 frrmod_last
= &rtinfo
->next
;
146 XFREE(MTYPE_MODULE_LOADARGS
, rtinfo
->load_args
);
147 XFREE(MTYPE_MODULE_LOADNAME
, rtinfo
->load_name
);
152 void frrmod_unload(struct frrmod_runtime
*module
)