From aa8bd8a8ba03068abe7bfc34638995e8a54054a7 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 27 Jan 2008 10:58:22 -0800 Subject: [PATCH] some more tutorial updates --- doc/tutorial/callbacks.texi | 32 +-- doc/tutorial/routing.texi | 373 +++++++++++++++++++++++++++++++++ doc/tutorial/troubleshoot.texi | 82 ++++++++ doc/tutorial/tutorial.texi | 6 + 4 files changed, 477 insertions(+), 16 deletions(-) create mode 100644 doc/tutorial/routing.texi create mode 100644 doc/tutorial/troubleshoot.texi diff --git a/doc/tutorial/callbacks.texi b/doc/tutorial/callbacks.texi index 70c07f599..377689975 100644 --- a/doc/tutorial/callbacks.texi +++ b/doc/tutorial/callbacks.texi @@ -22,7 +22,7 @@ way that you can do that is that you can make A and B each explicitly knowledgable about the other, so that they can invoke methods on each other. -@example +@verbatim class A { public: void ReceiveInput ( // parameters ); @@ -48,7 +48,7 @@ B::DoSomething() a_instance->ReceiveInput ( // parameters); ... } -@end example +@end verbatim This certainly works, but it has the drawback that it introduces a dependency on A and B to know about the other at compile time (this @@ -133,17 +133,17 @@ This is best observed via walking through an example, based on @subsection Using the Callback API with static functions Consider a function: -@example +@verbatim static double CbOne (double a, double b) { std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl; return a; } -@end example +@end verbatim Consider also the following main program snippett: -@example +@verbatim int main (int argc, char *argv[]) { // return type: double @@ -151,7 +151,7 @@ int main (int argc, char *argv[]) // second arg type: double Callback one; } -@end example +@end verbatim This class template Callback implements what is known as the Functor Design Pattern. It is used to declare the type of a callback. It contains @@ -185,20 +185,20 @@ the function signature. Now, let's bind our callback "one" to the function that matches its signature: -@example +@verbatim // build callback instance which points to cbOne function one = MakeCallback (&CbOne); -@end example +@end verbatim Then, later in the program, if the callback is to be used, it can be used as follows: -@example +@verbatim // this is not a null callback NS_ASSERT (!one.IsNull ()); // invoke cbOne function through callback instance double retOne; retOne = one (10.0, 20.0); -@end example +@end verbatim The check @code{IsNull()} ensures that the callback is not null; that there is a function to call behind this callback. Then, @code{one()} returns the @@ -214,7 +214,7 @@ argument is needed to the MakeCallback function, to tell the system on which object the function should be invoked. Consider this example, also from main-callback.cc: -@example +@verbatim class MyCb { public: int CbTwo (double a) { @@ -234,7 +234,7 @@ int main () two = MakeCallback (&MyCb::CbTwo, &cb); ... } -@end example +@end verbatim Here, we pass a (raw) pointer to the @code{MakeCallback<>} function, that says, when @code{two ()} is invoked, to call the @code{CbTwo} function @@ -245,7 +245,7 @@ pointers. The MakeCallback API takes a raw pointer, so we need to call @code{PeekPointer ()} to obtain this raw pointer. So the example above would look like: -@example +@verbatim class MyCb : public Object { public: int CbTwo (double a) { @@ -265,7 +265,7 @@ int main () two = MakeCallback (&MyCb::CbTwo, PeekPointer (cb)); ... } -@end example +@end verbatim @node Building Null Callbacks @subsection Building Null Callbacks @@ -274,14 +274,14 @@ It is possible for callbacks to be null; hence it may be wise to check before using them. There is a special construct for a null callback, which is preferable to simply passing "0" as an argument; it is the @code{MakeNullCallback<>} construct: -@example +@verbatim two = MakeNullCallback (); // invoking a null callback is just like // invoking a null function pointer: // it will crash at runtime. //int retTwoNull = two (20.0); NS_ASSERT (two.IsNull ()); -@end example +@end verbatim @node Callback locations in ns-3 @section Callback locations in @command{ns-3} diff --git a/doc/tutorial/routing.texi b/doc/tutorial/routing.texi new file mode 100644 index 000000000..953f8b5b9 --- /dev/null +++ b/doc/tutorial/routing.texi @@ -0,0 +1,373 @@ +@node ns-3 routing overview +@chapter ns-3 routing overview + +This chapter describes the overall design of routing in the +@code{src/internet-node} +module, and some details about the routing approachs currently +implemented. + +@node Overview +@section Overview + +We intend to support traditional routing approaches and protocols, +ports of open source routing implementations, and facilitate research +into unorthodox routing techniques. +For simulations that are not primarily focused on routing and that +simply want correct routing tables to occur somehow, we have an +global centralized routing capability. A singleton object +(GlobalRouteManager) be instantiated, builds a network map, and +populates a forwarding table on each node at time t=0 in the +simulation. Simulation script writers can use the same node +API to manually enter routes as well. + +@node Support for multiple routing protocols +@section Support for multiple routing protocols + +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 +faciliate 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. + +There are presently two routing protocols defined: +@itemize @bullet +@item class Ipv4StaticRouting (covering both unicast and multicast) +@item Optimized Link State Routing (a MANET protocol defined in +@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626}) +@end itemize +but first we describe how multiple routing protocols are supported. + +@subsection class Ipv4RoutingProtocol + +@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means +that it supports interface aggregation and reference counting. Routing +protocols should inherit from this class, defined in src/node/ipv4.cc. + +The main function that must be supported by these protocols is called +@code{RequestRoute}. +@verbatim + * This method is called whenever a node's IPv4 forwarding engine + * needs to lookup a route for a given packet and IP header. + * + * The routing protocol implementation may determine immediately it + * should not be handling this particular the route request. For + * instance, a routing protocol may decline to search for routes for + * certain classes of addresses, like link-local. In this case, + * RequestRoute() should return false and the routeReply callback + * must not be invoked. + * + * If the routing protocol implementations assumes it can provide + * the requested route, then it should return true, and the + * routeReply callback must be invoked, either immediately before + * returning true (synchronously), or in the future (asynchronous). + * The routing protocol may use any information available in the IP + * header and packet as routing key, although most routing protocols + * use only the destination address (as given by + * ipHeader.GetDestination ()). The routing protocol is also + * allowed to add a new header to the packet, which will appear + * immediately after the IP header, although most routing do not + * insert any extra header. + */ + virtual bool RequestRoute (uint32_t ifIndex, + const Ipv4Header &ipHeader, + Ptr packet, + RouteReplyCallback routeReply) = 0; +@end verbatim + +This class also provides a typedef (used above) for a special Callback +that will pass to the callback function the Ipv4Route that is found (see the +Doxygen documentation): +@verbatim + typedef Callback, const Ipv4Header&> RouteReplyCallback; +@end verbatim + +@subsection Ipv4::AddRoutingProtocol + +Class Ipv4 provides a pure virtual function declaration for the +method that allows one to add a routing protocol: +@verbatim + void AddRoutingProtocol (Ptr routingProtocol, + int16_t priority); +@end verbatim +This method is implemented by class Ipv4L3Protocol in the internet-node +module. + +The priority variable above governs the priority in which the routing +protocols are inserted. Notice that it is a signed int. +When the class Ipv4L3Protocol is instantiated, a single routing +protocol (Ipv4StaticRouting, introduced below) is added 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 + m_ipv4->AddRoutingProtocol (m_routingTable, -10); +@end verbatim + +@subsection Ipv4L3Protocol::Lookup + +The main function for obtaining a route is shown below: +@verbatim +Ipv4L3Protocol::Lookup ( + uint32_t ifIndex, + Ipv4Header const &ipHeader, + Ptr packet, + Ipv4RoutingProtocol::RouteReplyCallback routeReply) +@end verbatim + +This function will search the list of routing protocols, in priority order, +until a route is found. It will then invoke the RouteReplyCallback +and no further routing protocols will be searched. If the caller does +not want to constrain the possible interface, it can be wildcarded +as such: +@verbatim + Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply); +@end verbatim + +@node Roadmap and Future work +@section Roadmap and Future work + +Some goals for future support are: + +Users should be able to trace (either debug print, or redirect to a trace +file) the routing table in a format such as used in an +Unix implementation: +@verbatim +# netstat -nr (or # route -n) +Kernel IP routing table +Destination Gateway Genmask Flags MSS Window irtt Iface +127.0.0.1 * 255.255.255.255 UH 0 0 0 lo +172.16.1.0 * 255.255.255.0 U 0 0 0 eth0 +172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0 + +# ip route show +192.168.99.0/24 dev eth0 scope link +127.0.0.0/8 dev lo scope link +default via 192.168.99.254 dev eth0 +@end verbatim + +Global computation of multicast routing should be implemented as well. +This would ignore group membership and ensure that a copy of every +sourced multicast datagram would be delivered to each node. +This might be implemented as an RPF mechanism that functioned on-demand +by querying the forwarding table, +and perhaps optimized by a small multicast forwarding cache. It is +a bit trickier to implement over wireless links where the input +interface is the same as the output interface; other aspects of the +packet must be considered and the forwarding logic slightly changed +to allow for forwarding out the same interface. + +In the future, work on bringing XORP or quagga routing to ns, but it will +take several months to port and enable. + +There are presently no roadmap plans for IPv6. + +@node Static routing +@section Static routing + +The internet-node module provides one routing protocol (Ipv4StaticRouting) +by default. This routing protocol allows one to add unicast or multicast +static routes to a node. + +@node Unicast routing +@section Unicast routing + +The unicast static routing API may be accessed via the functions +@verbatim +void Ipv4::AddHostRouteTo () +void Ipv4::AddNetworkRouteTo () +void Ipv4::SetDefaultRoute () +uint32_t Ipv4::GetNRoutes () +Ipv4Route Ipv4::GetRoute () +@end verbatim + +@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation +provides full documentation of these methods. These methods are forwarding +functions to the actual implementation in Ipv4StaticRouting, when using +the internet-node module. + +@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 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 +exlicitly 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 + +@node Global centralized routing +@section Global centralized routing + +Presently, global centralized IPv4 @emph{unicast} routing over both +point-to-point and shared (CSMA) links is supported. +The global centralized routing will be modified in the future to +reduce computations once profiling finds the performance bottlenecks. + +@node Global Unicast Routing API +@section Global Unicast Routing API + +The public API is very minimal. User scripts include the following: +@verbatim +#include "ns3/global-route-manager.h" +@end verbatim + +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 + GlobalRouteManager::PopulateRoutingTables (); +@end verbatim + +@emph{Note:} A reminder that the wifi NetDevice is not yet supported +(only CSMA and PointToPoint). + +@node Global Routing Implementation +@section Global Routing Implementation + +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 >::iterator Iterator; + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; + Ptr globalRouter = Create (node); + node->AddInterface (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 Optimized Link State Routing (OLSR) +@section Optimized Link State Routing (OLSR) + +This is the first dynamic routing protocol for @command{ns-3}. The implementation +is found in the src/routing/olsr directory, and an example script is in +examples/simple-point-to-point-olsr.cc. + +The following commands will enable OLSR in a simulation. + +@verbatim + olsr::EnableAllNodes (); // Start OLSR on all nodes + olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on + // a list of nodes + olsr::EnableNode (Ptr node); // Start OLSR on "node" only +@end verbatim + +Once instantiated, the agent can be started with the Start() command, +and the OLSR "main interface" can be set with the SetMainInterface() +command. A number of protocol constants are defined in olsr-agent-impl.cc. + diff --git a/doc/tutorial/troubleshoot.texi b/doc/tutorial/troubleshoot.texi new file mode 100644 index 000000000..b02db203e --- /dev/null +++ b/doc/tutorial/troubleshoot.texi @@ -0,0 +1,82 @@ +@node Troubleshooting +@chapter Troubleshooting + +This chapter posts some information about possibly common errors in building +or running ns-3 programs. + +Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items. + +@node Build errors +@section Build errors + +@node Run-time errors +@section Run-time errors + +Sometimes, errors can occur with a program after a successful build. These +are run-time errors, and can commonly occur when memory is corrupted or +pointer values are unexpectedly null. + +Here is an example of what might occur: + +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point +Entering directory `/home/tomh/ns-3-nsc/build' +Compilation finished successfully +Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11 +@end verbatim + +The error message says that the program terminated unsuccessfully, but it is +not clear from this information what might be wrong. To examine more +closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}: + +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s" +Entering directory `/home/tomh/ns-3-nsc/build' +Compilation finished successfully +GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh) +Copyright 2004 Free Software Foundation, Inc. +GDB is free software, covered by the GNU General Public License, and you are +welcome to change it and/or distribute copies of it under certain conditions. +Type "show copying" to see the conditions. +There is absolutely no warranty for GDB. Type "show warranty" for details. +This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1". + +(gdb) run +Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point +Reading symbols from shared object read from target memory...done. +Loaded system supplied DSO at 0xf5c000 + +Program received signal SIGSEGV, Segmentation fault. +0x0804aa12 in main (argc=1, argv=0xbfdfefa4) + at ../examples/tcp-point-to-point.cc:136 +136 Ptr localSocket = socketFactory->CreateSocket (); +(gdb) p localSocket +$1 = {m_ptr = 0x3c5d65} +(gdb) p socketFactory +$2 = {m_ptr = 0x0} +(gdb) quit +The program is running. Exit anyway? (y or n) y +@end verbatim + +Note first the way the program was invoked-- pass the command to run as +an argument to the command template "gdb %s". + +This tells us that there was an attempt to dereference a null pointer +socketFactory. + +Let's look around line 136 of tcp-point-to-point, as gdb suggests: +@verbatim + Ptr socketFactory = n2->QueryInterface (Tcp::iid); + Ptr localSocket = socketFactory->CreateSocket (); + localSocket->Bind (); +@end verbatim + +The culprit here is that the return value of QueryInterface is not being +checked and may be null. + +Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory +checker} for more subtle errors. Again, you invoke the use of valgrind +similarly: +@verbatim +ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s" +@end verbatim diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi index 79d36498d..add933fb5 100644 --- a/doc/tutorial/tutorial.texi +++ b/doc/tutorial/tutorial.texi @@ -77,13 +77,16 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. @menu * Introduction:: +Part 1: Overview * Overview:: * Resources:: * The-Basics:: * Some-Prerequisites:: * A-First-ns-3-Script:: +Part 2: Details * ns-3 Callbacks:: * Simulation Output:: +* ns-3 routing overview:: * Other-network-topologies:: * Nonlinear-Thinking:: * Summary:: @@ -92,12 +95,15 @@ see @uref{http://www.nsnam.org/docs/tutorial.pdf}. * How-To-Change-Things:: * How-To-Set-Default-Values:: * How-To-Write-A-New-Application:: +@ Troubleshooting @end menu @include introduction.texi @include callbacks.texi @include output.texi +@include routing.texi @include other.texi +@include troubleshoot.texi @printindex cp