doc: document loadable module support

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2017-03-25 10:05:19 +01:00
parent 4f8ea50c0d
commit 6b0275ac35
16 changed files with 260 additions and 6 deletions

View File

@ -18,6 +18,7 @@ daemons.
* Config Commands:: Commands used in config files * Config Commands:: Commands used in config files
* Terminal Mode Commands:: Common commands used in a VTY * Terminal Mode Commands:: Common commands used in a VTY
* Common Invocation Options:: Starting the daemons * Common Invocation Options:: Starting the daemons
* Loadable Module Support:: Using extension modules
* Virtual Terminal Interfaces:: Interacting with the daemons * Virtual Terminal Interfaces:: Interacting with the daemons
@end menu @end menu
@ -372,6 +373,51 @@ Print program version.
@end table @end table
@node Loadable Module Support
@section Loadable Module Support
FRR supports loading extension modules at startup. Loading, reloading or
unloading modules at runtime is not supported (yet). To load a module, use
the following command line option at daemon startup:
@table @samp
@item -M @var{module:options}
@itemx --module @var{module:options}
Load the specified module, optionally passing options to it. If the module
name contains a slash (/), it is assumed to be a full pathname to a file to
be loaded. If it does not contain a slash, the
@code{@value{INSTALL_PREFIX_MODULES}} directory is searched for a module of
the given name; first with the daemon name prepended (e.g. @code{zebra_mod}
for @code{mod}), then without the daemon name prepended.
This option is available on all daemons, though some daemons may not have
any modules available to be loaded.
@end table
@subsection The SNMP Module
If SNMP is enabled during compile-time and installed as part of the package,
the @code{snmp} module can be loaded for the @command{zebra},
@command{bgpd}, @command{ospfd}, @command{ospf6d} and @command{ripd} daemons.
The module ignores any options passed to it. Refer to @ref{SNMP Support}
for information on its usage.
@subsection The FPM Module
If FPM is enabled during compile-time and installed as part of the package,
the @code{fpm} module can be loaded for the @command{zebra} daemon. This
provides the Forwarding Plane Manager ("FPM") API.
The module expects its argument to be either @code{netlink} or
@code{protobuf}, specifying the encapsulation to use. @code{netlink} is the
default, and @code{protobuf} may not be available if the module was built
without protobuf support. Refer to @ref{zebra FIB push interface} for more
information.
@node Virtual Terminal Interfaces @node Virtual Terminal Interfaces
@section Virtual Terminal Interfaces @section Virtual Terminal Interfaces

View File

@ -27,6 +27,9 @@ bgpd \- a BGPv4, BGPv4\+, BGPv4\- routing engine for use with @PACKAGE_FULLNAME@
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B bgpd .B bgpd
@ -76,6 +79,11 @@ When the program terminates, retain routes added by \fBbgpd\fR.
\fB\-S\fR, \fB\-\-skip_runas\fR \fB\-S\fR, \fB\-\-skip_runas\fR
Skip setting the process effective user and group. Skip setting the process effective user and group.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
The \fBsnmp\fR module may be available for
\fBbgpd\fR, if the package was built with SNMP support.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -13,6 +13,7 @@
@set INSTALL_PREFIX_ETC @CFG_SYSCONF@ @set INSTALL_PREFIX_ETC @CFG_SYSCONF@
@set INSTALL_PREFIX_SBIN @CFG_SBIN@ @set INSTALL_PREFIX_SBIN @CFG_SBIN@
@set INSTALL_PREFIX_STATE @CFG_STATE@ @set INSTALL_PREFIX_STATE @CFG_STATE@
@set INSTALL_PREFIX_MODULES @CFG_MODULE@
@set INSTALL_USER @enable_user@ @set INSTALL_USER @enable_user@
@set INSTALL_GROUP @enable_group@ @set INSTALL_GROUP @enable_group@
@set INSTALL_VTY_GROUP @enable_vty_group@ @set INSTALL_VTY_GROUP @enable_vty_group@

119
doc/dev-modules.md Normal file
View File

@ -0,0 +1,119 @@
# Module and Hook support (developer docs)
## What it does
It uses `dlopen()` to load DSOs at startup.
## Limitations
* can't load, unload, or reload during runtime. This just needs some work
and can probably be done in the future.
* doesn't fix any of the "things need to be changed in the code in the library"
issues. Most prominently, you can't add a CLI node because CLI nodes are
listed in the library...
* if your module crashes, the daemon crashes. Should be obvious.
* **does not provide a stable API or ABI**. Your module must match a version
of FRR and you may have to update it frequently to match changes.
* **does not create a license boundary**. Your module will need to link
libzebra and include header files from the daemons, meaning it will be
GPL-encumbered.
## Installation
Look for `moduledir` in `configure.ac`, default is normally
`/usr/lib64/frr/modules` but depends on `--libdir` / `--prefix`.
The daemon's name is prepended when looking for a module, e.g. "snmp" tries
to find "zebra_snmp" first when used in zebra. This is just to make it nicer
for the user, with the snmp module having the same name everywhere.
Modules can be packaged separately from FRR. The SNMP and FPM modules are
good candidates for this because they have dependencies (net-snmp / protobuf)
that are not FRR dependencies. However, any distro packages should have an
"exact-match" dependency onto the FRR package. Using a module from a
different FRR version will probably blow up nicely.
For snapcraft (and during development), modules can be loaded with full path
(e.g. -M `$SNAP/lib/frr/modules/zebra_snmp.so`). Note that libtool puts output
files in the .libs directory, so during development you have to use
`./zebra -M .libs/zebra_snmp.so`.
## Creating a module
... best to look at the existing SNMP or FPM modules.
Basic boilerplate:
```
#include "hook.h"
#include "module.h"
static int
module_init (void)
{
hook_register(frr_late_init, module_late_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "my module",
.version = "0.0",
.description = "my module",
.init = module_init,
)
```
The `frr_late_init` hook will be called after the daemon has finished its
other startup and is about to enter the main event loop; this is the best
place for most initialisation.
## Compiler & Linker magic
There's a `THIS_MODULE` (like in the Linux kernel), which uses `visibility`
attributes to restrict it to the current module. If you get a linker error
with `_frrmod_this_module`, there is some linker SNAFU. This shouldn't be
possible, though one way to get it would be to not include libzebra (which
provides a fallback definition for the symbol).
libzebra and the daemons each have their own `THIS_MODULE`, as do all loadable
modules. In any other libraries (e.g. `libfrrsnmp`), `THIS_MODULE` will use
the definition in libzebra; same applies if the main executable doesn't use
`FRR_DAEMON_INFO` (e.g. all testcases).
The deciding factor here is "what dynamic linker unit are you using the symbol
from." If you're in a library function and want to know who called you, you
can't use `THIS_MODULE` (because that'll just tell you you're in the library).
Put a macro around your function that adds `THIS_MODULE` in the *caller's
code calling your function*.
The idea is to use this in the future for module unloading. Hooks already
remember which module they were installed by, as groundwork for a function
that removes all of a module's installed hooks.
There's also the `frr_module` symbol in modules, pretty much a standard entry
point for loadable modules.
## Hooks
Hooks are just points in the code where you can register your callback to
be called. The parameter list is specific to the hook point. Since there is
no stable API, the hook code has some extra type safety checks making sure
you get a compiler warning when the hook parameter list doesn't match your
callback. Don't ignore these warnings.
## Relation to MTYPE macros
The MTYPE macros, while primarily designed to decouple MTYPEs from the library
and beautify the code, also work very nicely with loadable modules -- both
constructors and destructors are executed when loading/unloading modules.
This means there is absolutely no change required to MTYPEs, you can just use
them in a module and they will even clean up themselves when we implement
module unloading and an unload happens. In fact, it's impossible to create
a bug where unloading fails to de-register a MTYPE.

View File

@ -23,6 +23,9 @@ isisd \- an IS-IS routing engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B isisd .B isisd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR \fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR. Specify the user to run as. Default is \fI@enable_user@\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
There are currently no such modules for
\fBisisd\fR in the base package.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -23,6 +23,9 @@ ldpd \- an LDP engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B ldpd .B ldpd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR \fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR. Specify the user to run as. Default is \fI@enable_user@\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
There are currently no such modules for
\fBldpd\fR in the base package.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -385,7 +385,8 @@ ip protocol rip route-map RM1
Zebra supports a 'FIB push' interface that allows an external Zebra supports a 'FIB push' interface that allows an external
component to learn the forwarding information computed by the Frr component to learn the forwarding information computed by the Frr
routing suite. routing suite. This is a loadable module that needs to be enabled
at startup as described in @ref{Loadable Module Support}.
In Frr, the Routing Information Base (RIB) resides inside In Frr, the Routing Information Base (RIB) resides inside
zebra. Routing protocols communicate their best routes to zebra, and zebra. Routing protocols communicate their best routes to zebra, and
@ -440,9 +441,9 @@ independently.
@end itemize @end itemize
As mentioned before, zebra encodes routes sent to the FPM in netlink As mentioned before, zebra encodes routes sent to the FPM in netlink
format by default. The format can be controlled via the format by default. The format can be controlled via the FPM module's
@code{--fpm_format} command-line option to zebra, which currently load-time option to zebra, which currently takes the values @code{netlink}
takes the values @code{netlink} and @code{protobuf}. and @code{protobuf}.
The zebra FPM interface uses replace semantics. That is, if a 'route The zebra FPM interface uses replace semantics. That is, if a 'route
add' message for a prefix is followed by another 'route add' message, add' message for a prefix is followed by another 'route add' message,

View File

@ -23,6 +23,9 @@ nhrpd \- a Next Hop Routing Protocol routing engine for use with @PACKAGE_FULLNA
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B nhrpd .B nhrpd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR \fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR. Specify the user to run as. Default is \fI@enable_user@\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
There are currently no such modules for
\fBnhrpd\fR in the base package.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -23,6 +23,9 @@ ospf6d \- an OSPFv3 routing engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B ospf6d .B ospf6d
@ -64,6 +67,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR \fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR. Specify the user to run as. Default is \fI@enable_user@\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
The \fBsnmp\fR module may be available for
\fBospf6d\fR, if the package was built with SNMP support.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -23,6 +23,9 @@ ospfd \- an OSPFv2 routing engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B ospfd .B ospfd
@ -66,6 +69,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-a\fR, \fB\-\-apiserver \fR \fB\-a\fR, \fB\-\-apiserver \fR
Enable OSPF apiserver. Default is disabled. Enable OSPF apiserver. Default is disabled.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
The \fBsnmp\fR module may be available for
\fBospfd\fR, if the package was built with SNMP support.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -26,6 +26,9 @@ pimd \- a PIM routing for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B pimd .B pimd
@ -70,6 +73,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR \fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR. Specify the user to run as. Default is \fI@enable_user@\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
There are currently no such modules for
\fBpimd\fR in the base package.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.TP .TP

View File

@ -23,6 +23,9 @@ ripd \- a RIP routing engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B ripd .B ripd
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-r\fR, \fB\-\-retain\fR \fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBripd\fR. When the program terminates, retain routes added by \fBripd\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
The \fBsnmp\fR module may be available for
\fBripd\fR, if the package was built with SNMP support.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -23,6 +23,9 @@ ripngd \- a RIPNG routing engine for use with @PACKAGE_FULLNAME@.
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B ripngd .B ripngd
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-r\fR, \fB\-\-retain\fR \fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBripd\fR. When the program terminates, retain routes added by \fBripd\fR.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
There are currently no such modules for
\fBripngd\fR in the base package.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES

View File

@ -8,6 +8,10 @@ but is able to connect to a SNMP agent using the SMUX protocol
(@cite{RFC1227}) or the AgentX protocol (@cite{RFC2741}) and make the (@cite{RFC1227}) or the AgentX protocol (@cite{RFC2741}) and make the
routing protocol MIBs available through it. routing protocol MIBs available through it.
Note that SNMP Support needs to be enabled at compile-time and loaded as
module on daemon startup. Refer to @ref{Loadable Module Support} on
the latter.
@menu @menu
* Getting and installing an SNMP agent:: * Getting and installing an SNMP agent::
* AgentX configuration:: * AgentX configuration::

View File

@ -108,13 +108,13 @@ Set the logging
(LOG_DEBUG), but higher number can be supplied if extra debugging messages (LOG_DEBUG), but higher number can be supplied if extra debugging messages
are required. are required.
.TP .TP
.BI \-m " number" "\fR, \fB\-\-min\-restart\-interval " number .BI \-\-min\-restart\-interval " number
Set the minimum Set the minimum
.I number .I number
of seconds to wait between invocations of the daemon restart commands (the of seconds to wait between invocations of the daemon restart commands (the
default value is "60"). default value is "60").
.TP .TP
.BI \-M " number" "\fR, \fB\-\-max\-restart\-interval " number .BI \-\-max\-restart\-interval " number
Set the maximum Set the maximum
.I number .I number
of seconds to wait between invocations of the daemon restart commands (the of seconds to wait between invocations of the daemon restart commands (the

View File

@ -23,6 +23,9 @@ zebra \- a routing manager for use with associated @PACKAGE_FULLNAME@ components
] [ ] [
.B \-g .B \-g
.I group .I group
] [
.B \-M
.I module:options
] ]
.SH DESCRIPTION .SH DESCRIPTION
.B zebra .B zebra
@ -86,6 +89,14 @@ maximum before starting zebra.
Note that this affects Linux only. Note that this affects Linux only.
.TP .TP
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
Load a module at startup. May be specified more than once.
The \fBsnmp\fR and \fBfpm\fR modules may be
available for \fBzebra\fR, if the package was built with SNMP and FPM support
respectively. The \fBfpm\fR module takes an additional colon-separated
argument specifying the encapsulation, either \fBnetlink\fR or \fBprotobuf\fR.
It should thus be loaded with \fB-M fpm:netlink\fR or \fB-M fpm:protobuf\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version and exit. Print the version and exit.
.SH FILES .SH FILES