%
% $XORP: xorp/docs/xorpdev_101/xorpdev_101.tex,v 1.29 2008/12/24 22:33:31 jtc Exp $
%

\documentclass[11pt]{article}

%\usepackage[dvips]{changebar}

\usepackage{subfigure}
\usepackage{fullpage}
\usepackage{setspace}
\usepackage{times}
\usepackage{latexsym}
\usepackage{epsfig}
\usepackage{graphicx}
\usepackage{xspace}
\usepackage{color}
\usepackage{amsmath}
\usepackage{rotating}
\usepackage{moreverb}
\usepackage{listings}
\usepackage{alltt}
\usepackage{stmaryrd}
%\usepackage[dvipdf]{graphics}
%\usepackage[dvips]{graphicx}
%\usepackage{xorp}

\definecolor{gray}{rgb}{0.5,0.5,0.5}
\newcommand{\etc}{\emph{etc.}\xspace}
\newcommand{\ie}{\emph{i.e.,}\xspace}
\newcommand{\eg}{\emph{e.g.,}\xspace}
%\newcommand{\comment}[1]{{\color{gray}[\textsf{#1}]}}
%\newcommand{\comment}[1]{}

% Changebar stuff
% \newenvironment{colorcode}{\color{blue}}{}
% \renewcommand{\cbstart}{\begin{colorcode}}
% \renewcommand{\cbend}{\end{colorcode}}

% \pagestyle{empty}

\begin{document}

\title{An Introduction to Writing a XORP Process \\
\vspace{1ex}
Version 1.6-RC}
\author{ XORP, Inc.					\\
         {\it http://www.xorp.org/}			\\
	 {\it feedback@xorp.org}
}
\date{December 24, 2008}

\maketitle


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Local definitions
%
\newcommand{\stt}{\tt\small}
\newcommand{\SR}{{\tt\small static\_routes}\xspace}
\newcommand{\SRI}{{\it static\_routes}\xspace}

% Configure listings
\lstloadlanguages{C++,C}
\lstset{
    tabsize=8
  , basicstyle=\ttfamily\small
  , commentstyle=\color{gray}
  , flexiblecolumns=false
  , frame=TBLR
  , language=C++
  , stringstyle=\ttfamily
  , showstringspaces=false
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tableofcontents

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}

This document is intented for a developer who wishes to write a XORP
process, but doesn't know where to start.  We'll walk through a simple
XORP process, discussing how to define and use XRL interfaces, and how
the bits fit together.  

This is a first pass at such a document.  We're bound to have missed
things that are not obvious when you're starting out.  Please provide
us feedback as to how much help this document is; what really helped,
what's missing, and what isn't explained properly.

We'll assume that you have copies of four other XORP design documents:

\begin{itemize}
  \item XORP Design Overview\cite{xorp:design_arch}
  \item XORP Libxorp Library Overview\cite{xorp:libxorp}
  \item XORP Inter-Process Communication Library Overview\cite{xorp:xrl}
  \item XRL Interfaces: Specifications and Tools\cite{xorp:xrl_interfaces}
\end{itemize}

These are available from the XORP web server.  You should probably
have read these through quickly so you're aware what additional
information is available before reading this document further.  It's
recommended to read them in the order above.  

We will assume you are familiar with what an XRL request is, the
overall structure of the processes on a XORP router, and with C++.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Overview}

In this document we'll work through by example the structure of a
simple XORP process.  We've chosen the {\it static\_routes} process as
an example.  At the time of writing, this document is in sync with the
source code for static\_routes, but this is not guaranteed to always be
the case.

{\it static\_routes} is a very simple XORP process.  To a first
approximation, it receives XRL configuration requests from the
{\it xorp\_rtrmgr} to set up static routing entries, stores the entries, and
communicates them to the RIB using XRLs.  

This makes it a good example, because it exports an XRL interface to
other processes (typically the xorp\_rtrmgr) and calls XRLs on the XRL
interface of another XORP process (the RIB).  But it doesn't do all
that much else, so there are few files and the code is quite readable.

The source code for the \SRI process is found in the {\stt
xorp/static\_routes} subdirectory of the XORP source tree.

We'll walk through the main pieces of static\_routes in the following
order:

\begin{itemize}
  \item The XRL interface of static\_routes.
  \item Implementing the XRL interface of static\_routes.
  \item The main loop of static routes.
  \item Calling XRLs on the RIB.
  \item Compiling the source code
\end{itemize}


\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{The XRL Interface of {\it static\_routes}}

XRL interfaces are defined by a {\stt.xif} file (pronounced {\it dot-ziff}).
{\stt xif} stands for XRL InterFace.  All {\stt.xif} files reside in
{\stt xorp/xrl/interfaces}.

The relevant file for us is {\stt
xorp/xrl/interfaces/static\_routes.xif}. The first part of this file is
shown in Listing \ref{lst:xif}.

\begin{lstlisting}[caption={ The start of {\stt xorp/xrl/interfaces/static\_routes.xif} %
                                     \label{lst:xif} } ]{}
/*
 * Static Routes XRL interface.
 */

interface static_routes/0.1 {

	/**
	 * Enable/disable/start/stop StaticRoutes.
	 *
	 * @param enable if true, then enable StaticRoutes, otherwise
	 * disable it.
	 */
	enable_static_routes	? enable:bool
	start_static_routes
	stop_static_routes

	/**
	 * Add/replace/delete a static route.
	 *
	 * @param unicast if true, then the route would be used for unicast
	 * routing.
	 * @param multicast if true, then the route would be used in the
	 * MRIB (Multicast Routing Information Base) for multicast purpose
	 * (e.g., computing the Reverse-Path Forwarding information).
	 * @param network the network address prefix this route applies to.
	 * @param nexthop the address of the next-hop router for this route.
	 * @param metric the metric distance for this route.
	 */
	add_route4	? unicast:bool & multicast:bool & network:ipv4net \
			& nexthop:ipv4 & metric:u32

	add_route6	? unicast:bool & multicast:bool & network:ipv6net \
			& nexthop:ipv6 & metric:u32

...
}
\end{lstlisting}

The file {\stt static\_routes.xif} defines all the XRLs that are part of the
{\stt static\_routes} XRL interface.  These are XRLs that other processes can
call on the {\it static\_routes} process.

The format of the file is basically the keyword {\stt interface}
followed by the name and version of this particular interface,
followed by a list of XRLs.  
In this case the name of the interface is {\stt static\_routes}, but
this does not have to be the same as the name of the process.  The
version number is {\stt 0.1}.  Version numbers are generally increased
when a change is made that is not backwards compatible, but the
precise value has no important meaning.

The list of XRLs is demarked by braces {\stt \{ ... \}}, and one XRL is
given per line.  Blank lines and comments are allowed, and a backslash
before the newline can be used to split a long XRL over multiple lines
to aid readability.

\vspace{0.1in}
\noindent
Thus the first XRL in this file is:\\
 {\tt\small static\_routes/0.1/enable\_static\_routes?enable:bool}

\vspace{0.1in}
\noindent
When this XRL is actually called, it would look like:\\
{\tt\small
  finder://static\_routes/static\_routes/0.1/enable\_static\_routes?enable:bool=true}

\vspace{0.1in} The {\stt finder} part indicates that the XRL is an
abstract one - we don't yet know what the transport parameters are.
The first \SR indicates the name of the target process, and the second
\SR is the name of the interface, taken from the XIF
file.  A process can support more than one interface, and an interface
definition can be used by more than one process, hence the duplication
in a process as simple as \SRI.

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Using the {\tt static\_routes} XRL Interface}

Now we have seen how the XRLs comprising the static\_routes interface
are defined, we shall examine how processes actually use them.  For
any particular interface, there are two types of user:

\begin{itemize}

  \item The process that calls the XRLs and gets back responses.  This
  is called the XRL {\it caller}.

  \item The process on which the XRL is called, and which generates
  responses.  This is called the XRL {\it target}.

\end{itemize}

XORP provides scripts which can generate C++ code to make life much
easier for both these parties.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Generating stub code for the caller}

If we examine the file {\stt Makefile.am} (the automake Makefile) in
{\stt xorp/xrl/interfaces}, we find the fragment in Listing
\ref{lst:iftemp}.
\begin{lstlisting}[caption={ Fragment from {\stt xorp/xrl/interfaces/Makefile.am} %
                                     \label{lst:iftemp} } ]{}
###############################################################################
# Client Interface related
###############################################################################

# BGP MIB traps
noinst_LTLIBRARIES = libbgpmibtrapsxif.la
libbgpmibtrapsxif_la_SOURCES = bgp_mib_traps_xif.hh bgp_mib_traps_xif.cc

...

# StaticRoutes Interface
noinst_LTLIBRARIES += libstaticroutesxif.la
libstaticroutesxif_la_SOURCES = static_routes_xif.hh static_routes_xif.cc

...

###############################################################################
# Static Pattern Rules
###############################################################################

SCRIPT_DIR=$(top_srcdir)/xrl/scripts
CLNTGEN_PY=$(SCRIPT_DIR)/clnt-gen

@PYTHON_BUILD@%_xif.cc %_xif.hh $(srcdir)/%_xif.hh $(srcdir)/%_xif.cc: \
         $(srcdir)/%.xif $(CLNTGEN_PY)
@PYTHON_BUILD@	$(PYTHON) $(CLNTGEN_PY) $<

\end{lstlisting}%$

This adds {\stt libstaticroutesxif.la} to the list of libraries that
should be built, and indicates that the source files for this library
are {\stt static\_routes\_xif.hh} and {\stt static\_routes\_xif.cc}

The last part is pretty cryptic, but basically is a generic rule that
says that files ending with {\stt \_xif.cc} and {\stt \_xif.hh} will be
generated from files ending with {\stt .xif} using the python script
called {\stt clnt-gen}.

So what actually happens here is that the file {\stt static\_routes.xif}
is processed by {\stt clnt-gen} to produce {\stt static\_routes\_xif.hh}
and {\stt static\_routes\_xif.cc}, which are then compiled and linked
into the library {\stt libstaticroutesxif.la}.  Any process that wants
to call the \SRI interface can link with this library.

So what functionality does this library provide?  Listing
\ref{lst:sr.xif.hh} shows a fragment from the machine-generated file
{\stt static\_routes\_xif.hh}.  Between them, {\stt static\_routes\_xif.hh} and {\stt
static\_routes\_xif.cc} define the machine-generated class {\stt
XrlStaticRoutesV0p1Client} and its complete implementation.



\begin{lstlisting}[caption={ Fragment from {\stt xorp/xrl/interfaces/static\_routes\_xif.hh} %
                                     \label{lst:sr.xif.hh} } ]{}
class XrlStaticRoutesV0p1Client {
public:
    XrlStaticRoutesV0p1Client(XrlSender* s) : _sender(s) {}
    virtual ~XrlStaticRoutesV0p1Client() {}

...

    typedef XorpCallback1<void, const XrlError&>::RefPtr AddRoute4CB;
    /**
     *  Send Xrl intended to:
     *
     *  Add/replace/delete a static route.
     *
     *  @param dst_xrl_target_name the Xrl target name of the destination.
     *
     *  @param unicast if true, then the route would be used for unicast
     *  routing.
     *
     *  @param multicast if true, then the route would be used in the MRIB
     *  (Multicast Routing Information Base) for multicast purpose (e.g.,
     *  computing the Reverse-Path Forwarding information).
     *
     *  @param network the network address prefix this route applies to.
     *
     *  @param nexthop the address of the next-hop router for this route.
     *
     *  @param metric the metric distance for this route.
     */
    bool send_add_route4(
	const char*	dst_xrl_target_name,
	const bool&	unicast,
	const bool&	multicast,
	const IPv4Net&	network,
	const IPv4&	nexthop,
	const uint32_t&	metric,
	const AddRoute4CB&	cb
    );

...

}
\end{lstlisting}

\newpage

The constructor for {\stt XrlStaticRoutesV0p1Client} takes a pointer to
an {\stt XrlSender} as its parameter.  Typically this is actually an
{\stt XrlRouter} - we'll come to this in more detail later.

Then for every XRL defined in {\stt static\_routes.xif} there is a
method to be called on an instance of {\stt XrlStaticRoutesV0p1Client}.
The example we'll look at here is {\stt send\_add\_route4()}, although
there are many more methods defined in {\stt static\_routes.xif}.

If you compare the method {\stt send\_add\_route4()} in Listing
\ref{lst:sr.xif.hh} with the XRL {\stt add\_route4} in Listing
\ref{lst:xif}, it should be pretty clear where this comes from.
Basically, when you call \\
{\stt XrlStaticRoutesV0p1Client::send\_add\_route4} with all the
parameters ({\stt unicast}, {\stt nexthop}, etc).  set appropriately,
the XRL {\stt add\_route4} will be called.  You don't need to concern
yourself with how the parameters are marshalled into the right syntax
for the XRL, or how the XRL is actually transmitted, or even how the
target process is discovered.  But you do need to set the {\stt
target\_name} parameter to the same thing that the \SR process sets it
to, otherwise the XRL {\it finder} won't be able to route your XRL to
its destination.  Often the target name will be the same as the name
of the process - in this case \SRI - but if there are multiple
instances of the interface then you'll need to figure out which target
name to use.

You'll also notice that some of the parameters for XRL functions are
not native C++ types.  In this case, {\stt network} is of type {\stt
IPv4Net} and {\stt nexthop} is of type {\stt IPv4}.  Classes
instantiating the these additional types are found in {\stt libxorp}
and are used throughout XORP.  

The final parameter is {\stt const AddRoute4CB\& cb}.\\
Earlier in the
Listing we can see that this is defined as:\\
{\stt typedef XorpCallback1<void, const XrlError\&>::RefPtr
  AddRoute4CB;}\\
This defines {\stt AddRoute4CB} to be a {\it callback} which returns type
{\stt void} with one parameter of type {\stt const XrlError\&}.

But what exactly is a {\stt callback}?

Well, what we want is to call the {\stt send\_add\_route4()} method to
send an XRL request to the \SRI process, and then to go off and do
other things while we're waiting for the response to come back.  In a
multi-threaded architecture, this might be achieved by having {\stt
send\_add\_route4()} block until the response is ready, but XORP is
deliberately {\it not} a multi-threaded architecture. Thus what
happens is that {\stt send\_add\_route4()} will return immediately.
It will return false if a local error occurs, but will normally return
true before the XRL has actually been sent.  Some time later the
response will come back from the \SRI process, and we need a way to
direct the response to the right class instance that is expecting it.
This is achieved in XORP through the use of {\it callbacks}.

A callback is created using the {\stt callback()} function from
libxorp.  We'll discuss this in more detail when we look at how the
\SRI process sends changes to the RIB in Section \ref{rib}.  For now,
it suffices to say that a callback must be created and passed into
{\stt send\_add\_route4()}, and that this is how the response from the
{\stt add\_route4()} XRL is returned to the right place.

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Generating stub code for the target}

The other side to the XRL story is how the XRL target implements the
XRLs.  To illustrate this, we will look at how the \SRI process
implements the XRL interface defined in {\stt static\_routes.xif}.
A XORP process can implement more than one interface.  In fact most
XORP processes implement a special-purpose interface and also the
{\stt common} interface, which provides XRLs to query basic version
and status information about a target process.

\vspace{0.1in}
To see what interfaces a particular target process supports we must
look in the {\stt xorp/xrl/targets} directory.  Listing
\ref{lst:sr.tgt} shows the entire contents of {\stt
static\_routes.tgt}.
This file defines that the XRL target called \SR implements the two
interfaces {\stt common/0.1} and {\stt static\_routes/0.1}.

In the \SRI process, we'd prefer not to have to write all the code to
unmarshall XRLs into C++, and marshall the response back into an XRL
response, so again we use machine-generated C++ stubs to free the
programmer from having to do most of the tedious work.  Listing
\ref{lst:tgt.makefile} shows a number of fragments from {\stt
xorp/xrl/targets/Makefile.am} related to the {\stt static\_routes}
target.


In Listing \ref{lst:tgt.makefile}, the first important point is that
{\stt static\_routes.tgt} is added to the list of {\stt tgt\_files}.
From each {\stt .tgt} file, a {\stt .xrls} file will be generated
using the python script {\stt tgt-gen} according to the magic at the
bottom of the listing.

In the case of {\stt static\_routes.tgt}, the file {\stt
static\_routes.xrls} will be generated.  This file simply contains a
listing of all the fully expanded XRLs supported by the \SR XRL
target.

The next important point to note from Listing \ref{lst:tgt.makefile}
is that we have specified that we want to build a library called {\stt
libstaticroutesbase.la}.  This is going to be the library that the \SRI
process links with to get access to all the stub code to implement
the target part of this interface.

Finally there's the directive to build {\stt libstaticroutesbase.la}
from the machine-generated source files {\stt static\_routes\_base.hh}
and {\stt static\_routes\_base.cc}, and that these files depend on the
files {\stt common.xif} and {\stt static\_routes.xif}.

\vspace{0.1in}
So, what does {\stt libstaticroutesbase.la} actually provide?  Listing
\ref{lst:sr.base} shows some extracts from {\stt
static\_routes\_base.hh}.
Basically {\stt libstaticroutesbase.la} defines a class called \\
{\stt
XrlStaticRoutesTargetBase} which will be used to receive XRL requests.

The constructor for {\stt XrlStaticRoutesTargetBase} takes a single
parameter which is typically the {\stt XrlRouter} for the process.  An
{\stt XrlRouter} is an object that is bound to an {\it EventLoop} and
which sends and receives XRL requests.  Each process has its own {\it
EventLoop}.  In Section \ref{main} we'll look at what the EventLoop
does.  In any event, once an instance of {\stt
XrlStaticRoutesTargetBase} has been created with a pointer to a
working {\stt XrlRouter}, then the process is ready to receive XRL
requests for the \SR interface.  But first we have to actually write
some code.

If we look in at Listing \ref{lst:sr.base}, we see that the method
{\stt static\_routes\_0\_1\_add\_route4()} has been defined.  However the
method is a {\it pure virtual}, which means that it is defined here,
but there is no implementation of this in {\stt
XrlStaticRoutesTargetBase}.  So how do we actually make use of this?

The general idea is that the stub generation code knows the syntax for
this target interface, so it generates all the code needed to check
that incoming requests match the defined syntax and handle errors if
they don't.  But the stub generation code has no idea what this
interface actually {\it does}.  We need to supply an implemenation for {\stt
static\_routes\_0\_1\_add\_route4()} that actually does what we want when
this XRL is called.

\newpage

\begin{lstlisting}[caption={Contents of {\stt
	xorp/xrl/targets/static\_routes.tgt} %
                                     \label{lst:sr.tgt} } ]{}
#include "common.xif"
#include "finder_event_observer.xif"
#include "policy_backend.xif"
#include "static_routes.xif"

target static_routes implements	common/0.1,				\
				finder_event_observer/0.1,		\
				policy_backend/0.1,			\
				static_routes/0.1
\end{lstlisting}

\begin{lstlisting}[caption={Extracts from {\stt xorp/xrl/targets/Makefile.am} %
                                     \label{lst:tgt.makefile} } ]{}
###############################################################################
# Xrl Target related
###############################################################################

# Add your target file here
tgt_files                = bgp.tgt
...
tgt_files               += static_routes.tgt

...

# Automatically compute the list of the *.xrls files
xrls_files               = $(tgt_files:%.tgt=%.xrls)

...

# Add your target's library here
noinst_LTLIBRARIES	 = libbgpbase.la
noinst_LIBRARIES         = libbgpbase.a
...
noinst_LTLIBRARIES	+= libstaticroutesbase.la

...

# StaticRoutes
libstaticroutesbase_la_SOURCES = static_routes_base.hh static_routes_base.cc
$(srcdir)/static_routes_base.hh $(srcdir)/static_routes_base.cc:	\
		$(INTERFACES_DIR)/common.xif 				\
		$(INTERFACES_DIR)/finder_event_observer.xif		\
		$(INTERFACES_DIR)/policy_backend.xif			\
		$(INTERFACES_DIR)/static_routes.xif

...

###############################################################################
# Implicit Rules and related
###############################################################################

SCRIPT_DIR=$(top_srcdir)/xrl/scripts
TGTGEN_PY=$(SCRIPT_DIR)/tgt-gen

# If this code is commented out, please upgrade to python2.0 or above.

@PYTHON_BUILD@$(srcdir)/%_base.hh $(srcdir)/%_base.cc %_base.hh %_base.cc   \
@PYTHON_BUILD@$(srcdir)/%.xrls: $(srcdir)/%.tgt $(TGTGEN_PY)
@PYTHON_BUILD@      $(PYTHON) $(TGTGEN_PY) -I$(INTERFACES_DIR) $<
\end{lstlisting}

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/xrl/targets/static\_routes\_base.hh}%
                                     \label{lst:sr.base} } ]{}
class XrlStaticRoutesTargetBase {

...

public:
    /**
     * Constructor.
     *
     * @param cmds an XrlCmdMap that the commands associated with the target
     *             should be added to.  This is typically the XrlRouter
     *             associated with the target.
     */
    XrlStaticRoutesTargetBase(XrlCmdMap* cmds = 0);

...

protected:

    /**
     *  Pure-virtual function that needs to be implemented to:
     *
     *  Add/replace/delete a static route.
     *
     *  @param unicast if true, then the route would be used for unicast
     *  routing.
     *
     *  @param multicast if true, then the route would be used in the MRIB
     *  (Multicast Routing Information Base) for multicast purpose (e.g.,
     *  computing the Reverse-Path Forwarding information).
     *
     *  @param network the network address prefix this route applies to.
     *
     *  @param nexthop the address of the next-hop router for this route.
     *
     *  @param metric the metric distance for this route.
     */
    virtual XrlCmdError static_routes_0_1_add_route4(
        // Input values,
        const bool&     unicast,
        const bool&     multicast,
        const IPv4Net&  network,
        const IPv4&     nexthop,
        const uint32_t& metric) = 0;

...

}
\end{lstlisting}

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/static\_routes/xrl\_static\_routes\_node.hh} %
                                     \label{lst:srn.hh} } ]{}
class XrlStaticRoutesNode : public StaticRoutesNode,
			    public XrlStdRouter,
			    public XrlStaticRoutesTargetBase {
public:
    XrlStaticRoutesNode(EventLoop&	eventloop,
			const string&	class_name,
			const string&	finder_hostname,
			uint16_t	finder_port,
			const string&	finder_target,
			const string&	fea_target,
			const string&	rib_target);

...

protected:
    //
    // XRL target methods
    //

...

    XrlCmdError static_routes_0_1_add_route4(
        // Input values,
        const bool&     unicast,
        const bool&     multicast,
        const IPv4Net&  network,
        const IPv4&     nexthop,
        const uint32_t& metric);

...

private:
...
    XrlRibV0p1Client    _xrl_rib_client;
...
}
\end{lstlisting}

So now we come at last to the implementation of the \SRI process.
This is in the \\
{\stt xorp/static\_routes} directory.  

We have created a file called {\stt xrl\_static\_routes\_node.hh} to
define our class that actually implements the code to receive and
process XRLs.  An extract from this is shown in Listing
\ref{lst:srn.hh}.  We have defined our own class called {\stt
XrlStaticRoutesNode} which is a child class of {\stt
StaticRoutesNode}, {\stt XrlStdRouter} and {\stt XrlStaticRoutesTargetBase}
classes.  We'll
ignore the {\stt StaticRoutesNode} class in this explanation, because
it's specific to the \SRI process, but the important thing is that
{\stt XrlStaticRoutesNode} is a child of the {\stt
XrlStaticRoutesTargetBase} base class that was generated by the stub
compiler, and a child of the {\stt XrlStdRouter} base class.

The constructor for our {\stt XrlStaticRoutesNode} class takes a
number of parameters which are specific to this particular
implementation, but it also takes a number of parameters that are used
in the constructor of the {\stt XrlStdRouter} base class.

We also see from Listing \ref{lst:srn.hh} that our {\stt
XrlStaticRoutesNode} class is going to implement the \\ {\stt
static\_routes\_0\_1\_add\_route4()} method from the stub compiler
which was a pure virtual method in the base class.

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/static\_routes/xrl\_static\_routes\_node.cc} %
                                     \label{lst:srn.cc} } ]{}
...
#include "static_routes_node.hh"
#include "xrl_static_routes_node.hh"

...

XrlStaticRoutesNode::XrlStaticRoutesNode(EventLoop&	eventloop,
					 const string&	class_name,
					 const string&	finder_hostname,
					 uint16_t	finder_port,
					 const string&	finder_target,
					 const string&	fea_target,
					 const string&	rib_target)
    : StaticRoutesNode(eventloop),
      XrlStdRouter(eventloop, class_name.c_str(), finder_hostname.c_str(),
		   finder_port),
      XrlStaticRoutesTargetBase(&xrl_router()),
      ...
     _xrl_rib_client(&xrl_router()),
      ...
{
  ...
}

...

XrlCmdError
XrlStaticRoutesNode::static_routes_0_1_add_route4(
    // Input values,
    const bool&         unicast,
    const bool&         multicast,
    const IPv4Net&      network,
    const IPv4&         nexthop,
    const uint32_t&     metric)
{
    string error_msg;

    if (StaticRoutesNode::add_route4(unicast, multicast, network, nexthop,
                                     "", "", metric, error_msg)
        != XORP_OK) {
        return XrlCmdError::COMMAND_FAILED(error_msg);
    }

    return XrlCmdError::OKAY();
}
\end{lstlisting}

In Listing \ref{lst:srn.cc}, we see an extract from {\stt
xorp/static\_routes/xrl\_static\_routes\_node.cc} where we have
actually implemented the {\stt XrlStaticRoutesNode} class.  

The constructor for {\stt XrlStaticRoutesNode} passes
a number of arguments to the {\stt XrlStdRouter} base class,
and then passes to the constructor for the {\stt
XrlStaticRoutesTargetBase} base class a pointer to this {\stt XrlStdRouter}
base class (the return result for method {\stt xrl\_router()}).
In addition, it initializes a lot of its own state (not shown).
Note that if we were implementing a module that does not receive any XRLs (\ie
it won't use the equivalent of {\stt XrlStaticRoutesTargetBase}), then
we must call {\stt XrlStdRouter::finalize()} after {\stt XrlStdRouter}
has been created.

The complete implementation of {\stt
XrlStaticRoutesNode::static\_routes\_0\_1\_add\_route4()} is shown.  In
this case, most of the actual work is done elsewhere, but the general
idea is clear.  This is where we actually receive and process the
incoming XRL request.  

Once we have processed the request, we need to return from this
method.  If this XRL had actually taken any return values, there would
have been parameters to the {\stt static\_routes\_0\_1\_add\_route4}
method that were not {\stt const} references, and we would simply have
set the values of these variables before calling {\stt return} to pass
the values back to the XRL caller.  In the case of \SRI however, none
of the XRLs return any values other than success or failure.  We
return {\stt XrlCmdError::OKAY()} if all is well, or {\stt
XrlCmdError::COMMAND\_FAILED(error\_msg)} if something went seriously
wrong, passing back a human-readable string for diagnostic purposes.

In general, if an error response needs to return machine-readable
error information, it is often better to return {\stt
XrlCmdError::OKAY()} together with return parameters to indicate that
an error occurred and what actually happened, because if {\stt
COMMAND\_FAILED} is returned, the return parameter values are not
passed up to the caller application.

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{The Main Loop}
\label{main}

So far we've looked at how to define an XRL interface, how to compile
the C++ stubs for that interface, and how to define the actual
code that implements that interface.  Now we need to look at the main
loop of a XORP process to see how these pieces all come together.

In Listing \ref{lst:srn.main} the main pieces of {\stt
xorp/static\_routes/xorp\_static\_routes.cc} are shown.  These
comprise the entire initialization part and main loop of our \SRI
process.

First come the \#includes. Convention indicates that the first
of these ({\stt static\_routes\_module.h}) is a header file defining the
module name and version - this
information is used by later includes which will complain if this
information is not available. The content of {\stt static\_routes\_module.h}
is very simple. It must define \verb=XORP_MODULE_NAME= and
\verb=XORP_MODULE_VERSION=:

\begin{lstlisting}[caption={Listing of {\stt xorp/static\_routes/static\_routes\_module.h} %
                                     \label{lst:srn.module} } ]{}
#ifndef XORP_MODULE_NAME
#define XORP_MODULE_NAME	"STATIC_ROUTES"
#endif
#ifndef XORP_MODULE_VERSION
#define XORP_MODULE_VERSION	"0.1"
#endif
\end{lstlisting}


Then we include the functionality from
{\stt libxorp} that we'll need:

\begin{itemize}

  \item {\stt libxorp/xorp.h}: generic headers that should always be included.
  \item {\stt libxorp/xlog.h}: XORP logging functionality.  The convention is
  to use XLOG macros to log warnings and error messages, so we can
  redefine how logging if implemented in future without re-writing
  the code that uses logging. See Section~\ref{xlog} for more information
  about the XLOG facility.

  \item {\stt libxorp/debug.h}: XORP debugging functionality.

  \item {\stt libxorp/callback.hh}: XORP callback templates, needed to pass a
  handle into event handling code to be called later when an event
  occurs.

  \item {\stt libxorp/eventloop.hh}: the main XORP eventloop.

  \item {\stt libxorp/exceptions.hh}: standard exceptions for standard stuff -
  useful as a debugging aid.

\end{itemize}

Finally we include the definition of the class that implements the \SR
XRL interface target class we just defined.

In the processes {\stt main()} function, we intialize the {\stt xlog}
logging functionality.  Then (not shown) we handle command line
arguments.  

The main part of this process occurs within a single {\stt try/catch}
statement.  The {\stt catch} part then handles any of the xorp standard
exceptions that might be thrown.  It is not intended that any
unhandled exceptions actually get this far, but if they do, then {\stt
xorp\_catch\_standard\_exceptions()} will ensure that appropriate
diagnostic information is available when the process expires.  This is
not required, but it is good coding practice.

The actual main loop that does all the work is in {\stt
static\_routes\_main()}.

First, the {\tt EventLoop} is created.  Every XORP process should have
precisely one {\tt EventLoop}.  All processing in a XORP process is
event-driven from the eventloop.  When the process is idle, it will be
blocked in {\stt EventLoop::run()}.  When an XRL request arrives, or
an XRL response arrives, or a timer expires, or activity occurs on a
registered file handle, then an event handler will be called from the
eventloop.

Next we create an {\stt XrlStdRouter}.  This is the object that will
be used to send and receive XRLs from this process.  We pass it the
{\stt EventLoop} object, information about the host and port where the
XRL finder is located, and the XRL target name of this process: in
this case {\stt "static\_routes"}.

Then we create an instance of the {\stt XrlStaticRoutesNode} class we
defined earlier to receive XRLs on the \SR XRL target interface.
Inside this object there will be the corresponding {\stt XrlStdRouter}
object for sending and receiving XRLs from this process.
We pass to {\stt XrlStaticRoutesNode} the following:

\begin{itemize}

  \item The {\stt EventLoop} object.

  \item The XRL target name of this process: in this case
  {\stt "static\_routes"}.

  \item Information about the host and port where the XRL finder is located.

  \item Information about the names of other XRL targets we need to
  communicate with: the Finder, the FEA, and the RIB.

\end{itemize}

Before we proceed any further, we must give the XrlStdRouter time to
register our existence with the Finder.  Thus we call {\stt
wait\_until\_xrl\_router\_is\_ready()}.

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/static\_routes/xorp\_static\_routes.cc} %
                                     \label{lst:srn.main} } ]{}
//
// XORP StaticRoutes module implementation.
//

#include "static_routes_module.h"

#include "libxorp/xorp.h"
#include "libxorp/xlog.h"
#include "libxorp/debug.h"
#include "libxorp/callback.hh"
#include "libxorp/eventloop.hh"
#include "libxorp/exceptions.hh"

#include "xrl_static_routes_node.hh"

...

static void
static_routes_main(const string& finder_hostname, uint16_t finder_port)
{
    //
    // Init stuff
    //
    EventLoop eventloop;

    //
    // StaticRoutes node
    //
    XrlStaticRoutesNode xrl_static_routes_node(
	eventloop,
	"static_routes",
	finder_hostname,
	finder_port,
	"finder",
	"fea",
	"rib");
    wait_until_xrl_router_is_ready(eventloop,
				   xrl_static_routes_node.xrl_router());

    // Startup
    xrl_static_routes_node.startup();

    //
    // Main loop
    //
    while (! xrl_static_routes_node.is_done()) {
	eventloop.run();
    }
}

int
main(int argc, char *argv[])
{
    int ch;
    string::size_type idx;
    const char *argv0 = argv[0];
    string finder_hostname = FinderConstants::FINDER_DEFAULT_HOST().str();
    uint16_t finder_port = FinderConstants::FINDER_DEFAULT_PORT();

    //
    // Initialize and start xlog
    //
    xlog_init(argv[0], NULL);
    xlog_set_verbose(XLOG_VERBOSE_LOW);		// Least verbose messages
    // XXX: verbosity of the error messages temporary increased
    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);
    xlog_add_default_output();
    xlog_start();

...

    //
    // Run everything
    //
    try {
	static_routes_main(finder_hostname, finder_port);
    } catch(...) {
	xorp_catch_standard_exceptions();
    }

    //
    // Gracefully stop and exit xlog
    //
    xlog_stop();
    xlog_exit();

    exit (0);
}


\end{lstlisting}

Finally we're ready to go.  We set our internal state as ready, and
enter a tight loop that we will only exit when it is time to terminate
this process.  At the core of this loop, we call {\stt
EventLoop::run()} repeatedly.  {\stt run()} will block when there are
no events to process.  When an event is ready to process, the relevant
event handler will be called, either directly via a {\stt callback} or
indirectly through one of the XRL stub handler methods we defined
earlier.  Thus if another process calls the \\{\stt
  finder://static\_routes/static\_routes/0.1/add\_route4} XRL, the
first we'll know about it is when {\stt
  XrlStaticRoutesNode::static\_routes\_0\_1\_add\_route4()} is executed.

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Calling XRLs on the RIB}
\label{rib}

So far we have seen how we define an XRL interface, how we implement
the target side of such an interface, and how the main loop of a XORP
process is structured.  In the case of \SRI, we can now receive XRLs
informing us of routes.  The \SRI process will do some checks and
internal processing on these routes (such as checking that they go out
over a network interface that is currently up).  Finally it will
communicate the remaining routes to the RIB process for use by the
forwarding plane.  We will now examine how we send these routes to the
RIB.

If we look in {\stt xorp/xrl/interfaces} we find the file {\stt
rib.xif} which defines the XRLs available on the {\stt rib} interface.
Listing \ref{lst:rib.xif} shows some extracts from this file.  As
we've been following through the {\stt add\_route4} XRL, we'll again
look at that here.  We'll also look at the {\stt lookup\_route\_by\_dest4}
XRL because this is an example of an XRL that returns some data, although
this particular XRL is not actually used by the \SRI process. It is
also worth noting in passing that the RIB requires a routing protocol
(such as \SRI) to call {\stt add\_igp\_table4} before sending routes
to the RIB, or the RIB will not know what to do with the routes.

As we saw with the {\stt static\_routes.xif} file, the {\stt rib.xif}
file is processed by a python script to produce the files {\stt
rib\_xif.hh} and {\stt rib\_xif.cc} in the {\stt xorp/xrl/interfaces}
directory which are then compiled and linked to produce the {\stt
libribxif.la} library.  This library provides a class definition which
does all the work of marshalling C++ arguments into XRLs, sending the
XRL to the RIB process,  receiving the response, and calling the
relevant callback in the caller process with the response data.

Listing \ref{lst:ribxif.hh} shows some extracts from {\stt
rib\_xif.hh} so we can see what the C++ interface to this library
looks like.  The library implements a class called {\stt
XrlRibV0p1Client}.  To use this code, we must first create an instance
of this class, calling the constructor and supplying a pointer to an
{\stt XrlSender}.  Typically such an XrlSender is an instance of an
{\stt XrlRouter} object.  

In Listing \ref{lst:srn.hh} we can see that our implementation of class
{\stt XrlStaticRoutesNode} actually defined an instance of {\stt
XrlRibV0p1Client} called {\stt \_xrl\_rib\_client} as a member
variable, so this object is created automatically when our main loop
creates {\stt xrl\_static\_routes\_node} in Listing
\ref{lst:srn.main}.  In Listing \ref{lst:srn.cc} we can see that we
passed {\stt xrl\_router} into the constructor for {\stt
\_xrl\_rib\_client}.

So, once everything else has been initialized, we'll have access
to {\stt \_xrl\_rib\_client} from within {\stt
xrl\_static\_routes\_node}.  Now, how do we make use of this generated
code?  The answer is simple: to send a route to the RIB we simply call
{\stt \_xrl\_rib\_client.send\_add\_route4()} with the appropriate
parameters, and the generated library code will do the rest.  We can
see this in Listing \ref{lst:sr.send}, where this code is actually used.

The only real complication here is related to how we get the response
back from the XRL.  Recall that {\stt
\_xrl\_rib\_client.send\_add\_route4()} will return immediately with a local
success or failure response, before the XRL has actually been
transmitted to the RIB.  Thus we need to pass a {\it callback} in to
{\stt send\_add\_route4()}.  This callback will wrap up enough state so
that when the response finally returns to the XrlRouter in the \SRI
process, it will know which method to call on which object with which
parameters so as to send the response to the right place.

We can see in {\stt XrlRibV0p1Client} (Listing \ref{lst:srn.hh}) that
the type of the callback is:\\
{\stt XorpCallback1<void, const XrlError\&>::RefPtr}\\
This defines a callback function that returns {\stt void} and which
takes one argument of type {\stt const XrlError\&}.  If we look in
Listing \ref{lst:sr.send} we seen that the method {\stt
XrlStaticRoutesNode::send\_rib\_route\_change\_cb()} fits exactly these
criteria.  This is the method we are going to use to receive the
response from our XRL request.


\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/xrl/interfaces/rib.xif} %
                                     \label{lst:rib.xif} } ]{}
interface rib/0.1 {
...
        /**
         * Add/delete an IGP or EGP table.
         *
         * @param protocol the name of the protocol.
         * @param target_class the target class of the protocol.
         * @param target_instance the target instance of the protocol.
         * @param unicast true if the table is for the unicast RIB.
         * @param multicast true if the table is for the multicast RIB.
         */
        add_igp_table4          ? protocol:txt                          \
                                & target_class:txt & target_instance:txt\
                                & unicast:bool & multicast:bool
...
	/**
	 * Add/replace/delete a route.
	 *
	 * @param protocol the name of the protocol this route comes from.
	 * @param unicast true if the route is for the unicast RIB.
	 * @param multicast true if the route is for the multicast RIB.
	 * @param network the network address prefix of the route.
	 * @param nexthop the address of the next-hop router toward the
	 * destination.
	 * @param metric the routing metric.
	 * @param policytags a set of policy tags used for redistribution.
	 */
	add_route4	? protocol:txt & unicast:bool & multicast:bool	\
			& network:ipv4net & nexthop:ipv4 & metric:u32   \
			& policytags:list
	replace_route4	? protocol:txt & unicast:bool & multicast:bool	\
			& network:ipv4net & nexthop:ipv4 & metric:u32   \
			& policytags:list
	delete_route4	? protocol:txt & unicast:bool & multicast:bool	\
			& network:ipv4net

...
	/**
	 * Lookup nexthop.
	 *
	 * @param addr address to lookup.
	 * @param unicast look in unicast RIB.
	 * @param multicast look in multicast RIB.
	 * @param nexthop contains the resolved nexthop if successful,
	 * IPv4::ZERO otherwise.  It is an error for the unicast and multicast
	 * fields to both be true or both false.
	 */
	lookup_route_by_dest4 ? addr:ipv4 & unicast:bool & multicast:bool \
		-> nexthop:ipv4
}
\end{lstlisting}

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/xrl/interfaces/rib\_xif.hh} %
                                     \label{lst:ribxif.hh} } ]{}
class XrlRibV0p1Client {
public:
    XrlRibV0p1Client(XrlSender* s) : _sender(s) {}
...
    typedef XorpCallback1<void, const XrlError&>::RefPtr AddRoute4CB;
    /**
     *  Send Xrl intended to:
     *
     *  Add/replace/delete a route.
     *
     *  @param dst_xrl_target_name the Xrl target name of the destination.
     *  @param protocol the name of the protocol this route comes from.
     *  @param unicast true if the route is for the unicast RIB.
     *  @param multicast true if the route is for the multicast RIB.
     *  @param network the network address prefix of the route.
     *  @param nexthop the address of the next-hop router toward the
     *  destination.
     *  @param metric the routing metric.
     *  @param policytags a set of policy tags used for redistribution.
     */
    bool send_add_route4(
	const char*	dst_xrl_target_name,
	const string&	protocol,
	const bool&	unicast,
	const bool&	multicast,
	const IPv4Net&	network,
	const IPv4&	nexthop,
	const uint32_t&	metric,
	const XrlAtomList&	policytags,
	const AddRoute4CB&	cb
    );
...
    typedef XorpCallback2<void, const XrlError&, const IPv4*>::RefPtr LookupRo
uteByDest4CB;
    /**
     *  Send Xrl intended to:
     *
     *  Lookup nexthop.
     *
     *  @param dst_xrl_target_name the Xrl target name of the destination.
     *  @param addr address to lookup.
     *  @param unicast look in unicast RIB.
     *  @param multicast look in multicast RIB.
     */
    bool send_lookup_route_by_dest4(
        const char*     dst_xrl_target_name,
        const IPv4&     addr,
        const bool&     unicast,
        const bool&     multicast,
        const LookupRouteByDest4CB&   cb
    );
}
\end{lstlisting}

\newpage

\begin{lstlisting}[caption={Extracts from {\stt xorp/static\_routes/xrl\_static\_routes\_node.cc} %
                                     \label{lst:sr.send} } ]{}
void
XrlStaticRoutesNode::send_rib_route_change()
{
    bool success = true;
...
    StaticRoute& static_route = _inform_rib_queue.front();
...
    //
    // Send the appropriate XRL
    //
    if (static_route.is_add_route()) {
        if (static_route.is_ipv4()) {
            if (static_route.is_interface_route()) {
...
            } else {
		success = _xrl_rib_client.send_add_route4(
		    _rib_target.c_str(),
		    StaticRoutesNode::protocol_name(),
		    static_route.unicast(),
		    static_route.multicast(),
		    static_route.network().get_ipv4net(),
		    static_route.nexthop().get_ipv4(),
		    static_route.metric(),
		    static_route.policytags().xrl_atomlist(),
		    callback(this, &XrlStaticRoutesNode::send_rib_route_change_cb));
                if (success)
                    return;
            }
        }
...
}

void
XrlStaticRoutesNode::send_rib_route_change_cb(const XrlError& xrl_error)
{
    switch (xrl_error.error_code()) {
    case OKAY:
	//
	// If success, then send the next route change
	//
	_inform_rib_queue.pop_front();
	send_rib_route_change();
	break;

    case COMMAND_FAILED:
	//
	// If a command failed because the other side rejected it,
	// then print an error and send the next one.
	//
	...
	break;

    case NO_FINDER:
    case RESOLVE_FAILED:
    case SEND_FAILED:
	...
	break;

    case BAD_ARGS:
    case NO_SUCH_METHOD:
    case INTERNAL_ERROR:
	...
	break;

    case REPLY_TIMED_OUT:
    case SEND_FAILED_TRANSIENT:
	...
	break;
    }
}


\end{lstlisting}

\newpage

\noindent We actually create the callback using the call:\\
{\stt callback(this, \&XrlStaticRoutesNode::send\_rib\_route\_change\_cb)}\\
In the context of 
Listing \ref{lst:sr.send}, {\stt this} refers to a pointer to the
current instance of {\stt XrlStaticRoutesNode}.  So, what this
callback does is to wrap a pointer to the method {\stt
send\_rib\_route\_change\_cb()} on the current instance of {\stt
XrlStaticRoutesNode}.  Later on, when the response returns, the
XrlRouter will call the {\stt send\_rib\_route\_change\_cb()} method on
this specific instance of {\stt XrlStaticRoutesNode} and supply it
with a parameter of type {\stt const XrlError\&}.

In the implementation of {\stt send\_rib\_route\_change\_cb()} we can see
that we check the value of the {\stt xrl\_error} parameter to see
whether the XRL call was actually successful or not.
If the return error code is {\stt OKAY} we send the next route change.
Otherwise, we take different actions based on the error type.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Returning values in XRLs}

Because the \SRI process is so simple, none of the XRLs it calls
actually return any information in the response.  However, it's rather
common that we want to make a request of a target and get back some
information.  This is quite easy to do, but just requires a different
callback that can receive the relevant parameters.

In Listing \ref{lst:rib.xif} we saw that the XRL
{\stt lookup\_route\_by\_dest4}
returns one value of type {\stt ipv4} called {\stt nexthop}.  XRLs can
actually return multiple parameters - this is merely a simple
example.

In Listing \ref{lst:ribxif.hh} we can see that the callback we need to
suuply to {\stt send\_lookup\_route\_by\_dest4()} is of type:\\ {\stt
XorpCallback2<void, const XrlError\&, const IPv4*>::RefPtr}\\ This is
just like the callback we have already seen, except that the method
the callback will call must take two arguments.  The first must be of
type {\stt const XrlError\&} and the second must be of type {\stt
const IPv4*}.  Although \SRI has no such callback method, if it did it
might look like the function {\stt lookup\_route\_by\_dest4\_cb} in
Listing \ref{lst:lookup}.  The callback itself to be passed into {\stt
send\_lookup\_route\_by\_dest4()} is created in exactly the same way as
the one we passed into {\stt send\_add\_route4()}.

\begin{lstlisting}[caption={Hypothetical callback for  {\stt
	send\_lookup\_route\_by\_dest4()} \label{lst:lookup} }]{} %
void
XrlStaticRoutesNode::lookup_route_by_dest4_cb(const XrlError& xrl_error,
                                              const IPv4* nexthop)
{
    if (xrl_error == XrlError::OKAY()) {
        printf("the nexthop is %s\n", nexthop->str().c_str());
    }
...
}
\end{lstlisting}

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Compiling the Source Code}
\label{compiling}

If any of the Makefile.am or configure.in files are modified,
then the {\it ./bootstrap} script in the XORP top-level directory
must be executed first.
It will run the appropriate autotools to generate the corresponding
Makefile.in files and the {\it configure} script.
After that the {\it ./configure} script must be run followed by
{\it gmake}.

Note that XORP assumes certain versions of the autoconf/automake/libtool
versions have been installed. Those versions are listed in the README
in the top-level XORP directory. If the installed versions are
different, then the result is unredicted so it is best to install
versions that are as close as possible to those listed in the README.

The {\it bootstrap} script itself assumes that the autotools executable
programs have certain names. E.g.,:

\begin{verbatim}
ACLOCAL=${ACLOCAL:-"aclocal110"}
AUTOCONF=${AUTOCONF:-"autoconf261"}
AUTOHEADER=${AUTOHEADER:-"autoheader261"}
AUTOMAKE=${AUTOMAKE:-"automake110"}
LIBTOOLIZE=${LIBTOOLIZE:-"libtoolize"}
\end{verbatim}

If the default names don't match, then set the following variables in
the shell environment to the appropriate names before running
{\it ./bootstrap}:

\begin{itemize}
  \item {\it ACLOCAL}
  \item {\it AUTOCONF}
  \item {\it AUTOHEADER}
  \item {\it AUTOMAKE}
  \item {\it LIBTOOLIZE}
\end{itemize}


\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{The XLOG Logging Facility}
\label{xlog}

The XORP XLOG facility is used for log messages generation, similar to
syslog. The log messages may be output to multiple output streams
simultaneously. Below is a description of how to use the log utility.

\begin{itemize}

  \item The xlog utility assumes that \verb=XORP_MODULE_NAME= is defined
  (per module). To do so, you must have in your directory a file like
  ``foo\_module.h'', and inside it should contain something like:

\begin{verbatim}
#define XORP_MODULE_NAME "BGP"
\end{verbatim}

  This file then has to be included by each *.c and *.cc file,
  and MUST be the first of the included local files.

  \item Before using the xlog utility, a program MUST initialize it
  first (think of this as the xlog constructor):

\begin{verbatim}
int xlog_init(const char *process_name, const char *preamble_message);
\end{verbatim}

  Further, if a program tries to use xlog without initializing it
  first, the program will exit.

  \item To add output streams, you MUST use one of the following (or both):

\begin{verbatim}
int xlog_add_output(FILE* fp);
int xlog_add_default_output(void);
\end{verbatim}

  \item To change the verbosity of all xlog messages, use:

\begin{verbatim}
xlog_set_verbose(xlog_verbose_t verbose_level);
\end{verbatim}

  where ``verbose\_level'' is one of the following (\verb=XLOG_VERBOSE_MAX=
  excluded):

\begin{verbatim}
typedef enum {
    XLOG_VERBOSE_LOW = 0,       /* 0 */
    XLOG_VERBOSE_MEDIUM,        /* 1 */
    XLOG_VERBOSE_HIGH,          /* 2 */
    XLOG_VERBOSE_MAX
} xlog_verbose_t;
\end{verbatim}

  Default value is \verb=XLOG_VERBOSE_LOW= (least details).
  Larger value for ``verbose\_level'' adds more details to the
  preamble message (e.g., file name, line number, etc, about the place
  where the log message was initiated).

  Note that the verbosity level of message type \verb=XLOG_LEVEL_FATAL= (see
  below) cannot be changed and is always set to the most verbose level
  (\verb=XLOG_VERBOSE_HIGH=).

  \item To change the verbosity of a particular message type, use:

\begin{verbatim}
void xlog_level_set_verbose(xlog_level_t log_level,
	xlog_verbose_t verbose_level);
\end{verbatim}

  where ``log\_level'' is one of the following (\verb=XLOG_LEVEL_MIN=
  and \verb=XLOG_LEVEL_MAX= excluded):

\begin{verbatim}
typedef enum {
    XLOG_LEVEL_MIN = 0,         /* 0 */
    XLOG_LEVEL_FATAL = 0,       /* 0 */
    XLOG_LEVEL_ERROR,           /* 1 */
    XLOG_LEVEL_WARNING,         /* 2 */
    XLOG_LEVEL_INFO,            /* 3 */
    XLOG_LEVEL_TRACE,           /* 4 */
    XLOG_LEVEL_MAX
} xlog_level_t;
\end{verbatim}

  Note that the verbosity level of message type \verb=XLOG_LEVEL_FATAL=
  cannot be changed and is always set to the most verbose level
  (\verb=XLOG_VERBOSE_HIGH=).

  \item To start the xlog utility, you MUST use:

\begin{verbatim}
int xlog_start(void);
\end{verbatim}

  \item To enable or disable a particular message type, use:

\begin{verbatim}
int xlog_enable(xlog_level_t log_level);
int xlog_disable(xlog_level_t log_level);
\end{verbatim}

  By default, all levels are enabled.
  Note that \verb=XLOG_LEVEL_FATAL= cannot be disabled.

  \item To stop the logging, use:

\begin{verbatim}
int xlog_stop(void);
\end{verbatim}

  Later you can restart it again by \verb=xlog_start()=

  \item To gracefully exit the xlog utility, use

\begin{verbatim}
int     xlog_exit(void);
\end{verbatim}

  (think of this as the xlog destructor).

\end{itemize}

Listing \ref{lst:xlog.main} contains an example of using the XLOG facility.

\begin{lstlisting}[caption={An example of using the XLOG facility %
                                     \label{lst:xlog.main} } ]{}
int
main(int argc, char *argv[])
{
    //
    // Initialize and start xlog
    //
    xlog_init(argv[0], NULL);
    xlog_set_verbose(XLOG_VERBOSE_LOW);	// Least verbose messages
    // Increase verbosity of the error messages
    xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH);
    xlog_add_default_output();
    xlog_start();

    // Do something

    //
    // Gracefully stop and exit xlog
    //
    xlog_stop();
    xlog_exit();

    exit (0);
}
\end{lstlisting}

Typically, a developer would use the macros described below
to print a message, add an assert statement, place a marker, etc.
If a macro accepts a message to print, the format of the message is same
as printf(3). The only difference is that the xlog utility automatically
adds \verb='\n'=, (i.e. end-of-line) at the end of each string
specified by \verb=format=:

\begin{itemize}

  \item \verb=XLOG_FATAL(const char *format, ...)=
  \newline
  Write a FATAL message to the xlog output streams and abort the program.

  \item \verb=XLOG_ERROR(const char *format, ...)=
  \newline
  Write an ERROR message to the xlog output streams.

  \item \verb=XLOG_WARNING(const char *format, ...)=
  \newline
  Write a WARNING message to the xlog output streams.

  \item \verb=XLOG_INFO(const char *format, ...)=
  \newline
  Write an INFO message to the xlog output streams.

  \item \verb=XLOG_TRACE(int cond_boolean, const char *format, ...)=
  \newline
  Write a TRACE message to the xlog output stream, but only
  if \verb=cond_boolean= is not 0.

  \item \verb=XLOG_ASSERT(assertion)=
  \newline
  The XORP replacement for assert(3), except that it cannot be
  conditionally disabled and logs error messages through the standard
  xlog mechanism. It calls \verb=XLOG_FATAL()= if the assertion fails.

  \item \verb=XLOG_UNREACHABLE()=
  \newline
  A marker that can be used to indicate code that should never be executed.

  \item \verb=XLOG_UNFINISHED()=
  \newline
  A marker that can be used to indicate code that is not yet implemented
  and hence should not be run.

\end{itemize}

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{The {\it rtrmgr} Template Files}
\label{rtrmgr_templates}

TODO: add description how to write rtrmgr template files.

For the time being, the developer can check the ``XORP Router Manager Process
(rtrmgr)'' document for information about the template semantics, and can use
file {\stt xorp/etc/templates/static\_routes.tp} as an example.

\newpage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%     APPENDIX
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\appendix
\section{Modification History}

\begin{itemize}

  \item July 19, 2004: Initial version 1.0 completed.

  \item April 13, 2005: Updated to match XORP release 1.1:
   Added the XLOG logging facility section.

  \item March 8, 2006: Updated to match XORP release 1.2:
   Updated some of the sample source code.

  \item August 2, 2006: Updated to match XORP release 1.3:
   The XRL-related sample code is modified to match the original code.
   Miscellaneous cleanup.

  \item March 20, 2007: Updated to match XORP release 1.4:
   Updated some of the sample source code.

  \item July 18, 2007: Added Section 7: Compiling the Source Code.

  \item July 22, 2008: Updated to match XORP release 1.5:
   No significant changes.

\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%     BIBLIOGRAPHY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\bibliography{../tex/xorp}
\bibliographystyle{plain}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}
