checkpoint
authorCraig Dowell <craigdo@ee.washington.edu>
Tue, 10 Jul 2007 01:28:19 -0700
changeset 1056 dc7924932154
parent 1055 e9580901878f
child 1057 2620020dc72c
checkpoint
examples/simple-static-routing.cc
src/routing/routing-environment.cc
src/routing/routing-environment.h
src/routing/static-route-manager.cc
src/routing/static-router.cc
src/routing/static-router.h
--- a/examples/simple-static-routing.cc	Mon Jul 09 23:07:51 2007 -0700
+++ b/examples/simple-static-routing.cc	Tue Jul 10 01:28:19 2007 -0700
@@ -81,8 +81,8 @@
   DebugComponentEnable("Channel");
   DebugComponentEnable("PointToPointChannel");
   DebugComponentEnable("PointToPointNetDevice");
+  DebugComponentEnable("StaticRouter");
 #endif
-  DebugComponentEnable("StaticRouter");
 
   // Set up some default values for the simulation.  Use the Bind()
   // technique to tell the system what subclass of Queue to use,
--- a/src/routing/routing-environment.cc	Mon Jul 09 23:07:51 2007 -0700
+++ b/src/routing/routing-environment.cc	Tue Jul 10 01:28:19 2007 -0700
@@ -29,11 +29,18 @@
 BooleanDefaultValue g_doStaticRoutingDefaultValue ("DoStaticRouting", 
   "Enable global static routing", false);
 
-    bool
+  bool
 StaticRoutingEnabled(void)
 {
   return g_doStaticRoutingDefaultValue.GetValue();
 }
 
+  uint32_t
+AllocateRouterId(void)
+{
+  static uint32_t routerId = 0;
+  return ++routerId;
+}
+
 } // namespace RoutingEnvironment
 } // namespace ns3
--- a/src/routing/routing-environment.h	Mon Jul 09 23:07:51 2007 -0700
+++ b/src/routing/routing-environment.h	Tue Jul 10 01:28:19 2007 -0700
@@ -25,6 +25,7 @@
 namespace RoutingEnvironment {
 
 bool StaticRoutingEnabled(void);
+uint32_t AllocateRouterId(void);
 
 } // namespace RoutingEnvironment
 } // namespace ns3
--- a/src/routing/static-route-manager.cc	Mon Jul 09 23:07:51 2007 -0700
+++ b/src/routing/static-route-manager.cc	Tue Jul 10 01:28:19 2007 -0700
@@ -85,7 +85,18 @@
       NS_ASSERT_MSG(rtr, "QI for <StaticRouter> interface failed");
 
       uint32_t numLSAs = rtr->GetNumLSAs();
-      NS_DEBUG_UNCOND (numLSAs << "LSAs");
+      NS_DEBUG_UNCOND ("Found " << numLSAs << " LSAs");
+
+      for (uint32_t j = 0; j < numLSAs; ++j)
+        {
+          StaticRouterLSA lsa;
+          rtr->GetLSA(j, lsa);
+          NS_DEBUG_UNCOND ("LSA " << j);
+          NS_DEBUG_UNCOND ("----------------------------------------");
+          NS_DEBUG_UNCOND("m_linkStateId = " << lsa.m_linkStateId);
+          NS_DEBUG_UNCOND("m_advertisingRtr = " << lsa.m_advertisingRtr);
+          NS_DEBUG_UNCOND ("----------------------------------------");
+        }
     }
 }
 
--- a/src/routing/static-router.cc	Mon Jul 09 23:07:51 2007 -0700
+++ b/src/routing/static-router.cc	Tue Jul 10 01:28:19 2007 -0700
@@ -35,15 +35,57 @@
   NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()");
 }
 
+//
+// Copy constructor for StaticRouterLSA
+//
+StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa)
+  : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr)
+{
+  NS_DEBUG("StaticRouterLSA Copy Constructor");
+  NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before copy");
+
+  for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin ();
+        i != lsa.m_linkRecords.end (); 
+        i++)
+    {
+      StaticRouterLinkRecord *pSrc = *i;
+      StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord;
+      pDst->m_linkId = pSrc->m_linkId;
+      pDst->m_linkData = pSrc->m_linkData;
+      m_linkRecords.push_back(pDst);
+      pDst = 0;
+    }
+}
+
+//
+// Assignment operator for StaticRouterLSA
+//
+// This uses the non-obvious trick of taking the source LSA passed by
+// value instead of by reference.  This causes the copy constructor to be
+// invoked (where the real work is done -- see above).  All we have to do
+// here is to return the newly constructed LSA.
+//
+  StaticRouterLSA&
+StaticRouterLSA::operator= (StaticRouterLSA lsa)
+{
+  NS_DEBUG("StaticRouterLSA Operator =");
+  return *this;
+}
+
 StaticRouterLSA::~StaticRouterLSA()
 {
   NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()");
+  ClearLinkRecords ();
+}
 
+  void
+StaticRouterLSA::ClearLinkRecords(void)
+{
   for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
         i != m_linkRecords.end (); 
         i++)
     {
-      NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ():  free link record");
+      NS_DEBUG("StaticRouterLSA::ClearLinkRecords ():  free link record");
 
       StaticRouterLinkRecord *p = *i;
       delete p;
@@ -51,7 +93,7 @@
 
       *i = 0;
     }
-  NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ():  clear list");
+  NS_DEBUG("StaticRouterLSA::ClearLinkRecords():  clear list");
   m_linkRecords.clear();
 }
 
@@ -62,19 +104,77 @@
   return m_linkRecords.size ();
 }
 
+  bool
+StaticRouterLSA::IsEmpty (void)
+{
+  return m_linkRecords.size () == 0;
+}
+
+  void 
+StaticRouterLSA::Print (std::ostream &os)
+{
+  os << "m_linkStateId = " << m_linkStateId << std::endl <<
+        "m_advertisingRtr = " << m_advertisingRtr << std::endl;
+
+  for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
+        i != m_linkRecords.end (); 
+        i++)
+    {
+      StaticRouterLinkRecord *p = *i;
+      os << "----------" << std::endl;
+      os << "m_linkId = " << p->m_linkId << std::endl;
+      os << "m_linkData = " << p->m_linkData << std::endl;
+    }
+}
+
+std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa)
+{
+  lsa.Print (os);
+  return os;
+}
+
 const InterfaceId StaticRouter::iid = 
   MakeInterfaceId ("StaticRouter", Object::iid);
 
 StaticRouter::StaticRouter (Ptr<Node> node)
-  : m_node(node), m_numLSAs(0)
+  : m_node(node), m_LSAs()
 {
   NS_DEBUG("StaticRouter::StaticRouter ()");
   SetInterfaceId (StaticRouter::iid);
+  m_routerId.Set(RoutingEnvironment::AllocateRouterId());
 }
 
 StaticRouter::~StaticRouter ()
 {
   NS_DEBUG("StaticRouter::~StaticRouter ()");
+  ClearLSAs();
+}
+
+  void
+StaticRouter::ClearLSAs ()
+{
+  NS_DEBUG("StaticRouter::ClearLSAs ()");
+
+  for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
+        i != m_LSAs.end (); 
+        i++)
+    {
+      NS_DEBUG("StaticRouter::ClearLSAs ():  free LSA");
+
+      StaticRouterLSA *p = *i;
+      delete p;
+      p = 0;
+
+      *i = 0;
+    }
+  NS_DEBUG("StaticRouter::ClearLSAs ():  clear list");
+  m_LSAs.clear();
+}
+
+  Ipv4Address
+  StaticRouter::GetRouterId (void)
+{
+  return m_routerId;
 }
 
 //
@@ -85,6 +185,7 @@
 {
   NS_DEBUG("StaticRouter::GetNumLSAs ()");
   NS_ASSERT_MSG(m_node, "<Node> interface not set");
+  ClearLSAs ();
 //
 // We're aggregated to a node.  We need to ask the node for a pointer to its
 // Ipv4 interface.  This is where the information regarding the attached 
@@ -93,29 +194,24 @@
   Ptr<Ipv4> ipv4Local = m_node->QueryInterface<Ipv4> (Ipv4::iid);
   NS_ASSERT_MSG(ipv4Local, "QI for <Ipv4> interface failed");
 //
-// Now, we need to ask Ipv4 for the number of interfaces attached to this 
-// node. This isn't necessarily equal to the number of links to adjacent 
-// nodes (other routers); the number of interfaces may include interfaces
-// connected to stub networks (e.g., ethernets, etc.).  So we have to walk
-// through the list of net devices and see if they are directly connected
-// to another router.
+// We need to ask the node for the number of net devices attached. This isn't
+// necessarily equal to the number of links to adjacent nodes (other routers)
+// as the number of devices may include those for stub networks (e.g., 
+// ethernets, etc.).  So we have to walk through the list of net devices and
+// pay attention to those that are directly connected to another router through
+// a point-to-point channel.
 //
-// We'll start out at the maximum possible number of LSAs and reduce that
-// number if we discover a link that's not actually connected to another
-// router.
-//
-  m_numLSAs = 0;
   uint32_t numDevices = m_node->GetNDevices();
   NS_DEBUG("StaticRouter::GetNumLSAs (): numDevices = " << numDevices);
 //
 // Loop through the devices looking for those connected to a point-to-point
-// channel.  These are the ones that are used to route packets.
+// channel.
 //
   for (uint32_t i = 0; i < numDevices; ++i)
     {
-      Ptr<NetDevice> nd = m_node->GetDevice(i);
+      Ptr<NetDevice> ndLocal = m_node->GetDevice(i);
 
-      if (!nd->IsPointToPoint ())
+      if (!ndLocal->IsPointToPoint ())
         {
           NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device");
           continue;
@@ -124,11 +220,11 @@
       NS_DEBUG("StaticRouter::GetNumLSAs (): Point-to-point device");
 //
 // Now, we have to find the Ipv4 interface whose netdevice is the one we 
-// just found.  This is the IP on the local side of the channel.  There is 
-// a function to do this used down in the guts of the stack, but its not 
+// just found.  This is still the IP on the local side of the channel.  There 
+// is a function to do this used down in the guts of the stack, but it's not 
 // exported so we had to whip up an equivalent.
 //
-      uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, nd);
+      uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
 //
 // Now that we have the Ipv4 interface index, we can get the address and mask
 // we need.
@@ -137,12 +233,12 @@
       Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
       NS_DEBUG("Working with local address " << addrLocal);
 //
-// Now, we're going to link to the remote net device on the other end of the
-// point-to-point channel we know we have.  This is where our adjacent router
-// (to use OSPF lingo) is running.  
+// 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 
+// router (to use OSPF lingo) is running.  
 //
-      Ptr<Channel> ch = nd->GetChannel();
-      Ptr<NetDevice> ndRemote = GetAdjacent(nd, ch);
+      Ptr<Channel> ch = ndLocal->GetChannel();
+      Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
 //
 // The adjacent net device is aggregated to a node.  We need to ask that net 
 // device for its node, then ask that node for its Ipv4 interface.
@@ -151,6 +247,15 @@
       Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
       NS_ASSERT_MSG(ipv4Remote, "QI for remote <Ipv4> interface failed");
 //
+// Per the OSPF spec, we're going to need the remote router ID, so we might as
+// well get it now.
+//
+      Ptr<StaticRouter> srRemote = 
+        nodeRemote->QueryInterface<StaticRouter> (StaticRouter::iid);
+      NS_ASSERT_MSG(srRemote, "QI for remote <StaticRouter> failed");
+      Ipv4Address rtrIdRemote = srRemote->GetRouterId();
+      NS_DEBUG("Working with remote router " << rtrIdRemote);
+//
 // Now, just like we did above, we need to get the IP interface index for the 
 // net device on the other end of the point-to-point channel.
 //
@@ -162,15 +267,51 @@
       Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
       Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
       NS_DEBUG("Working with remote address " << addrRemote);
-      ++m_numLSAs;
+//
+// Now we can fill out the link state advertisement for this link.
+//
+      StaticRouterLSA *pLSA = new StaticRouterLSA;
+      pLSA->m_linkStateId = m_routerId;
+      pLSA->m_advertisingRtr = m_routerId;
+
+      StaticRouterLinkRecord *plr = new StaticRouterLinkRecord;
+      plr->m_linkType = StaticRouterLinkRecord::PointToPoint;
+      plr->m_linkId = rtrIdRemote;
+      plr->m_linkData = addrLocal;
+      pLSA->AddLinkRecord(plr);
+      plr = 0;
+
+      plr = new StaticRouterLinkRecord;
+      plr->m_linkType = StaticRouterLinkRecord::StubNetwork;
+      plr->m_linkId = addrRemote;
+      plr->m_linkData.Set(maskRemote.GetHostOrder());  // Frown
+      pLSA->AddLinkRecord(plr);
+      plr = 0;
+
+      m_LSAs.push_back (pLSA);
+      NS_DEBUG(*pLSA);
     }
 
-  return m_numLSAs;
+  return m_LSAs.size ();
 }
 
   bool
 StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa)
 {
+  NS_ASSERT_MSG(lsa.IsEmpty(), "Must pass empty LSA");
+
+  ListOfLSAs_t::iterator i = m_LSAs.begin ();
+  uint32_t j = 0;
+
+  for (; i != m_LSAs.end (); i++, j++)
+    {
+      if (j == n)
+        {
+          StaticRouterLSA *p = *i;
+          lsa = *p;
+          return true;
+        }
+    }
   return false;
 }
 
--- a/src/routing/static-router.h	Mon Jul 09 23:07:51 2007 -0700
+++ b/src/routing/static-router.h	Tue Jul 10 01:28:19 2007 -0700
@@ -23,6 +23,7 @@
 #include "ns3/node.h"
 #include "ns3/channel.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/routing-environment.h"
 
 namespace ns3 {
 
@@ -70,17 +71,26 @@
 {
 public:
   StaticRouterLSA();
+  StaticRouterLSA (StaticRouterLSA& lsa);
   ~StaticRouterLSA();
 
+  StaticRouterLSA& operator= (StaticRouterLSA lsa);
+
   uint32_t AddLinkRecord (StaticRouterLinkRecord* lr);
+  void ClearLinkRecords(void);
+  bool IsEmpty(void);
 
-  Ipv4Address  m_linkStateId;     // set to the NodeId
-  Ipv4Address  m_advertisingRtr;  // set to the NodeId
+  void Print (std::ostream &os);
+
+  Ipv4Address  m_linkStateId;
+  Ipv4Address  m_advertisingRtr;
 
   typedef std::list<StaticRouterLinkRecord*> ListOfLinkRecords_t;
   ListOfLinkRecords_t m_linkRecords;
 };
 
+std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa);
+
 /**
  * \brief An interface aggregated to a node to provide static routing info
  *
@@ -96,18 +106,24 @@
   static const InterfaceId iid;
   StaticRouter (Ptr<Node> node);
 
+  Ipv4Address GetRouterId(void);
   uint32_t GetNumLSAs (void);
   bool GetLSA (uint32_t n, StaticRouterLSA &lsa);
 
 protected:
   virtual ~StaticRouter ();
-
-  Ptr<Node>     m_node;
-  uint32_t      m_numLSAs;
+  void ClearLSAs (void);
 
   Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch);
   uint32_t FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd);
 
+  Ptr<Node>     m_node;
+
+  typedef std::list<StaticRouterLSA*> ListOfLSAs_t;
+  ListOfLSAs_t m_LSAs;
+
+  Ipv4Address m_routerId;
+
 private:
 };