--- 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:
};