mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 14:34:22 +00:00
Merge branch 'master'
This commit is contained in:
commit
422f8d0ca9
@ -67,6 +67,7 @@ INSTALL_SDATA=@INSTALL@ -m 600
|
|||||||
AM_CFLAGS = $(WERROR)
|
AM_CFLAGS = $(WERROR)
|
||||||
|
|
||||||
noinst_LIBRARIES = libbgp.a
|
noinst_LIBRARIES = libbgp.a
|
||||||
|
module_LTLIBRARIES =
|
||||||
sbin_PROGRAMS = bgpd
|
sbin_PROGRAMS = bgpd
|
||||||
bin_PROGRAMS = bgp_btoa
|
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 \
|
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_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_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_mplsvpn.c bgp_nexthop.c \
|
||||||
bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.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 \
|
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 \
|
bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \
|
||||||
bgp_ecommunity.h bgp_lcommunity.h \
|
bgp_ecommunity.h bgp_lcommunity.h \
|
||||||
bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h bgp_table.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_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
|
$(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_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
|
||||||
bgp_btoa_LDFLAGS = $(BGP_VNC_RFP_LD_FLAGS)
|
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)
|
examplesdir = $(exampledir)
|
||||||
dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
|
dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
|
||||||
bgpd.conf.vnc.sample
|
bgpd.conf.vnc.sample
|
||||||
|
@ -45,14 +45,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#include "bgpd/bgp_dump.h"
|
#include "bgpd/bgp_dump.h"
|
||||||
#include "bgpd/bgp_open.h"
|
#include "bgpd/bgp_open.h"
|
||||||
#include "bgpd/bgp_advertise.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_updgrp.h"
|
||||||
#include "bgpd/bgp_nht.h"
|
#include "bgpd/bgp_nht.h"
|
||||||
#include "bgpd/bgp_bfd.h"
|
#include "bgpd/bgp_bfd.h"
|
||||||
#include "bgpd/bgp_memory.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
|
/* Definition of display strings corresponding to FSM events. This should be
|
||||||
* kept consistent with the events defined in bgpd.h
|
* 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);
|
zlog_debug ("%s remove from all update group", peer->host);
|
||||||
update_group_remove_peer_afs(peer);
|
update_group_remove_peer_afs(peer);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(peer_backward_transition, peer);
|
||||||
bgpTrapBackwardTransition (peer);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
/* Reset peer synctime */
|
/* Reset peer synctime */
|
||||||
peer->synctime = 0;
|
peer->synctime = 0;
|
||||||
@ -1508,9 +1506,7 @@ bgp_establish (struct peer *peer)
|
|||||||
zlog_debug ("%s graceful restart timer stopped", peer->host);
|
zlog_debug ("%s graceful restart timer stopped", peer->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(peer_established, peer);
|
||||||
bgpTrapEstablished (peer);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
/* Reset uptime, send keepalive, send current table. */
|
/* Reset uptime, send keepalive, send current table. */
|
||||||
peer->uptime = bgp_clock ();
|
peer->uptime = bgp_clock ();
|
||||||
|
@ -109,4 +109,8 @@ extern void bgp_start_routeadv (struct bgp *);
|
|||||||
*/
|
*/
|
||||||
extern void bgp_adjust_routeadv (struct peer *);
|
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 */
|
#endif /* _QUAGGA_BGP_FSM_H */
|
||||||
|
@ -20,7 +20,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.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 "thread.h"
|
||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "hook.h"
|
||||||
|
#include "libfrr.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "bgpd/bgpd.h"
|
#include "bgpd/bgpd.h"
|
||||||
#include "bgpd/bgp_table.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_attr.h"
|
||||||
#include "bgpd/bgp_route.h"
|
#include "bgpd/bgp_route.h"
|
||||||
#include "bgpd/bgp_fsm.h"
|
#include "bgpd/bgp_fsm.h"
|
||||||
#include "bgpd/bgp_snmp.h"
|
|
||||||
|
|
||||||
/* BGP4-MIB described in RFC1657. */
|
/* BGP4-MIB described in RFC1657. */
|
||||||
#define BGP4MIB 1,3,6,1,2,1,15
|
#define BGP4MIB 1,3,6,1,2,1,15
|
||||||
@ -838,7 +839,7 @@ static struct trap_object bgpTrapList[] =
|
|||||||
{3, {3, 1, BGPPEERSTATE}}
|
{3, {3, 1, BGPPEERSTATE}}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static int
|
||||||
bgpTrapEstablished (struct peer *peer)
|
bgpTrapEstablished (struct peer *peer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -847,7 +848,7 @@ bgpTrapEstablished (struct peer *peer)
|
|||||||
|
|
||||||
ret = inet_aton (peer->host, &addr);
|
ret = inet_aton (peer->host, &addr);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
|
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
|
||||||
|
|
||||||
@ -857,9 +858,10 @@ bgpTrapEstablished (struct peer *peer)
|
|||||||
index, IN_ADDR_SIZE,
|
index, IN_ADDR_SIZE,
|
||||||
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
|
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
|
||||||
BGPESTABLISHED);
|
BGPESTABLISHED);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
bgpTrapBackwardTransition (struct peer *peer)
|
bgpTrapBackwardTransition (struct peer *peer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -868,7 +870,7 @@ bgpTrapBackwardTransition (struct peer *peer)
|
|||||||
|
|
||||||
ret = inet_aton (peer->host, &addr);
|
ret = inet_aton (peer->host, &addr);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
|
oid_copy_addr (index, &addr, IN_ADDR_SIZE);
|
||||||
|
|
||||||
@ -878,12 +880,29 @@ bgpTrapBackwardTransition (struct peer *peer)
|
|||||||
index, IN_ADDR_SIZE,
|
index, IN_ADDR_SIZE,
|
||||||
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
|
bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
|
||||||
BGPBACKWARDTRANSITION);
|
BGPBACKWARDTRANSITION);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
bgp_snmp_init (void)
|
bgp_snmp_init (struct thread_master *tm)
|
||||||
{
|
{
|
||||||
smux_init (bm->master);
|
smux_init (tm);
|
||||||
REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
|
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
|
||||||
|
)
|
||||||
|
@ -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 */
|
|
@ -72,9 +72,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#include "bgpd/bgp_vty.h"
|
#include "bgpd/bgp_vty.h"
|
||||||
#include "bgpd/bgp_mpath.h"
|
#include "bgpd/bgp_mpath.h"
|
||||||
#include "bgpd/bgp_nht.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_updgrp.h"
|
||||||
#include "bgpd/bgp_bfd.h"
|
#include "bgpd/bgp_bfd.h"
|
||||||
#include "bgpd/bgp_memory.h"
|
#include "bgpd/bgp_memory.h"
|
||||||
@ -7667,6 +7664,8 @@ bgp_if_finish (struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void bgp_snmp_init (void);
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_init (void)
|
bgp_init (void)
|
||||||
{
|
{
|
||||||
@ -7715,10 +7714,6 @@ bgp_init (void)
|
|||||||
/* Community list initialize. */
|
/* Community list initialize. */
|
||||||
bgp_clist = community_list_init ();
|
bgp_clist = community_list_init ();
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
bgp_snmp_init ();
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
/* BFD init */
|
/* BFD init */
|
||||||
bgp_bfd_init();
|
bgp_bfd_init();
|
||||||
}
|
}
|
||||||
|
68
configure.ac
68
configure.ac
@ -55,6 +55,13 @@ dnl XXX add --pkgsrcrcdir to autoconf standard directory list somehow
|
|||||||
AC_SUBST(pkgsrcdir)
|
AC_SUBST(pkgsrcdir)
|
||||||
AC_SUBST(pkgsrcrcdir)
|
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,
|
AC_ARG_ENABLE(tcmalloc,
|
||||||
AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]),
|
AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]),
|
||||||
[case "${enableval}" in
|
[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)
|
AC_DEFINE(HAVE_SHELL_ACCESS,,Allow user to use ssh/telnet/bash)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "${enable_fpm}" = "yes"; then
|
AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"])
|
||||||
AC_DEFINE(HAVE_FPM,,Forwarding Plane Manager support)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x${enable_dev_build}" = "xyes"; then
|
if test "x${enable_dev_build}" = "xyes"; then
|
||||||
AC_DEFINE(DEV_BUILD,,Build for development)
|
AC_DEFINE(DEV_BUILD,,Build for development)
|
||||||
@ -1322,8 +1327,8 @@ if test "${enable_snmp}" != ""; then
|
|||||||
if test x"$NETSNMP_CONFIG" = x"no"; then
|
if test x"$NETSNMP_CONFIG" = x"no"; then
|
||||||
AC_MSG_ERROR([--enable-snmp given but unable to find net-snmp-config])
|
AC_MSG_ERROR([--enable-snmp given but unable to find net-snmp-config])
|
||||||
fi
|
fi
|
||||||
LIBS="$LIBS `${NETSNMP_CONFIG} --agent-libs`"
|
SNMP_LIBS="`${NETSNMP_CONFIG} --agent-libs`"
|
||||||
CFLAGS="`${NETSNMP_CONFIG} --base-cflags` $CFLAGS"
|
SNMP_CFLAGS="`${NETSNMP_CONFIG} --base-cflags`"
|
||||||
AC_MSG_CHECKING([whether we can link to Net-SNMP])
|
AC_MSG_CHECKING([whether we can link to Net-SNMP])
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||||
int main(void);
|
int main(void);
|
||||||
@ -1335,7 +1340,6 @@ int main(void);
|
|||||||
])],[AC_MSG_RESULT(yes)],[
|
])],[AC_MSG_RESULT(yes)],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
AC_MSG_ERROR([--enable-snmp given but not usable])])
|
AC_MSG_ERROR([--enable-snmp given but not usable])])
|
||||||
AC_DEFINE(HAVE_SNMP,,SNMP)
|
|
||||||
case "${enable_snmp}" in
|
case "${enable_snmp}" in
|
||||||
yes)
|
yes)
|
||||||
SNMP_METHOD=agentx
|
SNMP_METHOD=agentx
|
||||||
@ -1351,6 +1355,53 @@ int main(void);
|
|||||||
AH_TEMPLATE([SNMP_AGENTX], [Use SNMP AgentX to interface with snmpd])
|
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)
|
AC_DEFINE_UNQUOTED(AS_TR_CPP(SNMP_${SNMP_METHOD}),,SNMP method to interface with snmpd)
|
||||||
fi
|
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 ---------------------------
|
||||||
dnl sockaddr and netinet checks
|
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_SYSCONF="$sysconfdir"
|
||||||
CFG_SBIN="$sbindir"
|
CFG_SBIN="$sbindir"
|
||||||
CFG_STATE="$frr_statedir"
|
CFG_STATE="$frr_statedir"
|
||||||
|
CFG_MODULE="$moduledir"
|
||||||
for I in 1 2 3 4 5 6 7 8 9 10; do
|
for I in 1 2 3 4 5 6 7 8 9 10; do
|
||||||
eval CFG_SYSCONF="\"$CFG_SYSCONF\""
|
eval CFG_SYSCONF="\"$CFG_SYSCONF\""
|
||||||
eval CFG_SBIN="\"$CFG_SBIN\""
|
eval CFG_SBIN="\"$CFG_SBIN\""
|
||||||
eval CFG_STATE="\"$CFG_STATE\""
|
eval CFG_STATE="\"$CFG_STATE\""
|
||||||
|
eval CFG_MODULE="\"$CFG_MODULE\""
|
||||||
done
|
done
|
||||||
AC_SUBST(CFG_SYSCONF)
|
AC_SUBST(CFG_SYSCONF)
|
||||||
AC_SUBST(CFG_SBIN)
|
AC_SUBST(CFG_SBIN)
|
||||||
AC_SUBST(CFG_STATE)
|
AC_SUBST(CFG_STATE)
|
||||||
|
AC_SUBST(CFG_MODULE)
|
||||||
|
AC_DEFINE_UNQUOTED(MODULE_PATH, "$CFG_MODULE", path to modules)
|
||||||
|
|
||||||
dnl ---------------------------
|
dnl ---------------------------
|
||||||
dnl Check htonl works correctly
|
dnl Check htonl works correctly
|
||||||
@ -1734,6 +1789,7 @@ linker flags : ${LDFLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM}
|
|||||||
state file directory : ${frr_statedir}
|
state file directory : ${frr_statedir}
|
||||||
config file directory : `eval echo \`echo ${sysconfdir}\``
|
config file directory : `eval echo \`echo ${sysconfdir}\``
|
||||||
example directory : `eval echo \`echo ${exampledir}\``
|
example directory : `eval echo \`echo ${exampledir}\``
|
||||||
|
module directory : ${CFG_MODULE}
|
||||||
user to run as : ${enable_user}
|
user to run as : ${enable_user}
|
||||||
group to run as : ${enable_group}
|
group to run as : ${enable_group}
|
||||||
group for vty sockets : ${enable_vty_group}
|
group for vty sockets : ${enable_vty_group}
|
||||||
|
@ -18,6 +18,7 @@ daemons.
|
|||||||
* Config Commands:: Commands used in config files
|
* Config Commands:: Commands used in config files
|
||||||
* Terminal Mode Commands:: Common commands used in a VTY
|
* Terminal Mode Commands:: Common commands used in a VTY
|
||||||
* Common Invocation Options:: Starting the daemons
|
* Common Invocation Options:: Starting the daemons
|
||||||
|
* Loadable Module Support:: Using extension modules
|
||||||
* Virtual Terminal Interfaces:: Interacting with the daemons
|
* Virtual Terminal Interfaces:: Interacting with the daemons
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@ -372,6 +373,51 @@ Print program version.
|
|||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node Loadable Module Support
|
||||||
|
@section Loadable Module Support
|
||||||
|
|
||||||
|
FRR supports loading extension modules at startup. Loading, reloading or
|
||||||
|
unloading modules at runtime is not supported (yet). To load a module, use
|
||||||
|
the following command line option at daemon startup:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item -M @var{module:options}
|
||||||
|
@itemx --module @var{module:options}
|
||||||
|
|
||||||
|
Load the specified module, optionally passing options to it. If the module
|
||||||
|
name contains a slash (/), it is assumed to be a full pathname to a file to
|
||||||
|
be loaded. If it does not contain a slash, the
|
||||||
|
@code{@value{INSTALL_PREFIX_MODULES}} directory is searched for a module of
|
||||||
|
the given name; first with the daemon name prepended (e.g. @code{zebra_mod}
|
||||||
|
for @code{mod}), then without the daemon name prepended.
|
||||||
|
|
||||||
|
This option is available on all daemons, though some daemons may not have
|
||||||
|
any modules available to be loaded.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@subsection The SNMP Module
|
||||||
|
|
||||||
|
If SNMP is enabled during compile-time and installed as part of the package,
|
||||||
|
the @code{snmp} module can be loaded for the @command{zebra},
|
||||||
|
@command{bgpd}, @command{ospfd}, @command{ospf6d} and @command{ripd} daemons.
|
||||||
|
|
||||||
|
The module ignores any options passed to it. Refer to @ref{SNMP Support}
|
||||||
|
for information on its usage.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection The FPM Module
|
||||||
|
|
||||||
|
If FPM is enabled during compile-time and installed as part of the package,
|
||||||
|
the @code{fpm} module can be loaded for the @command{zebra} daemon. This
|
||||||
|
provides the Forwarding Plane Manager ("FPM") API.
|
||||||
|
|
||||||
|
The module expects its argument to be either @code{netlink} or
|
||||||
|
@code{protobuf}, specifying the encapsulation to use. @code{netlink} is the
|
||||||
|
default, and @code{protobuf} may not be available if the module was built
|
||||||
|
without protobuf support. Refer to @ref{zebra FIB push interface} for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
|
||||||
@node Virtual Terminal Interfaces
|
@node Virtual Terminal Interfaces
|
||||||
@section Virtual Terminal Interfaces
|
@section Virtual Terminal Interfaces
|
||||||
|
@ -27,6 +27,9 @@ bgpd \- a BGPv4, BGPv4\+, BGPv4\- routing engine for use with @PACKAGE_FULLNAME@
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B bgpd
|
.B bgpd
|
||||||
@ -76,6 +79,11 @@ When the program terminates, retain routes added by \fBbgpd\fR.
|
|||||||
\fB\-S\fR, \fB\-\-skip_runas\fR
|
\fB\-S\fR, \fB\-\-skip_runas\fR
|
||||||
Skip setting the process effective user and group.
|
Skip setting the process effective user and group.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
The \fBsnmp\fR module may be available for
|
||||||
|
\fBbgpd\fR, if the package was built with SNMP support.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
@set INSTALL_PREFIX_ETC @CFG_SYSCONF@
|
@set INSTALL_PREFIX_ETC @CFG_SYSCONF@
|
||||||
@set INSTALL_PREFIX_SBIN @CFG_SBIN@
|
@set INSTALL_PREFIX_SBIN @CFG_SBIN@
|
||||||
@set INSTALL_PREFIX_STATE @CFG_STATE@
|
@set INSTALL_PREFIX_STATE @CFG_STATE@
|
||||||
|
@set INSTALL_PREFIX_MODULES @CFG_MODULE@
|
||||||
@set INSTALL_USER @enable_user@
|
@set INSTALL_USER @enable_user@
|
||||||
@set INSTALL_GROUP @enable_group@
|
@set INSTALL_GROUP @enable_group@
|
||||||
@set INSTALL_VTY_GROUP @enable_vty_group@
|
@set INSTALL_VTY_GROUP @enable_vty_group@
|
||||||
|
119
doc/dev-modules.md
Normal file
119
doc/dev-modules.md
Normal 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.
|
@ -23,6 +23,9 @@ isisd \- an IS-IS routing engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B isisd
|
.B isisd
|
||||||
@ -63,6 +66,11 @@ interfaces.
|
|||||||
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
||||||
Specify the user to run as. Default is \fI@enable_user@\fR.
|
Specify the user to run as. Default is \fI@enable_user@\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
There are currently no such modules for
|
||||||
|
\fBisisd\fR in the base package.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -23,6 +23,9 @@ ldpd \- an LDP engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ldpd
|
.B ldpd
|
||||||
@ -63,6 +66,11 @@ interfaces.
|
|||||||
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
||||||
Specify the user to run as. Default is \fI@enable_user@\fR.
|
Specify the user to run as. Default is \fI@enable_user@\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
There are currently no such modules for
|
||||||
|
\fBldpd\fR in the base package.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -385,7 +385,8 @@ ip protocol rip route-map RM1
|
|||||||
|
|
||||||
Zebra supports a 'FIB push' interface that allows an external
|
Zebra supports a 'FIB push' interface that allows an external
|
||||||
component to learn the forwarding information computed by the Frr
|
component to learn the forwarding information computed by the Frr
|
||||||
routing suite.
|
routing suite. This is a loadable module that needs to be enabled
|
||||||
|
at startup as described in @ref{Loadable Module Support}.
|
||||||
|
|
||||||
In Frr, the Routing Information Base (RIB) resides inside
|
In Frr, the Routing Information Base (RIB) resides inside
|
||||||
zebra. Routing protocols communicate their best routes to zebra, and
|
zebra. Routing protocols communicate their best routes to zebra, and
|
||||||
@ -440,9 +441,9 @@ independently.
|
|||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
As mentioned before, zebra encodes routes sent to the FPM in netlink
|
As mentioned before, zebra encodes routes sent to the FPM in netlink
|
||||||
format by default. The format can be controlled via the
|
format by default. The format can be controlled via the FPM module's
|
||||||
@code{--fpm_format} command-line option to zebra, which currently
|
load-time option to zebra, which currently takes the values @code{netlink}
|
||||||
takes the values @code{netlink} and @code{protobuf}.
|
and @code{protobuf}.
|
||||||
|
|
||||||
The zebra FPM interface uses replace semantics. That is, if a 'route
|
The zebra FPM interface uses replace semantics. That is, if a 'route
|
||||||
add' message for a prefix is followed by another 'route add' message,
|
add' message for a prefix is followed by another 'route add' message,
|
||||||
|
@ -23,6 +23,9 @@ nhrpd \- a Next Hop Routing Protocol routing engine for use with @PACKAGE_FULLNA
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B nhrpd
|
.B nhrpd
|
||||||
@ -63,6 +66,11 @@ interfaces.
|
|||||||
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
||||||
Specify the user to run as. Default is \fI@enable_user@\fR.
|
Specify the user to run as. Default is \fI@enable_user@\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
There are currently no such modules for
|
||||||
|
\fBnhrpd\fR in the base package.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -23,6 +23,9 @@ ospf6d \- an OSPFv3 routing engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ospf6d
|
.B ospf6d
|
||||||
@ -64,6 +67,11 @@ interfaces.
|
|||||||
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
||||||
Specify the user to run as. Default is \fI@enable_user@\fR.
|
Specify the user to run as. Default is \fI@enable_user@\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
The \fBsnmp\fR module may be available for
|
||||||
|
\fBospf6d\fR, if the package was built with SNMP support.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -23,6 +23,9 @@ ospfd \- an OSPFv2 routing engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ospfd
|
.B ospfd
|
||||||
@ -66,6 +69,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
|
|||||||
\fB\-a\fR, \fB\-\-apiserver \fR
|
\fB\-a\fR, \fB\-\-apiserver \fR
|
||||||
Enable OSPF apiserver. Default is disabled.
|
Enable OSPF apiserver. Default is disabled.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
The \fBsnmp\fR module may be available for
|
||||||
|
\fBospfd\fR, if the package was built with SNMP support.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -26,6 +26,9 @@ pimd \- a PIM routing for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B pimd
|
.B pimd
|
||||||
@ -70,6 +73,11 @@ interfaces.
|
|||||||
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
|
||||||
Specify the user to run as. Default is \fI@enable_user@\fR.
|
Specify the user to run as. Default is \fI@enable_user@\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
There are currently no such modules for
|
||||||
|
\fBpimd\fR in the base package.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.TP
|
.TP
|
||||||
|
@ -23,6 +23,9 @@ ripd \- a RIP routing engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ripd
|
.B ripd
|
||||||
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
|
|||||||
\fB\-r\fR, \fB\-\-retain\fR
|
\fB\-r\fR, \fB\-\-retain\fR
|
||||||
When the program terminates, retain routes added by \fBripd\fR.
|
When the program terminates, retain routes added by \fBripd\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
The \fBsnmp\fR module may be available for
|
||||||
|
\fBripd\fR, if the package was built with SNMP support.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -23,6 +23,9 @@ ripngd \- a RIPNG routing engine for use with @PACKAGE_FULLNAME@.
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ripngd
|
.B ripngd
|
||||||
@ -67,6 +70,11 @@ Specify the user to run as. Default is \fI@enable_user@\fR.
|
|||||||
\fB\-r\fR, \fB\-\-retain\fR
|
\fB\-r\fR, \fB\-\-retain\fR
|
||||||
When the program terminates, retain routes added by \fBripd\fR.
|
When the program terminates, retain routes added by \fBripd\fR.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
There are currently no such modules for
|
||||||
|
\fBripngd\fR in the base package.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -8,6 +8,10 @@ but is able to connect to a SNMP agent using the SMUX protocol
|
|||||||
(@cite{RFC1227}) or the AgentX protocol (@cite{RFC2741}) and make the
|
(@cite{RFC1227}) or the AgentX protocol (@cite{RFC2741}) and make the
|
||||||
routing protocol MIBs available through it.
|
routing protocol MIBs available through it.
|
||||||
|
|
||||||
|
Note that SNMP Support needs to be enabled at compile-time and loaded as
|
||||||
|
module on daemon startup. Refer to @ref{Loadable Module Support} on
|
||||||
|
the latter.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Getting and installing an SNMP agent::
|
* Getting and installing an SNMP agent::
|
||||||
* AgentX configuration::
|
* AgentX configuration::
|
||||||
|
@ -108,13 +108,13 @@ Set the logging
|
|||||||
(LOG_DEBUG), but higher number can be supplied if extra debugging messages
|
(LOG_DEBUG), but higher number can be supplied if extra debugging messages
|
||||||
are required.
|
are required.
|
||||||
.TP
|
.TP
|
||||||
.BI \-m " number" "\fR, \fB\-\-min\-restart\-interval " number
|
.BI \-\-min\-restart\-interval " number
|
||||||
Set the minimum
|
Set the minimum
|
||||||
.I number
|
.I number
|
||||||
of seconds to wait between invocations of the daemon restart commands (the
|
of seconds to wait between invocations of the daemon restart commands (the
|
||||||
default value is "60").
|
default value is "60").
|
||||||
.TP
|
.TP
|
||||||
.BI \-M " number" "\fR, \fB\-\-max\-restart\-interval " number
|
.BI \-\-max\-restart\-interval " number
|
||||||
Set the maximum
|
Set the maximum
|
||||||
.I number
|
.I number
|
||||||
of seconds to wait between invocations of the daemon restart commands (the
|
of seconds to wait between invocations of the daemon restart commands (the
|
||||||
|
@ -23,6 +23,9 @@ zebra \- a routing manager for use with associated @PACKAGE_FULLNAME@ components
|
|||||||
] [
|
] [
|
||||||
.B \-g
|
.B \-g
|
||||||
.I group
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-M
|
||||||
|
.I module:options
|
||||||
]
|
]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B zebra
|
.B zebra
|
||||||
@ -86,6 +89,14 @@ maximum before starting zebra.
|
|||||||
|
|
||||||
Note that this affects Linux only.
|
Note that this affects Linux only.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-M\fR, \fB\-\-module \fR\fImodule:options\fR
|
||||||
|
Load a module at startup. May be specified more than once.
|
||||||
|
The \fBsnmp\fR and \fBfpm\fR modules may be
|
||||||
|
available for \fBzebra\fR, if the package was built with SNMP and FPM support
|
||||||
|
respectively. The \fBfpm\fR module takes an additional colon-separated
|
||||||
|
argument specifying the encapsulation, either \fBnetlink\fR or \fBprotobuf\fR.
|
||||||
|
It should thus be loaded with \fB-M fpm:netlink\fR or \fB-M fpm:protobuf\fR.
|
||||||
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-version\fR
|
\fB\-v\fR, \fB\-\-version\fR
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
|
@ -20,7 +20,7 @@ libfrr_la_SOURCES = \
|
|||||||
command.c \
|
command.c \
|
||||||
sockunion.c prefix.c thread.c if.c buffer.c table.c hash.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 \
|
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 \
|
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 \
|
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 \
|
imsg-buffer.c imsg.c skiplist.c \
|
||||||
@ -31,12 +31,28 @@ libfrr_la_SOURCES = \
|
|||||||
spf_backoff.c \
|
spf_backoff.c \
|
||||||
libfrr.c \
|
libfrr.c \
|
||||||
strlcpy.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
|
BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h
|
||||||
|
|
||||||
libfrr_la_LIBADD = @LIBCAP@
|
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 = \
|
pkginclude_HEADERS = \
|
||||||
buffer.h checksum.h filter.h getopt.h hash.h \
|
buffer.h checksum.h filter.h getopt.h hash.h \
|
||||||
if.h linklist.h log.h \
|
if.h linklist.h log.h \
|
||||||
@ -54,6 +70,8 @@ pkginclude_HEADERS = \
|
|||||||
monotime.h \
|
monotime.h \
|
||||||
spf_backoff.h \
|
spf_backoff.h \
|
||||||
srcdest_table.h \
|
srcdest_table.h \
|
||||||
|
module.h \
|
||||||
|
hook.h \
|
||||||
libfrr.h \
|
libfrr.h \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#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-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
#include <net-snmp/agent/net-snmp-agent-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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SNMP */
|
#endif /* SNMP_AGENTX */
|
||||||
|
56
lib/hook.c
Normal file
56
lib/hook.c
Normal 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
187
lib/hook.h
Normal 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 */
|
38
lib/libfrr.c
38
lib/libfrr.c
@ -28,6 +28,9 @@
|
|||||||
#include "memory_vty.h"
|
#include "memory_vty.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
#include "log_int.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_sysconfdir[] = SYSCONFDIR;
|
||||||
const char frr_vtydir[] = DAEMON_VTY_DIR;
|
const char frr_vtydir[] = DAEMON_VTY_DIR;
|
||||||
@ -64,14 +67,16 @@ static const struct option lo_always[] = {
|
|||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'v' },
|
{ "version", no_argument, NULL, 'v' },
|
||||||
{ "daemon", no_argument, NULL, 'd' },
|
{ "daemon", no_argument, NULL, 'd' },
|
||||||
|
{ "module", no_argument, NULL, 'M' },
|
||||||
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
|
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
static const struct optspec os_always = {
|
static const struct optspec os_always = {
|
||||||
"hvdi:",
|
"hvdM:",
|
||||||
" -h, --help Display this help and exit\n"
|
" -h, --help Display this help and exit\n"
|
||||||
" -v, --version Print program version\n"
|
" -v, --version Print program version\n"
|
||||||
" -d, --daemon Runs in daemon mode\n"
|
" -d, --daemon Runs in daemon mode\n"
|
||||||
|
" -M, --module Load specified module\n"
|
||||||
" --vty_socket Override vty socket path\n",
|
" --vty_socket Override vty socket path\n",
|
||||||
lo_always
|
lo_always
|
||||||
};
|
};
|
||||||
@ -184,12 +189,18 @@ void frr_help_exit(int status)
|
|||||||
exit(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 errors = 0;
|
||||||
|
|
||||||
static int frr_opt(int opt)
|
static int frr_opt(int opt)
|
||||||
{
|
{
|
||||||
static int vty_port_set = 0;
|
static int vty_port_set = 0;
|
||||||
static int vty_addr_set = 0;
|
static int vty_addr_set = 0;
|
||||||
|
struct option_chain *oc;
|
||||||
char *err;
|
char *err;
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@ -203,6 +214,13 @@ static int frr_opt(int opt)
|
|||||||
case 'd':
|
case 'd':
|
||||||
di->daemon_mode = 1;
|
di->daemon_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'M':
|
||||||
|
oc = XMALLOC(MTYPE_TMP, sizeof(*oc));
|
||||||
|
oc->arg = optarg;
|
||||||
|
oc->next = NULL;
|
||||||
|
*modnext = oc;
|
||||||
|
modnext = &oc->next;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (di->flags & FRR_NO_CFG_PID_DRY)
|
if (di->flags & FRR_NO_CFG_PID_DRY)
|
||||||
return 1;
|
return 1;
|
||||||
@ -295,9 +313,12 @@ int frr_getopt(int argc, char * const argv[], int *longindex)
|
|||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct thread_master *master;
|
||||||
struct thread_master *frr_init(void)
|
struct thread_master *frr_init(void)
|
||||||
{
|
{
|
||||||
struct thread_master *master;
|
struct option_chain *oc;
|
||||||
|
struct frrmod_runtime *module;
|
||||||
|
char moderr[256];
|
||||||
|
|
||||||
srandom(time(NULL));
|
srandom(time(NULL));
|
||||||
|
|
||||||
@ -307,6 +328,17 @@ struct thread_master *frr_init(void)
|
|||||||
zlog_set_level (ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
|
zlog_set_level (ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
|
||||||
#endif
|
#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);
|
zprivs_init(di->privs);
|
||||||
|
|
||||||
master = thread_master_create();
|
master = thread_master_create();
|
||||||
@ -324,6 +356,8 @@ struct thread_master *frr_init(void)
|
|||||||
|
|
||||||
void frr_config_fork(void)
|
void frr_config_fork(void)
|
||||||
{
|
{
|
||||||
|
hook_call(frr_late_init, master);
|
||||||
|
|
||||||
if (di->instance) {
|
if (di->instance) {
|
||||||
snprintf(config_default, sizeof(config_default), "%s/%s-%d.conf",
|
snprintf(config_default, sizeof(config_default), "%s/%s-%d.conf",
|
||||||
frr_sysconfdir, di->name, di->instance);
|
frr_sysconfdir, di->name, di->instance);
|
||||||
|
15
lib/libfrr.h
15
lib/libfrr.h
@ -26,6 +26,8 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
#include "module.h"
|
||||||
|
#include "hook.h"
|
||||||
|
|
||||||
#define FRR_NO_PRIVSEP (1 << 0)
|
#define FRR_NO_PRIVSEP (1 << 0)
|
||||||
#define FRR_NO_TCPVTY (1 << 1)
|
#define FRR_NO_TCPVTY (1 << 1)
|
||||||
@ -40,6 +42,7 @@ struct frr_daemon_info {
|
|||||||
const char *name;
|
const char *name;
|
||||||
const char *logname;
|
const char *logname;
|
||||||
unsigned short instance;
|
unsigned short instance;
|
||||||
|
struct frrmod_runtime *module;
|
||||||
|
|
||||||
char *vty_addr;
|
char *vty_addr;
|
||||||
int vty_port;
|
int vty_port;
|
||||||
@ -67,15 +70,22 @@ struct frr_daemon_info {
|
|||||||
* i.e. "ZEBRA" or "BGP"
|
* i.e. "ZEBRA" or "BGP"
|
||||||
*
|
*
|
||||||
* note that this macro is also a latch-on point for other changes (e.g.
|
* 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.
|
* daemon should have one of these.
|
||||||
*/
|
*/
|
||||||
#define FRR_DAEMON_INFO(execname, constname, ...) \
|
#define FRR_DAEMON_INFO(execname, constname, ...) \
|
||||||
static struct frr_daemon_info execname ##_di = { \
|
static struct frr_daemon_info execname ##_di = { \
|
||||||
.name = # execname, \
|
.name = # execname, \
|
||||||
.logname = # constname, \
|
.logname = # constname, \
|
||||||
|
.module = THIS_MODULE, \
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
};
|
}; \
|
||||||
|
FRR_COREMOD_SETUP( \
|
||||||
|
.name = # execname, \
|
||||||
|
.description = # execname " daemon", \
|
||||||
|
.version = FRR_VERSION, \
|
||||||
|
) \
|
||||||
|
/* end */
|
||||||
|
|
||||||
extern void frr_preinit(struct frr_daemon_info *daemon,
|
extern void frr_preinit(struct frr_daemon_info *daemon,
|
||||||
int argc, char **argv);
|
int argc, char **argv);
|
||||||
@ -86,6 +96,7 @@ extern void frr_help_exit(int status);
|
|||||||
|
|
||||||
extern struct thread_master *frr_init(void);
|
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_config_fork(void);
|
||||||
|
|
||||||
extern void frr_vty_serv(void);
|
extern void frr_vty_serv(void);
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
* Memory management routine
|
* Memory and dynamic module VTY routine
|
||||||
|
*
|
||||||
* Copyright (C) 1998 Kunihiro Ishiguro
|
* 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
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* under the terms of the GNU General Public License as published by the
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* Free Software Foundation; either version 2, or (at your option) any
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
* later version.
|
* more details.
|
||||||
*
|
*
|
||||||
* GNU Zebra is distributed in the hope that it will be useful, but
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
@ -25,9 +24,12 @@
|
|||||||
#if (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
|
#if (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif /* HAVE_MALLINFO */
|
#endif /* HAVE_MALLINFO */
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <link.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "module.h"
|
||||||
#include "memory_vty.h"
|
#include "memory_vty.h"
|
||||||
|
|
||||||
/* Looking up memory status from vty interface. */
|
/* Looking up memory status from vty interface. */
|
||||||
@ -110,10 +112,55 @@ DEFUN (show_memory,
|
|||||||
return CMD_SUCCESS;
|
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
|
void
|
||||||
memory_init (void)
|
memory_init (void)
|
||||||
{
|
{
|
||||||
install_element (VIEW_NODE, &show_memory_cmd);
|
install_element (VIEW_NODE, &show_memory_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_modules_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stats querying from users */
|
/* Stats querying from users */
|
||||||
|
159
lib/module.c
Normal file
159
lib/module.c
Normal 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
104
lib/module.h
Normal 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 */
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#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-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
|
|
||||||
@ -1445,4 +1445,4 @@ smux_start(void)
|
|||||||
/* Schedule first connection. */
|
/* Schedule first connection. */
|
||||||
smux_event (SMUX_SCHEDULE, 0);
|
smux_event (SMUX_SCHEDULE, 0);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SNMP */
|
#endif /* SNMP_SMUX */
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.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;
|
return MATCH_SUCCEEDED;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
22
lib/thread.c
22
lib/thread.c
@ -1037,28 +1037,6 @@ thread_process_fds_helper (struct thread_master *m, struct thread *thread, threa
|
|||||||
|
|
||||||
#if defined(HAVE_POLL)
|
#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 */
|
/* check poll events */
|
||||||
static void
|
static void
|
||||||
check_pollfds(struct thread_master *m, fd_set *readfd, int num)
|
check_pollfds(struct thread_master *m, fd_set *readfd, int num)
|
||||||
|
@ -7,6 +7,7 @@ INSTALL_SDATA=@INSTALL@ -m 600
|
|||||||
AM_CFLAGS = $(WERROR)
|
AM_CFLAGS = $(WERROR)
|
||||||
|
|
||||||
noinst_LIBRARIES = libospf6.a
|
noinst_LIBRARIES = libospf6.a
|
||||||
|
module_LTLIBRARIES =
|
||||||
sbin_PROGRAMS = ospf6d
|
sbin_PROGRAMS = ospf6d
|
||||||
|
|
||||||
libospf6_a_SOURCES = \
|
libospf6_a_SOURCES = \
|
||||||
@ -14,7 +15,7 @@ libospf6_a_SOURCES = \
|
|||||||
ospf6_network.c ospf6_message.c ospf6_lsa.c ospf6_lsdb.c \
|
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_top.c ospf6_area.c ospf6_interface.c ospf6_neighbor.c \
|
||||||
ospf6_flood.c ospf6_route.c ospf6_intra.c ospf6_zebra.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
|
ospf6d.c ospf6_bfd.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
@ -22,7 +23,7 @@ noinst_HEADERS = \
|
|||||||
ospf6_network.h ospf6_message.h ospf6_lsa.h ospf6_lsdb.h \
|
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_top.h ospf6_area.h ospf6_interface.h ospf6_neighbor.h \
|
||||||
ospf6_flood.h ospf6_route.h ospf6_intra.h ospf6_zebra.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.h ospf6_bfd.h
|
||||||
|
|
||||||
ospf6d_SOURCES = \
|
ospf6d_SOURCES = \
|
||||||
@ -30,5 +31,12 @@ ospf6d_SOURCES = \
|
|||||||
|
|
||||||
ospf6d_LDADD = ../lib/libfrr.la @LIBCAP@
|
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)
|
examplesdir = $(exampledir)
|
||||||
dist_examples_DATA = ospf6d.conf.sample
|
dist_examples_DATA = ospf6d.conf.sample
|
||||||
|
@ -41,12 +41,14 @@
|
|||||||
#include "ospf6_neighbor.h"
|
#include "ospf6_neighbor.h"
|
||||||
#include "ospf6_intra.h"
|
#include "ospf6_intra.h"
|
||||||
#include "ospf6_spf.h"
|
#include "ospf6_spf.h"
|
||||||
#include "ospf6_snmp.h"
|
|
||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
#include "ospf6_bfd.h"
|
#include "ospf6_bfd.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
|
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
|
||||||
DEFINE_QOBJ_TYPE(ospf6_interface)
|
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;
|
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);
|
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf6_interface_change, oi, next_state, prev_state);
|
||||||
/* 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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define OSPF6_INTERFACE_H
|
#define OSPF6_INTERFACE_H
|
||||||
|
|
||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
|
#include "hook.h"
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
|
|
||||||
/* Debug option */
|
/* 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 int config_write_ospf6_debug_interface (struct vty *vty);
|
||||||
extern void install_element_ospf6_debug_interface (void);
|
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 */
|
#endif /* OSPF6_INTERFACE_H */
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "ospf6_neighbor.h"
|
#include "ospf6_neighbor.h"
|
||||||
#include "ospf6_intra.h"
|
#include "ospf6_intra.h"
|
||||||
#include "ospf6_flood.h"
|
#include "ospf6_flood.h"
|
||||||
#include "ospf6_snmp.h"
|
|
||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
#include "ospf6_bfd.h"
|
#include "ospf6_bfd.h"
|
||||||
#include "ospf6_abr.h"
|
#include "ospf6_abr.h"
|
||||||
@ -47,6 +46,10 @@
|
|||||||
#include "ospf6_spf.h"
|
#include "ospf6_spf.h"
|
||||||
#include "ospf6_zebra.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;
|
unsigned char conf_debug_ospf6_neighbor = 0;
|
||||||
|
|
||||||
const char *ospf6_neighbor_state_str[] =
|
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))
|
next_state != OSPF6_NEIGHBOR_LOADING))
|
||||||
ospf6_maxage_remove (on->ospf6_if->area->ospf6);
|
ospf6_maxage_remove (on->ospf6_if->area->ospf6);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf6_neighbor_change, on, next_state, prev_state);
|
||||||
/* Terminal state or regression */
|
|
||||||
if ((next_state == OSPF6_NEIGHBOR_FULL) ||
|
|
||||||
(next_state == OSPF6_NEIGHBOR_TWOWAY) ||
|
|
||||||
(next_state < prev_state))
|
|
||||||
ospf6TrapNbrStateChange (on);
|
|
||||||
#endif
|
|
||||||
ospf6_bfd_trigger_event(on, prev_state, next_state);
|
ospf6_bfd_trigger_event(on, prev_state, next_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#ifndef OSPF6_NEIGHBOR_H
|
#ifndef OSPF6_NEIGHBOR_H
|
||||||
#define OSPF6_NEIGHBOR_H
|
#define OSPF6_NEIGHBOR_H
|
||||||
|
|
||||||
|
#include "hook.h"
|
||||||
|
|
||||||
/* Debug option */
|
/* Debug option */
|
||||||
extern unsigned char conf_debug_ospf6_neighbor;
|
extern unsigned char conf_debug_ospf6_neighbor;
|
||||||
#define OSPF6_DEBUG_NEIGHBOR_STATE 0x01
|
#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 int config_write_ospf6_debug_neighbor (struct vty *vty);
|
||||||
extern void install_element_ospf6_debug_neighbor (void);
|
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 */
|
#endif /* OSPF6_NEIGHBOR_H */
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
|
|
||||||
@ -32,6 +30,8 @@
|
|||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
|
#include "libfrr.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "ospf6_proto.h"
|
#include "ospf6_proto.h"
|
||||||
#include "ospf6_lsa.h"
|
#include "ospf6_lsa.h"
|
||||||
@ -45,7 +45,6 @@
|
|||||||
#include "ospf6_abr.h"
|
#include "ospf6_abr.h"
|
||||||
#include "ospf6_asbr.h"
|
#include "ospf6_asbr.h"
|
||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
#include "ospf6_snmp.h"
|
|
||||||
|
|
||||||
/* OSPFv3-MIB */
|
/* OSPFv3-MIB */
|
||||||
#define OSPFv3MIB 1,3,6,1,2,1,191
|
#define OSPFv3MIB 1,3,6,1,2,1,191
|
||||||
@ -1139,11 +1138,18 @@ static struct trap_object ospf6IfTrapList[] =
|
|||||||
{4, {1, 7, 1, OSPFv3IFAREAID}}
|
{4, {1, 7, 1, OSPFv3IFAREAID}}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf6TrapNbrStateChange (struct ospf6_neighbor *on)
|
ospf6TrapNbrStateChange (struct ospf6_neighbor *on,
|
||||||
|
int next_state, int prev_state)
|
||||||
{
|
{
|
||||||
oid index[3];
|
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[0] = on->ospf6_if->interface->ifindex;
|
||||||
index[1] = on->ospf6_if->instance_id;
|
index[1] = on->ospf6_if->instance_id;
|
||||||
index[2] = ntohl (on->router_id);
|
index[2] = ntohl (on->router_id);
|
||||||
@ -1155,13 +1161,23 @@ ospf6TrapNbrStateChange (struct ospf6_neighbor *on)
|
|||||||
ospf6NbrTrapList,
|
ospf6NbrTrapList,
|
||||||
sizeof ospf6NbrTrapList / sizeof (struct trap_object),
|
sizeof ospf6NbrTrapList / sizeof (struct trap_object),
|
||||||
NBRSTATECHANGE);
|
NBRSTATECHANGE);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf6TrapIfStateChange (struct ospf6_interface *oi)
|
ospf6TrapIfStateChange (struct ospf6_interface *oi,
|
||||||
|
int next_state, int prev_state)
|
||||||
{
|
{
|
||||||
oid index[2];
|
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[0] = oi->interface->ifindex;
|
||||||
index[1] = oi->instance_id;
|
index[1] = oi->instance_id;
|
||||||
|
|
||||||
@ -1172,15 +1188,30 @@ ospf6TrapIfStateChange (struct ospf6_interface *oi)
|
|||||||
ospf6IfTrapList,
|
ospf6IfTrapList,
|
||||||
sizeof ospf6IfTrapList / sizeof (struct trap_object),
|
sizeof ospf6IfTrapList / sizeof (struct trap_object),
|
||||||
IFSTATECHANGE);
|
IFSTATECHANGE);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register OSPFv3-MIB. */
|
/* Register OSPFv3-MIB. */
|
||||||
void
|
static int
|
||||||
ospf6_snmp_init (struct thread_master *master)
|
ospf6_snmp_init (struct thread_master *master)
|
||||||
{
|
{
|
||||||
smux_init (master);
|
smux_init (master);
|
||||||
REGISTER_MIB ("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
|
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,
|
||||||
|
)
|
||||||
|
@ -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*/
|
|
||||||
|
|
||||||
|
|
@ -45,10 +45,6 @@
|
|||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
#include "ospf6_bfd.h"
|
#include "ospf6_bfd.h"
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include "ospf6_snmp.h"
|
|
||||||
#endif /*HAVE_SNMP*/
|
|
||||||
|
|
||||||
char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION;
|
char ospf6_daemon_version[] = OSPF6_DAEMON_VERSION;
|
||||||
|
|
||||||
struct route_node *
|
struct route_node *
|
||||||
@ -1215,10 +1211,6 @@ ospf6_init (void)
|
|||||||
ospf6_asbr_init ();
|
ospf6_asbr_init ();
|
||||||
ospf6_abr_init ();
|
ospf6_abr_init ();
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
ospf6_snmp_init (master);
|
|
||||||
#endif /*HAVE_SNMP*/
|
|
||||||
|
|
||||||
ospf6_bfd_init();
|
ospf6_bfd_init();
|
||||||
install_node (&debug_node, config_write_ospf6_debug);
|
install_node (&debug_node, config_write_ospf6_debug);
|
||||||
|
|
||||||
|
@ -6,13 +6,14 @@ DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
|
|||||||
INSTALL_SDATA=@INSTALL@ -m 600
|
INSTALL_SDATA=@INSTALL@ -m 600
|
||||||
|
|
||||||
noinst_LIBRARIES = libfrrospf.a
|
noinst_LIBRARIES = libfrrospf.a
|
||||||
|
module_LTLIBRARIES =
|
||||||
sbin_PROGRAMS = ospfd
|
sbin_PROGRAMS = ospfd
|
||||||
|
|
||||||
libfrrospf_a_SOURCES = \
|
libfrrospf_a_SOURCES = \
|
||||||
ospfd.c ospf_zebra.c ospf_interface.c ospf_ism.c ospf_neighbor.c \
|
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_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_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_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
|
ospf_bfd.c ospf_memory.c ospf_dump_api.c
|
||||||
|
|
||||||
@ -26,13 +27,20 @@ ospfdheader_HEADERS = \
|
|||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
ospf_interface.h ospf_neighbor.h ospf_network.h ospf_packet.h \
|
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_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
|
ospf_bfd.h ospf_memory.h
|
||||||
|
|
||||||
ospfd_SOURCES = ospf_main.c
|
ospfd_SOURCES = ospf_main.c
|
||||||
|
|
||||||
ospfd_LDADD = libfrrospf.a ../lib/libfrr.la @LIBCAP@ @LIBM@
|
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
|
EXTRA_DIST = OSPF-MIB.txt OSPF-TRAP-MIB.txt ChangeLog.opaque.txt
|
||||||
|
|
||||||
examplesdir = $(exampledir)
|
examplesdir = $(exampledir)
|
||||||
|
@ -47,11 +47,10 @@
|
|||||||
#include "ospfd/ospf_abr.h"
|
#include "ospfd/ospf_abr.h"
|
||||||
#include "ospfd/ospf_network.h"
|
#include "ospfd/ospf_network.h"
|
||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include "ospfd/ospf_snmp.h"
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
DEFINE_QOBJ_TYPE(ospf_interface)
|
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
|
int
|
||||||
ospf_if_get_output_cost (struct ospf_interface *oi)
|
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)
|
ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
|
||||||
{
|
{
|
||||||
listnode_add (ospf->vlinks, vl_data);
|
listnode_add (ospf->vlinks, vl_data);
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_vl_add, vl_data);
|
||||||
ospf_snmp_vl_add (vl_data);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1004,9 +1001,7 @@ ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
|
|||||||
ospf_vl_shutdown (vl_data);
|
ospf_vl_shutdown (vl_data);
|
||||||
ospf_vl_if_delete (vl_data);
|
ospf_vl_if_delete (vl_data);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_vl_delete, vl_data);
|
||||||
ospf_snmp_vl_delete (vl_data);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
listnode_delete (ospf->vlinks, vl_data);
|
listnode_delete (ospf->vlinks, vl_data);
|
||||||
|
|
||||||
ospf_vl_data_free (vl_data);
|
ospf_vl_data_free (vl_data);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define _ZEBRA_OSPF_INTERFACE_H
|
#define _ZEBRA_OSPF_INTERFACE_H
|
||||||
|
|
||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
|
#include "hook.h"
|
||||||
#include "ospfd/ospf_packet.h"
|
#include "ospfd/ospf_packet.h"
|
||||||
#include "ospfd/ospf_spf.h"
|
#include "ospfd/ospf_spf.h"
|
||||||
|
|
||||||
@ -309,4 +310,7 @@ extern u_char ospf_default_iftype (struct interface *ifp);
|
|||||||
state of the interface. */
|
state of the interface. */
|
||||||
extern void ospf_if_set_multicast (struct ospf_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 */
|
#endif /* _ZEBRA_OSPF_INTERFACE_H */
|
||||||
|
@ -43,7 +43,10 @@
|
|||||||
#include "ospfd/ospf_packet.h"
|
#include "ospfd/ospf_packet.h"
|
||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_abr.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 */
|
/* elect DR and BDR. Refer to RFC2319 section 9.4 */
|
||||||
static struct ospf_neighbor *
|
static struct ospf_neighbor *
|
||||||
@ -545,19 +548,7 @@ ism_change_state (struct ospf_interface *oi, int state)
|
|||||||
oi->state = state;
|
oi->state = state;
|
||||||
oi->state_change++;
|
oi->state_change++;
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_ism_change, oi, state, 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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set multicast memberships appropriately for new state. */
|
/* Set multicast memberships appropriately for new state. */
|
||||||
ospf_if_set_multicast(oi);
|
ospf_if_set_multicast(oi);
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#ifndef _ZEBRA_OSPF_ISM_H
|
#ifndef _ZEBRA_OSPF_ISM_H
|
||||||
#define _ZEBRA_OSPF_ISM_H
|
#define _ZEBRA_OSPF_ISM_H
|
||||||
|
|
||||||
|
#include "hook.h"
|
||||||
|
|
||||||
/* OSPF Interface State Machine Status. */
|
/* OSPF Interface State Machine Status. */
|
||||||
#define ISM_DependUpon 0
|
#define ISM_DependUpon 0
|
||||||
#define ISM_Down 1
|
#define ISM_Down 1
|
||||||
@ -35,10 +37,6 @@
|
|||||||
#define ISM_DR 7
|
#define ISM_DR 7
|
||||||
#define OSPF_ISM_STATE_MAX 8
|
#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. */
|
/* OSPF Interface State Machine Event. */
|
||||||
#define ISM_NoEvent 0
|
#define ISM_NoEvent 0
|
||||||
#define ISM_InterfaceUp 1
|
#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 void ism_change_status (struct ospf_interface *, int);
|
||||||
extern int ospf_hello_timer (struct thread *thread);
|
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 */
|
#endif /* _ZEBRA_OSPF_ISM_H */
|
||||||
|
@ -225,9 +225,6 @@ main (int argc, char **argv)
|
|||||||
ospf_bfd_init();
|
ospf_bfd_init();
|
||||||
|
|
||||||
ospf_route_map_init ();
|
ospf_route_map_init ();
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
ospf_snmp_init ();
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
ospf_opaque_init ();
|
ospf_opaque_init ();
|
||||||
|
|
||||||
/* Need to initialize the default ospf structure, so the interface mode
|
/* Need to initialize the default ospf structure, so the interface mode
|
||||||
|
@ -48,9 +48,12 @@
|
|||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_abr.h"
|
#include "ospfd/ospf_abr.h"
|
||||||
#include "ospfd/ospf_snmp.h"
|
|
||||||
#include "ospfd/ospf_bfd.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 *);
|
static void nsm_clear_adj (struct ospf_neighbor *);
|
||||||
|
|
||||||
/* OSPF NSM Timer functions. */
|
/* OSPF NSM Timer functions. */
|
||||||
@ -838,35 +841,12 @@ ospf_nsm_event (struct thread *thread)
|
|||||||
/* If state is changed. */
|
/* If state is changed. */
|
||||||
if (next_state != nbr->state)
|
if (next_state != nbr->state)
|
||||||
{
|
{
|
||||||
|
int old_state = nbr->state;
|
||||||
|
|
||||||
nsm_notice_state_change (nbr, next_state, event);
|
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);
|
nsm_change_state (nbr, next_state);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_nsm_change, nbr, next_state, old_state);
|
||||||
if (send_trap_virt) {
|
|
||||||
ospfTrapVirtNbrStateChange(nbr);
|
|
||||||
} else if (send_trap) {
|
|
||||||
ospfTrapNbrStateChange(nbr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure timer is set. */
|
/* Make sure timer is set. */
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#ifndef _ZEBRA_OSPF_NSM_H
|
#ifndef _ZEBRA_OSPF_NSM_H
|
||||||
#define _ZEBRA_OSPF_NSM_H
|
#define _ZEBRA_OSPF_NSM_H
|
||||||
|
|
||||||
|
#include "hook.h"
|
||||||
|
|
||||||
/* OSPF Neighbor State Machine State. */
|
/* OSPF Neighbor State Machine State. */
|
||||||
#define NSM_DependUpon 0
|
#define NSM_DependUpon 0
|
||||||
#define NSM_Deleted 1
|
#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 int ospf_db_summary_count (struct ospf_neighbor *);
|
||||||
extern void ospf_db_summary_clear (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 */
|
#endif /* _ZEBRA_OSPF_NSM_H */
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
|
|
||||||
@ -35,6 +34,8 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
|
#include "libfrr.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
@ -47,7 +48,7 @@
|
|||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_ism.h"
|
#include "ospfd/ospf_ism.h"
|
||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#include "ospfd/ospf_snmp.h"
|
#include "ospfd/ospf_zebra.h"
|
||||||
|
|
||||||
/* OSPF2-MIB. */
|
/* OSPF2-MIB. */
|
||||||
#define OSPF2MIB 1,3,6,1,2,1,14
|
#define OSPF2MIB 1,3,6,1,2,1,14
|
||||||
@ -205,6 +206,10 @@
|
|||||||
#define IPADDRESS ASN_IPADDRESS
|
#define IPADDRESS ASN_IPADDRESS
|
||||||
#define STRING ASN_OCTET_STR
|
#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. */
|
/* Declare static local variables for convenience. */
|
||||||
SNMP_LOCAL_VARIABLES
|
SNMP_LOCAL_VARIABLES
|
||||||
|
|
||||||
@ -1429,7 +1434,7 @@ ospf_snmp_if_free (struct ospf_snmp_if *osif)
|
|||||||
XFREE (MTYPE_TMP, osif);
|
XFREE (MTYPE_TMP, osif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf_snmp_if_delete (struct interface *ifp)
|
ospf_snmp_if_delete (struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
@ -1441,12 +1446,13 @@ ospf_snmp_if_delete (struct interface *ifp)
|
|||||||
{
|
{
|
||||||
list_delete_node (ospf_snmp_iflist, node);
|
list_delete_node (ospf_snmp_iflist, node);
|
||||||
ospf_snmp_if_free (osif);
|
ospf_snmp_if_free (osif);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf_snmp_if_update (struct interface *ifp)
|
ospf_snmp_if_update (struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
@ -1511,6 +1517,7 @@ ospf_snmp_if_update (struct interface *ifp)
|
|||||||
osif->ifp = ifp;
|
osif->ifp = ifp;
|
||||||
|
|
||||||
listnode_add_after (ospf_snmp_iflist, pn, osif);
|
listnode_add_after (ospf_snmp_iflist, pn, osif);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
static struct route_table *ospf_snmp_vl_table;
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
|
ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
|
||||||
{
|
{
|
||||||
struct prefix_ls lp;
|
struct prefix_ls lp;
|
||||||
@ -1931,9 +1938,10 @@ ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
|
|||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
|
|
||||||
rn->info = vl_data;
|
rn->info = vl_data;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
|
ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
|
||||||
{
|
{
|
||||||
struct prefix_ls lp;
|
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);
|
rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
|
||||||
if (! rn)
|
if (! rn)
|
||||||
return;
|
return 0;
|
||||||
rn->info = NULL;
|
rn->info = NULL;
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ospf_vl_data *
|
static struct ospf_vl_data *
|
||||||
@ -2651,7 +2660,7 @@ static struct trap_object ospfVirtIfTrapList[] =
|
|||||||
{3, {9, 1, OSPFVIRTIFSTATE}}
|
{3, {9, 1, OSPFVIRTIFSTATE}}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static void
|
||||||
ospfTrapNbrStateChange (struct ospf_neighbor *on)
|
ospfTrapNbrStateChange (struct ospf_neighbor *on)
|
||||||
{
|
{
|
||||||
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
||||||
@ -2673,7 +2682,7 @@ ospfTrapNbrStateChange (struct ospf_neighbor *on)
|
|||||||
NBRSTATECHANGE);
|
NBRSTATECHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
|
ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
|
||||||
{
|
{
|
||||||
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
||||||
@ -2692,7 +2701,29 @@ ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
|
|||||||
VIRTNBRSTATECHANGE);
|
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)
|
ospfTrapIfStateChange (struct ospf_interface *oi)
|
||||||
{
|
{
|
||||||
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
||||||
@ -2713,7 +2744,7 @@ ospfTrapIfStateChange (struct ospf_interface *oi)
|
|||||||
IFSTATECHANGE);
|
IFSTATECHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ospfTrapVirtIfStateChange (struct ospf_interface *oi)
|
ospfTrapVirtIfStateChange (struct ospf_interface *oi)
|
||||||
{
|
{
|
||||||
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
|
||||||
@ -2731,13 +2762,53 @@ ospfTrapVirtIfStateChange (struct ospf_interface *oi)
|
|||||||
sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
|
sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
|
||||||
VIRTIFSTATECHANGE);
|
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. */
|
/* Register OSPF2-MIB. */
|
||||||
void
|
static int
|
||||||
ospf_snmp_init ()
|
ospf_snmp_init (struct thread_master *tm)
|
||||||
{
|
{
|
||||||
ospf_snmp_iflist = list_new ();
|
ospf_snmp_iflist = list_new ();
|
||||||
ospf_snmp_vl_table = route_table_init ();
|
ospf_snmp_vl_table = route_table_init ();
|
||||||
smux_init (om->master);
|
smux_init (tm);
|
||||||
REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
|
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,
|
||||||
|
)
|
||||||
|
@ -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 */
|
|
@ -50,11 +50,11 @@
|
|||||||
#include "ospfd/ospf_neighbor.h"
|
#include "ospfd/ospf_neighbor.h"
|
||||||
#include "ospfd/ospf_nsm.h"
|
#include "ospfd/ospf_nsm.h"
|
||||||
#include "ospfd/ospf_zebra.h"
|
#include "ospfd/ospf_zebra.h"
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include "ospfd/ospf_snmp.h"
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
#include "ospfd/ospf_te.h"
|
#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. */
|
/* Zebra structure to hold current status. */
|
||||||
struct zclient *zclient = NULL;
|
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);
|
ospf_if_update (NULL, ifp);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_if_update, ifp);
|
||||||
ospf_snmp_if_update (ifp);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
return 0;
|
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",
|
("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);
|
ifp->name, ifp->vrf_id, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_if_delete, ifp);
|
||||||
ospf_snmp_if_delete (ifp);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
|
for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
|
||||||
if (rn->info)
|
if (rn->info)
|
||||||
@ -277,9 +273,7 @@ ospf_interface_address_add (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
ospf_if_update (NULL, c->ifp);
|
ospf_if_update (NULL, c->ifp);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_if_update, c->ifp);
|
||||||
ospf_snmp_if_update (c->ifp);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -324,9 +318,7 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
|
|||||||
/* Call interface hook functions to clean up */
|
/* Call interface hook functions to clean up */
|
||||||
ospf_if_free (oi);
|
ospf_if_free (oi);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(ospf_if_update, c->ifp);
|
||||||
ospf_snmp_if_update (c->ifp);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
connected_free (c);
|
connected_free (c);
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define _ZEBRA_OSPF_ZEBRA_H
|
#define _ZEBRA_OSPF_ZEBRA_H
|
||||||
|
|
||||||
#include "vty.h"
|
#include "vty.h"
|
||||||
|
#include "hook.h"
|
||||||
|
|
||||||
#define EXTERNAL_METRIC_TYPE_1 0
|
#define EXTERNAL_METRIC_TYPE_1 0
|
||||||
#define EXTERNAL_METRIC_TYPE_2 1
|
#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 *);
|
const char *, const char *);
|
||||||
extern void ospf_zebra_init(struct thread_master *, u_short);
|
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 */
|
#endif /* _ZEBRA_OSPF_ZEBRA_H */
|
||||||
|
|
||||||
|
@ -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_area_del_if (struct ospf_area *, struct ospf_interface *);
|
||||||
|
|
||||||
extern void ospf_route_map_init (void);
|
extern void ospf_route_map_init (void);
|
||||||
extern void ospf_snmp_init (void);
|
|
||||||
|
|
||||||
extern void ospf_master_init (struct thread_master *master);
|
extern void ospf_master_init (struct thread_master *master);
|
||||||
|
|
||||||
|
@ -7,11 +7,12 @@ INSTALL_SDATA=@INSTALL@ -m 600
|
|||||||
AM_CFLAGS = $(WERROR)
|
AM_CFLAGS = $(WERROR)
|
||||||
|
|
||||||
noinst_LIBRARIES = librip.a
|
noinst_LIBRARIES = librip.a
|
||||||
|
module_LTLIBRARIES =
|
||||||
sbin_PROGRAMS = ripd
|
sbin_PROGRAMS = ripd
|
||||||
|
|
||||||
librip_a_SOURCES = \
|
librip_a_SOURCES = \
|
||||||
rip_memory.c \
|
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
|
rip_routemap.c rip_peer.c rip_offset.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
@ -23,6 +24,13 @@ ripd_SOURCES = \
|
|||||||
|
|
||||||
ripd_LDADD = ../lib/libfrr.la @LIBCAP@
|
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)
|
examplesdir = $(exampledir)
|
||||||
dist_examples_DATA = ripd.conf.sample
|
dist_examples_DATA = ripd.conf.sample
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
#include "ripd/rip_debug.h"
|
#include "ripd/rip_debug.h"
|
||||||
#include "ripd/rip_interface.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 prototypes */
|
||||||
static void rip_enable_apply (struct interface *);
|
static void rip_enable_apply (struct interface *);
|
||||||
static void rip_passive_interface_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 */
|
/* Check if this prefix needs to be redistributed */
|
||||||
rip_apply_address_add(ifc);
|
rip_apply_address_add(ifc);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(rip_ifaddr_add, ifc);
|
||||||
rip_ifaddr_add (ifc->ifp, ifc);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -723,9 +724,7 @@ rip_interface_address_delete (int command, struct zclient *zclient,
|
|||||||
zlog_debug ("connected address %s/%d is deleted",
|
zlog_debug ("connected address %s/%d is deleted",
|
||||||
inet_ntoa (p->u.prefix4), p->prefixlen);
|
inet_ntoa (p->u.prefix4), p->prefixlen);
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
hook_call(rip_ifaddr_del, ifc);
|
||||||
rip_ifaddr_delete (ifc->ifp, ifc);
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
/* Chech wether this prefix needs to be removed */
|
/* Chech wether this prefix needs to be removed */
|
||||||
rip_apply_address_del(ifc);
|
rip_apply_address_del(ifc);
|
||||||
|
@ -21,16 +21,18 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
|
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
|
#include "vrf.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
|
#include "libfrr.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "ripd/ripd.h"
|
#include "ripd/ripd.h"
|
||||||
|
|
||||||
@ -174,24 +176,27 @@ rip2Globals (struct variable *v, oid name[], size_t *length,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
rip_ifaddr_add (struct interface *ifp, struct connected *ifc)
|
rip_snmp_ifaddr_add (struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp = ifc->ifp;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
|
||||||
p = ifc->address;
|
p = ifc->address;
|
||||||
|
|
||||||
if (p->family != AF_INET)
|
if (p->family != AF_INET)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
rn = route_node_get (rip_ifaddr_table, p);
|
rn = route_node_get (rip_ifaddr_table, p);
|
||||||
rn->info = ifp;
|
rn->info = ifp;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
rip_ifaddr_delete (struct interface *ifp, struct connected *ifc)
|
rip_snmp_ifaddr_del (struct connected *ifc)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp = ifc->ifp;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct interface *i;
|
struct interface *i;
|
||||||
@ -199,11 +204,11 @@ rip_ifaddr_delete (struct interface *ifp, struct connected *ifc)
|
|||||||
p = ifc->address;
|
p = ifc->address;
|
||||||
|
|
||||||
if (p->family != AF_INET)
|
if (p->family != AF_INET)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
rn = route_node_lookup (rip_ifaddr_table, p);
|
rn = route_node_lookup (rip_ifaddr_table, p);
|
||||||
if (! rn)
|
if (! rn)
|
||||||
return;
|
return 0;
|
||||||
i = rn->info;
|
i = rn->info;
|
||||||
if (rn && !strncmp(i->name,ifp->name,INTERFACE_NAMSIZ))
|
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);
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct interface *
|
static struct interface *
|
||||||
@ -582,12 +588,29 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Register RIPv2-MIB. */
|
/* Register RIPv2-MIB. */
|
||||||
void
|
static int
|
||||||
rip_snmp_init ()
|
rip_snmp_init (struct thread_master *master)
|
||||||
{
|
{
|
||||||
rip_ifaddr_table = route_table_init ();
|
rip_ifaddr_table = route_table_init ();
|
||||||
|
|
||||||
smux_init (master);
|
smux_init (master);
|
||||||
REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid);
|
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,
|
||||||
|
)
|
||||||
|
@ -4064,11 +4064,6 @@ rip_init (void)
|
|||||||
/* Debug related init. */
|
/* Debug related init. */
|
||||||
rip_debug_init ();
|
rip_debug_init ();
|
||||||
|
|
||||||
/* SNMP init. */
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
rip_snmp_init ();
|
|
||||||
#endif /* HAVE_SNMP */
|
|
||||||
|
|
||||||
/* Access list install. */
|
/* Access list install. */
|
||||||
access_list_init ();
|
access_list_init ();
|
||||||
access_list_add_hook (rip_distribute_update_all_wrapper);
|
access_list_add_hook (rip_distribute_update_all_wrapper);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define _ZEBRA_RIP_H
|
#define _ZEBRA_RIP_H
|
||||||
|
|
||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
|
#include "hook.h"
|
||||||
#include "rip_memory.h"
|
#include "rip_memory.h"
|
||||||
|
|
||||||
/* RIP version number. */
|
/* RIP version number. */
|
||||||
@ -391,7 +392,6 @@ extern void rip_if_init (void);
|
|||||||
extern void rip_if_down_all (void);
|
extern void rip_if_down_all (void);
|
||||||
extern void rip_route_map_init (void);
|
extern void rip_route_map_init (void);
|
||||||
extern void rip_route_map_reset (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_init(struct thread_master *);
|
||||||
extern void rip_zclient_reset (void);
|
extern void rip_zclient_reset (void);
|
||||||
extern void rip_offset_init (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 void rip_info_free (struct rip_info *);
|
||||||
extern u_char rip_distance_apply (struct rip_info *);
|
extern u_char rip_distance_apply (struct rip_info *);
|
||||||
extern void rip_redistribute_clean (void);
|
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_add (struct rip_info *);
|
||||||
extern struct rip_info *rip_ecmp_replace (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. */
|
/* RIP statistics for SNMP. */
|
||||||
extern long rip_global_route_changes;
|
extern long rip_global_route_changes;
|
||||||
extern long rip_global_queries;
|
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 */
|
#endif /* _ZEBRA_RIP_H */
|
||||||
|
@ -2010,6 +2010,24 @@ DEFUNSH (VTYSH_ZEBRA,
|
|||||||
return CMD_SUCCESS;
|
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 */
|
/* Memory */
|
||||||
DEFUN (vtysh_show_memory,
|
DEFUN (vtysh_show_memory,
|
||||||
vtysh_show_memory_cmd,
|
vtysh_show_memory_cmd,
|
||||||
@ -2017,20 +2035,16 @@ DEFUN (vtysh_show_memory,
|
|||||||
SHOW_STR
|
SHOW_STR
|
||||||
"Memory statistics\n")
|
"Memory statistics\n")
|
||||||
{
|
{
|
||||||
unsigned int i;
|
return show_per_daemon ("show memory\n", "Memory statistics for %s:\n");
|
||||||
int ret = CMD_SUCCESS;
|
}
|
||||||
char line[] = "show memory\n";
|
|
||||||
|
DEFUN (vtysh_show_modules,
|
||||||
for (i = 0; i < array_size(vtysh_client); i++)
|
vtysh_show_modules_cmd,
|
||||||
if ( vtysh_client[i].fd >= 0 )
|
"show modules",
|
||||||
{
|
SHOW_STR
|
||||||
fprintf (stdout, "Memory statistics for %s:\n",
|
"Loaded modules\n")
|
||||||
vtysh_client[i].name);
|
{
|
||||||
ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
|
return show_per_daemon ("show modules\n", "Module information for %s:\n");
|
||||||
fprintf (stdout,"\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Logging commands. */
|
/* Logging commands. */
|
||||||
@ -3388,6 +3402,7 @@ vtysh_init_vty (void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
install_element (VIEW_NODE, &vtysh_show_memory_cmd);
|
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_cmd);
|
||||||
install_element (VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
|
install_element (VIEW_NODE, &vtysh_show_work_queues_daemon_cmd);
|
||||||
|
@ -19,33 +19,22 @@ mpls_method = @MPLS_METHOD@
|
|||||||
otherobj = $(ioctl_method) $(ipforward) $(if_method) \
|
otherobj = $(ioctl_method) $(ipforward) $(if_method) \
|
||||||
$(rt_method) $(rtread_method) $(kernel_method) $(mpls_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)
|
AM_CFLAGS = $(WERROR)
|
||||||
|
|
||||||
sbin_PROGRAMS = zebra
|
sbin_PROGRAMS = zebra
|
||||||
|
|
||||||
noinst_PROGRAMS = testzebra
|
noinst_PROGRAMS = testzebra
|
||||||
|
module_LTLIBRARIES =
|
||||||
|
|
||||||
zebra_SOURCES = \
|
zebra_SOURCES = \
|
||||||
zebra_memory.c \
|
zebra_memory.c \
|
||||||
zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.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 \
|
redistribute.c debug.c rtadv.c zebra_vty.c \
|
||||||
irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
|
irdp_main.c irdp_interface.c irdp_packet.c router-id.c \
|
||||||
$(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.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 \
|
zebra_ns.c zebra_vrf.c zebra_static.c zebra_mpls.c zebra_mpls_vty.c \
|
||||||
$(protobuf_srcs) zebra_mroute.c \
|
zebra_mroute.c \
|
||||||
$(dev_srcs) label_manager.c
|
label_manager.c \
|
||||||
|
# end
|
||||||
|
|
||||||
testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
|
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 \
|
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \
|
||||||
@ -57,17 +46,41 @@ noinst_HEADERS = \
|
|||||||
zebra_memory.h \
|
zebra_memory.h \
|
||||||
connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.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 \
|
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_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \
|
||||||
zebra_ns.h zebra_vrf.h ioctl_solaris.h zebra_static.h zebra_mpls.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
|
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)
|
testzebra_LDADD = ../lib/libfrr.la $(LIBCAP)
|
||||||
|
|
||||||
zebra_DEPENDENCIES = $(otherobj)
|
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 \
|
EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c \
|
||||||
if_sysctl.c ipforward_proc.c \
|
if_sysctl.c ipforward_proc.c \
|
||||||
ipforward_solaris.c ipforward_sysctl.c rt_netlink.c \
|
ipforward_solaris.c ipforward_sysctl.c rt_netlink.c \
|
||||||
|
20
zebra/main.c
20
zebra/main.c
@ -43,7 +43,6 @@
|
|||||||
#include "zebra/router-id.h"
|
#include "zebra/router-id.h"
|
||||||
#include "zebra/irdp.h"
|
#include "zebra/irdp.h"
|
||||||
#include "zebra/rtadv.h"
|
#include "zebra/rtadv.h"
|
||||||
#include "zebra/zebra_fpm.h"
|
|
||||||
#include "zebra/zebra_ptm.h"
|
#include "zebra/zebra_ptm.h"
|
||||||
#include "zebra/zebra_ns.h"
|
#include "zebra/zebra_ns.h"
|
||||||
#include "zebra/redistribute.h"
|
#include "zebra/redistribute.h"
|
||||||
@ -84,7 +83,6 @@ struct option longopts[] =
|
|||||||
{ "batch", no_argument, NULL, 'b'},
|
{ "batch", no_argument, NULL, 'b'},
|
||||||
{ "allow_delete", no_argument, NULL, 'a'},
|
{ "allow_delete", no_argument, NULL, 'a'},
|
||||||
{ "keep_kernel", no_argument, NULL, 'k'},
|
{ "keep_kernel", no_argument, NULL, 'k'},
|
||||||
{ "fpm_format", required_argument, NULL, 'F'},
|
|
||||||
{ "socket", required_argument, NULL, 'z'},
|
{ "socket", required_argument, NULL, 'z'},
|
||||||
{ "ecmp", required_argument, NULL, 'e'},
|
{ "ecmp", required_argument, NULL, 'e'},
|
||||||
{ "label_socket", no_argument, NULL, 'l'},
|
{ "label_socket", no_argument, NULL, 'l'},
|
||||||
@ -221,21 +219,18 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
// int batch_mode = 0;
|
// int batch_mode = 0;
|
||||||
char *zserv_path = NULL;
|
char *zserv_path = NULL;
|
||||||
char *fpm_format = NULL;
|
|
||||||
/* Socket to external label manager */
|
/* Socket to external label manager */
|
||||||
char *lblmgr_path = NULL;
|
char *lblmgr_path = NULL;
|
||||||
|
|
||||||
|
|
||||||
frr_preinit(&zebra_di, argc, argv);
|
frr_preinit(&zebra_di, argc, argv);
|
||||||
|
|
||||||
frr_opt_add("bakF:z:e:l:r"
|
frr_opt_add("bakz:e:l:r"
|
||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
"s:"
|
"s:"
|
||||||
#endif
|
#endif
|
||||||
, longopts,
|
, longopts,
|
||||||
" -b, --batch Runs in batch mode\n"
|
" -b, --batch Runs in batch mode\n"
|
||||||
" -a, --allow_delete Allow other processes to delete zebra routes\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"
|
" -z, --socket Set path of zebra socket\n"
|
||||||
" -e, --ecmp Specify ECMP to use.\n"
|
" -e, --ecmp Specify ECMP to use.\n"
|
||||||
" -l, --label_socket Socket to external label manager\n"\
|
" -l, --label_socket Socket to external label manager\n"\
|
||||||
@ -266,9 +261,6 @@ main (int argc, char **argv)
|
|||||||
case 'k':
|
case 'k':
|
||||||
keep_kernel_mode = 1;
|
keep_kernel_mode = 1;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
|
||||||
fpm_format = optarg;
|
|
||||||
break;
|
|
||||||
case 'e':
|
case 'e':
|
||||||
multipath_num = atoi (optarg);
|
multipath_num = atoi (optarg);
|
||||||
if (multipath_num > MULTIPATH_NUM || multipath_num <= 0)
|
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. */
|
/* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */
|
||||||
zebra_ns_init ();
|
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
|
/* Process the configuration file. Among other configuration
|
||||||
* directives we can meet those installing static routes. Such
|
* directives we can meet those installing static routes. Such
|
||||||
* requests will not be executed immediately, but queued in
|
* requests will not be executed immediately, but queued in
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "zebra/rtadv.h"
|
#include "zebra/rtadv.h"
|
||||||
#include "zebra/irdp.h"
|
#include "zebra/irdp.h"
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
#include "zebra/zebra_fpm.h"
|
|
||||||
|
|
||||||
void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; }
|
void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; }
|
||||||
void irdp_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
|
#ifdef HAVE_NET_RT_IFLIST
|
||||||
void ifstat_update_sysctl (void) { return; }
|
void ifstat_update_sysctl (void) { return; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
|
||||||
zfpm_trigger_update (struct route_node *rn, const char *reason)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define _ZEBRA_RIB_H
|
#define _ZEBRA_RIB_H
|
||||||
|
|
||||||
#include "zebra.h"
|
#include "zebra.h"
|
||||||
|
#include "hook.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
@ -490,4 +491,6 @@ rib_tables_iter_cleanup (rib_tables_iter_t *iter)
|
|||||||
iter->state = RIB_TABLES_ITER_S_DONE;
|
iter->state = RIB_TABLES_ITER_S_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_HOOK(rib_update, (struct route_node *rn, const char *reason), (rn, reason))
|
||||||
|
|
||||||
#endif /*_ZEBRA_RIB_H */
|
#endif /*_ZEBRA_RIB_H */
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.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/stream.h>
|
||||||
#include <sys/tihdr.h>
|
#include <sys/tihdr.h>
|
||||||
|
|
||||||
|
@ -25,10 +25,12 @@
|
|||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "libfrr.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -36,7 +38,6 @@
|
|||||||
#include "zebra/zebra_vrf.h"
|
#include "zebra/zebra_vrf.h"
|
||||||
|
|
||||||
#include "fpm/fpm.h"
|
#include "fpm/fpm.h"
|
||||||
#include "zebra_fpm.h"
|
|
||||||
#include "zebra_fpm_private.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_glob_space;
|
||||||
static zfpm_glob_t *zfpm_g = &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_read_cb (struct thread *thread);
|
||||||
static int zfpm_write_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);
|
zfpm_set_state (ZFPM_STATE_ACTIVE, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (HAVE_FPM)
|
|
||||||
/*
|
/*
|
||||||
* zfpm_is_enabled
|
* zfpm_is_enabled
|
||||||
*
|
*
|
||||||
@ -1307,7 +1309,6 @@ zfpm_is_enabled (void)
|
|||||||
{
|
{
|
||||||
return zfpm_g->enabled;
|
return zfpm_g->enabled;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zfpm_conn_is_up
|
* zfpm_conn_is_up
|
||||||
@ -1331,7 +1332,7 @@ zfpm_conn_is_up (void)
|
|||||||
* The zebra code invokes this function to indicate that we should
|
* The zebra code invokes this function to indicate that we should
|
||||||
* send an update to the FPM about the given route_node.
|
* send an update to the FPM about the given route_node.
|
||||||
*/
|
*/
|
||||||
void
|
static int
|
||||||
zfpm_trigger_update (struct route_node *rn, const char *reason)
|
zfpm_trigger_update (struct route_node *rn, const char *reason)
|
||||||
{
|
{
|
||||||
rib_dest_t *dest;
|
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.
|
* all destinations once the connection comes up.
|
||||||
*/
|
*/
|
||||||
if (!zfpm_conn_is_up ())
|
if (!zfpm_conn_is_up ())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
dest = rib_dest_from_rnode (rn);
|
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)))
|
if (!zfpm_is_table_for_fpm (rib_dest_table (dest)))
|
||||||
{
|
{
|
||||||
zfpm_g->stats.non_fpm_table_triggers++;
|
zfpm_g->stats.non_fpm_table_triggers++;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)) {
|
if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)) {
|
||||||
zfpm_g->stats.redundant_triggers++;
|
zfpm_g->stats.redundant_triggers++;
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reason)
|
if (reason)
|
||||||
@ -1375,9 +1376,10 @@ zfpm_trigger_update (struct route_node *rn, const char *reason)
|
|||||||
* Make sure that writes are enabled.
|
* Make sure that writes are enabled.
|
||||||
*/
|
*/
|
||||||
if (zfpm_g->t_write)
|
if (zfpm_g->t_write)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
zfpm_write_on ();
|
zfpm_write_on ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1411,7 +1413,6 @@ zfpm_stats_timer_cb (struct thread *t)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (HAVE_FPM)
|
|
||||||
/*
|
/*
|
||||||
* zfpm_stop_stats_timer
|
* zfpm_stop_stats_timer
|
||||||
*/
|
*/
|
||||||
@ -1424,7 +1425,6 @@ zfpm_stop_stats_timer (void)
|
|||||||
zfpm_debug ("Stopping existing stats timer");
|
zfpm_debug ("Stopping existing stats timer");
|
||||||
THREAD_TIMER_OFF (zfpm_g->t_stats);
|
THREAD_TIMER_OFF (zfpm_g->t_stats);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zfpm_start_stats_timer
|
* zfpm_start_stats_timer
|
||||||
@ -1447,7 +1447,6 @@ zfpm_start_stats_timer (void)
|
|||||||
zfpm_g->last_ivl_stats.counter, VTY_NEWLINE); \
|
zfpm_g->last_ivl_stats.counter, VTY_NEWLINE); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#if defined (HAVE_FPM)
|
|
||||||
/*
|
/*
|
||||||
* zfpm_show_stats
|
* zfpm_show_stats
|
||||||
*/
|
*/
|
||||||
@ -1600,7 +1599,6 @@ DEFUN ( no_fpm_remote_ip,
|
|||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zfpm_init_message_format
|
* zfpm_init_message_format
|
||||||
@ -1670,7 +1668,7 @@ zfpm_init_message_format (const char *format)
|
|||||||
* Returns ZERO on success.
|
* 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;
|
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
|
* zfpm_init
|
||||||
*
|
*
|
||||||
@ -1695,17 +1702,12 @@ int fpm_remote_srv_write (struct vty *vty )
|
|||||||
*
|
*
|
||||||
* Returns TRUE on success.
|
* Returns TRUE on success.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
zfpm_init (struct thread_master *master, int enable, uint16_t port,
|
zfpm_init (struct thread_master *master)
|
||||||
const char *format)
|
|
||||||
{
|
{
|
||||||
static int initialized = 0;
|
int enable = 1;
|
||||||
|
uint16_t port = 0;
|
||||||
if (initialized) {
|
const char *format = THIS_MODULE->load_args;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialized = 1;
|
|
||||||
|
|
||||||
memset (zfpm_g, 0, sizeof (*zfpm_g));
|
memset (zfpm_g, 0, sizeof (*zfpm_g));
|
||||||
zfpm_g->master = master;
|
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->last_ivl_stats);
|
||||||
zfpm_stats_init (&zfpm_g->cumulative_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, &show_zebra_fpm_stats_cmd);
|
||||||
install_element (ENABLE_NODE, &clear_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, &fpm_remote_ip_cmd);
|
||||||
install_element (CONFIG_NODE, &no_fpm_remote_ip_cmd);
|
install_element (CONFIG_NODE, &no_fpm_remote_ip_cmd);
|
||||||
#endif
|
|
||||||
|
|
||||||
zfpm_init_message_format(format);
|
zfpm_init_message_format(format);
|
||||||
|
|
||||||
@ -1734,10 +1735,6 @@ zfpm_init (struct thread_master *master, int enable, uint16_t port,
|
|||||||
|
|
||||||
zfpm_g->enabled = enable;
|
zfpm_g->enabled = enable;
|
||||||
|
|
||||||
if (!enable) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!zfpm_g->fpm_server)
|
if (!zfpm_g->fpm_server)
|
||||||
zfpm_g->fpm_server = FPM_DEFAULT_IP;
|
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_stats_timer ();
|
||||||
zfpm_start_connect_timer ("initialized");
|
zfpm_start_connect_timer ("initialized");
|
||||||
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
@ -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 */
|
|
@ -53,7 +53,7 @@ create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fpm__delete_route__init(msg);
|
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));
|
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);
|
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));
|
qpb_address_family_set (&msg->address_family, rib_dest_af(dest));
|
||||||
|
|
||||||
|
@ -48,11 +48,12 @@
|
|||||||
#include "zebra/redistribute.h"
|
#include "zebra/redistribute.h"
|
||||||
#include "zebra/zebra_routemap.h"
|
#include "zebra/zebra_routemap.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
#include "zebra/zebra_fpm.h"
|
|
||||||
#include "zebra/zebra_rnh.h"
|
#include "zebra/zebra_rnh.h"
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
#include "zebra/connected.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 */
|
/* Should we allow non Quagga processes to delete our routes */
|
||||||
extern int allow_delete;
|
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
|
* Make sure we update the FPM any time we send new information to
|
||||||
* the kernel.
|
* 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);
|
ret = kernel_route_rib (p, src_p, old, rib);
|
||||||
|
|
||||||
/* If install succeeds, update FIB flag for nexthops. */
|
/* 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
|
* Make sure we update the FPM any time we send new information to
|
||||||
* the kernel.
|
* 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);
|
ret = kernel_route_rib (p, src_p, rib, NULL);
|
||||||
|
|
||||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
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 (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||||
{
|
{
|
||||||
if (info->safi == SAFI_UNICAST)
|
if (info->safi == SAFI_UNICAST)
|
||||||
zfpm_trigger_update (rn, "rib_uninstall");
|
hook_call(rib_update, rn, "rib_uninstall");
|
||||||
|
|
||||||
if (! RIB_SYSTEM_ROUTE (rib))
|
if (! RIB_SYSTEM_ROUTE (rib))
|
||||||
rib_uninstall_kernel (rn, rib);
|
rib_uninstall_kernel (rn, rib);
|
||||||
@ -1253,7 +1254,7 @@ static void
|
|||||||
rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct rib *new)
|
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. */
|
/* Update real nexthop. This may actually determine if nexthop is active or not. */
|
||||||
if (!nexthop_active_update (rn, new, 1))
|
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,
|
rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct rib *old)
|
struct rib *old)
|
||||||
{
|
{
|
||||||
zfpm_trigger_update (rn, "removing existing route");
|
hook_call(rib_update, rn, "removing existing route");
|
||||||
|
|
||||||
/* Uninstall from kernel. */
|
/* Uninstall from kernel. */
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
@ -1326,7 +1327,7 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
if (new != old ||
|
if (new != old ||
|
||||||
CHECK_FLAG (new->status, RIB_ENTRY_CHANGED))
|
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. */
|
/* Update the nexthop; we could determine here that nexthop is inactive. */
|
||||||
if (nexthop_active_update (rn, new, 1))
|
if (nexthop_active_update (rn, new, 1))
|
||||||
@ -2874,7 +2875,7 @@ rib_close_table (struct route_table *table)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info->safi == SAFI_UNICAST)
|
if (info->safi == SAFI_UNICAST)
|
||||||
zfpm_trigger_update (rn, NULL);
|
hook_call(rib_update, rn, NULL);
|
||||||
|
|
||||||
if (! RIB_SYSTEM_ROUTE (rib))
|
if (! RIB_SYSTEM_ROUTE (rib))
|
||||||
rib_uninstall_kernel (rn, rib);
|
rib_uninstall_kernel (rn, rib);
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
|
||||||
#include <net-snmp/net-snmp-config.h>
|
#include <net-snmp/net-snmp-config.h>
|
||||||
#include <net-snmp/net-snmp-includes.h>
|
#include <net-snmp/net-snmp-includes.h>
|
||||||
|
|
||||||
@ -36,6 +35,9 @@
|
|||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
|
#include "hook.h"
|
||||||
|
#include "libfrr.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -571,10 +573,24 @@ ipCidrTable (struct variable *v, oid objid[], size_t *objid_len,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static int
|
||||||
zebra_snmp_init ()
|
zebra_snmp_init (struct thread_master *tm)
|
||||||
{
|
{
|
||||||
smux_init (zebrad.master);
|
smux_init (tm);
|
||||||
REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid);
|
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,
|
||||||
|
)
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
#include "zebra/zebra_ptm.h"
|
#include "zebra/zebra_ptm.h"
|
||||||
#include "zebra/rtadv.h"
|
#include "zebra/rtadv.h"
|
||||||
#include "zebra/zebra_mpls.h"
|
#include "zebra/zebra_mpls.h"
|
||||||
#include "zebra/zebra_fpm.h"
|
|
||||||
#include "zebra/zebra_mroute.h"
|
#include "zebra/zebra_mroute.h"
|
||||||
#include "zebra/label_manager.h"
|
#include "zebra/label_manager.h"
|
||||||
|
|
||||||
@ -2851,25 +2850,6 @@ static struct cmd_node forwarding_node =
|
|||||||
1
|
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. */
|
/* Initialisation of zebra and installation of commands. */
|
||||||
void
|
void
|
||||||
zebra_init (void)
|
zebra_init (void)
|
||||||
@ -2880,9 +2860,6 @@ zebra_init (void)
|
|||||||
/* Install configuration write function. */
|
/* Install configuration write function. */
|
||||||
install_node (&table_node, config_write_table);
|
install_node (&table_node, config_write_table);
|
||||||
install_node (&forwarding_node, config_write_forwarding);
|
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 (VIEW_NODE, &show_ip_forwarding_cmd);
|
||||||
install_element (CONFIG_NODE, &ip_forwarding_cmd);
|
install_element (CONFIG_NODE, &ip_forwarding_cmd);
|
||||||
|
@ -149,7 +149,6 @@ extern void route_read (struct zebra_ns *);
|
|||||||
extern void kernel_init (struct zebra_ns *);
|
extern void kernel_init (struct zebra_ns *);
|
||||||
extern void kernel_terminate (struct zebra_ns *);
|
extern void kernel_terminate (struct zebra_ns *);
|
||||||
extern void zebra_route_map_init (void);
|
extern void zebra_route_map_init (void);
|
||||||
extern void zebra_snmp_init (void);
|
|
||||||
extern void zebra_vty_init (void);
|
extern void zebra_vty_init (void);
|
||||||
|
|
||||||
extern int zsend_vrf_add (struct zserv *, struct zebra_vrf *);
|
extern int zsend_vrf_add (struct zserv *, struct zebra_vrf *);
|
||||||
|
Loading…
Reference in New Issue
Block a user