Add support for non-unit-cost metrics for Ipv4Interfaces (for use in routing); add example script simple-alternate-routing.cc
authorTom Henderson <tomh@tomh.org>
Sat, 06 Oct 2007 21:21:07 -0700
changeset 1776 0d5be0c3d229
parent 1775 5abf6f0d1eca
child 1777 0b294c1347f1
Add support for non-unit-cost metrics for Ipv4Interfaces (for use in routing); add example script simple-alternate-routing.cc
examples/simple-alternate-routing.cc
examples/wscript
src/devices/csma/csma-ipv4-topology.cc
src/devices/csma/csma-ipv4-topology.h
src/devices/point-to-point/point-to-point-topology.cc
src/devices/point-to-point/point-to-point-topology.h
src/internet-node/ipv4-impl.cc
src/internet-node/ipv4-impl.h
src/internet-node/ipv4-interface.cc
src/internet-node/ipv4-interface.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/node/ipv4.h
src/routing/global-routing/global-route-manager-impl.cc
src/routing/global-routing/global-router-interface.cc
src/routing/global-routing/global-router-interface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/simple-alternate-routing.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+//
+// Network topology
+//
+//  n0
+//     \ 5 Mb/s, 2ms
+//      \          1.5Mb/s, 10ms
+//       n2 ------------------------n3
+//      /                          /
+//     / 5 Mb/s, 2ms              /
+//   n1--------------------------
+//          1.5 Mb/s, 100ms
+//
+// this is a modification of simple-global-routing to allow for
+// a single hop but higher-cost path between n1 and n3
+// 
+// - Tracing of queues and packet receptions to file "simple-rerouting.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/log.h"
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/onoff-application.h"
+#include "ns3/packet-sink.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("SimpleAlternateRoutingExample");
+
+int 
+main (int argc, char *argv[])
+{
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+#if 0 
+  LogComponentEnable("GlobalRouteManager", LOG_LOGIC);
+  LogComponentEnable("GlobalRouter", LOG_LOGIC);
+  LogComponentEnable("Object", LOG_LEVEL_ALL);
+  LogComponentEnable("Queue", LOG_LEVEL_ALL);
+  LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
+  LogComponentEnable("Channel", LOG_LEVEL_ALL);
+  LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL);
+  LogComponentEnable("NetDevice", LOG_LEVEL_ALL);
+  LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable("PacketSocket", LOG_LEVEL_ALL);
+  LogComponentEnable("Socket", LOG_LEVEL_ALL);
+  LogComponentEnable("UdpSocket", LOG_LEVEL_ALL);
+  LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
+  LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL);
+  LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL);
+  LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
+  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
+  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
+#endif
+  // Set up some default values for the simulation.  Use the 
+  // DefaultValue::Bind () technique to tell the system what subclass of 
+  // Queue to use, and what the queue limit is
+
+  // The below Bind command tells the queue factory which class to
+  // instantiate, when the queue factory is invoked in the topology code
+  DefaultValue::Bind ("Queue", "DropTailQueue");
+
+  DefaultValue::Bind ("OnOffApplicationPacketSize", "210");
+  DefaultValue::Bind ("OnOffApplicationDataRate", "300b/s");
+
+  // The below metric, if set to 3 or higher, will cause packets between
+  // n1 and n3 to take the 2-hop route through n2
+  // 
+  // Additionally, we plumb this metric into the default value / command 
+  // line argument system as well, for exemplary purposes.  This means 
+  // that it can be resettable at the command-line to the program, 
+  // rather than recompiling
+  // e.g. waf --run "simple-alternate-routing --AlternateCost=5"
+  uint16_t sampleMetric = 1;
+  CommandLine::AddArgValue ("AlternateCost",
+    "This metric is used in the example script between n3 and n1 ", 
+    sampleMetric);
+
+  // Allow the user to override any of the defaults and the above
+  // DefaultValue::Bind ()s at run-time, via command-line arguments
+  CommandLine::Parse (argc, argv);
+
+  // Here, we will explicitly create four nodes.  In more sophisticated
+  // topologies, we could configure a node factory.
+  NS_LOG_INFO ("Create nodes.");
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> (); 
+  Ptr<Node> n2 = Create<InternetNode> (); 
+  Ptr<Node> n3 = Create<InternetNode> ();
+
+  // We create the channels first without any IP addressing information
+  NS_LOG_INFO ("Create channels.");
+  Ptr<PointToPointChannel> channel0 = 
+    PointToPointTopology::AddPointToPointLink (
+      n0, n2, DataRate (5000000), MilliSeconds (2));
+
+  Ptr<PointToPointChannel> channel1 = 
+    PointToPointTopology::AddPointToPointLink (
+      n1, n2, DataRate (5000000), MilliSeconds (2));
+  
+  Ptr<PointToPointChannel> channel2 = 
+    PointToPointTopology::AddPointToPointLink (
+      n2, n3, DataRate (1500000), MilliSeconds (10));
+  
+  Ptr<PointToPointChannel> channel3 = 
+    PointToPointTopology::AddPointToPointLink (
+      n1, n3, DataRate (1500000), MilliSeconds (100));
+  
+  // Later, we add IP addresses.  The middle two octets correspond to 
+ // the channel number.  
+  NS_LOG_INFO ("Assign IP Addresses.");
+  PointToPointTopology::AddIpv4Addresses (
+      channel0, n0, Ipv4Address ("10.0.0.1"),
+      n2, Ipv4Address ("10.0.0.2"));
+  
+  PointToPointTopology::AddIpv4Addresses (
+      channel1, n1, Ipv4Address ("10.1.1.1"),
+      n2, Ipv4Address ("10.1.1.2"));
+  
+  PointToPointTopology::AddIpv4Addresses (
+      channel2, n2, Ipv4Address ("10.2.2.1"),
+      n3, Ipv4Address ("10.2.2.2"));
+
+  PointToPointTopology::AddIpv4Addresses (
+      channel3, n1, Ipv4Address ("10.3.3.1"),
+      n3, Ipv4Address ("10.3.3.2"));
+
+  PointToPointTopology::SetIpv4Metric (
+      channel3, n1, n3, sampleMetric);
+
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  // Create the OnOff application to send UDP datagrams 
+  NS_LOG_INFO ("Create Application.");
+  uint16_t port = 9;   // Discard port (RFC 863)
+
+  // Create a flow from n3 to n1, starting at time 1.1 seconds
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+    n3, 
+    InetSocketAddress ("10.1.1.1", port),
+    "Udp",
+    ConstantVariable (1), 
+    ConstantVariable (0));
+  // Start the application
+  ooff->Start (Seconds (1.1));
+  ooff->Stop (Seconds (10.0));
+
+  // Create a packet sink to receive these packets
+  Ptr<PacketSink> sink = Create<PacketSink> (
+    n1, 
+    InetSocketAddress (Ipv4Address::GetAny (), port), 
+    "Udp");
+  // Start the sink
+  sink->Start (Seconds (1.1));
+  sink->Stop (Seconds (10.0));
+
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+  // Trace output will be sent to the simple-alternate-routing.tr file
+  NS_LOG_INFO ("Configure Tracing.");
+  AsciiTrace asciitrace ("simple-alternate-routing.tr");
+  asciitrace.TraceAllQueues ();
+  asciitrace.TraceAllNetDeviceRx ();
+
+  // Also configure some tcpdump traces; each interface will be traced
+  // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
+  PcapTrace pcaptrace ("simple-alternate-routing.pcap");
+  pcaptrace.TraceAllIp ();
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+
+  return 0;
+}
--- a/examples/wscript	Fri Oct 12 13:41:24 2007 -0700
+++ b/examples/wscript	Sat Oct 06 21:21:07 2007 -0700
@@ -6,6 +6,10 @@
         ['point-to-point', 'internet-node', 'global-routing'])
     obj.source = 'simple-global-routing.cc'
 
+    obj = bld.create_ns3_program('simple-alternate-routing',
+        ['point-to-point', 'internet-node', 'global-routing'])
+    obj.source = 'simple-alternate-routing.cc'
+
     obj = bld.create_ns3_program('simple-point-to-point',
         ['point-to-point', 'internet-node'])
     obj.source = 'simple-point-to-point.cc'
--- a/src/devices/csma/csma-ipv4-topology.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/devices/csma/csma-ipv4-topology.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -96,7 +96,8 @@
   Ptr<Node>             node,
   uint32_t              netDeviceNumber,
   const Ipv4Address     address,
-  const Ipv4Mask        mask)
+  const Ipv4Mask        mask,
+  uint16_t              metric)
 {
   Ptr<NetDevice> nd = node->GetDevice(netDeviceNumber);
 
@@ -105,6 +106,7 @@
 
   ipv4->SetAddress (ifIndex, address);
   ipv4->SetNetworkMask (ifIndex, mask);
+  ipv4->SetMetric (ifIndex, metric);
   ipv4->SetUp (ifIndex);
   return ifIndex;
 }
--- a/src/devices/csma/csma-ipv4-topology.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/devices/csma/csma-ipv4-topology.h	Sat Oct 06 21:21:07 2007 -0700
@@ -103,6 +103,7 @@
    *        the address.
    * \param address The Ipv4 Address for the interface.
    * \param network The network mask for the interface
+   * \param metric (optional) metric (cost) to assign for routing calculations
    * 
    * Add an Ipv4Address to the Ipv4 interface associated with the
    * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel
@@ -110,7 +111,8 @@
   static uint32_t AddIpv4Address(Ptr<Node> node,
                                  uint32_t netDeviceNumber, 
                                  const Ipv4Address address,
-                                 const Ipv4Mask mask);
+                                 const Ipv4Mask mask,
+                                 uint16_t metric = 1);
 
   /**
    * \param nd1 Node
--- a/src/devices/point-to-point/point-to-point-topology.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/devices/point-to-point/point-to-point-topology.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -104,6 +104,59 @@
 }
 
 void
+PointToPointTopology::SetIpv4Metric(
+  Ptr<const PointToPointChannel> chan,
+  Ptr<Node> n1, Ptr<Node> n2, const uint16_t metric)
+{
+
+  // The PointToPoint channel is used to find the relevant NetDevices
+  NS_ASSERT (chan->GetNDevices () == 2);
+  Ptr<NetDevice> nd1 = chan->GetDevice (0);
+  Ptr<NetDevice> nd2 = chan->GetDevice (1);
+  // Make sure that nd1 belongs to n1 and nd2 to n2
+  if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && 
+       (nd2->GetNode ()->GetId () == n1->GetId () ) )
+    {
+      std::swap(nd1, nd2);
+    }
+  NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+  NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
+  
+  // The NetDevice ifIndex does not correspond to the
+  // ifIndex used by Ipv4.  Therefore, we have to iterate
+  // through the NetDevices until we find the Ipv4 ifIndex
+  // that corresponds to NetDevice nd1
+  // Get interface indexes for both nodes corresponding to the right channel
+  uint32_t index = 0;
+  bool found = false;
+  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+    {
+      if (ip1 ->GetNetDevice (i) == nd1)
+        {
+          index = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+  ip1->SetMetric (index, metric);
+
+  index = 0;
+  found = false;
+  Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
+  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+    {
+      if (ip2 ->GetNetDevice (i) == nd2)
+        {
+          index = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+  ip2->SetMetric (index, metric);
+}
+
+void
 PointToPointTopology::AddIpv4Routes (
   Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
 { 
--- a/src/devices/point-to-point/point-to-point-topology.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/devices/point-to-point/point-to-point-topology.h	Sat Oct 06 21:21:07 2007 -0700
@@ -70,6 +70,20 @@
     Ptr<Node> n1, const Ipv4Address& addr1,
     Ptr<Node> n2, const Ipv4Address& addr2);
 
+  /** 
+   * \param chan PointToPointChannel to use
+   * \param n1 Node
+   * \param n2 Node
+   * \param metric link metric to assign on Ipv4Link on chan between n1 and n2
+   * 
+   * Add a non-unit-cost link metric (bidirectionally) to the Ipv4 
+   * interfaces associated with the two PointToPointNetDevices on the 
+   * provided PointToPointChannel
+   */
+  static void SetIpv4Metric(
+    Ptr<const PointToPointChannel> chan,
+    Ptr<Node> n1, Ptr<Node> n2, const uint16_t metric);
+
   /**
    * \param channel PointToPointChannel to use
    * \param n1 Node
--- a/src/internet-node/ipv4-impl.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-impl.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -201,6 +201,18 @@
   return m_ipv4->GetAddress (i);
 }
 
+void
+Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) 
+{
+  m_ipv4->SetMetric (i, metric);
+}
+
+uint16_t
+Ipv4Impl::GetMetric (uint32_t i) const
+{
+  return m_ipv4->GetMetric (i);
+}
+
 bool
 Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
 {
--- a/src/internet-node/ipv4-impl.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-impl.h	Sat Oct 06 21:21:07 2007 -0700
@@ -88,6 +88,8 @@
   virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
   virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
   virtual Ipv4Address GetAddress (uint32_t i) const;
+  virtual void SetMetric (uint32_t i, uint16_t metric);
+  virtual uint16_t GetMetric (uint32_t i) const;
   virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
   virtual bool GetIfIndexForDestination (Ipv4Address dest, 
     uint32_t &ifIndex) const;
--- a/src/internet-node/ipv4-interface.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-interface.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -37,7 +37,8 @@
    */
 Ipv4Interface::Ipv4Interface (Ptr<NetDevice> nd) 
   : m_netdevice (nd), 
-    m_ifup(false)
+    m_ifup(false),
+    m_metric(1)
 {
   NS_LOG_FUNCTION;
   NS_LOG_PARAM ("(" << &nd << ")");
@@ -96,6 +97,21 @@
   return m_netmask;
 }
 
+void
+Ipv4Interface::SetMetric (uint16_t metric)
+{
+  NS_LOG_FUNCTION;
+  NS_LOG_PARAM ("(" << metric << ")");
+  m_metric = metric;
+}
+
+uint16_t
+Ipv4Interface::GetMetric (void) const
+{
+  NS_LOG_FUNCTION;
+  return m_metric;
+}
+
 Ipv4Address 
 Ipv4Interface::GetAddress (void) const
 {
--- a/src/internet-node/ipv4-interface.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-interface.h	Sat Oct 06 21:21:07 2007 -0700
@@ -97,6 +97,14 @@
    */
   Ipv4Mask GetNetworkMask (void) const;
   /**
+   * \param configured routing metric (cost) of this interface
+   */
+  void SetMetric (uint16_t);
+  /**
+   * \returns configured routing metric (cost) of this interface
+   */
+  uint16_t GetMetric (void) const;
+  /**
    * \returns the ipv4 address of this interface
    */
   Ipv4Address GetAddress (void) const;
@@ -147,6 +155,7 @@
   bool m_ifup;
   Ipv4Address m_address;
   Ipv4Mask m_netmask;
+  uint16_t m_metric;
 };
 
 }; // namespace ns3
--- a/src/internet-node/ipv4-l3-protocol.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -821,6 +821,24 @@
   return interface->GetAddress ();
 }
 
+void 
+Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
+{
+  NS_LOG_FUNCTION;
+  NS_LOG_PARAM ("(" << i << ", " << metric << ")");
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetMetric (metric);
+}
+
+uint16_t
+Ipv4L3Protocol::GetMetric (uint32_t i) const
+{
+  NS_LOG_FUNCTION;
+  NS_LOG_PARAM ("(" << i << ")");
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetMetric ();
+}
+
 bool
 Ipv4L3Protocol::GetIfIndexForDestination (
   Ipv4Address destination, uint32_t& ifIndex) const
--- a/src/internet-node/ipv4-l3-protocol.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/internet-node/ipv4-l3-protocol.h	Sat Oct 06 21:21:07 2007 -0700
@@ -198,6 +198,8 @@
   void SetNetworkMask (uint32_t i, Ipv4Mask mask);
   Ipv4Mask GetNetworkMask (uint32_t t) const;
   Ipv4Address GetAddress (uint32_t i) const;
+  void SetMetric (uint32_t i, uint16_t metric);
+  uint16_t GetMetric (uint32_t i) const;
   bool GetIfIndexForDestination (Ipv4Address destination, 
                                  uint32_t& ifIndex) const;
   uint16_t GetMtu (uint32_t i) const;
--- a/src/node/ipv4.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/node/ipv4.h	Sat Oct 06 21:21:07 2007 -0700
@@ -385,6 +385,20 @@
 
   /**
    * \param i index of ipv4 interface
+   * \param metric routing metric (cost) associated to the underlying 
+   *          ipv4 interface
+   */
+  virtual void SetMetric (uint32_t i, uint16_t metric) = 0;
+
+  /**
+   * \param i index of ipv4 interface
+   * \returns routing metric (cost) associated to the underlying 
+   *          ipv4 interface
+   */
+  virtual uint16_t GetMetric (uint32_t i) const = 0;
+
+  /**
+   * \param i index of ipv4 interface
    * \returns the address associated to the underlying ipv4 interface
    */
   virtual Ipv4Address GetAddress (uint32_t i) const = 0;
--- a/src/routing/global-routing/global-route-manager-impl.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -529,7 +529,8 @@
 // Get w_lsa:  In case of V is Router-LSA
       if (v->GetVertexType () == SPFVertex::VertexRouter) 
         {
-          NS_LOG_LOGIC ("Examining " << v->GetVertexId () << "'s " <<
+          NS_LOG_LOGIC ("Examining link " << i << " of " << 
+            v->GetVertexId () << "'s " <<
             v->GetLSA ()->GetNLinkRecords () << " link records");
 //
 // (a) If this is a link to a stub network, examine the next link in V's LSA.
@@ -637,7 +638,8 @@
               candidate.Push (w);
               NS_LOG_LOGIC ("Pushing " << 
                 w->GetVertexId () << ", parent vertexId: " << 
-                v->GetVertexId ());
+                v->GetVertexId () << ", distance: " <<
+                w->GetDistanceFromRoot ());
             }
         }
       else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
@@ -688,7 +690,7 @@
 }
 
 //
-// This method is derived from quagga ospf_next_hop_calculation() 16.1.1.  
+// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.  
 //
 // Calculate nexthop from root through V (parent) to vertex W (destination)
 // with given distance from root->W.
@@ -784,11 +786,13 @@
 //
           w->SetOutgoingInterfaceId (
             FindOutgoingInterfaceId (l->GetLinkData ()));
-
+          w->SetDistanceFromRoot (distance);
+          w->SetParent (v);
           NS_LOG_LOGIC ("Next hop from " << 
             v->GetVertexId () << " to " << w->GetVertexId () << 
             " goes through next hop " << w->GetNextHop () <<
-            " via outgoing interface " << w->GetOutgoingInterfaceId ());
+            " via outgoing interface " << w->GetOutgoingInterfaceId () <<
+            " with distance " << distance);
         }  // end W is a router vertes
       else 
         {
@@ -804,7 +808,8 @@
           w->SetParent (v);
           NS_LOG_LOGIC ("Next hop from " << 
             v->GetVertexId () << " to network " << w->GetVertexId () << 
-            " via outgoing interface " << w->GetOutgoingInterfaceId ());
+            " via outgoing interface " << w->GetOutgoingInterfaceId () <<
+            " with distance " << distance);
           return 1;
         }
     } // end v is the root
@@ -997,6 +1002,7 @@
   m_spfroot= v;
   v->SetDistanceFromRoot (0);
   v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
+  NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
 
   for (;;)
     {
--- a/src/routing/global-routing/global-router-interface.cc	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/routing/global-routing/global-router-interface.cc	Sat Oct 06 21:21:07 2007 -0700
@@ -50,7 +50,7 @@
   LinkType    linkType, 
   Ipv4Address linkId, 
   Ipv4Address linkData, 
-  uint32_t    metric)
+  uint16_t    metric)
 :
   m_linkId (linkId),
   m_linkData (linkData),
@@ -110,7 +110,7 @@
   m_linkType = linkType;
 }
 
-  uint32_t
+  uint16_t
 GlobalRoutingLinkRecord::GetMetric (void) const
 {
   NS_LOG_FUNCTION;
@@ -118,7 +118,7 @@
 }
 
   void
-GlobalRoutingLinkRecord::SetMetric (uint32_t metric)
+GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
 {
   NS_LOG_FUNCTION;
   m_metric = metric;
@@ -202,6 +202,7 @@
       pDst->SetLinkType (pSrc->GetLinkType ());
       pDst->SetLinkId (pSrc->GetLinkId ());
       pDst->SetLinkData (pSrc->GetLinkData ());
+      pDst->SetMetric (pSrc->GetMetric ());
 
       m_linkRecords.push_back(pDst);
       pDst = 0;
@@ -397,6 +398,7 @@
           os << "----------" << std::endl;
           os << "m_linkId = " << p->GetLinkId () << std::endl;
           os << "m_linkData = " << p->GetLinkData () << std::endl;
+          os << "m_metric = " << p->GetMetric () << std::endl;
         }
     }
   else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
@@ -547,6 +549,7 @@
           Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
           Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
           NS_LOG_LOGIC ("Working with local address " << addrLocal);
+          uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
 //
 // Now, we're going to walk over to the remote net device on the other end of 
 // the point-to-point channel we now know we have.  This is where our adjacent 
@@ -566,8 +569,7 @@
               Ipv4Address maskLocalAddr;
               maskLocalAddr.Set(maskLocal.GetHostOrder ());
               plr->SetLinkData (maskLocalAddr);
-              // Cost is interface's configured output cost (NOTYET)
-              plr->SetMetric (1);
+              plr->SetMetric (metricLocal);
               pLSA->AddLinkRecord(plr);
               plr = 0;
               continue;
@@ -589,8 +591,7 @@
               plr->SetLinkId (desigRtr);
               // Link Data is router's own IP address
               plr->SetLinkData (addrLocal);
-              // Cost is interface's configured output cost (NOTYET)
-              plr->SetMetric (1);
+              plr->SetMetric (metricLocal);
               pLSA->AddLinkRecord (plr);
               plr = 0;
               continue;
@@ -613,6 +614,7 @@
           Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
           Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
           NS_LOG_LOGIC ("Working with local address " << addrLocal);
+          uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
 //
 // Now, we're going to walk over to the remote net device on the other end of 
 // the point-to-point channel we now know we have.  This is where our adjacent 
@@ -659,6 +661,7 @@
           plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
           plr->SetLinkId (rtrIdRemote);
           plr->SetLinkData (addrLocal);
+          plr->SetMetric (metricLocal);
           pLSA->AddLinkRecord (plr);
           plr = 0;
 
@@ -666,6 +669,7 @@
           plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
           plr->SetLinkId (addrRemote);
           plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder()));  // Frown
+          plr->SetMetric (metricLocal);
           pLSA->AddLinkRecord (plr);
           plr = 0;
         }
--- a/src/routing/global-routing/global-router-interface.h	Fri Oct 12 13:41:24 2007 -0700
+++ b/src/routing/global-routing/global-router-interface.h	Sat Oct 06 21:21:07 2007 -0700
@@ -82,7 +82,7 @@
     LinkType    linkType, 
     Ipv4Address linkId, 
     Ipv4Address linkData, 
-    uint32_t    metric);
+    uint16_t    metric);
 
 /**
  * @brief Destroy a Global Routing Link Record.
@@ -176,7 +176,7 @@
  *
  * @returns The metric field of the Global Routing Link Record.
  */
-  uint32_t GetMetric(void) const;
+  uint16_t GetMetric(void) const;
 
 /**
  * @brief Set the Metric Data field of the Global Routing Link Record.
@@ -189,7 +189,7 @@
  *
  * @param metric The new metric for the current Global Routing Link Record.
  */
-  void SetMetric(uint32_t metric);
+  void SetMetric(uint16_t metric);
 
 private:
 /**
@@ -230,7 +230,7 @@
  * of two hops relate to the cost of sending a packet); rather you should
  * use something like delay.
  */
-  uint32_t m_metric;  
+  uint16_t m_metric;  
 };
 
 /**