Merge branch 'master'

This commit is contained in:
David Lamparter 2017-04-04 20:04:07 +02:00
commit 422f8d0ca9
74 changed files with 1421 additions and 507 deletions

View File

@ -67,6 +67,7 @@ INSTALL_SDATA=@INSTALL@ -m 600
AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libbgp.a
module_LTLIBRARIES =
sbin_PROGRAMS = bgpd
bin_PROGRAMS = bgp_btoa
@ -75,7 +76,7 @@ libbgp_a_SOURCES = \
bgpd.c bgp_fsm.c bgp_aspath.c bgp_community.c bgp_attr.c \
bgp_debug.c bgp_route.c bgp_zebra.c bgp_open.c bgp_routemap.c \
bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c bgp_clist.c \
bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_lcommunity.c \
bgp_dump.c bgp_ecommunity.c bgp_lcommunity.c \
bgp_mplsvpn.c bgp_nexthop.c \
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
@ -89,7 +90,7 @@ noinst_HEADERS = \
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
bgp_ecommunity.h bgp_lcommunity.h \
bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.h \
bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h bgp_nht.h \
bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \
bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h \
$(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h bgp_vpn.h
@ -101,6 +102,14 @@ bgp_btoa_SOURCES = bgp_btoa.c
bgp_btoa_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
if SNMP
module_LTLIBRARIES += bgpd_snmp.la
endif
bgpd_snmp_la_SOURCES = bgp_snmp.c
bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
examplesdir = $(exampledir)
dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
bgpd.conf.vnc.sample

View File

@ -45,14 +45,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_advertise.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
#include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_bfd.h"
#include "bgpd/bgp_memory.h"
DEFINE_HOOK(peer_backward_transition, (struct peer *peer), (peer))
DEFINE_HOOK(peer_established, (struct peer *peer), (peer))
/* Definition of display strings corresponding to FSM events. This should be
* kept consistent with the events defined in bgpd.h
*/
@ -1061,9 +1061,7 @@ bgp_stop (struct peer *peer)
zlog_debug ("%s remove from all update group", peer->host);
update_group_remove_peer_afs(peer);
#ifdef HAVE_SNMP
bgpTrapBackwardTransition (peer);
#endif /* HAVE_SNMP */
hook_call(peer_backward_transition, peer);
/* Reset peer synctime */
peer->synctime = 0;
@ -1508,9 +1506,7 @@ bgp_establish (struct peer *peer)
zlog_debug ("%s graceful restart timer stopped", peer->host);
}
#ifdef HAVE_SNMP
bgpTrapEstablished (peer);
#endif /* HAVE_SNMP */
hook_call(peer_established, peer);
/* Reset uptime, send keepalive, send current table. */
peer->uptime = bgp_clock ();

View File

@ -109,4 +109,8 @@ extern void bgp_start_routeadv (struct bgp *);
*/
extern void bgp_adjust_routeadv (struct peer *);
#include "hook.h"
DECLARE_HOOK(peer_backward_transition, (struct peer *peer), (peer))
DECLARE_HOOK(peer_established, (struct peer *peer), (peer))
#endif /* _QUAGGA_BGP_FSM_H */

View File

@ -20,7 +20,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -31,6 +30,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "thread.h"
#include "smux.h"
#include "filter.h"
#include "hook.h"
#include "libfrr.h"
#include "version.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -38,7 +40,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_snmp.h"
/* BGP4-MIB described in RFC1657. */
#define BGP4MIB 1,3,6,1,2,1,15
@ -838,7 +839,7 @@ static struct trap_object bgpTrapList[] =
{3, {3, 1, BGPPEERSTATE}}
};
void
static int
bgpTrapEstablished (struct peer *peer)
{
int ret;
@ -847,7 +848,7 @@ bgpTrapEstablished (struct peer *peer)
ret = inet_aton (peer->host, &addr);
if (ret == 0)
return;
return 0;
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
@ -857,9 +858,10 @@ bgpTrapEstablished (struct peer *peer)
index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
BGPESTABLISHED);
return 0;
}
void
static int
bgpTrapBackwardTransition (struct peer *peer)
{
int ret;
@ -868,7 +870,7 @@ bgpTrapBackwardTransition (struct peer *peer)
ret = inet_aton (peer->host, &addr);
if (ret == 0)
return;
return 0;
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
@ -878,12 +880,29 @@ bgpTrapBackwardTransition (struct peer *peer)
index, IN_ADDR_SIZE,
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
BGPBACKWARDTRANSITION);
return 0;
}
void
bgp_snmp_init (void)
static int
bgp_snmp_init (struct thread_master *tm)
{
smux_init (bm->master);
smux_init (tm);
REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
return 0;
}
#endif /* HAVE_SNMP */
static int
bgp_snmp_module_init (void)
{
hook_register(peer_established, bgpTrapEstablished);
hook_register(peer_backward_transition, bgpTrapBackwardTransition);
hook_register(frr_late_init, bgp_snmp_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "bgpd_snmp",
.version = FRR_VERSION,
.description = "bgpd AgentX SNMP module",
.init = bgp_snmp_module_init
)

View File

@ -1,28 +0,0 @@
/* BGP4 SNMP support
Copyright (C) 1999, 2000 Kunihiro Ishiguro
This file is part of GNU Zebra.
GNU Zebra is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU Zebra is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Zebra; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef _QUAGGA_BGP_SNMP_H
#define _QUAGGA_BGP_SNMP_H
extern void bgp_snmp_init (void);
extern void bgpTrapEstablished (struct peer *);
extern void bgpTrapBackwardTransition (struct peer *);
#endif /* _QUAGGA_BGP_SNMP_H */

View File

@ -72,9 +72,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
#include "bgpd/bgp_updgrp.h"
#include "bgpd/bgp_bfd.h"
#include "bgpd/bgp_memory.h"
@ -7667,6 +7664,8 @@ bgp_if_finish (struct bgp *bgp)
}
}
extern void bgp_snmp_init (void);
void
bgp_init (void)
{
@ -7715,10 +7714,6 @@ bgp_init (void)
/* Community list initialize. */
bgp_clist = community_list_init ();
#ifdef HAVE_SNMP
bgp_snmp_init ();
#endif /* HAVE_SNMP */
/* BFD init */
bgp_bfd_init();
}

View File

@ -55,6 +55,13 @@ dnl XXX add --pkgsrcrcdir to autoconf standard directory list somehow
AC_SUBST(pkgsrcdir)
AC_SUBST(pkgsrcrcdir)
AC_ARG_WITH([moduledir], [AS_HELP_STRING([--with-moduledir=DIR], [module directory (${libdir}/frr/modules)])], [
moduledir="$withval"
], [
moduledir="\${libdir}/frr/modules"
])
AC_SUBST([moduledir], [$moduledir])
AC_ARG_ENABLE(tcmalloc,
AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]),
[case "${enableval}" in
@ -363,9 +370,7 @@ if test "${enable_shell_access}" = "yes"; then
AC_DEFINE(HAVE_SHELL_ACCESS,,Allow user to use ssh/telnet/bash)
fi
if test "${enable_fpm}" = "yes"; then
AC_DEFINE(HAVE_FPM,,Forwarding Plane Manager support)
fi
AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"])
if test "x${enable_dev_build}" = "xyes"; then
AC_DEFINE(DEV_BUILD,,Build for development)
@ -1322,8 +1327,8 @@ if test "${enable_snmp}" != ""; then
if test x"$NETSNMP_CONFIG" = x"no"; then
AC_MSG_ERROR([--enable-snmp given but unable to find net-snmp-config])
fi
LIBS="$LIBS `${NETSNMP_CONFIG} --agent-libs`"
CFLAGS="`${NETSNMP_CONFIG} --base-cflags` $CFLAGS"
SNMP_LIBS="`${NETSNMP_CONFIG} --agent-libs`"
SNMP_CFLAGS="`${NETSNMP_CONFIG} --base-cflags`"
AC_MSG_CHECKING([whether we can link to Net-SNMP])
AC_LINK_IFELSE([AC_LANG_PROGRAM([
int main(void);
@ -1335,7 +1340,6 @@ int main(void);
])],[AC_MSG_RESULT(yes)],[
AC_MSG_RESULT(no)
AC_MSG_ERROR([--enable-snmp given but not usable])])
AC_DEFINE(HAVE_SNMP,,SNMP)
case "${enable_snmp}" in
yes)
SNMP_METHOD=agentx
@ -1351,6 +1355,53 @@ int main(void);
AH_TEMPLATE([SNMP_AGENTX], [Use SNMP AgentX to interface with snmpd])
AC_DEFINE_UNQUOTED(AS_TR_CPP(SNMP_${SNMP_METHOD}),,SNMP method to interface with snmpd)
fi
AM_CONDITIONAL([SNMP], [test "x${SNMP_METHOD}" != "x"])
AC_SUBST(SNMP_LIBS)
AC_SUBST(SNMP_CFLAGS)
dnl ---------------
dnl dlopen & dlinfo
dnl ---------------
AC_SEARCH_LIBS(dlopen, [dl dld], [], [
AC_MSG_ERROR([unable to find the dlopen()])
])
AC_CHECK_HEADERS([link.h])
AC_MSG_CHECKING([for dlinfo(RTLD_DI_ORIGIN)])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
#ifdef HAVE_LINK_H
#include <link.h>
#endif
#include <dlfcn.h>
]], [[
char origin[1];
dlinfo (NULL, RTLD_DI_ORIGIN, &origin);
]])], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DLINFO_ORIGIN, 1, [Have dlinfo RTLD_DI_ORIGIN])
], [
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([for dlinfo(RTLD_DI_LINKMAP)])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
#ifdef HAVE_LINK_H
#include <link.h>
#endif
#include <dlfcn.h>
]], [[
struct link_map *lm = NULL;
dlinfo (NULL, RTLD_DI_LINKMAP, &lm);
]])], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DLINFO_LINKMAP, 1, [Have dlinfo RTLD_DI_LINKMAP])
], [
AC_MSG_RESULT(no)
])
dnl ---------------------------
dnl sockaddr and netinet checks
@ -1651,14 +1702,18 @@ AC_DEFINE_UNQUOTED(VTYSH_BIN_PATH, "$vtysh_bin",path to vtysh binary)
CFG_SYSCONF="$sysconfdir"
CFG_SBIN="$sbindir"
CFG_STATE="$frr_statedir"
CFG_MODULE="$moduledir"
for I in 1 2 3 4 5 6 7 8 9 10; do
eval CFG_SYSCONF="\"$CFG_SYSCONF\""
eval CFG_SBIN="\"$CFG_SBIN\""
eval CFG_STATE="\"$CFG_STATE\""
eval CFG_MODULE="\"$CFG_MODULE\""
done
AC_SUBST(CFG_SYSCONF)
AC_SUBST(CFG_SBIN)
AC_SUBST(CFG_STATE)
AC_SUBST(CFG_MODULE)
AC_DEFINE_UNQUOTED(MODULE_PATH, "$CFG_MODULE", path to modules)
dnl ---------------------------
dnl Check htonl works correctly
@ -1734,6 +1789,7 @@ linker flags : ${LDFLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
state file directory : ${frr_statedir}
config file directory : `eval echo \`echo ${sysconfdir}\``
example directory : `eval echo \`echo ${exampledir}\``
module directory : ${CFG_MODULE}
user to run as : ${enable_user}
group to run as : ${enable_group}
group for vty sockets : ${enable_vty_group}

View File

@ -18,6 +18,7 @@ daemons.
* Config Commands:: Commands used in config files
* Terminal Mode Commands:: Common commands used in a VTY
* Common Invocation Options:: Starting the daemons
* Loadable Module Support:: Using extension modules
* Virtual Terminal Interfaces:: Interacting with the daemons
@end menu
@ -372,6 +373,51 @@ Print program version.
@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
@section Virtual Terminal Interfaces

View File

@ -27,6 +27,9 @@ bgpd \- a BGPv4, BGPv4\+, BGPv4\- routing engine for use with @PACKAGE_FULLNAME@
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B bgpd
@ -76,6 +79,11 @@ When the program terminates, retain routes added by \fBbgpd\fR.
\fB\-S\fR, \fB\-\-skip_runas\fR
Skip setting the process effective user and group.
.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
Print the version and exit.
.SH FILES

View File

@ -13,6 +13,7 @@
@set INSTALL_PREFIX_ETC @CFG_SYSCONF@
@set INSTALL_PREFIX_SBIN @CFG_SBIN@
@set INSTALL_PREFIX_STATE @CFG_STATE@
@set INSTALL_PREFIX_MODULES @CFG_MODULE@
@set INSTALL_USER @enable_user@
@set INSTALL_GROUP @enable_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
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B isisd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR.
.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
Print the version and exit.
.SH FILES

View File

@ -23,6 +23,9 @@ ldpd \- an LDP engine for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B ldpd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR.
.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
Print the version and exit.
.SH FILES

View File

@ -385,7 +385,8 @@ ip protocol rip route-map RM1
Zebra supports a 'FIB push' interface that allows an external
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
zebra. Routing protocols communicate their best routes to zebra, and
@ -440,9 +441,9 @@ independently.
@end itemize
As mentioned before, zebra encodes routes sent to the FPM in netlink
format by default. The format can be controlled via the
@code{--fpm_format} command-line option to zebra, which currently
takes the values @code{netlink} and @code{protobuf}.
format by default. The format can be controlled via the FPM module's
load-time option to zebra, which currently takes the values @code{netlink}
and @code{protobuf}.
The zebra FPM interface uses replace semantics. That is, if a 'route
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
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B nhrpd
@ -63,6 +66,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR.
.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
Print the version and exit.
.SH FILES

View File

@ -23,6 +23,9 @@ ospf6d \- an OSPFv3 routing engine for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B ospf6d
@ -64,6 +67,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR.
.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
Print the version and exit.
.SH FILES

View File

@ -23,6 +23,9 @@ ospfd \- an OSPFv2 routing engine for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B ospfd
@ -66,6 +69,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-a\fR, \fB\-\-apiserver \fR
Enable OSPF apiserver. Default is disabled.
.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
Print the version and exit.
.SH FILES

View File

@ -26,6 +26,9 @@ pimd \- a PIM routing for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B pimd
@ -70,6 +73,11 @@ interfaces.
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fI@enable_user@\fR.
.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
Print the version and exit.
.TP

View File

@ -23,6 +23,9 @@ ripd \- a RIP routing engine for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B ripd
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBripd\fR.
.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
Print the version and exit.
.SH FILES

View File

@ -23,6 +23,9 @@ ripngd \- a RIPNG routing engine for use with @PACKAGE_FULLNAME@.
] [
.B \-g
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B ripngd
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBripd\fR.
.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
Print the version and exit.
.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
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
* Getting and installing an SNMP agent::
* AgentX configuration::

View File

@ -108,13 +108,13 @@ Set the logging
(LOG_DEBUG), but higher number can be supplied if extra debugging messages
are required.
.TP
.BI \-m " number" "\fR, \fB\-\-min\-restart\-interval " number
.BI \-\-min\-restart\-interval " number
Set the minimum
.I number
of seconds to wait between invocations of the daemon restart commands (the
default value is "60").
.TP
.BI \-M " number" "\fR, \fB\-\-max\-restart\-interval " number
.BI \-\-max\-restart\-interval " number
Set the maximum
.I number
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
.I group
] [
.B \-M
.I module:options
]
.SH DESCRIPTION
.B zebra
@ -86,6 +89,14 @@ maximum before starting zebra.
Note that this affects Linux only.
.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
Print the version and exit.
.SH FILES

View File

@ -20,7 +20,7 @@ libfrr_la_SOURCES = \
command.c \
sockunion.c prefix.c thread.c if.c buffer.c table.c hash.c \
filter.c routemap.c distribute.c stream.c log.c plist.c \
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
zclient.c sockopt.c md5.c if_rmap.c keychain.c privs.c \
sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \
ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \
imsg-buffer.c imsg.c skiplist.c \
@ -31,12 +31,28 @@ libfrr_la_SOURCES = \
spf_backoff.c \
libfrr.c \
strlcpy.c \
strlcat.c
strlcat.c \
module.c \
hook.c \
# end
BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h
libfrr_la_LIBADD = @LIBCAP@
if SNMP
lib_LTLIBRARIES += libfrrsnmp.la
endif
libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
libfrrsnmp_la_LDFLAGS = -version-info 0:0:0
libfrrsnmp_la_LIBADD = libfrr.la $(SNMP_LIBS)
libfrrsnmp_la_SOURCES = \
agentx.c \
smux.c \
snmp.c \
#end
pkginclude_HEADERS = \
buffer.h checksum.h filter.h getopt.h hash.h \
if.h linklist.h log.h \
@ -54,6 +70,8 @@ pkginclude_HEADERS = \
monotime.h \
spf_backoff.h \
srcdest_table.h \
module.h \
hook.h \
libfrr.h \
# end

View File

@ -21,7 +21,7 @@
#include <zebra.h>
#if defined HAVE_SNMP && defined SNMP_AGENTX
#ifdef SNMP_AGENTX
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
@ -315,4 +315,4 @@ smux_trap (struct variable *vp, size_t vp_len,
return 1;
}
#endif /* HAVE_SNMP */
#endif /* SNMP_AGENTX */

56
lib/hook.c Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016 David Lamparter, for NetDEF, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "memory.h"
#include "hook.h"
DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry")
void _hook_register(struct hook *hook, void *funcptr, void *arg, bool has_arg,
struct frrmod_runtime *module, const char *funcname)
{
struct hookent *he = XCALLOC(MTYPE_HOOK_ENTRY, sizeof(*he));
he->hookfn = funcptr;
he->hookarg = arg;
he->has_arg = has_arg;
he->module = module;
he->fnname = funcname;
he->next = hook->entries;
hook->entries = he;
}
void _hook_unregister(struct hook *hook, void *funcptr,
void *arg, bool has_arg)
{
struct hookent *he, **prev;
for (prev = &hook->entries; (he = *prev) != NULL; prev = &he->next)
if (he->hookfn == funcptr && he->hookarg == arg
&& he->has_arg == has_arg)
{
*prev = he->next;
XFREE(MTYPE_HOOK_ENTRY, he);
break;
}
}

187
lib/hook.h Normal file
View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2016 David Lamparter, for NetDEF, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _FRR_HOOK_H
#define _FRR_HOOK_H
#include <stdbool.h>
#include "module.h"
#include "memory.h"
/* type-safe subscribable hook points
*
* where "type-safe" applies to the function pointers used for subscriptions
*
* overall usage:
* - to create a hook:
*
* mydaemon.h:
* #include "hook.h"
* DECLARE_HOOK (some_update_event, (struct eventinfo *info), (info))
*
* mydaemon.c:
* DEFINE_HOOK (some_update_event, (struct eventinfo *info), (info))
* ...
* hook_call (some_update_event, info)
*
* Note: the second and third macro args must be the hook function's
* parameter list, with the same names for each parameter. The second
* macro arg is with types (used for defining things), the third arg is
* just the names (used for passing along parameters).
*
* Do not use parameter names starting with "hook", these can collide with
* names used by the hook code itself.
*
* The return value is always "int" for now; hook_call will sum up the
* return values from each registered user. Default is 0.
*
* There are no pre-defined semantics for the value, in most cases it is
* ignored. For success/failure indication, 0 should be success, and
* handlers should make sure to only return 0 or 1 (not -1 or other values).
*
*
* - to use a hook / create a handler:
*
* #include "mydaemon.h"
* int event_handler (struct eventinfo *info) { ... }
* hook_register (some_update_event, event_handler);
*
* or, if you need an argument to be passed along (addonptr will be added
* as first argument when calling the handler):
*
* #include "mydaemon.h"
* int event_handler (void *addonptr, struct eventinfo *info) { ... }
* hook_register_arg (some_update_event, event_handler, addonptr);
*
* (addonptr isn't typesafe, but that should be manageable.)
*/
/* TODO:
* - hook_unregister_all_module()
* - introspection / CLI / debug
* - testcases ;)
*
* For loadable modules, the idea is that hooks could be automatically
* unregistered when a module is unloaded.
*
* It's also possible to add a constructor (MTYPE style) to DEFINE_HOOK,
* which would make it possible for the CLI to show all hooks and all
* registered handlers.
*/
struct hookent {
struct hookent *next;
void *hookfn; /* actually a function pointer */
void *hookarg;
bool has_arg;
struct frrmod_runtime *module;
const char *fnname;
};
struct hook {
const char *name;
struct hookent *entries;
};
/* subscribe/add callback function to a hook
*
* always use hook_register(), which uses the static inline helper from
* DECLARE_HOOK in order to get type safety
*/
extern void _hook_register(struct hook *hook, void *funcptr, void *arg,
bool has_arg, struct frrmod_runtime *module,
const char *funcname);
#define hook_register(hookname, func) \
_hook_register(&_hook_ ## hookname, \
_hook_typecheck_ ## hookname (func), \
NULL, false, THIS_MODULE, #func)
#define hook_register_arg(hookname, func, arg) \
_hook_register(&_hook_ ## hookname, \
_hook_typecheck_arg_ ## hookname (func), \
arg, true, THIS_MODULE, #func)
extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg,
bool has_arg);
#define hook_unregister(hookname, func) \
_hook_unregister(&_hook_ ## hookname, \
_hook_typecheck_ ## hookname (func), NULL, false)
#define hook_unregister_arg(hookname, func, arg) \
_hook_unregister(&_hook_ ## hookname, \
_hook_typecheck_arg_ ## hookname (func), arg, true)
/* invoke hooks
* this is private (static) to the file that has the DEFINE_HOOK statement
*/
#define hook_call(hookname, ...) \
hook_call_ ## hookname (__VA_ARGS__)
/* helpers to add the void * arg */
#define HOOK_ADDDEF(...) (void *hookarg , ## __VA_ARGS__)
#define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__)
/* use in header file - declares the hook and its arguments
* usage: DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2))
* as above, "passlist" must use the same order and same names as "arglist"
*
* theoretically passlist is not neccessary, but let's keep things simple and
* use exact same args on DECLARE and DEFINE.
*/
#define DECLARE_HOOK(hookname, arglist, passlist) \
extern struct hook _hook_ ## hookname; \
__attribute__((unused)) \
static void *_hook_typecheck_ ## hookname ( \
int (*funcptr) arglist) { \
return (void *)funcptr; } \
__attribute__((unused)) \
static void *_hook_typecheck_arg_ ## hookname ( \
int (*funcptr) HOOK_ADDDEF arglist) { \
return (void *)funcptr; }
/* use in source file - contains hook-related definitions.
*/
#define DEFINE_HOOK(hookname, arglist, passlist) \
struct hook _hook_ ## hookname = { \
.name = #hookname, \
.entries = NULL, \
}; \
static int hook_call_ ## hookname arglist { \
int hooksum = 0; \
struct hookent *he = _hook_ ## hookname .entries; \
void *hookarg; \
union { \
void *voidptr; \
int (*fptr) arglist; \
int (*farg) HOOK_ADDDEF arglist; \
} hookp; \
for (; he; he = he->next) { \
hookarg = he->hookarg; \
hookp.voidptr = he->hookfn; \
if (!he->has_arg) \
hooksum += hookp.fptr passlist; \
else \
hooksum += hookp.farg HOOK_ADDARG passlist; \
} \
return hooksum; \
}
#endif /* _FRR_HOOK_H */

View File

@ -28,6 +28,9 @@
#include "memory_vty.h"
#include "zclient.h"
#include "log_int.h"
#include "module.h"
DEFINE_HOOK(frr_late_init, (struct thread_master *tm), (tm))
const char frr_sysconfdir[] = SYSCONFDIR;
const char frr_vtydir[] = DAEMON_VTY_DIR;
@ -64,14 +67,16 @@ static const struct option lo_always[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "daemon", no_argument, NULL, 'd' },
{ "module", no_argument, NULL, 'M' },
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ NULL }
};
static const struct optspec os_always = {
"hvdi:",
"hvdM:",
" -h, --help Display this help and exit\n"
" -v, --version Print program version\n"
" -d, --daemon Runs in daemon mode\n"
" -M, --module Load specified module\n"
" --vty_socket Override vty socket path\n",
lo_always
};
@ -184,12 +189,18 @@ void frr_help_exit(int status)
exit(status);
}
struct option_chain {
struct option_chain *next;
const char *arg;
};
static struct option_chain *modules = NULL, **modnext = &modules;
static int errors = 0;
static int frr_opt(int opt)
{
static int vty_port_set = 0;
static int vty_addr_set = 0;
struct option_chain *oc;
char *err;
switch (opt) {
@ -203,6 +214,13 @@ static int frr_opt(int opt)
case 'd':
di->daemon_mode = 1;
break;
case 'M':
oc = XMALLOC(MTYPE_TMP, sizeof(*oc));
oc->arg = optarg;
oc->next = NULL;
*modnext = oc;
modnext = &oc->next;
break;
case 'i':
if (di->flags & FRR_NO_CFG_PID_DRY)
return 1;
@ -295,9 +313,12 @@ int frr_getopt(int argc, char * const argv[], int *longindex)
return opt;
}
static struct thread_master *master;
struct thread_master *frr_init(void)
{
struct thread_master *master;
struct option_chain *oc;
struct frrmod_runtime *module;
char moderr[256];
srandom(time(NULL));
@ -307,6 +328,17 @@ struct thread_master *frr_init(void)
zlog_set_level (ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
#endif
frrmod_init(di->module);
while (modules) {
modules = (oc = modules)->next;
module = frrmod_load(oc->arg, moderr, sizeof(moderr));
if (!module) {
fprintf(stderr, "%s\n", moderr);
exit(1);
}
XFREE(MTYPE_TMP, oc);
}
zprivs_init(di->privs);
master = thread_master_create();
@ -324,6 +356,8 @@ struct thread_master *frr_init(void)
void frr_config_fork(void)
{
hook_call(frr_late_init, master);
if (di->instance) {
snprintf(config_default, sizeof(config_default), "%s/%s-%d.conf",
frr_sysconfdir, di->name, di->instance);

View File

@ -26,6 +26,8 @@
#include "thread.h"
#include "log.h"
#include "getopt.h"
#include "module.h"
#include "hook.h"
#define FRR_NO_PRIVSEP (1 << 0)
#define FRR_NO_TCPVTY (1 << 1)
@ -40,6 +42,7 @@ struct frr_daemon_info {
const char *name;
const char *logname;
unsigned short instance;
struct frrmod_runtime *module;
char *vty_addr;
int vty_port;
@ -67,15 +70,22 @@ struct frr_daemon_info {
* i.e. "ZEBRA" or "BGP"
*
* note that this macro is also a latch-on point for other changes (e.g.
* upcoming plugin support) that need to place some per-daemon things. Each
* upcoming module support) that need to place some per-daemon things. Each
* daemon should have one of these.
*/
#define FRR_DAEMON_INFO(execname, constname, ...) \
static struct frr_daemon_info execname ##_di = { \
.name = # execname, \
.logname = # constname, \
.module = THIS_MODULE, \
__VA_ARGS__ \
};
}; \
FRR_COREMOD_SETUP( \
.name = # execname, \
.description = # execname " daemon", \
.version = FRR_VERSION, \
) \
/* end */
extern void frr_preinit(struct frr_daemon_info *daemon,
int argc, char **argv);
@ -86,6 +96,7 @@ extern void frr_help_exit(int status);
extern struct thread_master *frr_init(void);
DECLARE_HOOK(frr_late_init, (struct thread_master *tm), (tm))
extern void frr_config_fork(void);
extern void frr_vty_serv(void);

View File

@ -1,23 +1,22 @@
/*
* Memory management routine
* Memory and dynamic module VTY routine
*
* Copyright (C) 1998 Kunihiro Ishiguro
* Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc.
*
* This file is part of GNU Zebra.
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <zebra.h>
@ -25,9 +24,12 @@
#if (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
#include <malloc.h>
#endif /* HAVE_MALLINFO */
#include <dlfcn.h>
#include <link.h>
#include "log.h"
#include "memory.h"
#include "module.h"
#include "memory_vty.h"
/* Looking up memory status from vty interface. */
@ -110,10 +112,55 @@ DEFUN (show_memory,
return CMD_SUCCESS;
}
DEFUN (show_modules,
show_modules_cmd,
"show modules",
"Show running system information\n"
"Loaded modules\n")
{
struct frrmod_runtime *plug = frrmod_list;
vty_out (vty, "%-12s %-25s %s%s%s",
"Module Name", "Version", "Description",
VTY_NEWLINE, VTY_NEWLINE);
while (plug)
{
const struct frrmod_info *i = plug->info;
vty_out (vty, "%-12s %-25s %s%s", i->name, i->version, i->description,
VTY_NEWLINE);
if (plug->dl_handle)
{
#ifdef HAVE_DLINFO_ORIGIN
char origin[MAXPATHLEN] = "";
dlinfo (plug->dl_handle, RTLD_DI_ORIGIN, &origin);
# ifdef HAVE_DLINFO_LINKMAP
const char *name;
struct link_map *lm = NULL;
dlinfo (plug->dl_handle, RTLD_DI_LINKMAP, &lm);
if (lm)
{
name = strrchr(lm->l_name, '/');
name = name ? name + 1 : lm->l_name;
vty_out (vty, "\tfrom: %s/%s%s", origin, name, VTY_NEWLINE);
}
# else
vty_out (vty, "\tfrom: %s %s", origin, plug->load_name, VTY_NEWLINE);
# endif
#else
vty_out (vty, "\tfrom: %s%s", plug->load_name, VTY_NEWLINE);
#endif
}
plug = plug->next;
}
return CMD_SUCCESS;
}
void
memory_init (void)
{
install_element (VIEW_NODE, &show_memory_cmd);
install_element (VIEW_NODE, &show_modules_cmd);
}
/* Stats querying from users */

159
lib/module.c Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <dlfcn.h>
#include "module.h"
#include "memory.h"
#include "version.h"
DEFINE_MTYPE_STATIC(LIB, MODULE_LOADNAME, "Module loading name")
DEFINE_MTYPE_STATIC(LIB, MODULE_LOADARGS, "Module loading arguments")
static struct frrmod_info frrmod_default_info = {
.name = "libfrr",
.version = FRR_VERSION,
.description = "libfrr core module",
};
union _frrmod_runtime_u frrmod_default = {
.r.info = &frrmod_default_info,
.r.finished_loading = 1,
};
// if defined(HAVE_SYS_WEAK_ALIAS_ATTRIBUTE)
// union _frrmod_runtime_u _frrmod_this_module
// __attribute__((weak, alias("frrmod_default")));
// elif defined(HAVE_SYS_WEAK_ALIAS_PRAGMA)
#pragma weak _frrmod_this_module = frrmod_default
// else
// error need weak symbol support
// endif
struct frrmod_runtime *frrmod_list = &frrmod_default.r;
static struct frrmod_runtime **frrmod_last = &frrmod_default.r.next;
static const char *execname = NULL;
void frrmod_init(struct frrmod_runtime *modinfo)
{
modinfo->finished_loading = 1;
*frrmod_last = modinfo;
frrmod_last = &modinfo->next;
execname = modinfo->info->name;
}
struct frrmod_runtime *frrmod_load(const char *spec,
char *err, size_t err_len)
{
void *handle = NULL;
char name[PATH_MAX], fullpath[PATH_MAX], *args;
struct frrmod_runtime *rtinfo, **rtinfop;
const struct frrmod_info *info;
snprintf(name, sizeof(name), "%s", spec);
args = strchr(name, ':');
if (args)
*args++ = '\0';
if (!strchr(name, '/')) {
if (!handle && execname) {
snprintf(fullpath, sizeof(fullpath), "%s/%s_%s.so",
MODULE_PATH, execname, name);
handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
}
if (!handle) {
snprintf(fullpath, sizeof(fullpath), "%s/%s.so",
MODULE_PATH, name);
handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
}
}
if (!handle) {
snprintf(fullpath, sizeof(fullpath), "%s", name);
handle = dlopen(fullpath, RTLD_NOW | RTLD_GLOBAL);
}
if (!handle) {
if (err)
snprintf(err, err_len,
"loading module \"%s\" failed: %s",
name, dlerror());
return NULL;
}
rtinfop = dlsym(handle, "frr_module");
if (!rtinfop) {
dlclose(handle);
if (err)
snprintf(err, err_len,
"\"%s\" is not a Quagga module: %s",
name, dlerror());
return NULL;
}
rtinfo = *rtinfop;
rtinfo->load_name = XSTRDUP(MTYPE_MODULE_LOADNAME, name);
rtinfo->dl_handle = handle;
if (args)
rtinfo->load_args = XSTRDUP(MTYPE_MODULE_LOADARGS, args);
info = rtinfo->info;
if (rtinfo->finished_loading) {
dlclose(handle);
if (err)
snprintf(err, err_len,
"module \"%s\" already loaded",
name);
goto out_fail;
}
if (info->init && info->init()) {
dlclose(handle);
if (err)
snprintf(err, err_len,
"module \"%s\" initialisation failed",
name);
goto out_fail;
}
rtinfo->finished_loading = 1;
*frrmod_last = rtinfo;
frrmod_last = &rtinfo->next;
return rtinfo;
out_fail:
if (rtinfo->load_args)
XFREE(MTYPE_MODULE_LOADARGS, rtinfo->load_args);
XFREE(MTYPE_MODULE_LOADNAME, rtinfo->load_name);
return NULL;
}
#if 0
void frrmod_unload(struct frrmod_runtime *module)
{
}
#endif

104
lib/module.h Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2015-16 David Lamparter, for NetDEF, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _FRR_MODULE_H
#define _FRR_MODULE_H
#include <stdint.h>
#include <stdbool.h>
#if !defined(__GNUC__)
# error module code needs GCC visibility extensions
#elif __GNUC__ < 4
# error module code needs GCC visibility extensions
#else
# define DSO_PUBLIC __attribute__ ((visibility ("default")))
# define DSO_SELF __attribute__ ((visibility ("protected")))
# define DSO_LOCAL __attribute__ ((visibility ("hidden")))
#endif
struct frrmod_runtime;
struct frrmod_info {
/* single-line few-word title */
const char *name;
/* human-readable version number, should not contain spaces */
const char *version;
/* one-paragraph description */
const char *description;
int (*init)(void);
};
/* primary entry point structure to be present in loadable module under
* "_frrmod_this_module" dlsym() name
*
* note space for future extensions is reserved below, so other modules
* (e.g. memory management, hooks) can add fields
*
* const members/info are in frrmod_info.
*/
struct frrmod_runtime {
struct frrmod_runtime *next;
const struct frrmod_info *info;
void *dl_handle;
bool finished_loading;
char *load_name;
char *load_args;
};
/* space-reserving foo */
struct _frrmod_runtime_size {
struct frrmod_runtime r;
/* this will barf if frrmod_runtime exceeds 1024 bytes ... */
uint8_t space[1024 - sizeof(struct frrmod_runtime)];
};
union _frrmod_runtime_u {
struct frrmod_runtime r;
struct _frrmod_runtime_size s;
};
extern union _frrmod_runtime_u _frrmod_this_module;
#define THIS_MODULE (&_frrmod_this_module.r)
#define FRR_COREMOD_SETUP(...) \
static const struct frrmod_info _frrmod_info = { __VA_ARGS__ }; \
DSO_LOCAL union _frrmod_runtime_u _frrmod_this_module = { \
.r.info = &_frrmod_info, \
};
#define FRR_MODULE_SETUP(...) \
FRR_COREMOD_SETUP(__VA_ARGS__) \
DSO_SELF struct frrmod_runtime *frr_module = &_frrmod_this_module.r;
extern struct frrmod_runtime *frrmod_list;
extern void frrmod_init(struct frrmod_runtime *modinfo);
extern struct frrmod_runtime *frrmod_load(const char *spec,
char *err, size_t err_len);
#if 0
/* not implemented yet */
extern void frrmod_unload(struct frrmod_runtime *module);
#endif
#endif /* _FRR_MODULE_H */

View File

@ -21,7 +21,7 @@
#include <zebra.h>
#if defined HAVE_SNMP && defined SNMP_SMUX
#ifdef SNMP_SMUX
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -1445,4 +1445,4 @@ smux_start(void)
/* Schedule first connection. */
smux_event (SMUX_SCHEDULE, 0);
}
#endif /* HAVE_SNMP */
#endif /* SNMP_SMUX */

View File

@ -21,7 +21,6 @@
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -130,4 +129,3 @@ smux_header_table (struct variable *v, oid *name, size_t *length, int exact,
return MATCH_SUCCEEDED;
}
#endif /* HAVE_SNMP */

View File

@ -1037,28 +1037,6 @@ thread_process_fds_helper (struct thread_master *m, struct thread *thread, threa
#if defined(HAVE_POLL)
#if defined(HAVE_SNMP)
/* add snmp fds to poll set */
static void
add_snmp_pollfds(struct thread_master *m, fd_set *snmpfds, int fdsetsize)
{
int i;
m->handler.pfdcountsnmp = m->handler.pfdcount;
/* cycle trough fds and add neccessary fds to poll set */
for (i=0;i<fdsetsize;++i)
{
if (FD_ISSET(i, snmpfds))
{
assert (m->handler.pfdcountsnmp <= m->handler.pfdsize);
m->handler.pfds[m->handler.pfdcountsnmp].fd = i;
m->handler.pfds[m->handler.pfdcountsnmp].events = POLLIN;
m->handler.pfdcountsnmp++;
}
}
}
#endif
/* check poll events */
static void
check_pollfds(struct thread_master *m, fd_set *readfd, int num)

View File

@ -7,6 +7,7 @@ INSTALL_SDATA=@INSTALL@ -m 600
AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libospf6.a
module_LTLIBRARIES =
sbin_PROGRAMS = ospf6d
libospf6_a_SOURCES = \
@ -14,7 +15,7 @@ libospf6_a_SOURCES = \
ospf6_network.c ospf6_message.c ospf6_lsa.c ospf6_lsdb.c \
ospf6_top.c ospf6_area.c ospf6_interface.c ospf6_neighbor.c \
ospf6_flood.c ospf6_route.c ospf6_intra.c ospf6_zebra.c \
ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6_abr.c ospf6_snmp.c \
ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6_abr.c \
ospf6d.c ospf6_bfd.c
noinst_HEADERS = \
@ -22,7 +23,7 @@ noinst_HEADERS = \
ospf6_network.h ospf6_message.h ospf6_lsa.h ospf6_lsdb.h \
ospf6_top.h ospf6_area.h ospf6_interface.h ospf6_neighbor.h \
ospf6_flood.h ospf6_route.h ospf6_intra.h ospf6_zebra.h \
ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6_abr.h ospf6_snmp.h \
ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6_abr.h \
ospf6d.h ospf6_bfd.h
ospf6d_SOURCES = \
@ -30,5 +31,12 @@ ospf6d_SOURCES = \
ospf6d_LDADD = ../lib/libfrr.la @LIBCAP@
if SNMP
module_LTLIBRARIES += ospf6d_snmp.la
endif
ospf6d_snmp_la_SOURCES = ospf6_snmp.c
ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ospf6d_snmp_la_LIBADD = ../lib/libfrrsnmp.la
examplesdir = $(exampledir)
dist_examples_DATA = ospf6d.conf.sample

View File

@ -41,12 +41,14 @@
#include "ospf6_neighbor.h"
#include "ospf6_intra.h"
#include "ospf6_spf.h"
#include "ospf6_snmp.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
DEFINE_QOBJ_TYPE(ospf6_interface)
DEFINE_HOOK(ospf6_interface_change,
(struct ospf6_interface *oi, int state, int old_state),
(oi, state, old_state))
unsigned char conf_debug_ospf6_interface = 0;
@ -518,16 +520,7 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
}
#ifdef HAVE_SNMP
/* Terminal state or regression */
if ((next_state == OSPF6_INTERFACE_POINTTOPOINT) ||
(next_state == OSPF6_INTERFACE_DROTHER) ||
(next_state == OSPF6_INTERFACE_BDR) ||
(next_state == OSPF6_INTERFACE_DR) ||
(next_state < prev_state))
ospf6TrapIfStateChange (oi);
#endif
hook_call(ospf6_interface_change, oi, next_state, prev_state);
}

View File

@ -23,6 +23,7 @@
#define OSPF6_INTERFACE_H
#include "qobj.h"
#include "hook.h"
#include "if.h"
/* Debug option */
@ -182,4 +183,8 @@ extern void install_element_ospf6_clear_interface (void);
extern int config_write_ospf6_debug_interface (struct vty *vty);
extern void install_element_ospf6_debug_interface (void);
DECLARE_HOOK(ospf6_interface_change,
(struct ospf6_interface *oi, int state, int old_state),
(oi, state, old_state))
#endif /* OSPF6_INTERFACE_H */

View File

@ -38,7 +38,6 @@
#include "ospf6_neighbor.h"
#include "ospf6_intra.h"
#include "ospf6_flood.h"
#include "ospf6_snmp.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
#include "ospf6_abr.h"
@ -47,6 +46,10 @@
#include "ospf6_spf.h"
#include "ospf6_zebra.h"
DEFINE_HOOK(ospf6_neighbor_change,
(struct ospf6_neighbor *on, int state, int next_state),
(on, state, next_state))
unsigned char conf_debug_ospf6_neighbor = 0;
const char *ospf6_neighbor_state_str[] =
@ -202,13 +205,7 @@ ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int e
next_state != OSPF6_NEIGHBOR_LOADING))
ospf6_maxage_remove (on->ospf6_if->area->ospf6);
#ifdef HAVE_SNMP
/* Terminal state or regression */
if ((next_state == OSPF6_NEIGHBOR_FULL) ||
(next_state == OSPF6_NEIGHBOR_TWOWAY) ||
(next_state < prev_state))
ospf6TrapNbrStateChange (on);
#endif
hook_call(ospf6_neighbor_change, on, next_state, prev_state);
ospf6_bfd_trigger_event(on, prev_state, next_state);
}

View File

@ -22,6 +22,8 @@
#ifndef OSPF6_NEIGHBOR_H
#define OSPF6_NEIGHBOR_H
#include "hook.h"
/* Debug option */
extern unsigned char conf_debug_ospf6_neighbor;
#define OSPF6_DEBUG_NEIGHBOR_STATE 0x01
@ -179,4 +181,8 @@ extern void ospf6_neighbor_init (void);
extern int config_write_ospf6_debug_neighbor (struct vty *vty);
extern void install_element_ospf6_debug_neighbor (void);
DECLARE_HOOK(ospf6_neighbor_change,
(struct ospf6_neighbor *on, int state, int next_state),
(on, state, next_state))
#endif /* OSPF6_NEIGHBOR_H */

View File

@ -21,8 +21,6 @@
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -32,6 +30,8 @@
#include "vector.h"
#include "vrf.h"
#include "smux.h"
#include "libfrr.h"
#include "version.h"
#include "ospf6_proto.h"
#include "ospf6_lsa.h"
@ -45,7 +45,6 @@
#include "ospf6_abr.h"
#include "ospf6_asbr.h"
#include "ospf6d.h"
#include "ospf6_snmp.h"
/* OSPFv3-MIB */
#define OSPFv3MIB 1,3,6,1,2,1,191
@ -1139,11 +1138,18 @@ static struct trap_object ospf6IfTrapList[] =
{4, {1, 7, 1, OSPFv3IFAREAID}}
};
void
ospf6TrapNbrStateChange (struct ospf6_neighbor *on)
static int
ospf6TrapNbrStateChange (struct ospf6_neighbor *on,
int next_state, int prev_state)
{
oid index[3];
/* Terminal state or regression */
if ((next_state != OSPF6_NEIGHBOR_FULL) &&
(next_state != OSPF6_NEIGHBOR_TWOWAY) &&
(next_state >= prev_state))
return 0;
index[0] = on->ospf6_if->interface->ifindex;
index[1] = on->ospf6_if->instance_id;
index[2] = ntohl (on->router_id);
@ -1155,13 +1161,23 @@ ospf6TrapNbrStateChange (struct ospf6_neighbor *on)
ospf6NbrTrapList,
sizeof ospf6NbrTrapList / sizeof (struct trap_object),
NBRSTATECHANGE);
return 0;
}
void
ospf6TrapIfStateChange (struct ospf6_interface *oi)
static int
ospf6TrapIfStateChange (struct ospf6_interface *oi,
int next_state, int prev_state)
{
oid index[2];
/* Terminal state or regression */
if ((next_state != OSPF6_INTERFACE_POINTTOPOINT) &&
(next_state != OSPF6_INTERFACE_DROTHER) &&
(next_state != OSPF6_INTERFACE_BDR) &&
(next_state != OSPF6_INTERFACE_DR) &&
(next_state >= prev_state))
return 0;
index[0] = oi->interface->ifindex;
index[1] = oi->instance_id;
@ -1172,15 +1188,30 @@ ospf6TrapIfStateChange (struct ospf6_interface *oi)
ospf6IfTrapList,
sizeof ospf6IfTrapList / sizeof (struct trap_object),
IFSTATECHANGE);
return 0;
}
/* Register OSPFv3-MIB. */
void
static int
ospf6_snmp_init (struct thread_master *master)
{
smux_init (master);
REGISTER_MIB ("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
return 0;
}
#endif /* HAVE_SNMP */
static int
ospf6_snmp_module_init (void)
{
hook_register(ospf6_interface_change, ospf6TrapIfStateChange);
hook_register(ospf6_neighbor_change, ospf6TrapNbrStateChange);
hook_register(frr_late_init, ospf6_snmp_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "ospf6d_snmp",
.version = FRR_VERSION,
.description = "ospf6d AgentX SNMP module",
.init = ospf6_snmp_module_init,
)

View File

@ -1,31 +0,0 @@
/* OSPFv3 SNMP support
* Copyright (C) 2004 Yasuhiro Ohara
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef OSPF6_SNMP_H
#define OSPF6_SNMP_H
extern void ospf6TrapNbrStateChange (struct ospf6_neighbor *);
extern void ospf6TrapIfStateChange (struct ospf6_interface *);
extern void ospf6_snmp_init (struct thread_master *);
#endif /*OSPF6_SNMP_H*/

View File

@ -45,10 +45,6 @@
#include "ospf6d.h"
#include "ospf6_bfd.h"
#ifdef HAVE_SNMP
#include "ospf6_snmp.h"
#endif /*HAVE_SNMP*/
char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION;
struct route_node *
@ -1215,10 +1211,6 @@ ospf6_init (void)
ospf6_asbr_init ();
ospf6_abr_init ();
#ifdef HAVE_SNMP
ospf6_snmp_init (master);
#endif /*HAVE_SNMP*/
ospf6_bfd_init();
install_node (&debug_node, config_write_ospf6_debug);

View File

@ -6,13 +6,14 @@ DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
noinst_LIBRARIES = libfrrospf.a
module_LTLIBRARIES =
sbin_PROGRAMS = ospfd
libfrrospf_a_SOURCES = \
ospfd.c ospf_zebra.c ospf_interface.c ospf_ism.c ospf_neighbor.c \
ospf_nsm.c ospf_dump.c ospf_network.c ospf_packet.c ospf_lsa.c \
ospf_spf.c ospf_route.c ospf_ase.c ospf_abr.c ospf_ia.c ospf_flood.c \
ospf_lsdb.c ospf_asbr.c ospf_routemap.c ospf_snmp.c \
ospf_lsdb.c ospf_asbr.c ospf_routemap.c \
ospf_opaque.c ospf_te.c ospf_ri.c ospf_vty.c ospf_api.c ospf_apiserver.c \
ospf_bfd.c ospf_memory.c ospf_dump_api.c
@ -26,13 +27,20 @@ ospfdheader_HEADERS = \
noinst_HEADERS = \
ospf_interface.h ospf_neighbor.h ospf_network.h ospf_packet.h \
ospf_zebra.h ospf_spf.h ospf_route.h ospf_ase.h ospf_abr.h ospf_ia.h \
ospf_flood.h ospf_snmp.h ospf_te.h ospf_ri.h ospf_vty.h ospf_apiserver.h \
ospf_flood.h ospf_te.h ospf_ri.h ospf_vty.h ospf_apiserver.h \
ospf_bfd.h ospf_memory.h
ospfd_SOURCES = ospf_main.c
ospfd_LDADD = libfrrospf.a ../lib/libfrr.la @LIBCAP@ @LIBM@
if SNMP
module_LTLIBRARIES += ospfd_snmp.la
endif
ospfd_snmp_la_SOURCES = ospf_snmp.c
ospfd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ospfd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
EXTRA_DIST = OSPF-MIB.txt OSPF-TRAP-MIB.txt ChangeLog.opaque.txt
examplesdir = $(exampledir)

View File

@ -47,11 +47,10 @@
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_dump.h"
#ifdef HAVE_SNMP
#include "ospfd/ospf_snmp.h"
#endif /* HAVE_SNMP */
DEFINE_QOBJ_TYPE(ospf_interface)
DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data *vd), (vd))
DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data *vd), (vd))
int
ospf_if_get_output_cost (struct ospf_interface *oi)
@ -993,9 +992,7 @@ void
ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
{
listnode_add (ospf->vlinks, vl_data);
#ifdef HAVE_SNMP
ospf_snmp_vl_add (vl_data);
#endif /* HAVE_SNMP */
hook_call(ospf_vl_add, vl_data);
}
void
@ -1004,9 +1001,7 @@ ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
ospf_vl_shutdown (vl_data);
ospf_vl_if_delete (vl_data);
#ifdef HAVE_SNMP
ospf_snmp_vl_delete (vl_data);
#endif /* HAVE_SNMP */
hook_call(ospf_vl_delete, vl_data);
listnode_delete (ospf->vlinks, vl_data);
ospf_vl_data_free (vl_data);

View File

@ -24,6 +24,7 @@
#define _ZEBRA_OSPF_INTERFACE_H
#include "qobj.h"
#include "hook.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
@ -309,4 +310,7 @@ extern u_char ospf_default_iftype (struct interface *ifp);
state of the interface. */
extern void ospf_if_set_multicast (struct ospf_interface *);
DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data *vd), (vd))
DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data *vd), (vd))
#endif /* _ZEBRA_OSPF_INTERFACE_H */

View File

@ -43,7 +43,10 @@
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_snmp.h"
DEFINE_HOOK(ospf_ism_change,
(struct ospf_interface *oi, int state, int oldstate),
(oi, state, oldstate))
/* elect DR and BDR. Refer to RFC2319 section 9.4 */
static struct ospf_neighbor *
@ -545,19 +548,7 @@ ism_change_state (struct ospf_interface *oi, int state)
oi->state = state;
oi->state_change++;
#ifdef HAVE_SNMP
/* Terminal state or regression */
if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) ||
(state == ISM_PointToPoint) || (state < old_state))
{
/* ospfVirtIfStateChange */
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
ospfTrapVirtIfStateChange (oi);
/* ospfIfStateChange */
else
ospfTrapIfStateChange (oi);
}
#endif
hook_call(ospf_ism_change, oi, state, old_state);
/* Set multicast memberships appropriately for new state. */
ospf_if_set_multicast(oi);

View File

@ -24,6 +24,8 @@
#ifndef _ZEBRA_OSPF_ISM_H
#define _ZEBRA_OSPF_ISM_H
#include "hook.h"
/* OSPF Interface State Machine Status. */
#define ISM_DependUpon 0
#define ISM_Down 1
@ -35,10 +37,6 @@
#define ISM_DR 7
#define OSPF_ISM_STATE_MAX 8
/* Because DR/DROther values are exhanged wrt RFC */
#define ISM_SNMP(x) (((x) == ISM_DROther) ? ISM_DR : \
((x) == ISM_DR) ? ISM_DROther : (x))
/* OSPF Interface State Machine Event. */
#define ISM_NoEvent 0
#define ISM_InterfaceUp 1
@ -111,4 +109,8 @@ extern int ospf_ism_event (struct thread *);
extern void ism_change_status (struct ospf_interface *, int);
extern int ospf_hello_timer (struct thread *thread);
DECLARE_HOOK(ospf_ism_change,
(struct ospf_interface *oi, int state, int oldstate),
(oi, state, oldstate))
#endif /* _ZEBRA_OSPF_ISM_H */

View File

@ -225,9 +225,6 @@ main (int argc, char **argv)
ospf_bfd_init();
ospf_route_map_init ();
#ifdef HAVE_SNMP
ospf_snmp_init ();
#endif /* HAVE_SNMP */
ospf_opaque_init ();
/* Need to initialize the default ospf structure, so the interface mode

View File

@ -48,9 +48,12 @@
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_snmp.h"
#include "ospfd/ospf_bfd.h"
DEFINE_HOOK(ospf_nsm_change,
(struct ospf_neighbor *on, int state, int oldstate),
(on, state, oldstate))
static void nsm_clear_adj (struct ospf_neighbor *);
/* OSPF NSM Timer functions. */
@ -838,35 +841,12 @@ ospf_nsm_event (struct thread *thread)
/* If state is changed. */
if (next_state != nbr->state)
{
int old_state = nbr->state;
nsm_notice_state_change (nbr, next_state, event);
#ifdef HAVE_SNMP
int send_trap_virt = 0;
int send_trap = 0;
/* Terminal state or regression */
if ((next_state == NSM_Full)
|| (next_state == NSM_TwoWay)
|| (next_state < nbr->state))
{
/* ospfVirtNbrStateChange */
if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
send_trap_virt = 1;
/* ospfNbrStateChange trap */
else
/* To/From FULL, only managed by DR */
if (((next_state != NSM_Full) && (nbr->state != NSM_Full))
|| (nbr->oi->state == ISM_DR))
send_trap = 1;
}
#endif
nsm_change_state (nbr, next_state);
#ifdef HAVE_SNMP
if (send_trap_virt) {
ospfTrapVirtNbrStateChange(nbr);
} else if (send_trap) {
ospfTrapNbrStateChange(nbr);
}
#endif
hook_call(ospf_nsm_change, nbr, next_state, old_state);
}
/* Make sure timer is set. */

View File

@ -24,6 +24,8 @@
#ifndef _ZEBRA_OSPF_NSM_H
#define _ZEBRA_OSPF_NSM_H
#include "hook.h"
/* OSPF Neighbor State Machine State. */
#define NSM_DependUpon 0
#define NSM_Deleted 1
@ -86,5 +88,9 @@ extern int ospf_db_summary_isempty (struct ospf_neighbor *);
extern int ospf_db_summary_count (struct ospf_neighbor *);
extern void ospf_db_summary_clear (struct ospf_neighbor *);
DECLARE_HOOK(ospf_nsm_change,
(struct ospf_neighbor *on, int state, int oldstate),
(on, state, oldstate))
#endif /* _ZEBRA_OSPF_NSM_H */

View File

@ -24,7 +24,6 @@
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -35,6 +34,8 @@
#include "command.h"
#include "memory.h"
#include "smux.h"
#include "libfrr.h"
#include "version.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@ -47,7 +48,7 @@
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_snmp.h"
#include "ospfd/ospf_zebra.h"
/* OSPF2-MIB. */
#define OSPF2MIB 1,3,6,1,2,1,14
@ -205,6 +206,10 @@
#define IPADDRESS ASN_IPADDRESS
#define STRING ASN_OCTET_STR
/* Because DR/DROther values are exhanged wrt RFC */
#define ISM_SNMP(x) (((x) == ISM_DROther) ? ISM_DR : \
((x) == ISM_DR) ? ISM_DROther : (x))
/* Declare static local variables for convenience. */
SNMP_LOCAL_VARIABLES
@ -1429,7 +1434,7 @@ ospf_snmp_if_free (struct ospf_snmp_if *osif)
XFREE (MTYPE_TMP, osif);
}
void
static int
ospf_snmp_if_delete (struct interface *ifp)
{
struct listnode *node, *nnode;
@ -1441,12 +1446,13 @@ ospf_snmp_if_delete (struct interface *ifp)
{
list_delete_node (ospf_snmp_iflist, node);
ospf_snmp_if_free (osif);
return;
break;
}
}
return 0;
}
void
static int
ospf_snmp_if_update (struct interface *ifp)
{
struct listnode *node;
@ -1511,6 +1517,7 @@ ospf_snmp_if_update (struct interface *ifp)
osif->ifp = ifp;
listnode_add_after (ospf_snmp_iflist, pn, osif);
return 0;
}
static int
@ -1914,7 +1921,7 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
static struct route_table *ospf_snmp_vl_table;
void
static int
ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
{
struct prefix_ls lp;
@ -1931,9 +1938,10 @@ ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
route_unlock_node (rn);
rn->info = vl_data;
return 0;
}
void
static int
ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
{
struct prefix_ls lp;
@ -1947,10 +1955,11 @@ ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
if (! rn)
return;
return 0;
rn->info = NULL;
route_unlock_node (rn);
route_unlock_node (rn);
return 0;
}
static struct ospf_vl_data *
@ -2651,7 +2660,7 @@ static struct trap_object ospfVirtIfTrapList[] =
{3, {9, 1, OSPFVIRTIFSTATE}}
};
void
static void
ospfTrapNbrStateChange (struct ospf_neighbor *on)
{
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
@ -2673,7 +2682,7 @@ ospfTrapNbrStateChange (struct ospf_neighbor *on)
NBRSTATECHANGE);
}
void
static void
ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
{
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
@ -2692,7 +2701,29 @@ ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
VIRTNBRSTATECHANGE);
}
void
static int
ospf_snmp_nsm_change (struct ospf_neighbor *nbr,
int next_state, int old_state)
{
/* Terminal state or regression */
if ((next_state == NSM_Full)
|| (next_state == NSM_TwoWay)
|| (next_state < old_state))
{
/* ospfVirtNbrStateChange */
if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
ospfTrapVirtNbrStateChange(nbr);
/* ospfNbrStateChange trap */
else
/* To/From FULL, only managed by DR */
if (((next_state != NSM_Full) && (nbr->state != NSM_Full))
|| (nbr->oi->state == ISM_DR))
ospfTrapNbrStateChange(nbr);
}
return 0;
}
static void
ospfTrapIfStateChange (struct ospf_interface *oi)
{
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
@ -2713,7 +2744,7 @@ ospfTrapIfStateChange (struct ospf_interface *oi)
IFSTATECHANGE);
}
void
static void
ospfTrapVirtIfStateChange (struct ospf_interface *oi)
{
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
@ -2731,13 +2762,53 @@ ospfTrapVirtIfStateChange (struct ospf_interface *oi)
sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
VIRTIFSTATECHANGE);
}
static int
ospf_snmp_ism_change (struct ospf_interface *oi,
int state, int old_state)
{
/* Terminal state or regression */
if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) ||
(state == ISM_PointToPoint) || (state < old_state))
{
/* ospfVirtIfStateChange */
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
ospfTrapVirtIfStateChange (oi);
/* ospfIfStateChange */
else
ospfTrapIfStateChange (oi);
}
return 0;
}
/* Register OSPF2-MIB. */
void
ospf_snmp_init ()
static int
ospf_snmp_init (struct thread_master *tm)
{
ospf_snmp_iflist = list_new ();
ospf_snmp_vl_table = route_table_init ();
smux_init (om->master);
smux_init (tm);
REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
return 0;
}
#endif /* HAVE_SNMP */
static int
ospf_snmp_module_init (void)
{
hook_register(ospf_if_update, ospf_snmp_if_update);
hook_register(ospf_if_delete, ospf_snmp_if_delete);
hook_register(ospf_vl_add, ospf_snmp_vl_add);
hook_register(ospf_vl_delete, ospf_snmp_vl_delete);
hook_register(ospf_ism_change, ospf_snmp_ism_change);
hook_register(ospf_nsm_change, ospf_snmp_nsm_change);
hook_register(frr_late_init, ospf_snmp_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "ospfd_snmp",
.version = FRR_VERSION,
.description = "ospfd AgentX SNMP module",
.init = ospf_snmp_module_init,
)

View File

@ -1,38 +0,0 @@
/* OSPFv2 SNMP support
* Copyright (C) 2000 IP Infusion Inc.
*
* Written by Kunihiro Ishiguro <kunihiro@zebra.org>
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_OSPF_SNMP_H
#define _ZEBRA_OSPF_SNMP_H
extern void ospf_snmp_if_update (struct interface *);
extern void ospf_snmp_if_delete (struct interface *);
extern void ospf_snmp_vl_add (struct ospf_vl_data *);
extern void ospf_snmp_vl_delete (struct ospf_vl_data *);
extern void ospfTrapIfStateChange (struct ospf_interface *);
extern void ospfTrapVirtIfStateChange (struct ospf_interface *);
extern void ospfTrapNbrStateChange (struct ospf_neighbor *);
extern void ospfTrapVirtNbrStateChange (struct ospf_neighbor *);
#endif /* _ZEBRA_OSPF_SNMP_H */

View File

@ -50,11 +50,11 @@
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_zebra.h"
#ifdef HAVE_SNMP
#include "ospfd/ospf_snmp.h"
#endif /* HAVE_SNMP */
#include "ospfd/ospf_te.h"
DEFINE_HOOK(ospf_if_update, (struct interface *ifp), (ifp))
DEFINE_HOOK(ospf_if_delete, (struct interface *ifp), (ifp))
/* Zebra structure to hold current status. */
struct zclient *zclient = NULL;
@ -112,9 +112,7 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length,
ospf_if_update (NULL, ifp);
#ifdef HAVE_SNMP
ospf_snmp_if_update (ifp);
#endif /* HAVE_SNMP */
hook_call(ospf_if_update, ifp);
return 0;
}
@ -143,9 +141,7 @@ ospf_interface_delete (int command, struct zclient *zclient,
("Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d",
ifp->name, ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
#ifdef HAVE_SNMP
ospf_snmp_if_delete (ifp);
#endif /* HAVE_SNMP */
hook_call(ospf_if_delete, ifp);
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
if (rn->info)
@ -277,9 +273,7 @@ ospf_interface_address_add (int command, struct zclient *zclient,
ospf_if_update (NULL, c->ifp);
#ifdef HAVE_SNMP
ospf_snmp_if_update (c->ifp);
#endif /* HAVE_SNMP */
hook_call(ospf_if_update, c->ifp);
return 0;
}
@ -324,9 +318,7 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
/* Call interface hook functions to clean up */
ospf_if_free (oi);
#ifdef HAVE_SNMP
ospf_snmp_if_update (c->ifp);
#endif /* HAVE_SNMP */
hook_call(ospf_if_update, c->ifp);
connected_free (c);

View File

@ -24,6 +24,7 @@
#define _ZEBRA_OSPF_ZEBRA_H
#include "vty.h"
#include "hook.h"
#define EXTERNAL_METRIC_TYPE_1 0
#define EXTERNAL_METRIC_TYPE_2 1
@ -79,5 +80,8 @@ extern int ospf_distance_unset (struct vty *, struct ospf *, const char *,
const char *, const char *);
extern void ospf_zebra_init(struct thread_master *, u_short);
DECLARE_HOOK(ospf_if_update, (struct interface *ifp), (ifp))
DECLARE_HOOK(ospf_if_delete, (struct interface *ifp), (ifp))
#endif /* _ZEBRA_OSPF_ZEBRA_H */

View File

@ -574,7 +574,6 @@ extern void ospf_area_add_if (struct ospf_area *, struct ospf_interface *);
extern void ospf_area_del_if (struct ospf_area *, struct ospf_interface *);
extern void ospf_route_map_init (void);
extern void ospf_snmp_init (void);
extern void ospf_master_init (struct thread_master *master);

View File

@ -7,11 +7,12 @@ INSTALL_SDATA=@INSTALL@ -m 600
AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = librip.a
module_LTLIBRARIES =
sbin_PROGRAMS = ripd
librip_a_SOURCES = \
rip_memory.c \
ripd.c rip_zebra.c rip_interface.c rip_debug.c rip_snmp.c \
ripd.c rip_zebra.c rip_interface.c rip_debug.c \
rip_routemap.c rip_peer.c rip_offset.c
noinst_HEADERS = \
@ -23,6 +24,13 @@ ripd_SOURCES = \
ripd_LDADD = ../lib/libfrr.la @LIBCAP@
if SNMP
module_LTLIBRARIES += ripd_snmp.la
endif
ripd_snmp_la_SOURCES = rip_snmp.c
ripd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ripd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
examplesdir = $(exampledir)
dist_examples_DATA = ripd.conf.sample

View File

@ -42,6 +42,9 @@
#include "ripd/rip_debug.h"
#include "ripd/rip_interface.h"
DEFINE_HOOK(rip_ifaddr_add, (struct connected *ifc), (ifc))
DEFINE_HOOK(rip_ifaddr_del, (struct connected *ifc), (ifc))
/* static prototypes */
static void rip_enable_apply (struct interface *);
static void rip_passive_interface_apply (struct interface *);
@ -673,9 +676,7 @@ rip_interface_address_add (int command, struct zclient *zclient,
/* Check if this prefix needs to be redistributed */
rip_apply_address_add(ifc);
#ifdef HAVE_SNMP
rip_ifaddr_add (ifc->ifp, ifc);
#endif /* HAVE_SNMP */
hook_call(rip_ifaddr_add, ifc);
}
return 0;
@ -723,9 +724,7 @@ rip_interface_address_delete (int command, struct zclient *zclient,
zlog_debug ("connected address %s/%d is deleted",
inet_ntoa (p->u.prefix4), p->prefixlen);
#ifdef HAVE_SNMP
rip_ifaddr_delete (ifc->ifp, ifc);
#endif /* HAVE_SNMP */
hook_call(rip_ifaddr_del, ifc);
/* Chech wether this prefix needs to be removed */
rip_apply_address_del(ifc);

View File

@ -21,16 +21,18 @@
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "if.h"
#include "vrf.h"
#include "log.h"
#include "prefix.h"
#include "command.h"
#include "table.h"
#include "smux.h"
#include "libfrr.h"
#include "version.h"
#include "ripd/ripd.h"
@ -174,24 +176,27 @@ rip2Globals (struct variable *v, oid name[], size_t *length,
return NULL;
}
void
rip_ifaddr_add (struct interface *ifp, struct connected *ifc)
static int
rip_snmp_ifaddr_add (struct connected *ifc)
{
struct interface *ifp = ifc->ifp;
struct prefix *p;
struct route_node *rn;
p = ifc->address;
if (p->family != AF_INET)
return;
return 0;
rn = route_node_get (rip_ifaddr_table, p);
rn->info = ifp;
return 0;
}
void
rip_ifaddr_delete (struct interface *ifp, struct connected *ifc)
static int
rip_snmp_ifaddr_del (struct connected *ifc)
{
struct interface *ifp = ifc->ifp;
struct prefix *p;
struct route_node *rn;
struct interface *i;
@ -199,11 +204,11 @@ rip_ifaddr_delete (struct interface *ifp, struct connected *ifc)
p = ifc->address;
if (p->family != AF_INET)
return;
return 0;
rn = route_node_lookup (rip_ifaddr_table, p);
if (! rn)
return;
return 0;
i = rn->info;
if (rn && !strncmp(i->name,ifp->name,INTERFACE_NAMSIZ))
{
@ -211,6 +216,7 @@ rip_ifaddr_delete (struct interface *ifp, struct connected *ifc)
route_unlock_node (rn);
route_unlock_node (rn);
}
return 0;
}
static struct interface *
@ -582,12 +588,29 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length,
}
/* Register RIPv2-MIB. */
void
rip_snmp_init ()
static int
rip_snmp_init (struct thread_master *master)
{
rip_ifaddr_table = route_table_init ();
smux_init (master);
REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid);
return 0;
}
#endif /* HAVE_SNMP */
static int
rip_snmp_module_init (void)
{
hook_register(rip_ifaddr_add, rip_snmp_ifaddr_add);
hook_register(rip_ifaddr_del, rip_snmp_ifaddr_del);
hook_register(frr_late_init, rip_snmp_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "ripd_snmp",
.version = FRR_VERSION,
.description = "ripd AgentX SNMP module",
.init = rip_snmp_module_init,
)

View File

@ -4064,11 +4064,6 @@ rip_init (void)
/* Debug related init. */
rip_debug_init ();
/* SNMP init. */
#ifdef HAVE_SNMP
rip_snmp_init ();
#endif /* HAVE_SNMP */
/* Access list install. */
access_list_init ();
access_list_add_hook (rip_distribute_update_all_wrapper);

View File

@ -23,6 +23,7 @@
#define _ZEBRA_RIP_H
#include "qobj.h"
#include "hook.h"
#include "rip_memory.h"
/* RIP version number. */
@ -391,7 +392,6 @@ extern void rip_if_init (void);
extern void rip_if_down_all (void);
extern void rip_route_map_init (void);
extern void rip_route_map_reset (void);
extern void rip_snmp_init (void);
extern void rip_zclient_init(struct thread_master *);
extern void rip_zclient_reset (void);
extern void rip_offset_init (void);
@ -432,8 +432,6 @@ extern void rip_offset_clean (void);
extern void rip_info_free (struct rip_info *);
extern u_char rip_distance_apply (struct rip_info *);
extern void rip_redistribute_clean (void);
extern void rip_ifaddr_add (struct interface *, struct connected *);
extern void rip_ifaddr_delete (struct interface *, struct connected *);
extern struct rip_info *rip_ecmp_add (struct rip_info *);
extern struct rip_info *rip_ecmp_replace (struct rip_info *);
@ -448,4 +446,8 @@ extern struct thread_master *master;
/* RIP statistics for SNMP. */
extern long rip_global_route_changes;
extern long rip_global_queries;
DECLARE_HOOK(rip_ifaddr_add, (struct connected *ifc), (ifc))
DECLARE_HOOK(rip_ifaddr_del, (struct connected *ifc), (ifc))
#endif /* _ZEBRA_RIP_H */

View File

@ -2010,6 +2010,24 @@ DEFUNSH (VTYSH_ZEBRA,
return CMD_SUCCESS;
}
static int
show_per_daemon (const char *line, const char *headline)
{
unsigned int i;
int ret = CMD_SUCCESS;
for (i = 0; i < array_size(vtysh_client); i++)
if ( vtysh_client[i].fd >= 0 )
{
fprintf (stdout, headline,
vtysh_client[i].name);
ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
fprintf (stdout,"\n");
}
return ret;
}
/* Memory */
DEFUN (vtysh_show_memory,
vtysh_show_memory_cmd,
@ -2017,20 +2035,16 @@ DEFUN (vtysh_show_memory,
SHOW_STR
"Memory statistics\n")
{
unsigned int i;
int ret = CMD_SUCCESS;
char line[] = "show memory\n";
for (i = 0; i < array_size(vtysh_client); i++)
if ( vtysh_client[i].fd >= 0 )
{
fprintf (stdout, "Memory statistics for %s:\n",
vtysh_client[i].name);
ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
fprintf (stdout,"\n");
}
return ret;
return show_per_daemon ("show memory\n", "Memory statistics for %s:\n");
}
DEFUN (vtysh_show_modules,
vtysh_show_modules_cmd,
"show modules",
SHOW_STR
"Loaded modules\n")
{
return show_per_daemon ("show modules\n", "Module information for %s:\n");
}
/* Logging commands. */
@ -3388,6 +3402,7 @@ vtysh_init_vty (void)
#endif
install_element (VIEW_NODE, &vtysh_show_memory_cmd);
install_element (VIEW_NODE, &vtysh_show_modules_cmd);
install_element (VIEW_NODE, &vtysh_show_work_queues_cmd);
install_element (VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);

View File

@ -19,33 +19,22 @@ mpls_method = @MPLS_METHOD@
otherobj = $(ioctl_method) $(ipforward) $(if_method) \
$(rt_method) $(rtread_method) $(kernel_method) $(mpls_method)
if HAVE_NETLINK
othersrc = zebra_fpm_netlink.c
endif
if HAVE_PROTOBUF
protobuf_srcs = zebra_fpm_protobuf.c
endif
if DEV_BUILD
dev_srcs = zebra_fpm_dt.c
endif
AM_CFLAGS = $(WERROR)
sbin_PROGRAMS = zebra
noinst_PROGRAMS = testzebra
module_LTLIBRARIES =
zebra_SOURCES = \
zebra_memory.c \
zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
$(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \
redistribute.c debug.c rtadv.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c \
zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \
zebra_ns.c zebra_vrf.c zebra_static.c zebra_mpls.c zebra_mpls_vty.c \
$(protobuf_srcs) zebra_mroute.c \
$(dev_srcs) label_manager.c
zebra_mroute.c \
label_manager.c \
# end
testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \
@ -57,17 +46,41 @@ noinst_HEADERS = \
zebra_memory.h \
connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \
interface.h ipforward.h irdp.h router-id.h kernel_socket.h \
rt_netlink.h zebra_fpm.h zebra_fpm_private.h zebra_rnh.h \
rt_netlink.h zebra_fpm_private.h zebra_rnh.h \
zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \
zebra_ns.h zebra_vrf.h ioctl_solaris.h zebra_static.h zebra_mpls.h \
kernel_netlink.h if_netlink.h zebra_mroute.h label_manager.h
zebra_LDADD = $(otherobj) ../lib/libfrr.la $(LIBCAP) $(Q_FPM_PB_CLIENT_LDOPTS)
zebra_LDADD = $(otherobj) ../lib/libfrr.la $(LIBCAP)
testzebra_LDADD = ../lib/libfrr.la $(LIBCAP)
zebra_DEPENDENCIES = $(otherobj)
if SNMP
module_LTLIBRARIES += zebra_snmp.la
endif
zebra_snmp_la_SOURCES = zebra_snmp.c
zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_snmp_la_LIBADD = ../lib/libfrrsnmp.la
if FPM
module_LTLIBRARIES += zebra_fpm.la
endif
zebra_fpm_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_fpm_la_LIBADD = $(Q_FPM_PB_CLIENT_LDOPTS)
zebra_fpm_la_SOURCES = zebra_fpm.c
if HAVE_NETLINK
zebra_fpm_la_SOURCES += zebra_fpm_netlink.c
endif
if HAVE_PROTOBUF
zebra_fpm_la_SOURCES += zebra_fpm_protobuf.c
endif
if DEV_BUILD
zebra_fpm_la_SOURCES += zebra_fpm_dt.c
endif
EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c \
if_sysctl.c ipforward_proc.c \
ipforward_solaris.c ipforward_sysctl.c rt_netlink.c \

View File

@ -43,7 +43,6 @@
#include "zebra/router-id.h"
#include "zebra/irdp.h"
#include "zebra/rtadv.h"
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_ptm.h"
#include "zebra/zebra_ns.h"
#include "zebra/redistribute.h"
@ -84,7 +83,6 @@ struct option longopts[] =
{ "batch", no_argument, NULL, 'b'},
{ "allow_delete", no_argument, NULL, 'a'},
{ "keep_kernel", no_argument, NULL, 'k'},
{ "fpm_format", required_argument, NULL, 'F'},
{ "socket", required_argument, NULL, 'z'},
{ "ecmp", required_argument, NULL, 'e'},
{ "label_socket", no_argument, NULL, 'l'},
@ -221,21 +219,18 @@ main (int argc, char **argv)
{
// int batch_mode = 0;
char *zserv_path = NULL;
char *fpm_format = NULL;
/* Socket to external label manager */
char *lblmgr_path = NULL;
frr_preinit(&zebra_di, argc, argv);
frr_opt_add("bakF:z:e:l:r"
frr_opt_add("bakz:e:l:r"
#ifdef HAVE_NETLINK
"s:"
#endif
, longopts,
" -b, --batch Runs in batch mode\n"
" -a, --allow_delete Allow other processes to delete zebra routes\n"
" -F, --fpm_format Set fpm format to 'netlink' or 'protobuf'\n"
" -z, --socket Set path of zebra socket\n"
" -e, --ecmp Specify ECMP to use.\n"
" -l, --label_socket Socket to external label manager\n"\
@ -266,9 +261,6 @@ main (int argc, char **argv)
case 'k':
keep_kernel_mode = 1;
break;
case 'F':
fpm_format = optarg;
break;
case 'e':
multipath_num = atoi (optarg);
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
@ -329,16 +321,6 @@ main (int argc, char **argv)
/* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */
zebra_ns_init ();
#ifdef HAVE_SNMP
zebra_snmp_init ();
#endif /* HAVE_SNMP */
#ifdef HAVE_FPM
zfpm_init (zebrad.master, 1, 0, fpm_format);
#else
zfpm_init (zebrad.master, 0, 0, fpm_format);
#endif
/* Process the configuration file. Among other configuration
* directives we can meet those installing static routes. Such
* requests will not be executed immediately, but queued in

View File

@ -25,7 +25,6 @@
#include "zebra/rtadv.h"
#include "zebra/irdp.h"
#include "zebra/interface.h"
#include "zebra/zebra_fpm.h"
void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; }
void irdp_config_write (struct vty *vty, struct interface *ifp) { return; }
@ -35,9 +34,3 @@ void ifstat_update_proc (void) { return; }
#ifdef HAVE_NET_RT_IFLIST
void ifstat_update_sysctl (void) { return; }
#endif
void
zfpm_trigger_update (struct route_node *rn, const char *reason)
{
return;
}

View File

@ -24,6 +24,7 @@
#define _ZEBRA_RIB_H
#include "zebra.h"
#include "hook.h"
#include "linklist.h"
#include "prefix.h"
#include "table.h"
@ -490,4 +491,6 @@ rib_tables_iter_cleanup (rib_tables_iter_t *iter)
iter->state = RIB_TABLES_ITER_S_DONE;
}
DECLARE_HOOK(rib_update, (struct route_node *rn, const char *reason), (rn, reason))
#endif /*_ZEBRA_RIB_H */

View File

@ -31,6 +31,10 @@
#include "zebra/rib.h"
#include "zebra/zserv.h"
/* Thank you, Solaris, for polluting application symbol namespace. */
#undef hook_register
#undef hook_unregister
#include <sys/stream.h>
#include <sys/tihdr.h>

View File

@ -25,10 +25,12 @@
#include <zebra.h>
#include "log.h"
#include "libfrr.h"
#include "stream.h"
#include "thread.h"
#include "network.h"
#include "command.h"
#include "version.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@ -36,7 +38,6 @@
#include "zebra/zebra_vrf.h"
#include "fpm/fpm.h"
#include "zebra_fpm.h"
#include "zebra_fpm_private.h"
/*
@ -254,6 +255,8 @@ typedef struct zfpm_glob_t_
static zfpm_glob_t zfpm_glob_space;
static zfpm_glob_t *zfpm_g = &zfpm_glob_space;
static int zfpm_trigger_update (struct route_node *rn, const char *reason);
static int zfpm_read_cb (struct thread *thread);
static int zfpm_write_cb (struct thread *thread);
@ -1296,7 +1299,6 @@ zfpm_start_connect_timer (const char *reason)
zfpm_set_state (ZFPM_STATE_ACTIVE, reason);
}
#if defined (HAVE_FPM)
/*
* zfpm_is_enabled
*
@ -1307,7 +1309,6 @@ zfpm_is_enabled (void)
{
return zfpm_g->enabled;
}
#endif
/*
* zfpm_conn_is_up
@ -1331,7 +1332,7 @@ zfpm_conn_is_up (void)
* The zebra code invokes this function to indicate that we should
* send an update to the FPM about the given route_node.
*/
void
static int
zfpm_trigger_update (struct route_node *rn, const char *reason)
{
rib_dest_t *dest;
@ -1342,7 +1343,7 @@ zfpm_trigger_update (struct route_node *rn, const char *reason)
* all destinations once the connection comes up.
*/
if (!zfpm_conn_is_up ())
return;
return 0;
dest = rib_dest_from_rnode (rn);
@ -1353,12 +1354,12 @@ zfpm_trigger_update (struct route_node *rn, const char *reason)
if (!zfpm_is_table_for_fpm (rib_dest_table (dest)))
{
zfpm_g->stats.non_fpm_table_triggers++;
return;
return 0;
}
if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)) {
zfpm_g->stats.redundant_triggers++;
return;
return 0;
}
if (reason)
@ -1375,9 +1376,10 @@ zfpm_trigger_update (struct route_node *rn, const char *reason)
* Make sure that writes are enabled.
*/
if (zfpm_g->t_write)
return;
return 0;
zfpm_write_on ();
return 0;
}
/*
@ -1411,7 +1413,6 @@ zfpm_stats_timer_cb (struct thread *t)
return 0;
}
#if defined (HAVE_FPM)
/*
* zfpm_stop_stats_timer
*/
@ -1424,7 +1425,6 @@ zfpm_stop_stats_timer (void)
zfpm_debug ("Stopping existing stats timer");
THREAD_TIMER_OFF (zfpm_g->t_stats);
}
#endif
/*
* zfpm_start_stats_timer
@ -1447,7 +1447,6 @@ zfpm_start_stats_timer (void)
zfpm_g->last_ivl_stats.counter, VTY_NEWLINE); \
} while (0)
#if defined (HAVE_FPM)
/*
* zfpm_show_stats
*/
@ -1600,7 +1599,6 @@ DEFUN ( no_fpm_remote_ip,
return CMD_SUCCESS;
}
#endif
/*
* zfpm_init_message_format
@ -1670,7 +1668,7 @@ zfpm_init_message_format (const char *format)
* Returns ZERO on success.
*/
int fpm_remote_srv_write (struct vty *vty )
static int fpm_remote_srv_write (struct vty *vty)
{
struct in_addr in;
@ -1684,6 +1682,15 @@ int fpm_remote_srv_write (struct vty *vty )
}
/* Zebra node */
static struct cmd_node zebra_node =
{
ZEBRA_NODE,
"",
1
};
/**
* zfpm_init
*
@ -1695,17 +1702,12 @@ int fpm_remote_srv_write (struct vty *vty )
*
* Returns TRUE on success.
*/
int
zfpm_init (struct thread_master *master, int enable, uint16_t port,
const char *format)
static int
zfpm_init (struct thread_master *master)
{
static int initialized = 0;
if (initialized) {
return 1;
}
initialized = 1;
int enable = 1;
uint16_t port = 0;
const char *format = THIS_MODULE->load_args;
memset (zfpm_g, 0, sizeof (*zfpm_g));
zfpm_g->master = master;
@ -1717,12 +1719,11 @@ zfpm_init (struct thread_master *master, int enable, uint16_t port,
zfpm_stats_init (&zfpm_g->last_ivl_stats);
zfpm_stats_init (&zfpm_g->cumulative_stats);
#if defined (HAVE_FPM)
install_node (&zebra_node, fpm_remote_srv_write);
install_element (ENABLE_NODE, &show_zebra_fpm_stats_cmd);
install_element (ENABLE_NODE, &clear_zebra_fpm_stats_cmd);
install_element (CONFIG_NODE, &fpm_remote_ip_cmd);
install_element (CONFIG_NODE, &no_fpm_remote_ip_cmd);
#endif
zfpm_init_message_format(format);
@ -1734,10 +1735,6 @@ zfpm_init (struct thread_master *master, int enable, uint16_t port,
zfpm_g->enabled = enable;
if (!enable) {
return 1;
}
if (!zfpm_g->fpm_server)
zfpm_g->fpm_server = FPM_DEFAULT_IP;
@ -1751,6 +1748,20 @@ zfpm_init (struct thread_master *master, int enable, uint16_t port,
zfpm_start_stats_timer ();
zfpm_start_connect_timer ("initialized");
return 1;
return 0;
}
static int
zebra_fpm_module_init (void)
{
hook_register(rib_update, zfpm_trigger_update);
hook_register(frr_late_init, zfpm_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "zebra_fpm",
.version = FRR_VERSION,
.description = "zebra FPM (Forwarding Plane Manager) module",
.init = zebra_fpm_module_init,
)

View File

@ -1,36 +0,0 @@
/*
* Header file exported by the zebra FPM module to zebra.
*
* Copyright (C) 2012 by Open Source Routing.
* Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_FPM_H
#define _ZEBRA_FPM_H
/*
* Externs.
*/
extern int zfpm_init (struct thread_master *master, int enable, uint16_t port,
const char *message_format);
extern void zfpm_trigger_update (struct route_node *rn, const char *reason);
extern int fpm_remote_srv_write (struct vty *vty);
#endif /* _ZEBRA_FPM_H */

View File

@ -53,7 +53,7 @@ create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
}
fpm__delete_route__init(msg);
msg->vrf_id = rib_dest_vrf(dest)->vrf->vrf_id;
msg->vrf_id = zvrf_id(rib_dest_vrf(dest));
qpb_address_family_set(&msg->address_family, rib_dest_af(dest));
@ -159,7 +159,7 @@ create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
fpm__add_route__init(msg);
msg->vrf_id = rib_dest_vrf(dest)->vrf->vrf_id;
msg->vrf_id = zvrf_id(rib_dest_vrf(dest));
qpb_address_family_set (&msg->address_family, rib_dest_af(dest));

View File

@ -48,11 +48,12 @@
#include "zebra/redistribute.h"
#include "zebra/zebra_routemap.h"
#include "zebra/debug.h"
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_rnh.h"
#include "zebra/interface.h"
#include "zebra/connected.h"
DEFINE_HOOK(rib_update, (struct route_node *rn, const char *reason), (rn, reason))
/* Should we allow non Quagga processes to delete our routes */
extern int allow_delete;
@ -1110,7 +1111,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old)
* Make sure we update the FPM any time we send new information to
* the kernel.
*/
zfpm_trigger_update (rn, "installing in kernel");
hook_call(rib_update, rn, "installing in kernel");
ret = kernel_route_rib (p, src_p, old, rib);
/* If install succeeds, update FIB flag for nexthops. */
@ -1154,7 +1155,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
* Make sure we update the FPM any time we send new information to
* the kernel.
*/
zfpm_trigger_update (rn, "uninstalling from kernel");
hook_call(rib_update, rn, "uninstalling from kernel");
ret = kernel_route_rib (p, src_p, rib, NULL);
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
@ -1172,7 +1173,7 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
{
if (info->safi == SAFI_UNICAST)
zfpm_trigger_update (rn, "rib_uninstall");
hook_call(rib_update, rn, "rib_uninstall");
if (! RIB_SYSTEM_ROUTE (rib))
rib_uninstall_kernel (rn, rib);
@ -1253,7 +1254,7 @@ static void
rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct rib *new)
{
zfpm_trigger_update (rn, "new route selected");
hook_call(rib_update, rn, "new route selected");
/* Update real nexthop. This may actually determine if nexthop is active or not. */
if (!nexthop_active_update (rn, new, 1))
@ -1289,7 +1290,7 @@ static void
rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
struct rib *old)
{
zfpm_trigger_update (rn, "removing existing route");
hook_call(rib_update, rn, "removing existing route");
/* Uninstall from kernel. */
if (IS_ZEBRA_DEBUG_RIB)
@ -1326,7 +1327,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
if (new != old ||
CHECK_FLAG (new->status, RIB_ENTRY_CHANGED))
{
zfpm_trigger_update (rn, "updating existing route");
hook_call(rib_update, rn, "updating existing route");
/* Update the nexthop; we could determine here that nexthop is inactive. */
if (nexthop_active_update (rn, new, 1))
@ -2874,7 +2875,7 @@ rib_close_table (struct route_table *table)
continue;
if (info->safi == SAFI_UNICAST)
zfpm_trigger_update (rn, NULL);
hook_call(rib_update, rn, NULL);
if (! RIB_SYSTEM_ROUTE (rib))
rib_uninstall_kernel (rn, rib);

View File

@ -25,7 +25,6 @@
#include <zebra.h>
#ifdef HAVE_SNMP
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -36,6 +35,9 @@
#include "smux.h"
#include "table.h"
#include "vrf.h"
#include "hook.h"
#include "libfrr.h"
#include "version.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@ -571,10 +573,24 @@ ipCidrTable (struct variable *v, oid objid[], size_t *objid_len,
return NULL;
}
void
zebra_snmp_init ()
static int
zebra_snmp_init (struct thread_master *tm)
{
smux_init (zebrad.master);
smux_init (tm);
REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
return 0;
}
#endif /* HAVE_SNMP */
static int
zebra_snmp_module_init (void)
{
hook_register(frr_late_init, zebra_snmp_init);
return 0;
}
FRR_MODULE_SETUP(
.name = "zebra_snmp",
.version = FRR_VERSION,
.description = "zebra AgentX SNMP module",
.init = zebra_snmp_module_init,
)

View File

@ -53,7 +53,6 @@
#include "zebra/zebra_ptm.h"
#include "zebra/rtadv.h"
#include "zebra/zebra_mpls.h"
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_mroute.h"
#include "zebra/label_manager.h"
@ -2851,25 +2850,6 @@ static struct cmd_node forwarding_node =
1
};
#ifdef HAVE_FPM
/* function to write the fpm config info */
static int
config_write_fpm (struct vty *vty)
{
return
fpm_remote_srv_write (vty);
}
/* Zebra node */
static struct cmd_node zebra_node =
{
ZEBRA_NODE,
"",
1
};
#endif
/* Initialisation of zebra and installation of commands. */
void
zebra_init (void)
@ -2880,9 +2860,6 @@ zebra_init (void)
/* Install configuration write function. */
install_node (&table_node, config_write_table);
install_node (&forwarding_node, config_write_forwarding);
#ifdef HAVE_FPM
install_node (&zebra_node, config_write_fpm);
#endif
install_element (VIEW_NODE, &show_ip_forwarding_cmd);
install_element (CONFIG_NODE, &ip_forwarding_cmd);

View File

@ -149,7 +149,6 @@ extern void route_read (struct zebra_ns *);
extern void kernel_init (struct zebra_ns *);
extern void kernel_terminate (struct zebra_ns *);
extern void zebra_route_map_init (void);
extern void zebra_snmp_init (void);
extern void zebra_vty_init (void);
extern int zsend_vrf_add (struct zserv *, struct zebra_vrf *);