]> git.proxmox.com Git - mirror_frr.git/blame - doc/developer/modules.rst
*: Convert event.h to frrevent.h
[mirror_frr.git] / doc / developer / modules.rst
CommitLineData
bf9735b2
DS
1.. _modules:
2
b30de709
QY
3Modules
4=======
d1890d04 5
b30de709
QY
6FRR has facilities to load DSOs at startup via ``dlopen()``. These are used to
7implement modules, such as SNMP and FPM.
d1890d04
QY
8
9Limitations
10-----------
11
12- can't load, unload, or reload during runtime. This just needs some
13 work and can probably be done in the future.
14- doesn't fix any of the "things need to be changed in the code in the
15 library" issues. Most prominently, you can't add a CLI node because
16 CLI nodes are listed in the library...
17- if your module crashes, the daemon crashes. Should be obvious.
18- **does not provide a stable API or ABI**. Your module must match a
19 version of FRR and you may have to update it frequently to match
20 changes.
21- **does not create a license boundary**. Your module will need to link
22 libzebra and include header files from the daemons, meaning it will
23 be GPL-encumbered.
24
25Installation
26------------
27
28Look for ``moduledir`` in ``configure.ac``, default is normally
29``/usr/lib64/frr/modules`` but depends on ``--libdir`` / ``--prefix``.
30
31The daemon's name is prepended when looking for a module, e.g. "snmp"
32tries to find "zebra\_snmp" first when used in zebra. This is just to
33make it nicer for the user, with the snmp module having the same name
34everywhere.
35
36Modules can be packaged separately from FRR. The SNMP and FPM modules
37are good candidates for this because they have dependencies (net-snmp /
38protobuf) that are not FRR dependencies. However, any distro packages
39should have an "exact-match" dependency onto the FRR package. Using a
40module from a different FRR version will probably blow up nicely.
41
42For snapcraft (and during development), modules can be loaded with full
43path (e.g. -M ``$SNAP/lib/frr/modules/zebra_snmp.so``). Note that
44libtool puts output files in the .libs directory, so during development
45you have to use ``./zebra -M .libs/zebra_snmp.so``.
46
47Creating a module
48-----------------
49
50... best to look at the existing SNMP or FPM modules.
51
52Basic boilerplate:
53
54::
55
56 #include "hook.h"
57 #include "module.h"
2a7d9471 58 #include "libfrr.h"
24a58196 59 #include "frrevent.h"
2a7d9471 60
cd9d0537 61 static int module_late_init(struct event_loop *master)
2a7d9471
DS
62 {
63 /* Do initialization stuff here */
a2bd5d4c 64 return 0;
2a7d9471 65 }
d1890d04
QY
66
67 static int
68 module_init (void)
69 {
70 hook_register(frr_late_init, module_late_init);
71 return 0;
72 }
73
74 FRR_MODULE_SETUP(
75 .name = "my module",
76 .version = "0.0",
77 .description = "my module",
78 .init = module_init,
80413c20 79 );
d1890d04
QY
80
81The ``frr_late_init`` hook will be called after the daemon has finished
82its other startup and is about to enter the main event loop; this is the
83best place for most initialisation.
84
85Compiler & Linker magic
86-----------------------
87
88There's a ``THIS_MODULE`` (like in the Linux kernel), which uses
89``visibility`` attributes to restrict it to the current module. If you
90get a linker error with ``_frrmod_this_module``, there is some linker
91SNAFU. This shouldn't be possible, though one way to get it would be to
92not include libzebra (which provides a fallback definition for the
93symbol).
94
95libzebra and the daemons each have their own ``THIS_MODULE``, as do all
96loadable modules. In any other libraries (e.g. ``libfrrsnmp``),
97``THIS_MODULE`` will use the definition in libzebra; same applies if the
98main executable doesn't use ``FRR_DAEMON_INFO`` (e.g. all testcases).
99
100The deciding factor here is "what dynamic linker unit are you using the
101symbol from." If you're in a library function and want to know who
102called you, you can't use ``THIS_MODULE`` (because that'll just tell you
103you're in the library). Put a macro around your function that adds
104``THIS_MODULE`` in the *caller's code calling your function*.
105
106The idea is to use this in the future for module unloading. Hooks
107already remember which module they were installed by, as groundwork for
108a function that removes all of a module's installed hooks.
109
110There's also the ``frr_module`` symbol in modules, pretty much a
111standard entry point for loadable modules.
112
9e2f406a
EDP
113Command line parameters
114-----------------------
115
4c97fd1a
QY
116Command line parameters can be passed directly to a module by appending a
117colon to the module name when loading it, e.g. ``-M mymodule:myparameter``.
118The text after the colon will be accessible in the module's code through
9e2f406a
EDP
119``THIS_MODULE->load_args``. For example, see how the format parameter is
120configured in the ``zfpm_init()`` function inside ``zebra_fpm.c``.
121
d1890d04
QY
122Hooks
123-----
124
125Hooks are just points in the code where you can register your callback
126to be called. The parameter list is specific to the hook point. Since
127there is no stable API, the hook code has some extra type safety checks
128making sure you get a compiler warning when the hook parameter list
129doesn't match your callback. Don't ignore these warnings.
130
131Relation to MTYPE macros
132------------------------
133
134The MTYPE macros, while primarily designed to decouple MTYPEs from the
135library and beautify the code, also work very nicely with loadable
136modules -- both constructors and destructors are executed when
137loading/unloading modules.
138
139This means there is absolutely no change required to MTYPEs, you can
140just use them in a module and they will even clean up themselves when we
141implement module unloading and an unload happens. In fact, it's
142impossible to create a bug where unloading fails to de-register a MTYPE.