doc/tutorial/building-topologies.texi
author Craig Dowell <craigdo@ee.washington.edu>
Sat, 28 Jun 2008 19:46:55 -0700
changeset 3332 da67e8efa347
child 3336 1bb6f018fc42
permissions -rw-r--r--
swap in new tutorial


@c ========================================================================
@c Begin document body here
@c ========================================================================

@c ========================================================================
@c PART:  Building Topologies
@c ========================================================================
@c The below chapters are under the major heading "Building Topologies"
@c This is similar to the Latex \part command
@c
@c ========================================================================
@c Building Topologies
@c ========================================================================
@node Building Topologies
@chapter Building Topologies

@menu
* Building a Star Topology
@end menu

@c ========================================================================
@c Building a Star Topology
@c ========================================================================
@node Building a Star Topology
@section Building a Star Topology

@cindex topology
@cindex topology|star
In this section we are going to use the point-to-point topology primitive we
have explored in quite some detail to construct a star network.  In the star,
there is a central node that is connected to other nodes in a ``hub and spoke''
fashion, with each ``spoke'' being a point-to-point link.

We provide an example of a star topology simulation script on our 
@code{examples} directory.  Go ahead and open @code{examples/star.cc} in your
favorite editor.  You will have already seen enough ns-3 code to understand
this example, but we will go over the script briefly and examine some of the 
output.

There is an amazingly beautiful bit of ASCII art at the beginning of the file
that shows the topology used in the script.  Most ns-3 example programs 
provide this, which can be surprisingly useful in understanding the code.

@verbatim
  // Network topology
  //
  //                  n3    n2
  //                   |   /
  //                    | /
  //              n4 --- n0 --- n1
  //                    /  |
  //                   /    |
  //                  n5    n6
@end verbatim

There are seven nodes in this simulation, nodes zero through six.  Node zero is
the hub of this star network.  We are going to discover that there will be a
flow of echo packets between node four and node one, between node three and 
node  six, and node five and node two.

The script starts by creating seven nodes in a @code{NodeContainer} and 
installs internet protocol stacks on all seven.

@verbatim
    int
  main (int argc, char *argv[])
  {
    NodeContainer nodes;
    nodes.Create (7);

    InternetStackHelper stack;
    stack.Install (nodes);

    ...
@end verbatim

It then creates six more @code{NodeContainer}s representing the nodes at each
end of the six spokes.  In all cases, the first node in the spoke is node zero.

@verbatim
  NodeContainer nodes0and1 = NodeContainer (nodes.Get (0), nodes.Get (1));
  NodeContainer nodes0and2 = NodeContainer (nodes.Get (0), nodes.Get (2));
  NodeContainer nodes0and3 = NodeContainer (nodes.Get (0), nodes.Get (3));
  NodeContainer nodes0and4 = NodeContainer (nodes.Get (0), nodes.Get (4));
  NodeContainer nodes0and5 = NodeContainer (nodes.Get (0), nodes.Get (5));
  NodeContainer nodes0and6 = NodeContainer (nodes.Get (0), nodes.Get (6));
@end verbatim

These node containers will be used during the creation of the point-to-point
links by the @code{PointToPointHelper}.  The next bit of code instantiates
a helper and sets the default values for the device @code{DataRate} and the
channel @code{Delay} attributes as we have previously seen.

@verbatim
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps"));
  pointToPoint.SetChannelParameter ("Delay", StringValue ("2ms"));
@end verbatim

The next step is to install the net devices on the nodes referenced by the 
six node containers and connect them via channels.  We used one instance
of the @code{pointToPoint.Install} method to construct our single 
point-to-point link in the @code{first.cc} script.  This code just does that
six times between different combinations of nodes.

@verbatim
  NetDeviceContainer devicesOnNodes0and1 = pointToPoint.Install (nodes0and1);
  NetDeviceContainer devicesOnNodes0and2 = pointToPoint.Install (nodes0and2);
  NetDeviceContainer devicesOnNodes0and3 = pointToPoint.Install (nodes0and3);
  NetDeviceContainer devicesOnNodes0and4 = pointToPoint.Install (nodes0and4);
  NetDeviceContainer devicesOnNodes0and5 = pointToPoint.Install (nodes0and5);
  NetDeviceContainer devicesOnNodes0and6 = pointToPoint.Install (nodes0and6);
@end verbatim

Note that this does mean that node zero will have six net devices after this
code executes.  Recall that we need to keep containers holding the net devices
we created in order to do IP address assignment.  This is the next step in the
script.

Just as in @code{first.cc} we use the Ipv4AddressHelper to make it easy to
deal with addressing.  We need to create different networks for each stub, so
we have to call the @code{SetBase} method and provide a different network
number before assigning addresses to the devices on each network.  We make it
easy to remember what is what by setting the least significant bits of the 
network number to the unique node on the spoke.  For example, the spoke between
nodes zero and one is network 10.1.1; and the spoke between nodes zero and
two is 10.1.2, etc.  Note that the network mask is set to 255.255.255.252 in
all cases.

@verbatim
  Ipv4AddressHelper ipv4;

  ipv4.SetBase ("10.1.1.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and1 =
    ipv4.Assign (devicesOnNodes0and1);

  ipv4.SetBase ("10.1.2.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and2 =
    ipv4.Assign (devicesOnNodes0and2);

  ipv4.SetBase ("10.1.3.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and3 =
    ipv4.Assign (devicesOnNodes0and3);

  ipv4.SetBase ("10.1.4.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and4 =
    ipv4.Assign (devicesOnNodes0and4);

  ipv4.SetBase ("10.1.5.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and5 =
    ipv4.Assign (devicesOnNodes0and5);

  ipv4.SetBase ("10.1.6.0", "255.255.255.252");
  Ipv4InterfaceContainer interfacesOnNodes0and6 =
    ipv4.Assign (devicesOnNodes0and6);
@end verbatim

When the above code has executed, we will have the topology complete and then
need to move on to applications.  The code to do this should be familiar to 
you, but we have rearranged it slightly.

We use an ApplicationContainer to hold the results of the helper operations,
and use the UdpEchoServerHelper and UdpEchoClient server to configure the 
apps just as we did in the @code{first.cc} script.

@verbatim
  uint16_t port = 9;

  ApplicationContainer apps;

  UdpEchoServerHelper server;
  server.SetPort (port);

  UdpEchoClientHelper client;
  client.SetAppAttribute ("MaxPackets", UintegerValue (10));
  client.SetAppAttribute ("Interval", StringValue ("10ms"));
  client.SetAppAttribute ("PacketSize", UintegerValue (137));
@end verbatim

The next section of code is repeated three times, once for each data flow.
We'll skim over the first instance quickly.  The other two differ only in
the nodes selected and the starting times of the flows.

Just as we did in the @code{first.cc} script, we use the 
@code{UdpEchoServerHelper} to install the echo server on a node (in this case,
node number one -- the rightmost spoke in the topology).  We tell the server
application to start at a simulation time of one second.  We use the
@code{UdpEchoClientHelper} to install the echo client on a node (in this case,
node number four -- the leftmost spoke in the topology).  We tell the client
to start sending data at a simulation time of two seconds.

@verbatim
  //
  // Echo from node 4 to node 1 starting at 2 sec
  //
    apps = server.Install (nodes.Get (1));
    apps.Start (Seconds (1.0));

    client.SetRemote (interfacesOnNodes0and1.GetAddress (1), port);
    apps = client.Install (nodes.Get (4));
    apps.Start (Seconds (2.0));
@end verbatim

The next sections do the same thing, but for nodes three and six with a flow 
starting at 2.1 seconds, and for nodes five and two with flow starting at 2.2
seconds.

The only piece of code you may not have seen before follows.  Since we have
built an internetwork, we need some form of internetwork routing.  Ns-3 
provides what we call a global route manager to set up the routing tables on
nodes.  This route manager has a global function that runs though the nodes
of the simulation and does the hard work of setting up routing for you.  

Basically, what happens is that each node behaves as if it were an OSPF router
that communicates instantly and magically with all other routers.  Each node
generates link advertisements to the global route manager, which uses this 
information to construct the routing tables for each node.

@verbatim
  GlobalRouteManager::PopulateRoutingTables ();
@end verbatim

The remainder of the script should be very familiar to you.  We just enable
ASCII and pcap tracing and run the simulation:

@verbatim
    std::ofstream ascii;
    ascii.open (``star.tr'');
    PointToPointHelper::EnableAsciiAll (ascii);
    PointToPointHelper::EnablePcapAll (``star'');
  
    Simulator::Run ();
    Simulator::Destroy ();
  }
@end verbatim

In order to run this example, you use waf.  All of our example programs are
built by default, so all you have to do is run it.  Now, you did not build
this script by copying it into the scratch directory, so you don't have to
add the scratch directory to the run command.  You just do the following,

@verbatim
  ./waf --run star
@end verbatim

There is no output from this script by default.  It will just go off and 
silently do its thing.  All you will see are waf messages:

@verbatim
  ~/repos/ns-3-tutorial > ./waf --run star
  Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
  Compilation finished successfully
  ~/repos/ns-3-tutorial >
@end verbatim

If you now go and look in the top level directory, you will find a number of
trace files:

@verbatim
  ~/repos/ns-3-tutorial > ls *.pcap *.tr
  star-0-0.pcap  star-0-3.pcap  star-1-0.pcap  star-4-0.pcap  star.tr
  star-0-1.pcap  star-0-4.pcap  star-2-0.pcap  star-5-0.pcap
  star-0-2.pcap  star-0-5.pcap  star-3-0.pcap  star-6-0.pcap
  ~/repos/ns-3-tutorial >
@end verbatim

If you have gone through the tracing section of this tutorial, you know how to
interpret all of these files.  For your reading pleasure, we reproduce a
tcpdump from the net device on node four:

@verbatim
  [ns-regression] ~/repos/ns-3-tutorial > tcpdump -r star-4-0.pcap -nn -tt
  reading from file star-4-0.pcap, link-type PPP (PPP)
  2.000000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.009068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.010000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.019068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.020000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.029068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.030000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.039068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.040000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.049068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.050000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.059068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.060000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.069068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.070000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.079068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.080000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.089068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  2.090000 IP 10.1.4.2.49153 > 10.1.1.2.9: UDP, length 137
  2.099068 IP 10.1.1.2.9 > 10.1.4.2.49153: UDP, length 137
  [ns-regression] ~/repos/ns-3-tutorial >
@end verbatim

You are encouraged to think through the pcap traces and map them back to the
script.  Also, take a look at the @code{star.tr} ASCII trace file (which is
quite large) to make sure you understand what it is telling you.