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