Skip to content

Commit

Permalink
zebra: add module to communicate routes to FPM
Browse files Browse the repository at this point in the history
Enhance zebra to send routes to the (optional) Forwarding Path Manager
component using the interface defined by fpm/fpm.h.

  * configure.ac

    - Add --enable-fpm flag.

      The FPM-related code in zebra is activated only if the build is
      configured with '--enable-fpm'.

    - Add HAVE_NETLINK automake conditional.

      This allows us to conditionally build netlink-dependent C code.

  * zebra/{rib.h,zebra_rib.c}

    - Add the 'fpm_q_entries' field to the rib_dest_t structure. This
      allows dests to be placed on the fpm queue.

    - Define a couple new rib_dest_t flags that hold FPM-related
      state.

    - Invoke the zfpm_trigger_update() function for a route_node
      whenever the information to be sent to the FPM changes.

    - rib_can_delete_dest(): Return FALSE if we have to update the FPM
      about the given dest. This ensures that the dest is not deleted
      even if there are no ribs hanging off of it.

  * zebra/zebra_fpm.c

    This file holds most of the code for interacting with the FPM.

    - If quagga was configured with '--enable-fpm', periodically try
      to connect to the FPM.

    - When the connection comes up, enqueue all relevent dests to the
      FPM queue.

    - When the FPM socket is readable, dequeue the next rib_dest_t
      from the FPM queue, encode it in to a message and send the
      message to the FPM.

    - When the connection to the FPM goes down, remove all dests from
      the FPM queue, and then start trying to connect to the FPM
      again.

    - Expose the following new operational commands:

      show zebra fpm stats
      clear zebra fpm stats

  * zebra/zebra_fpm_netlink.c

    - zfpm_netlink_encode_route(): Function to encode information
      about a rib_dest_t in netlink format.

  * zebra/zebra_fpm_private.h

    Private header file for the zebra FPM module.

  * zebra/zebra_fpm.h

    Header file exported by zebra FPM module to the rest of zebra.

  * zebra/debug.c

    Add the 'debug zebra fpm' command.

  * zebra/main.c

    Initialize the zebra-FPM code on startup.

  * zebra/misc_null.c

    Add stub for zfpm_trigger_update().

  * zebra/Makefile.am

    - Include new file zebra_fpm.c in build.

    - Include zebra_fpm_netlink.c in build if HAVE_NETLINK is defined.

  * vtysh/Makefile.am

    Include zebra_fpm.c in list of files that define cli commands.

Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
  • Loading branch information
avnshs authored and eqvinox committed Nov 30, 2012
1 parent 443b993 commit 5adc252
Show file tree
Hide file tree
Showing 13 changed files with 2,344 additions and 2 deletions.
7 changes: 7 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ AC_ARG_ENABLE(time-check,
[ --disable-time-check disable slow thread warning messages])
AC_ARG_ENABLE(pcreposix,
[ --enable-pcreposix enable using PCRE Posix libs for regex functions])
AC_ARG_ENABLE(fpm,
[ --enable-fpm enable Forwarding Plane Manager support])

if test x"${enable_gcc_ultra_verbose}" = x"yes" ; then
CFLAGS="${CFLAGS} -W -Wcast-qual -Wstrict-prototypes"
Expand All @@ -292,6 +294,10 @@ if test x"${enable_time_check}" != x"no" ; then
fi
fi

if test "${enable_fpm}" = "yes"; then
AC_DEFINE(HAVE_FPM,,Forwarding Plane Manager support)
fi

if test "${enable_broken_aliases}" = "yes"; then
if test "${enable_netlink}" = "yes"
then
Expand Down Expand Up @@ -828,6 +834,7 @@ fi
AC_SUBST(RT_METHOD)
AC_SUBST(KERNEL_METHOD)
AC_SUBST(OTHER_METHOD)
AM_CONDITIONAL([HAVE_NETLINK], [test "x$netlink" = "xyes"])

dnl --------------------------
dnl Determine IS-IS I/O method
Expand Down
3 changes: 2 additions & 1 deletion vtysh/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \
$(top_srcdir)/zebra/irdp_interface.c \
$(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
$(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \
$(top_srcdir)/zebra/zebra_routemap.c
$(top_srcdir)/zebra/zebra_routemap.c \
$(top_srcdir)/zebra/zebra_fpm.c

vtysh_cmd.c: $(vtysh_cmd_FILES)
./$(EXTRA_DIST) $(vtysh_cmd_FILES) > vtysh_cmd.c
Expand Down
7 changes: 6 additions & 1 deletion zebra/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ ioctl_method = @IOCTL_METHOD@
otherobj = $(ioctl_method) $(ipforward) $(if_method) $(if_proc) \
$(rt_method) $(rtread_method) $(kernel_method) $(other_method)

if HAVE_NETLINK
othersrc = zebra_fpm_netlink.c
endif

AM_CFLAGS = $(PICFLAGS)
AM_LDFLAGS = $(PILDFLAGS)

Expand All @@ -29,7 +33,8 @@ noinst_PROGRAMS = testzebra
zebra_SOURCES = \
zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c
irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
$(othersrc)

testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
zebra_vty.c \
Expand Down
37 changes: 37 additions & 0 deletions zebra/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ unsigned long zebra_debug_event;
unsigned long zebra_debug_packet;
unsigned long zebra_debug_kernel;
unsigned long zebra_debug_rib;
unsigned long zebra_debug_fpm;

DEFUN (show_debugging_zebra,
show_debugging_zebra_cmd,
Expand Down Expand Up @@ -71,6 +72,9 @@ DEFUN (show_debugging_zebra,
if (IS_ZEBRA_DEBUG_RIB_Q)
vty_out (vty, " Zebra RIB queue debugging is on%s", VTY_NEWLINE);

if (IS_ZEBRA_DEBUG_FPM)
vty_out (vty, " Zebra FPM debugging is on%s", VTY_NEWLINE);

return CMD_SUCCESS;
}

Expand Down Expand Up @@ -169,6 +173,17 @@ DEFUN (debug_zebra_rib_q,
return CMD_SUCCESS;
}

DEFUN (debug_zebra_fpm,
debug_zebra_fpm_cmd,
"debug zebra fpm",
DEBUG_STR
"Zebra configuration\n"
"Debug zebra FPM events\n")
{
SET_FLAG (zebra_debug_fpm, ZEBRA_DEBUG_FPM);
return CMD_SUCCESS;
}

DEFUN (no_debug_zebra_events,
no_debug_zebra_events_cmd,
"no debug zebra events",
Expand Down Expand Up @@ -247,6 +262,18 @@ DEFUN (no_debug_zebra_rib_q,
return CMD_SUCCESS;
}

DEFUN (no_debug_zebra_fpm,
no_debug_zebra_fpm_cmd,
"no debug zebra fpm",
NO_STR
DEBUG_STR
"Zebra configuration\n"
"Debug zebra FPM events\n")
{
zebra_debug_fpm = 0;
return CMD_SUCCESS;
}

/* Debug node. */
struct cmd_node debug_node =
{
Expand Down Expand Up @@ -302,6 +329,11 @@ config_write_debug (struct vty *vty)
vty_out (vty, "debug zebra rib queue%s", VTY_NEWLINE);
write++;
}
if (IS_ZEBRA_DEBUG_FPM)
{
vty_out (vty, "debug zebra fpm%s", VTY_NEWLINE);
write++;
}
return write;
}

Expand All @@ -312,6 +344,7 @@ zebra_debug_init (void)
zebra_debug_packet = 0;
zebra_debug_kernel = 0;
zebra_debug_rib = 0;
zebra_debug_fpm = 0;

install_node (&debug_node, config_write_debug);

Expand All @@ -325,11 +358,13 @@ zebra_debug_init (void)
install_element (ENABLE_NODE, &debug_zebra_kernel_cmd);
install_element (ENABLE_NODE, &debug_zebra_rib_cmd);
install_element (ENABLE_NODE, &debug_zebra_rib_q_cmd);
install_element (ENABLE_NODE, &debug_zebra_fpm_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_events_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_packet_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_kernel_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_rib_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_rib_q_cmd);
install_element (ENABLE_NODE, &no_debug_zebra_fpm_cmd);

install_element (CONFIG_NODE, &debug_zebra_events_cmd);
install_element (CONFIG_NODE, &debug_zebra_packet_cmd);
Expand All @@ -338,9 +373,11 @@ zebra_debug_init (void)
install_element (CONFIG_NODE, &debug_zebra_kernel_cmd);
install_element (CONFIG_NODE, &debug_zebra_rib_cmd);
install_element (CONFIG_NODE, &debug_zebra_rib_q_cmd);
install_element (CONFIG_NODE, &debug_zebra_fpm_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_events_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_packet_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_kernel_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_rib_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_rib_q_cmd);
install_element (CONFIG_NODE, &no_debug_zebra_fpm_cmd);
}
5 changes: 5 additions & 0 deletions zebra/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#define ZEBRA_DEBUG_RIB 0x01
#define ZEBRA_DEBUG_RIB_Q 0x02

#define ZEBRA_DEBUG_FPM 0x01

/* Debug related macro. */
#define IS_ZEBRA_DEBUG_EVENT (zebra_debug_event & ZEBRA_DEBUG_EVENT)

Expand All @@ -49,10 +51,13 @@
#define IS_ZEBRA_DEBUG_RIB (zebra_debug_rib & ZEBRA_DEBUG_RIB)
#define IS_ZEBRA_DEBUG_RIB_Q (zebra_debug_rib & ZEBRA_DEBUG_RIB_Q)

#define IS_ZEBRA_DEBUG_FPM (zebra_debug_fpm & ZEBRA_DEBUG_FPM)

extern unsigned long zebra_debug_event;
extern unsigned long zebra_debug_packet;
extern unsigned long zebra_debug_kernel;
extern unsigned long zebra_debug_rib;
extern unsigned long zebra_debug_fpm;

extern void zebra_debug_init (void);

Expand Down
7 changes: 7 additions & 0 deletions zebra/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "zebra/router-id.h"
#include "zebra/irdp.h"
#include "zebra/rtadv.h"
#include "zebra/zebra_fpm.h"

/* Zebra instance */
struct zebra_t zebrad =
Expand Down Expand Up @@ -349,6 +350,12 @@ main (int argc, char **argv)
zebra_snmp_init ();
#endif /* HAVE_SNMP */

#ifdef HAVE_FPM
zfpm_init (zebrad.master, 1, 0);
#else
zfpm_init (zebrad.master, 0, 0);
#endif

/* Process the configuration file. Among other configuration
* directives we can meet those installing static routes. Such
* requests will not be executed immediately, but queued in
Expand Down
7 changes: 7 additions & 0 deletions zebra/misc_null.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
#include "zebra/rtadv.h"
#include "zebra/irdp.h"
#include "zebra/interface.h"
#include "zebra/zebra_fpm.h"

void ifstat_update_proc (void) { return; }
#pragma weak rtadv_config_write = ifstat_update_proc
#pragma weak irdp_config_write = ifstat_update_proc
#pragma weak ifstat_update_sysctl = ifstat_update_proc

void
zfpm_trigger_update (struct route_node *rn, const char *reason)
{
return;
}
18 changes: 18 additions & 0 deletions zebra/rib.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "prefix.h"
#include "table.h"
#include "queue.h"

#define DISTANCE_INFINITY 255

Expand Down Expand Up @@ -116,6 +117,11 @@ typedef struct rib_dest_t_
*/
u_int32_t flags;

/*
* Linkage to put dest on the FPM processing queue.
*/
TAILQ_ENTRY(rib_dest_t_) fpm_q_entries;

} rib_dest_t;

#define RIB_ROUTE_QUEUED(x) (1 << (x))
Expand All @@ -125,6 +131,18 @@ typedef struct rib_dest_t_
*/
#define ZEBRA_MAX_QINDEX (MQ_SIZE - 1)

/*
* This flag indicates that a given prefix has been 'advertised' to
* the FPM to be installed in the forwarding plane.
*/
#define RIB_DEST_SENT_TO_FPM (1 << (ZEBRA_MAX_QINDEX + 1))

/*
* This flag is set when we need to send an update to the FPM about a
* dest.
*/
#define RIB_DEST_UPDATE_FPM (1 << (ZEBRA_MAX_QINDEX + 2))

/*
* Macro to iterate over each route for a destination (prefix).
*/
Expand Down
Loading

0 comments on commit 5adc252

Please sign in to comment.