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