@node Routing overview
@chapter Routing overview

@menu
* Routing architecture::
* Global centralized routing::
* Unicast routing::
* Multicast routing::
@end menu

ns-3 is intended to support traditional routing approaches and protocols,
support ports of open source routing implementations, and facilitate research
into unorthodox routing techniques.  The overall routing architecture
is described below in @ref{Routing architecture}.  Users who wish to 
just read about how to configure global routing for wired topologies
can read @ref{Global centralized routing}.  Unicast routing protocols 
are described in @ref{Unicast routing}.  Multicast routing is documented in
@ref{Multicast routing}.

@node Routing architecture
@section Routing architecture

@float Figure,fig:routing
@caption{Overview of routing}
@image{figures/routing, 6in}
@end float

@ref{fig:routing} shows the overall routing architecture for Ipv4.  The key objects
are Ipv4L3Protocol, Ipv4RoutingProtocol(s) (a class to which all 
routing/forwarding has been delegated from Ipv4L3Protocol), and Ipv4Route(s).

Ipv4L3Protocol must have at least one Ipv4RoutingProtocol added to
it at simulation setup time.  This is done explicitly by calling
Ipv4::SetRoutingProtocol ().

The abstract base class Ipv4RoutingProtocol () declares a minimal interface,
consisting of two methods:  RouteOutput () and RouteInput ().  
For packets traveling outbound from a host, the transport protocol will query
Ipv4 for the Ipv4RoutingProtocol object interface, and will request
a route via Ipv4RoutingProtocol::RouteOutput ().
A Ptr to Ipv4Route object is returned.  This is analagous to a
dst_cache entry in Linux.  The Ipv4Route is carried down to the
Ipv4L3Protocol to avoid a second lookup there.  However, some
cases (e.g. Ipv4 raw sockets) will require a call to RouteOutput()
directly from Ipv4L3Protocol.

For packets received inbound for forwarding or delivery, 
the following steps occur.  Ipv4L3Protocol::Receive() calls 
Ipv4RoutingProtocol::RouteInput().
This passes the packet ownership to the Ipv4RoutingProtocol object.  There
are four callbacks associated with this call:
@itemize @bullet
@item LocalDeliver 
@item UnicastForward
@item MulticastForward
@item Error
@end itemize  
The Ipv4RoutingProtocol must eventually call one of these callbacks for each
packet that it takes responsibility for.  This is basically
how the input routing process works in Linux.

@float Figure,fig:routing-specialization
@caption{Ipv4Routing specialization}
@image{figures/routing-specialization, 5in}
@end float

This overall architecture is designed to support different routing
approaches, including (in the future) a Linux-like policy-based routing
implementation, proactive and on-demand routing protocols, and simple
routing protocols for when the simulation user does not really care
about routing.

@ref{fig:routing-specialization} illustrates how multiple routing protocols
derive from this base class.  A class Ipv4ListRouting
(implementation class Ipv4ListRoutingImpl) provides the existing
list routing approach in ns-3.  Its API is the same as base class
Ipv4Routing except for the ability to add multiple prioritized routing
protocols 
(Ipv4ListRouting::AddRoutingProtocol(), Ipv4ListRouting::GetRoutingProtocol()).

The details of these routing protocols are described below in
@ref{Unicast routing}.  For now, we will first start with a basic
unicast routing capability that is intended to globally build routing
tables at simulation time t=0 for simulation users who do not care
about dynamic routing.

@node Global centralized routing
@section Global centralized routing

Global centralized routing is sometimes called ''God'' routing; it
is a special implementation that walks the simulation topology and
runs a shortest path algorithm, and populates each node's routing
tables.  No actual protocol overhead (on the simulated links) is incurred
with this approach.  It does have a few constraints:

@itemize @bullet
@item @strong{Wired only:}  It is not intended for use in wireless networks.
@item @strong{Unicast only:} It does not do multicast.
@item @strong{Scalability:}  Some users of this on large topologies 
(e.g. 1000 nodes) 
have noticed that the current implementation is not very scalable.  
The global centralized routing will be modified in the future to
reduce computations and runtime performance.
@end itemize

Presently, global centralized IPv4 unicast routing over both 
point-to-point and shared (CSMA) links is supported.

By default, when using the ns-3 helper API and the default InternetStackHelper,
global routing capability will be added  to the node, and global routing
will be inserted as a routing protocol with lower priority than the
static routes (i.e., users can insert routes via Ipv4StaticRouting API
and they will take precedence over routes found by global routing).

@subsection Global Unicast Routing API

The public API is very minimal.  User scripts include the following:
@verbatim
#include "ns3/helper-module.h"
@end verbatim

If the default InternetStackHelper is used, then an instance of
global routing will be aggregated to each node.
After IP addresses are configured, the following function call will
cause all of the nodes that have an Ipv4 interface to receive
forwarding tables entered automatically by the GlobalRouteManager:
@verbatim
  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
@end verbatim

@emph{Note:} A reminder that the wifi NetDevice will work but does not
take any wireless effects into account.  For wireless, we recommend
OLSR dynamic routing described below.

It is possible to call this function again in the midst of a simulation
using the following additional public function:
@verbatim
  Ipv4GlobalRoutingHelper::RecomputeRoutingTables ();
@end verbatim
which flushes the old tables, queries the nodes for new interface information,
and rebuilds the routes.

For instance, this scheduling call will cause the tables to be rebuilt
at time 5 seconds:
@verbatim
  Simulator::Schedule (Seconds (5),
    &Ipv4GlobalRoutingHelper::RecomputeRoutingTables);
@end verbatim

There are two attributes that govern the behavior.  The first is 
Ipv4GlobalRouting::RandomEcmpRouting.  If set to true, packets are randomly
routed across equal-cost multipath routes.  If set to false (default), 
only one route is consistently used.  The second is 
Ipv4GlobalRouting::RespondToInterfaceEvents.  If set to true, dynamically 
recompute the global routes upon Interface notification events (up/down, 
or add/remove address).  If set to false (default), routing may break
unless the user manually calls RecomputeRoutingTables() after such events.
The default is set to false to preserve legacy ns-3 program behavior.

@subsection Global Routing Implementation

This section is for those readers who care about how this is implemented.
A singleton object (GlobalRouteManager) is responsible for populating
the static routes on each node, using the public Ipv4 API of that node.
It queries each node in the topology for a "globalRouter" interface.
If found, it uses the API of that interface to obtain a "link state
advertisement (LSA)" for the router.  Link State Advertisements
are used in OSPF routing, and we follow their formatting.

The GlobalRouteManager populates a link state database with LSAs
gathered from the entire topology.  Then, for each router in the topology,
the GlobalRouteManager executes the OSPF shortest path first (SPF)
computation on the database, and populates the routing tables on each
node.

The quagga (http://www.quagga.net) OSPF implementation was used as the
basis for the routing computation logic.
One benefit of following an existing OSPF SPF implementation is that
OSPF already has defined link state advertisements for all common
types of network links:
@itemize @bullet
@item point-to-point (serial links)
@item point-to-multipoint (Frame Relay, ad hoc wireless)
@item non-broadcast multiple access (ATM)
@item broadcast (Ethernet)
@end itemize
Therefore, we think that enabling these other link types will be more
straightforward now that the underlying OSPF SPF framework is in place.

Presently, we can handle IPv4 point-to-point, numbered links, as well
as shared broadcast (CSMA) links, and we do not do equal-cost multipath.  

The GlobalRouteManager first walks the list of nodes and aggregates
a GlobalRouter interface to each one as follows:
@verbatim
  typedef std::vector < Ptr<Node> >::iterator Iterator;
  for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
    {
      Ptr<Node> node = *i;
      Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
      node->AggregateObject (globalRouter);
    }
@end verbatim

This interface is later queried and used to generate a Link State
Advertisement for each router, and this link state database is
fed into the OSPF shortest path computation logic.  The Ipv4 API
is finally used to populate the routes themselves. 

@node Unicast routing
@section Unicast routing

There are presently five unicast routing protocols defined for IPv4 and
two for IPv6:
@itemize @bullet
@item class Ipv4StaticRouting (covering both unicast and multicast)
@item  IPv4 Optimized Link State Routing (a MANET protocol defined in
@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
@item class Ipv4ListRouting (used to store a prioritized list of routing
protocols)
@item class Ipv4GlobalRouting (used to store routes computed by the global
route manager, if that is used)
@item class Ipv4NixVectorRouting (a more efficient version of global routing
that stores source routes in a packet header field)
@item class Ipv6ListRouting (used to store a prioritized list of routing
protocols)
@item class Ipv6StaticRouting 
@end itemize

In the future, this architecture should also allow someone to implement
a Linux-like implementation with routing cache, or a Click modular
router, but those are out of scope for now.

@subsection Ipv4ListRouting

This section describes the current default ns-3 Ipv4RoutingProtocol.
Typically, multiple routing protocols are supported in user space and
coordinate to write a single forwarding table in the kernel.  Presently
in @command{ns-3}, the implementation instead allows for multiple routing 
protocols to build/keep their own routing state, and the IPv4 implementation
will query each one of these routing protocols (in some order determined
by the simulation author) until a route is found.  

We chose this approach because it may better
facilitate the integration of disparate routing approaches that may 
be difficult to coordinate the writing to a single table, approaches
where more information than destination IP address (e.g., source
routing) is used to determine the next hop, and on-demand
routing approaches where packets must be cached.  

@subsubsection Ipv4ListRouting::AddRoutingProtocol

Class Ipv4ListRouting provides a pure virtual function declaration for the
method that allows one to add a routing protocol:
@verbatim
  void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
                           int16_t priority);
@end verbatim
This method is implemented by class Ipv4ListRoutingImpl in the internet-stack
module.

The priority variable above governs the priority in which the routing
protocols are inserted.  Notice that it is a signed int.
By default in ns-3, the helper classes will instantiate a Ipv4ListRoutingImpl
object, and add to it an Ipv4StaticRoutingImpl object at priority zero. 
Internally, a list of Ipv4RoutingProtocols is stored, and
and the routing protocols are each consulted in decreasing order
of priority to see whether a match is found.  Therefore, if you
want your Ipv4RoutingProtocol to have priority lower than the static
routing, insert it with priority less than 0; e.g.:
@verbatim
  Ptr<MyRoutingProtocol> myRoutingProto = CreateObject<MyRoutingProtocol> ();
  listRoutingPtr->AddRoutingProtocol (myRoutingProto, -10);
@end verbatim

Upon calls to RouteOutput() or RouteInput(), the list routing object will 
search the list of routing protocols, in priority order, until a route 
is found.  Such routing protocol will invoke the appropriate callback
and no further routing protocols will be searched.  

@subsection Optimized Link State Routing (OLSR)

This IPv4 routing protocol was originally ported from the OLSR-UM 
implementation for ns-2.  The implementation
is found in the src/routing/olsr directory, and an example script is in
examples/simple-point-to-point-olsr.cc.

Typically, OLSR is enabled in a main program by use of an OlsrHelper class
that installs OLSR into an Ipv4ListRoutingProtocol object.  
The following sample commands will enable OLSR in a simulation using
this helper class along with some other routing helper objects.
The setting of priority value 10, ahead of
the staticRouting priority of 0, means that OLSR will be consulted for
a route before the node's static routing table.  

@verbatim
  NodeContainer c:
  ...
 // Enable OLSR
  NS_LOG_INFO ("Enabling OLSR Routing.");
  OlsrHelper olsr;

  Ipv4StaticRoutingHelper staticRouting;

  Ipv4ListRoutingHelper list;
  list.Add (staticRouting, 0);
  list.Add (olsr, 10);

  InternetStackHelper internet;
  internet.SetRoutingHelper (list);
  internet.Install (c);
@end verbatim

Once installed,the OLSR "main interface" can be set with the 
SetMainInterface() command.  If the user does not specify a main address,
the protocol will select the first primary IP address that it finds, starting
first the loopback interface and then the next non-loopback interface
found, in order of Ipv4 interface index.  The loopback address of 127.0.0.1
is not selected.  In addition, a number of protocol constants are defined in 
olsr-routing-protocol.cc.

Olsr is started at time zero of the simulation, based on a call to
Object::Start() that eventually calls OlsrRoutingProtocol::DoStart().
Note:  a patch to allow the user to start and stop the protocol at other
times would be welcome.

Presently, OLSR is limited to use with an Ipv4ListRouting object, and
does not respond to dynamic changes to a device's IP address or link up/down
notifications; i.e. the topology changes are due to loss/gain of connectivity
over a wireless channel.

@node Multicast routing
@section Multicast routing

The following function is used to add a static multicast route
to a node:
@verbatim
void 
Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin,
                          Ipv4Address group,
                          uint32_t inputInterface,
                          std::vector<uint32_t> outputInterfaces);
@end verbatim

A multicast route must specify an origin IP address, a multicast group and
an input network interface index as conditions and provide a vector of
output network interface indices over which packets matching the conditions
are sent.

Typically there are two main types of multicast routes:  routes of the 
first kind are used during forwarding.  All of the conditions must be
explicitly provided.  The second kind of routes are used to get packets off
of a local node.  The difference is in the input interface.  Routes for
forwarding will always have an explicit input interface specified.  Routes
off of a node will always set the input interface to a wildcard specified
by the index Ipv4RoutingProtocol::IF\_INDEX\_ANY.

For routes off of a local node wildcards may be used in the origin and
multicast group addresses.  The wildcard used for Ipv4Adresses is that 
address returned by Ipv4Address::GetAny () -- typically "0.0.0.0".  Usage
of a wildcard allows one to specify default behavior to varying degrees.

For example, making the origin address a wildcard, but leaving the 
multicast group specific allows one (in the case of a node with multiple
interfaces) to create different routes using different output interfaces
for each multicast group.

If the origin and multicast addresses are made wildcards, you have created
essentially a default multicast address that can forward to multiple 
interfaces.  Compare this to the actual default multicast address that is
limited to specifying a single output interface for compatibility with
existing functionality in other systems.

Another command sets the default multicast route:
@verbatim
void 
Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface);
@end verbatim

This is the multicast equivalent of the unicast version SetDefaultRoute.
We tell the routing system what to do in the case where a specific route
to a destination multicast group is not found.  The system forwards 
packets out the specified interface in the hope that "something out there"
knows better how to route the packet.  This method is only used in 
initially sending packets off of a host.  The default multicast route is
not consulted during forwarding -- exact routes must be specified using
AddMulticastRoute for that case.

Since we're basically sending packets to some entity we think may know
better what to do, we don't pay attention to "subtleties" like origin
address, nor do we worry about forwarding out multiple  interfaces.  If the
default multicast route is set, it is returned as the selected route from 
LookupStatic irrespective of origin or multicast group if another specific
route is not found.

Finally, a number of additional functions are provided to fetch and
remove multicast routes:
@verbatim
  uint32_t GetNMulticastRoutes (void) const;

  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;

  Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;

  bool RemoveMulticastRoute (Ipv4Address origin,
                             Ipv4Address group,
                             uint32_t inputInterface);

  void RemoveMulticastRoute (uint32_t index);
@end verbatim


