implement SPFIntraAddRouter
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "ns3/fatal-error.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/node-list.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "static-router.h"
|
||||
#include "static-route-manager.h"
|
||||
#include "candidate-queue.h"
|
||||
@@ -352,6 +353,10 @@ StaticRouteManager::SPFNexthopCalculation (
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Figure out which interface that the node represented by v will want to use
|
||||
// to send packets to the node represented by w over the link represented by l
|
||||
//
|
||||
uint32_t
|
||||
StaticRouteManager::FindOutgoingInterface (
|
||||
SPFVertex* v,
|
||||
@@ -359,6 +364,12 @@ StaticRouteManager::FindOutgoingInterface (
|
||||
StaticRouterLinkRecord* l
|
||||
)
|
||||
{
|
||||
NS_ASSERT_MSG(v == m_spfroot,
|
||||
"StaticRouterManager""FindOutgoingInterface (): "
|
||||
"The node of interest must be the root node");
|
||||
|
||||
// want interface that v uses to send packets
|
||||
|
||||
// Using the Ipv4 public APIs of a node, find the outgoing
|
||||
// interface ID corresponding to the link l between vertex v and w
|
||||
// where v is the root of the tree
|
||||
@@ -444,7 +455,6 @@ StaticRouteManager::SPFCalculate(Ipv4Address root)
|
||||
void
|
||||
StaticRouteManager::SPFIntraAddRouter(SPFVertex* v)
|
||||
{
|
||||
|
||||
// This vertex has just been added to the SPF tree
|
||||
// - the vertex should have a valid m_root_oid corresponding
|
||||
// to the outgoing interface on the root router of the tree
|
||||
@@ -460,6 +470,75 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v)
|
||||
// i.e. Query Interface for the IPv4-route interface
|
||||
// ii) for each point-to-point link in v->m_lsa
|
||||
// ipv4-route::AddHostRouteTo(m_linkData, m_root_oid);
|
||||
|
||||
NS_ASSERT_MSG(m_spfroot,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): Root pointer not set");
|
||||
|
||||
Ipv4Address routerId = m_spfroot->m_vertexId;
|
||||
|
||||
std::vector<Ptr<Node> >::iterator i = NodeList::Begin();
|
||||
for (; i != NodeList::End(); i++)
|
||||
{
|
||||
Ptr<Node> node = *i;
|
||||
|
||||
Ptr<StaticRouter> rtr =
|
||||
node->QueryInterface<StaticRouter> (StaticRouter::iid);
|
||||
NS_ASSERT_MSG(rtr,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"QI for <StaticRouter> interface failed");
|
||||
|
||||
if (rtr->GetRouterId () == routerId)
|
||||
{
|
||||
NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"setting routes for node " << node->GetId ());
|
||||
|
||||
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT_MSG(ipv4,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"QI for <Ipv4> interface failed");
|
||||
|
||||
StaticRouterLSA *lsa = v->m_lsa;
|
||||
NS_ASSERT_MSG(lsa,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"Expected valid LSA in SPFVertex* v");
|
||||
|
||||
uint32_t nLinkRecords = lsa->GetNLinkRecords ();
|
||||
|
||||
NS_ASSERT_MSG((nLinkRecords & 1) == 0,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"Expected exen number of Link Records");
|
||||
|
||||
for (uint32_t j = 0; j < nLinkRecords; j += 2)
|
||||
{
|
||||
StaticRouterLinkRecord *lrp2p = lsa->GetLinkRecord (j);
|
||||
NS_ASSERT_MSG(
|
||||
lrp2p->m_linkType == StaticRouterLinkRecord::PointToPoint,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"Expected PointToPoint Link Record");
|
||||
|
||||
StaticRouterLinkRecord *lrstub = lsa->GetLinkRecord (j + 1);
|
||||
NS_ASSERT_MSG(
|
||||
lrstub->m_linkType == StaticRouterLinkRecord::StubNetwork,
|
||||
"StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"Expected StubNetwork Link Record");
|
||||
//
|
||||
// BUGBUG
|
||||
//
|
||||
// Where does the next hop address come from?
|
||||
//
|
||||
NS_ASSERT_MSG(false, "BUGBUG");
|
||||
|
||||
NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): "
|
||||
"Add route to " << lrp2p->m_linkData <<
|
||||
" using next hop " << lrp2p->m_linkData <<
|
||||
" via interface " << v->m_root_oif);
|
||||
|
||||
ipv4->AddHostRouteTo(lrp2p->m_linkData, lrp2p->m_linkData,
|
||||
v->m_root_oif);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a vertex to the list of children in each of its parents.
|
||||
@@ -529,21 +608,21 @@ StaticRouteManagerTest::RunTests (void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
CandidateQueue candidate; // <----------------
|
||||
CandidateQueue candidate;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
SPFVertex *v = new SPFVertex;
|
||||
v->m_distanceFromRoot = rand () % 100;
|
||||
candidate.Push (v); // <----------------
|
||||
candidate.Push (v);
|
||||
}
|
||||
|
||||
uint32_t lastDistance = 0;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
SPFVertex *v = candidate.Top (); // <----------------
|
||||
candidate.Pop (); // <----------------
|
||||
SPFVertex *v = candidate.Top ();
|
||||
candidate.Pop ();
|
||||
if (v->m_distanceFromRoot < lastDistance)
|
||||
{
|
||||
ok = false;
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
VertexNetwork
|
||||
} m_vertexType;
|
||||
|
||||
Ipv4Address m_vertexId;
|
||||
Ipv4Address m_vertexId; // router id
|
||||
|
||||
StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa)
|
||||
: m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr),
|
||||
m_stat(lsa.m_stat)
|
||||
{
|
||||
NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty in its constructor!");
|
||||
NS_ASSERT_MSG(IsEmpty(),
|
||||
"StaticRouterLSA::StaticRouterLSA (): Non-empty LSA in constructor");
|
||||
CopyLinkRecords (lsa);
|
||||
}
|
||||
|
||||
@@ -105,6 +106,30 @@ StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr)
|
||||
return m_linkRecords.size ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
StaticRouterLSA::GetNLinkRecords (void)
|
||||
{
|
||||
return m_linkRecords.size ();
|
||||
}
|
||||
|
||||
StaticRouterLinkRecord *
|
||||
StaticRouterLSA::GetLinkRecord (uint32_t n)
|
||||
{
|
||||
uint32_t j = 0;
|
||||
for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
|
||||
i != m_linkRecords.end ();
|
||||
i++, j++)
|
||||
{
|
||||
if (j == n)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
NS_ASSERT_MSG(false, "StaticRouterLSA::GetLinkRecord (): invalid index");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StaticRouterLSA::IsEmpty (void)
|
||||
{
|
||||
@@ -186,7 +211,9 @@ StaticRouter::GetRouterId (void)
|
||||
StaticRouter::DiscoverLSAs (void)
|
||||
{
|
||||
NS_DEBUG("StaticRouter::DiscoverLSAs ()");
|
||||
NS_ASSERT_MSG(m_node, "<Node> interface not set");
|
||||
NS_ASSERT_MSG(m_node,
|
||||
"StaticRouter::DiscoverLSAs (): <Node> interface not set");
|
||||
|
||||
ClearLSAs ();
|
||||
//
|
||||
// We're aggregated to a node. We need to ask the node for a pointer to its
|
||||
@@ -194,7 +221,8 @@ StaticRouter::DiscoverLSAs (void)
|
||||
// interfaces lives.
|
||||
//
|
||||
Ptr<Ipv4> ipv4Local = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT_MSG(ipv4Local, "QI for <Ipv4> interface failed");
|
||||
NS_ASSERT_MSG(ipv4Local,
|
||||
"StaticRouter::DiscoverLSAs (): QI for <Ipv4> interface failed");
|
||||
//
|
||||
// We are, for now at least, only going to report RouterLSAs in this method.
|
||||
// What this means is that there is going to be one advertisement with some
|
||||
@@ -257,14 +285,16 @@ StaticRouter::DiscoverLSAs (void)
|
||||
//
|
||||
Ptr<Node> nodeRemote = ndRemote->GetNode();
|
||||
Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT_MSG(ipv4Remote, "QI for remote <Ipv4> interface failed");
|
||||
NS_ASSERT_MSG(ipv4Remote,
|
||||
"StaticRouter::DiscoverLSAs (): QI for remote <Ipv4> 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");
|
||||
NS_ASSERT_MSG(srRemote,
|
||||
"StaticRouter::DiscoverLSAs (): QI for remote <StaticRouter> failed");
|
||||
Ipv4Address rtrIdRemote = srRemote->GetRouterId();
|
||||
NS_DEBUG("Working with remote router " << rtrIdRemote);
|
||||
//
|
||||
@@ -319,7 +349,7 @@ StaticRouter::GetNumLSAs (void)
|
||||
bool
|
||||
StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa)
|
||||
{
|
||||
NS_ASSERT_MSG(lsa.IsEmpty(), "Must pass empty LSA");
|
||||
NS_ASSERT_MSG(lsa.IsEmpty(), "StaticRouter::GetLSA (): Must pass empty LSA");
|
||||
//
|
||||
// All of the work was done in GetNumLSAs. All we have to do here is to
|
||||
// walk the list of link state advertisements created there and return the
|
||||
@@ -355,7 +385,7 @@ StaticRouter::GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch)
|
||||
|
||||
uint32_t nDevices = ch->GetNDevices();
|
||||
NS_ASSERT_MSG(nDevices == 2,
|
||||
"Point to point channel with other than two devices is not expected");
|
||||
"StaticRouter::GetAdjacent (): Channel with other than two devices");
|
||||
//
|
||||
// This is a point to point channel with two endpoints. Get both of them.
|
||||
//
|
||||
@@ -376,8 +406,8 @@ StaticRouter::GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch)
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT_MSG(0,
|
||||
"Neither channel endpoint thinks it is connected to this net device");
|
||||
NS_ASSERT_MSG(false,
|
||||
"StaticRouter::GetAdjacent (): Wrong or confused channel?");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,13 +125,25 @@ public:
|
||||
*/
|
||||
void CopyLinkRecords (StaticRouterLSA& lsa);
|
||||
/**
|
||||
* Add a given Static Router Link Record to a given Static Router Link
|
||||
* State Advertisement.
|
||||
* Add a given Static Router Link Record to the LSA.
|
||||
*
|
||||
* @param lr The Static Router Link Record to be added.
|
||||
* @returns The number of link records in the list.
|
||||
*/
|
||||
uint32_t AddLinkRecord (StaticRouterLinkRecord* lr);
|
||||
/**
|
||||
* Return the number of Static Router Link Records in the LSA.
|
||||
*
|
||||
* @returns The number of link records in the list.
|
||||
*/
|
||||
uint32_t GetNLinkRecords (void);
|
||||
/**
|
||||
* Return a pointer to the specified Static Router Link Record.
|
||||
*
|
||||
* @param n The LSA number desired.
|
||||
* @returns The number of link records in the list.
|
||||
*/
|
||||
StaticRouterLinkRecord* GetLinkRecord (uint32_t n);
|
||||
/**
|
||||
* Release all of the Static Router Link Records present in the Static
|
||||
* Router Link State Advertisement and make the list of link records empty.
|
||||
|
||||
Reference in New Issue
Block a user