branch merge

This commit is contained in:
Craig Dowell
2007-08-12 22:43:25 -07:00
7 changed files with 1200 additions and 374 deletions

View File

@@ -0,0 +1,199 @@
/* -*- 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
*
*/
// This script exercises global routing code in a mixed point-to-point
// and csma/cd environment
//
// Network topology
//
// n0
// \ p-p
// \ (shared csma/cd)
// n2 -------------------------n3
// / | |
// / p-p n4 n5 ---------- n6
// n1 p-p
//
// - CBR/UDP flows from n0 to n6
// - Tracing of queues and packet receptions to file "mixed-global-routing.tr"
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/debug.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/csma-channel.h"
#include "ns3/csma-net-device.h"
#include "ns3/csma-topology.h"
#include "ns3/csma-ipv4-topology.h"
#include "ns3/eui48-address.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/global-route-manager.h"
using namespace ns3;
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
DebugComponentEnable ("Object");
DebugComponentEnable ("Queue");
DebugComponentEnable ("DropTailQueue");
DebugComponentEnable ("Channel");
DebugComponentEnable ("PointToPointChannel");
DebugComponentEnable ("PointToPointNetDevice");
DebugComponentEnable ("GlobalRouter");
DebugComponentEnable ("GlobalRouteManager");
#endif
// Set up some default values for the simulation. Use the Bind ()
// technique to tell the system what subclass of Queue to use,
// and what the queue limit is
// The below DefaultValue::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", "448kb/s");
//DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);
// Allow the user to override any of the defaults and the above
// Bind ()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
Ptr<Node> n3 = Create<InternetNode> ();
Ptr<Node> n4 = Create<InternetNode> ();
Ptr<Node> n5 = Create<InternetNode> ();
Ptr<Node> n6 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
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 (
n5, n6, DataRate (1500000), MilliSeconds (10));
// We create the channels first without any IP addressing information
Ptr<CsmaChannel> channelc0 =
CsmaTopology::CreateCsmaChannel(
DataRate(5000000), MilliSeconds(2));
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0,
Eui48Address("10:54:23:54:23:50"));
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0,
Eui48Address("10:54:23:54:23:51"));
uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0,
Eui48Address("10:54:23:54:23:52"));
uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0,
Eui48Address("10:54:23:54:23:53"));
// Later, we add IP addresses.
PointToPointTopology::AddIpv4Addresses (
channel0, n0, Ipv4Address ("10.1.1.1"),
n2, Ipv4Address ("10.1.1.2"));
PointToPointTopology::AddIpv4Addresses (
channel1, n1, Ipv4Address ("10.1.2.1"),
n2, Ipv4Address ("10.1.2.2"));
PointToPointTopology::AddIpv4Addresses (
channel2, n5, Ipv4Address ("10.1.3.1"),
n6, Ipv4Address ("10.1.3.2"));
CsmaIpv4Topology::AddIpv4Address (
n2, n2ifIndex, Ipv4Address("10.250.1.1"), Ipv4Mask("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n3, n3ifIndex, Ipv4Address("10.250.1.2"), Ipv4Mask("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n4, n4ifIndex, Ipv4Address("10.250.1.3"), Ipv4Mask("255.255.255.0"));
CsmaIpv4Topology::AddIpv4Address (
n5, n5ifIndex, Ipv4Address("10.250.1.4"), Ipv4Mask("255.255.255.0"));
// 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 of size
// 210 bytes at a rate of 448 Kb/s
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
InetSocketAddress ("10.1.3.2", 80),
"Udp",
ConstantVariable (1),
ConstantVariable (0),
DataRate("300bps"),
50);
// Start the application
ooff->Start (Seconds (1.0));
ooff->Stop (Seconds (10.0));
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-global-routing.tr file
AsciiTrace asciitrace ("mixed-global-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 ("mixed-global-routing.pcap");
pcaptrace.TraceAllIp ();
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -22,3 +22,6 @@ def build(bld):
['csma', 'internet-node'])
obj.source = 'csma-multicast.cc'
obj = bld.create_ns3_program( 'mixed-global-routing',
['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
obj.source = 'mixed-global-routing.cc'

View File

@@ -133,7 +133,6 @@ CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
SetSendEnable (sendEnable);
SetReceiveEnable (receiveEnable);

View File

@@ -48,8 +48,7 @@ SPFVertex::SPFVertex () :
{
}
SPFVertex::SPFVertex (GlobalRouterLSA* lsa) :
m_vertexType (VertexRouter),
SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) :
m_vertexId (lsa->GetLinkStateId ()),
m_lsa (lsa),
m_distanceFromRoot (SPF_INFINITY),
@@ -58,6 +57,16 @@ SPFVertex::SPFVertex (GlobalRouterLSA* lsa) :
m_parent (0),
m_children ()
{
if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA)
{
NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexRouter");
m_vertexType = SPFVertex::VertexRouter;
}
else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA)
{
NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexNetwork");
m_vertexType = SPFVertex::VertexNetwork;
}
}
SPFVertex::~SPFVertex ()
@@ -99,12 +108,12 @@ SPFVertex::GetVertexId (void) const
}
void
SPFVertex::SetLSA (GlobalRouterLSA* lsa)
SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
{
m_lsa = lsa;
}
GlobalRouterLSA*
GlobalRoutingLSA*
SPFVertex::GetLSA (void) const
{
return m_lsa;
@@ -210,7 +219,7 @@ GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
for (i= m_database.begin (); i!= m_database.end (); i++)
{
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA");
GlobalRouterLSA* temp = i->second;
GlobalRoutingLSA* temp = i->second;
delete temp;
}
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB (): clear map");
@@ -225,19 +234,19 @@ GlobalRouteManagerLSDB::Initialize ()
LSDBMap_t::iterator i;
for (i= m_database.begin (); i!= m_database.end (); i++)
{
GlobalRouterLSA* temp = i->second;
temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
GlobalRoutingLSA* temp = i->second;
temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
}
}
void
GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa)
GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
{
NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()");
m_database.insert (LSDBPair_t (addr, lsa));
}
GlobalRouterLSA*
GlobalRoutingLSA*
GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
{
NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()");
@@ -255,6 +264,31 @@ GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
return 0;
}
GlobalRoutingLSA*
GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
{
NS_DEBUG ("GlobalRouteManagerLSDB::GetLSAByLinkData ()");
//
// Look up an LSA by its address.
//
LSDBMap_t::const_iterator i;
for (i= m_database.begin (); i!= m_database.end (); i++)
{
GlobalRoutingLSA* temp = i->second;
// Iterate among temp's Link Records
for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
{
GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
lr->GetLinkData () == addr)
{
return temp;
}
}
}
return 0;
}
// ---------------------------------------------------------------------------
//
// GlobalRouteManagerImpl Implementation
@@ -359,13 +393,12 @@ GlobalRouteManagerImpl::BuildGlobalRoutingDatabase ()
for (uint32_t j = 0; j < numLSAs; ++j)
{
GlobalRouterLSA* lsa = new GlobalRouterLSA ();
GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
//
// This is the call to actually fetch a Link State Advertisement from the
// router.
//
rtr->GetLSA (j, *lsa);
NS_DEBUG ("LSA " << j);
NS_DEBUG (*lsa);
//
// Write the newly discovered link state advertisement to the database.
@@ -453,52 +486,86 @@ GlobalRouteManagerImpl::InitializeRoutes ()
GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
{
SPFVertex* w = 0;
GlobalRouterLSA* w_lsa = 0;
GlobalRoutingLSA* w_lsa = 0;
GlobalRoutingLinkRecord *l = 0;
uint32_t distance = 0;
uint32_t numRecordsInVertex = 0;
NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()");
//
// Always true for now, since all our LSAs are RouterLSAs.
//
if (v->GetVertexType () == SPFVertex::VertexRouter)
// V points to a Router-LSA or Network-LSA
// Loop over the links in router LSA or attached routers in Network LSA
if (v->GetVertexType () == SPFVertex::VertexRouter)
{
if (true)
numRecordsInVertex = v->GetLSA ()->GetNLinkRecords ();
}
if (v->GetVertexType () == SPFVertex::VertexNetwork)
{
numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters ();
}
for (uint32_t i = 0; i < numRecordsInVertex; i++)
{
// Get w_lsa: In case of V is Router-LSA
if (v->GetVertexType () == SPFVertex::VertexRouter)
{
NS_DEBUG ("SPFNext: Examining " << v->GetVertexId () << "'s " <<
v->GetLSA ()->GetNLinkRecords () << " link records");
//
// Walk the list of link records in the link state advertisement associated
// with the "current" router (represented by vertex <v>).
//
for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
{
//
// (a) If this is a link to a stub network, examine the next link in V's LSA.
// Links to stub networks will be considered in the second stage of the
// shortest path calculation.
//
GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork)
{
NS_DEBUG ("SPFNext: Found a Stub record to " <<
l->GetLinkId ());
continue;
}
l = v->GetLSA ()->GetLinkRecord (i);
if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
{
NS_DEBUG ("SPFNext: Found a Stub record to " <<
l->GetLinkId ());
continue;
}
//
// (b) Otherwise, W is a transit vertex (router or transit network). Look up
// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
// database.
//
if (l->GetLinkType () == GlobalRouterLinkRecord::PointToPoint)
{
if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
{
//
// Lookup the link state advertisement of the new link -- we call it <w> in
// the link state database.
//
w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
NS_ASSERT (w_lsa);
NS_DEBUG ("SPFNext: Found a P2P record from " <<
v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
NS_ASSERT (w_lsa);
NS_DEBUG ("SPFNext: Found a P2P record from " <<
v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
}
else if (l->GetLinkType () ==
GlobalRoutingLinkRecord::TransitNetwork)
{
w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
NS_ASSERT (w_lsa);
NS_DEBUG ("SPFNext: Found a Transit record from " <<
v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
}
else
{
NS_ASSERT_MSG (0, "illegal Link Type");
}
}
// Get w_lsa: In case of V is Network-LSA
if (v->GetVertexType () == SPFVertex::VertexNetwork)
{
w_lsa = m_lsdb->GetLSAByLinkData
(v->GetLSA ()->GetAttachedRouter (i));
if (!w_lsa)
{
continue;
}
NS_DEBUG ("SPFNext: Found a Network LSA from " <<
v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
}
// Note: w_lsa at this point may be either RouterLSA or NetworkLSA
//
// (c) If vertex W is already on the shortest-path tree, examine the next
// link in the LSA.
@@ -506,57 +573,56 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
// If the link is to a router that is already in the shortest path first tree
// then we have it covered -- ignore it.
//
if (w_lsa->GetStatus () ==
GlobalRouterLSA::LSA_SPF_IN_SPFTREE)
{
NS_DEBUG ("SPFNext: Skipping-> LSA "<<
w_lsa->GetLinkStateId () << " already in SPF tree");
continue;
}
//
// The link is to a router we haven't dealt with yet.
if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE)
{
NS_DEBUG ("SPFNext: Skipping-> LSA "<<
w_lsa->GetLinkStateId () << " already in SPF tree");
continue;
}
//
// (d) Calculate the link state cost D of the resulting path from the root to
// vertex W. D is equal to the sum of the link state cost of the (already
// calculated) shortest path to vertex V and the advertised cost of the link
// between vertices V and W.
//
distance = v->GetDistanceFromRoot () + l->GetMetric ();
if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
{
distance = v->GetDistanceFromRoot () + l->GetMetric ();
}
else
{
distance = v->GetDistanceFromRoot ();
}
NS_DEBUG ("SPFNext: Considering w_lsa " <<
w_lsa->GetLinkStateId ());
NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
if (w_lsa->GetStatus () ==
GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
{
//
// If we haven't yet considered the link represented by <w> we have to create
// a new SPFVertex to represent it.
//
w = new SPFVertex (w_lsa);
//
// Is there already vertex w in candidate list?
if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
{
// prepare vertex w
w = new SPFVertex (w_lsa);
// Calculate nexthop to w
// We need to figure out how to actually get to the new router represented
// by <w>. This will (among other things) find the next hop address to send
// packets destined for this network to, and also find the outbound interface
// used to forward the packets.
//
if (SPFNexthopCalculation (v, w, l, distance))
{
w_lsa->SetStatus (
GlobalRouterLSA::LSA_SPF_CANDIDATE);
if (SPFNexthopCalculation (v, w, l, distance))
{
w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
//
// Push this new vertex onto the priority queue (ordered by distance from the
// root node).
//
candidate.Push (w);
NS_DEBUG ("SPFNext: Pushing " <<
w->GetVertexId () << ", parent vertexId: " <<
v->GetVertexId ());
}
}
} else if (w_lsa->GetStatus () ==
GlobalRouterLSA::LSA_SPF_CANDIDATE)
{
candidate.Push (w);
NS_DEBUG ("SPFNext: Pushing " <<
w->GetVertexId () << ", parent vertexId: " <<
v->GetVertexId ());
}
}
else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
{
//
// We have already considered the link represented by <w>. What wse have to
// do now is to decide if this new router represents a route with a shorter
@@ -564,23 +630,23 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
//
// So, locate the vertex in the candidate queue and take a look at the
// distance.
w = candidate.Find (w_lsa->GetLinkStateId ());
if (w->GetDistanceFromRoot () < distance)
{
w = candidate.Find (w_lsa->GetLinkStateId ());
if (w->GetDistanceFromRoot () < distance)
{
//
// This is not a shorter path, so don't do anything.
//
continue;
}
else if (w->GetDistanceFromRoot () == distance)
{
continue;
}
else if (w->GetDistanceFromRoot () == distance)
{
//
// This path is one with an equal cost. Do nothing for now -- we're not doing
// equal-cost multipath cases yet.
//
}
else
{
}
else
{
//
// this path represents a new, lower-cost path to <w> (the vertex we found in
// the current link record of the link state advertisement of the current root
@@ -589,27 +655,26 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
// it will call spf_add_parents, which will flush the old parents
//
if (SPFNexthopCalculation (v, w, l, distance))
{
if (SPFNexthopCalculation (v, w, l, distance))
{
//
// If we've changed the cost to get to the vertex represented by <w>, we
// must reorder the priority queue keyed to that cost.
//
candidate.Reorder ();
}
}
} // point-to-point
} // for loop
}
}
candidate.Reorder ();
}
} // new lower cost path found
} // end W is already on the candidate list
} // end loop over the links in V's LSA
}
//
// This method is derived from quagga ospf_next_hop_calculation() 16.1.1.
//
// Calculate the next hop IP address and the outgoing interface required to
// get packets from the root through <v> (parent) to vertex <w> (destination),
// over a given distance.
// Calculate nexthop from root through V (parent) to vertex W (destination)
// with given distance from root->W.
//
// As appropriate, set w's parent, distance, and nexthop information
//
// For now, this is greatly simplified from the quagga code
//
@@ -617,10 +682,19 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
GlobalRouteManagerImpl::SPFNexthopCalculation (
SPFVertex* v,
SPFVertex* w,
GlobalRouterLinkRecord* l,
GlobalRoutingLinkRecord* l,
uint32_t distance)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()");
// If w is a NetworkVertex, l should be null
/*
if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
{
NS_ASSERT_MSG(0, "Error: SPFNexthopCalculation parameter problem");
}
*/
//
// The vertex m_spfroot is a distinguished vertex representing the node at
// the root of the calculations. That is, it is the node for which we are
@@ -669,7 +743,8 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
// return the link record describing the link from <w> to <v>. Think of it as
// SPFGetLink.
//
GlobalRouterLinkRecord *linkRemote = 0;
NS_ASSERT(l);
GlobalRoutingLinkRecord *linkRemote = 0;
linkRemote = SPFGetNextLink (w, v, linkRemote);
//
// At this point, <l> is the Global Router Link Record describing the point-
@@ -695,6 +770,56 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
v->GetVertexId () << " to " << w->GetVertexId () <<
" goes through next hop " << w->GetNextHop () <<
" via outgoing interface " << w->GetOutgoingInterfaceId ());
} // end W is a router vertes
else
{
NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
// W is a directly connected network; no next hop is required
GlobalRoutingLSA* w_lsa = w->GetLSA ();
NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
// Find outgoing interface ID for this network
w->SetOutgoingInterfaceId (
FindOutgoingInterfaceId (w_lsa->GetLinkStateId (),
w_lsa->GetNetworkLSANetworkMask () ));
w->SetDistanceFromRoot (distance);
w->SetParent (v);
NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
v->GetVertexId () << " to network " << w->GetVertexId () <<
" via outgoing interface " << w->GetOutgoingInterfaceId ());
return 1;
}
} // end v is the root
else if (v->GetVertexType () == SPFVertex::VertexNetwork)
{
// See if any of v's parents are the root
if (v->GetParent () == m_spfroot)
{
// 16.1.1 para 5. ...the parent vertex is a network that
// directly connects the calculating router to the destination
// router. The list of next hops is then determined by
// examining the destination's router-LSA...
NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
GlobalRoutingLinkRecord *linkRemote = 0;
while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
{
/* ...For each link in the router-LSA that points back to the
* parent network, the link's Link Data field provides the IP
* address of a next hop router. The outgoing interface to
* use can then be derived from the next hop IP address (or
* it can be inherited from the parent network).
*/
w->SetNextHop(linkRemote->GetLinkData ());
w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
v->GetVertexId () << " to " << w->GetVertexId () <<
" goes through next hop " << w->GetNextHop () <<
" via outgoing interface " << w->GetOutgoingInterfaceId ());
}
}
else
{
w->SetNextHop (v->GetNextHop ());
w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
}
}
else
@@ -736,19 +861,17 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
// to <w>. If prev_link is not NULL, we return a Global Router Link Record
// representing a possible *second* link from <v> to <w>.
//
// BUGBUG FIXME: This seems to be a bug. Shouldn't this function look for
// any link records after pre_link and not just after the first?
//
GlobalRouterLinkRecord*
GlobalRoutingLinkRecord*
GlobalRouteManagerImpl::SPFGetNextLink (
SPFVertex* v,
SPFVertex* w,
GlobalRouterLinkRecord* prev_link)
GlobalRoutingLinkRecord* prev_link)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()");
bool skip = true;
GlobalRouterLinkRecord* l;
bool found_prev_link = false;
GlobalRoutingLinkRecord* l;
//
// If prev_link is 0, we are really looking for the first link, not the next
// link.
@@ -756,6 +879,7 @@ GlobalRouteManagerImpl::SPFGetNextLink (
if (prev_link == 0)
{
skip = false;
found_prev_link = true;
}
//
// Iterate through the Global Router Link Records advertised by the vertex
@@ -765,10 +889,6 @@ GlobalRouteManagerImpl::SPFGetNextLink (
for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
{
l = v->GetLSA ()->GetLinkRecord (i);
if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
{
continue;
}
//
// The link ID of a link record representing a point-to-point link is set to
// the router ID of the neighboring router -- the router to which the link
@@ -777,8 +897,16 @@ GlobalRouteManagerImpl::SPFGetNextLink (
// We're just checking to see if the link <l> is actually the link from <v> to
// <w>.
//
if (l->GetLinkId () == w->GetVertexId ()) {
NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
if (l->GetLinkId () == w->GetVertexId ())
{
if (!found_prev_link)
{
NS_DEBUG ("SPFGetNextLink: Skipping links before prev_link found");
found_prev_link = true;
continue;
}
NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
l->GetLinkId () << " linkData = " << l->GetLinkData ());
//
// If skip is false, don't (not too surprisingly) skip the link found -- it's
@@ -849,7 +977,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
//
m_spfroot= v;
v->SetDistanceFromRoot (0);
v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
for (;;)
{
@@ -894,7 +1022,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
// Update the status field of the vertex to indicate that it is in the SPF
// tree.
//
v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
//
// The current vertex has a parent pointer. By calling this rather oddly
// named method (blame quagga) we add the current vertex to the list of
@@ -932,7 +1060,18 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
// through its point-to-point links, adding a *host* route to the local IP
// address (at the <v> side) for each of those links.
//
SPFIntraAddRouter (v);
if (v->GetVertexType () == SPFVertex::VertexRouter)
{
SPFIntraAddRouter (v);
}
else if (v->GetVertexType () == SPFVertex::VertexNetwork)
{
SPFIntraAddTransit (v);
}
else
{
NS_ASSERT_MSG(0, "illegal SPFVertex type");
}
//
// RFC2328 16.1. (5).
//
@@ -1025,6 +1164,80 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a)
return 0;
}
//
// XXX This should probably be a method on Ipv4
//
// Return the interface index corresponding to a given IP address
//
uint32_t
GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
{
//
// We have an IP address <a> and a vertex ID of the root of the SPF tree.
// The question is what interface index does this address correspond to.
// The answer is a little complicated since we have to find a pointer to
// the node corresponding to the vertex ID, find the Ipv4 interface on that
// node in order to iterate the interfaces and find the one corresponding to
// the address in question.
//
Ipv4Address routerId = m_spfroot->GetVertexId ();
//
// Walk the list of nodes in the system looking for the one corresponding to
// the node at the root of the SPF tree. This is the node for which we are
// building the routing table.
//
std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
for (; i != NodeList::End (); i++)
{
Ptr<Node> node = *i;
Ptr<GlobalRouter> rtr =
node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
//
// If the node doesn't have a GlobalRouter interface it can't be the one
// we're interested in.
//
if (rtr == 0)
{
continue;
}
if (rtr->GetRouterId () == routerId)
{
//
// This is the node we're building the routing table for. We're going to need
// the Ipv4 interface to look for the ipv4 interface index. Since this node
// is participating in routing IP version 4 packets, it certainly must have
// an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT_MSG (ipv4,
"GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
"QI for <Ipv4> interface failed");
//
// Look through the interfaces on this node for one that has the IP address
// we're looking for. If we find one, return the corresponding interface
// index.
//
for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
{
if (ipv4->GetAddress (i).CombineMask(amask) ==
a.CombineMask(amask) )
{
NS_DEBUG (
"GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
"Interface match for " << a);
return i;
}
}
}
}
//
// Couldn't find it.
//
return 0;
}
//
// This method is derived from quagga ospf_intra_add_router ()
//
@@ -1109,7 +1322,7 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
GlobalRouterLSA *lsa = v->GetLSA ();
GlobalRoutingLSA *lsa = v->GetLSA ();
NS_ASSERT_MSG (lsa,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
@@ -1128,8 +1341,8 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
//
// We are only concerned about point-to-point links
//
GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j);
if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
{
continue;
}
@@ -1162,6 +1375,91 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
}
}
}
void
GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit ()");
NS_ASSERT_MSG (m_spfroot,
"GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
//
// The root of the Shortest Path First tree is the router to which we are
// going to write the actual routing table entries. The vertex corresponding
// to this router has a vertex ID which is the router ID of that node. We're
// going to use this ID to discover which node it is that we're actually going
// to update.
//
Ipv4Address routerId = m_spfroot->GetVertexId ();
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"Vertex ID = " << routerId);
//
// We need to walk the list of nodes looking for the one that has the router
// ID corresponding to the root vertex. This is the one we're going to write
// the routing information to.
//
std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
for (; i != NodeList::End (); i++)
{
Ptr<Node> node = *i;
//
// The router ID is accessible through the GlobalRouter interface, so we need
// to QI for that interface. If there's no GlobalRouter interface, the node
// in question cannot be the router we want, so we continue.
//
Ptr<GlobalRouter> rtr =
node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
if (rtr == 0)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"No GlobalRouter interface on node " << node->GetId ());
continue;
}
//
// If the router ID of the current node is equal to the router ID of the
// root of the SPF tree, then this node is the one for which we need to
// write the routing tables.
//
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"Considering router " << rtr->GetRouterId ());
if (rtr->GetRouterId () == routerId)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"setting routes for node " << node->GetId ());
//
// Routing information is updated using the Ipv4 interface. We need to QI
// for that interface. If the node is acting as an IP version 4 router, it
// should absolutely have an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT_MSG (ipv4,
"GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"QI for <Ipv4> interface failed");
//
// Get the Global Router Link State Advertisement from the vertex we're
// adding the routes to. The LSA will have a number of attached Global Router
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
GlobalRoutingLSA *lsa = v->GetLSA ();
NS_ASSERT_MSG (lsa,
"GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"Expected valid LSA in SPFVertex* v");
Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
Ipv4Address tempip = lsa->GetLinkStateId ();
tempip = tempip.CombineMask (tempmask);
ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
v->GetOutgoingInterfaceId ());
NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddNetwork (): "
" Node " << node->GetId () <<
" add network route to " << tempip <<
" using next hop " << v->GetNextHop () <<
" via interface " << v->GetOutgoingInterfaceId ());
}
}
}
// Derived from quagga ospf_vertex_add_parents ()
//
@@ -1275,81 +1573,81 @@ GlobalRouteManagerImplTest::RunTests (void)
// link2: 10.1.3.1/30, 10.1.3.2/30
//
// Router 0
GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2", // router ID 0.0.0.2
"10.1.1.1", // local ID
1); // metric
GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.1",
"255.255.255.252",
1);
GlobalRouterLSA* lsa0 = new GlobalRouterLSA ();
GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
lsa0->SetLinkStateId ("0.0.0.0");
lsa0->SetAdvertisingRouter ("0.0.0.0");
lsa0->AddLinkRecord (lr0);
lsa0->AddLinkRecord (lr1);
// Router 1
GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
GlobalRouterLSA* lsa1 = new GlobalRouterLSA ();
GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
lsa1->SetLinkStateId ("0.0.0.1");
lsa1->SetAdvertisingRouter ("0.0.0.1");
lsa1->AddLinkRecord (lr2);
lsa1->AddLinkRecord (lr3);
// Router 2
GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.0",
"10.1.1.2",
1);
GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.2",
"255.255.255.252",
1);
GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.1",
"10.1.2.2",
1);
GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.2",
"255.255.255.252",
1);
GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.3",
"10.1.3.2",
1);
GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.3.2",
"255.255.255.252",
1);
GlobalRouterLSA* lsa2 = new GlobalRouterLSA ();
GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
lsa2->SetLinkStateId ("0.0.0.2");
lsa2->SetAdvertisingRouter ("0.0.0.2");
lsa2->AddLinkRecord (lr4);
@@ -1360,19 +1658,19 @@ GlobalRouteManagerImplTest::RunTests (void)
lsa2->AddLinkRecord (lr9);
// Router 3
GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::PointToPoint,
GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord (
GlobalRouterLinkRecord::StubNetwork,
GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
GlobalRouterLSA* lsa3 = new GlobalRouterLSA ();
GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
lsa3->SetLinkStateId ("0.0.0.3");
lsa3->SetAdvertisingRouter ("0.0.0.3");
lsa3->AddLinkRecord (lr10);

View File

@@ -102,10 +102,10 @@ public:
*
* @see SPFVertex::SPFVertex ()
* @see VertexType
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @param lsa The Link State Advertisement used for finding initial values.
*/
SPFVertex(GlobalRouterLSA* lsa);
SPFVertex(GlobalRoutingLSA* lsa);
/**
* @brief Destroy an SPFVertex (Shortest Path First Vertex).
@@ -181,12 +181,12 @@ public:
* @internal
*
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see GlobalRouter::DiscoverLSAs ()
* @returns A pointer to the GlobalRouterLSA found by the router represented
* @returns A pointer to the GlobalRoutingLSA found by the router represented
* by this SPFVertex object.
*/
GlobalRouterLSA* GetLSA (void) const;
GlobalRoutingLSA* GetLSA (void) const;
/**
* @brief Set the Global Router Link State Advertisement returned by the
@@ -196,13 +196,13 @@ public:
*
* @see SPFVertex::GetLSA ()
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see GlobalRouter::DiscoverLSAs ()
* @warning Ownership of the LSA is transferred to the "this" SPFVertex. You
* must not delete the LSA after calling this method.
* @param lsa A pointer to the GlobalRouterLSA.
* @param lsa A pointer to the GlobalRoutingLSA.
*/
void SetLSA (GlobalRouterLSA* lsa);
void SetLSA (GlobalRoutingLSA* lsa);
/**
* @brief Get the distance from the root vertex to "this" SPFVertex object.
@@ -283,8 +283,8 @@ public:
* SPFVertex."
*
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRouterLinkRecord
* @see GlobalRoutingLSA
* @see GlobalRoutingLinkRecord
* @returns The interface index to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -325,8 +325,8 @@ public:
* by "this" SPFVertex.
*
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRouterLinkRecord
* @see GlobalRoutingLSA
* @see GlobalRoutingLinkRecord
* @param id The interface index to use when forwarding packets to the host or
* network represented by "this" SPFVertex.
*/
@@ -368,8 +368,8 @@ public:
* by 'this' SPFVertex."
*
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRouterLinkRecord
* @see GlobalRoutingLSA
* @see GlobalRoutingLinkRecord
* @returns The IP address to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -411,8 +411,8 @@ public:
* host represented by 'this' SPFVertex."
*
* @see GlobalRouter
* @see GlobalRouterLSA
* @see GlobalRouterLinkRecord
* @see GlobalRoutingLSA
* @see GlobalRoutingLinkRecord
* @param nextHop The IP address to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -543,7 +543,7 @@ public:
private:
VertexType m_vertexType;
Ipv4Address m_vertexId;
GlobalRouterLSA* m_lsa;
GlobalRoutingLSA* m_lsa;
uint32_t m_distanceFromRoot;
uint32_t m_rootOif;
Ipv4Address m_nextHop;
@@ -604,33 +604,47 @@ public:
* State Database.
* @internal
*
* The IPV4 address and the GlobalRouterLSA given as parameters are converted
* The IPV4 address and the GlobalRoutingLSA given as parameters are converted
* to an STL pair and are inserted into the database map.
*
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see Ipv4Address
* @param addr The IP address associated with the LSA. Typically the Router
* ID.
* @param lsa A pointer to the Link State Advertisement for the router.
*/
void Insert(Ipv4Address addr, GlobalRouterLSA* lsa);
void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
/**
* @brief Look up the Link State Advertisement associated with the given
* IP Address.
* link state ID (address).
* @internal
*
* The database map is searched for the given IPV4 address and corresponding
* GlobalRouterLSA is returned.
* GlobalRoutingLSA is returned.
*
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see Ipv4Address
* @param addr The IP address associated with the LSA. Typically the Router
* ID.
* @returns A pointer to the Link State Advertisement for the router specified
* by the IP address addr.
*/
GlobalRouterLSA* GetLSA (Ipv4Address addr) const;
GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
/**
* @brief Look up the Link State Advertisement associated with the given
* link state ID (address). This is a variation of the GetLSA call
* to allow the LSA to be found by matching addr with the LinkData field
* of the TransitNetwork link record.
* @internal
*
* @see GetLSA
* @param addr The IP address associated with the LSA. Typically the Router
* @returns A pointer to the Link State Advertisement for the router specified
* by the IP address addr.
* ID.
*/
GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
/**
* @brief Set all LSA flags to an initialized state, for SPF computation
@@ -641,14 +655,14 @@ public:
* prior to each SPF calculation to reset the state of the SPFVertex structures
* that will reference the LSAs during the calculation.
*
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see SPFVertex
*/
void Initialize ();
private:
typedef std::map<Ipv4Address, GlobalRouterLSA*> LSDBMap_t;
typedef std::pair<Ipv4Address, GlobalRouterLSA*> LSDBPair_t;
typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
LSDBMap_t m_database;
/**
@@ -734,12 +748,14 @@ private:
void SPFCalculate (Ipv4Address root);
void SPFNext (SPFVertex*, CandidateQueue&);
int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
GlobalRouterLinkRecord* l, uint32_t distance);
GlobalRoutingLinkRecord* l, uint32_t distance);
void SPFVertexAddParent (SPFVertex* v);
GlobalRouterLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
GlobalRouterLinkRecord* prev_link);
GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
GlobalRoutingLinkRecord* prev_link);
void SPFIntraAddRouter (SPFVertex* v);
void SPFIntraAddTransit (SPFVertex* v);
uint32_t FindOutgoingInterfaceId (Ipv4Address a);
uint32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask);
};
} // namespace ns3

View File

@@ -28,21 +28,21 @@ namespace ns3 {
// ---------------------------------------------------------------------------
//
// GlobalRouterLinkRecord Implementation
// GlobalRoutingLinkRecord Implementation
//
// ---------------------------------------------------------------------------
GlobalRouterLinkRecord::GlobalRouterLinkRecord ()
GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
:
m_linkId ("0.0.0.0"),
m_linkData ("0.0.0.0"),
m_linkType (Unknown),
m_metric (0)
{
NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord ()");
NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()");
}
GlobalRouterLinkRecord::GlobalRouterLinkRecord (
GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
LinkType linkType,
Ipv4Address linkId,
Ipv4Address linkData,
@@ -53,116 +53,126 @@ GlobalRouterLinkRecord::GlobalRouterLinkRecord (
m_linkType (linkType),
m_metric (metric)
{
NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord (" <<
NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (" <<
linkType << ", " << linkId << ", " << linkData << ", " << metric << ")");
}
GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()
GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
{
NS_DEBUG("GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()");
NS_DEBUG("GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()");
}
Ipv4Address
GlobalRouterLinkRecord::GetLinkId (void) const
GlobalRoutingLinkRecord::GetLinkId (void) const
{
NS_DEBUG("GlobalRouterLinkRecord::GetLinkId ()");
NS_DEBUG("GlobalRoutingLinkRecord::GetLinkId ()");
return m_linkId;
}
void
GlobalRouterLinkRecord::SetLinkId (Ipv4Address addr)
GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
{
NS_DEBUG("GlobalRouterLinkRecord::SetLinkId ()");
NS_DEBUG("GlobalRoutingLinkRecord::SetLinkId ()");
m_linkId = addr;
}
Ipv4Address
GlobalRouterLinkRecord::GetLinkData (void) const
GlobalRoutingLinkRecord::GetLinkData (void) const
{
NS_DEBUG("GlobalRouterLinkRecord::GetLinkData ()");
NS_DEBUG("GlobalRoutingLinkRecord::GetLinkData ()");
return m_linkData;
}
void
GlobalRouterLinkRecord::SetLinkData (Ipv4Address addr)
GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
{
NS_DEBUG("GlobalRouterLinkRecord::SetLinkData ()");
NS_DEBUG("GlobalRoutingLinkRecord::SetLinkData ()");
m_linkData = addr;
}
GlobalRouterLinkRecord::LinkType
GlobalRouterLinkRecord::GetLinkType (void) const
GlobalRoutingLinkRecord::LinkType
GlobalRoutingLinkRecord::GetLinkType (void) const
{
NS_DEBUG("GlobalRouterLinkRecord::GetLinkType ()");
NS_DEBUG("GlobalRoutingLinkRecord::GetLinkType ()");
return m_linkType;
}
void
GlobalRouterLinkRecord::SetLinkType (
GlobalRouterLinkRecord::LinkType linkType)
GlobalRoutingLinkRecord::SetLinkType (
GlobalRoutingLinkRecord::LinkType linkType)
{
NS_DEBUG("GlobalRouterLinkRecord::SetLinkType ()");
NS_DEBUG("GlobalRoutingLinkRecord::SetLinkType ()");
m_linkType = linkType;
}
uint32_t
GlobalRouterLinkRecord::GetMetric (void) const
GlobalRoutingLinkRecord::GetMetric (void) const
{
NS_DEBUG("GlobalRouterLinkRecord::GetMetric ()");
NS_DEBUG("GlobalRoutingLinkRecord::GetMetric ()");
return m_metric;
}
void
GlobalRouterLinkRecord::SetMetric (uint32_t metric)
GlobalRoutingLinkRecord::SetMetric (uint32_t metric)
{
NS_DEBUG("GlobalRouterLinkRecord::SetMetric ()");
NS_DEBUG("GlobalRoutingLinkRecord::SetMetric ()");
m_metric = metric;
}
// ---------------------------------------------------------------------------
//
// GlobalRouterLSA Implementation
// GlobalRoutingLSA Implementation
//
// ---------------------------------------------------------------------------
GlobalRouterLSA::GlobalRouterLSA()
GlobalRoutingLSA::GlobalRoutingLSA()
:
m_lsType (GlobalRoutingLSA::Unknown),
m_linkStateId("0.0.0.0"),
m_advertisingRtr("0.0.0.0"),
m_linkRecords(),
m_status(GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
m_networkLSANetworkMask("0.0.0.0"),
m_attachedRouters(),
m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
{
NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA ()");
NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA ()");
}
GlobalRouterLSA::GlobalRouterLSA (
GlobalRouterLSA::SPFStatus status,
GlobalRoutingLSA::GlobalRoutingLSA (
GlobalRoutingLSA::SPFStatus status,
Ipv4Address linkStateId,
Ipv4Address advertisingRtr)
:
m_lsType (GlobalRoutingLSA::Unknown),
m_linkStateId(linkStateId),
m_advertisingRtr(advertisingRtr),
m_linkRecords(),
m_networkLSANetworkMask("0.0.0.0"),
m_attachedRouters(),
m_status(status)
{
NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA (" << status << ", " <<
NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA (" << status << ", " <<
linkStateId << ", " << advertisingRtr << ")");
}
GlobalRouterLSA::GlobalRouterLSA (GlobalRouterLSA& lsa)
: m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr),
GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
: m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId),
m_advertisingRtr(lsa.m_advertisingRtr),
m_networkLSANetworkMask(lsa.m_networkLSANetworkMask),
m_status(lsa.m_status)
{
NS_ASSERT_MSG(IsEmpty(),
"GlobalRouterLSA::GlobalRouterLSA (): Non-empty LSA in constructor");
"GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
CopyLinkRecords (lsa);
}
GlobalRouterLSA&
GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa)
GlobalRoutingLSA&
GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
{
m_lsType = lsa.m_lsType;
m_linkStateId = lsa.m_linkStateId;
m_advertisingRtr = lsa.m_advertisingRtr;
m_networkLSANetworkMask = lsa.m_networkLSANetworkMask,
m_status = lsa.m_status;
ClearLinkRecords ();
@@ -171,14 +181,14 @@ GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa)
}
void
GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa)
GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
{
for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
i != lsa.m_linkRecords.end ();
i++)
{
GlobalRouterLinkRecord *pSrc = *i;
GlobalRouterLinkRecord *pDst = new GlobalRouterLinkRecord;
GlobalRoutingLinkRecord *pSrc = *i;
GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
pDst->SetLinkType (pSrc->GetLinkType ());
pDst->SetLinkId (pSrc->GetLinkId ());
@@ -187,48 +197,50 @@ GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa)
m_linkRecords.push_back(pDst);
pDst = 0;
}
m_attachedRouters = lsa.m_attachedRouters;
}
GlobalRouterLSA::~GlobalRouterLSA()
GlobalRoutingLSA::~GlobalRoutingLSA()
{
NS_DEBUG("GlobalRouterLSA::~GlobalRouterLSA ()");
NS_DEBUG("GlobalRoutingLSA::~GlobalRoutingLSA ()");
ClearLinkRecords ();
}
void
GlobalRouterLSA::ClearLinkRecords(void)
GlobalRoutingLSA::ClearLinkRecords(void)
{
for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
i != m_linkRecords.end ();
i++)
{
NS_DEBUG("GlobalRouterLSA::ClearLinkRecords (): free link record");
NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords (): free link record");
GlobalRouterLinkRecord *p = *i;
GlobalRoutingLinkRecord *p = *i;
delete p;
p = 0;
*i = 0;
}
NS_DEBUG("GlobalRouterLSA::ClearLinkRecords(): clear list");
NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords(): clear list");
m_linkRecords.clear();
}
uint32_t
GlobalRouterLSA::AddLinkRecord (GlobalRouterLinkRecord* lr)
GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
{
m_linkRecords.push_back (lr);
return m_linkRecords.size ();
}
uint32_t
GlobalRouterLSA::GetNLinkRecords (void) const
GlobalRoutingLSA::GetNLinkRecords (void) const
{
return m_linkRecords.size ();
}
GlobalRouterLinkRecord *
GlobalRouterLSA::GetLinkRecord (uint32_t n) const
GlobalRoutingLinkRecord *
GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
{
uint32_t j = 0;
for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
@@ -240,70 +252,146 @@ GlobalRouterLSA::GetLinkRecord (uint32_t n) const
return *i;
}
}
NS_ASSERT_MSG(false, "GlobalRouterLSA::GetLinkRecord (): invalid index");
NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
return 0;
}
bool
GlobalRouterLSA::IsEmpty (void) const
GlobalRoutingLSA::IsEmpty (void) const
{
return m_linkRecords.size () == 0;
}
GlobalRoutingLSA::LSType
GlobalRoutingLSA::GetLSType (void) const
{
return m_lsType;
}
void
GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ)
{
m_lsType = typ;
}
Ipv4Address
GlobalRouterLSA::GetLinkStateId (void) const
GlobalRoutingLSA::GetLinkStateId (void) const
{
return m_linkStateId;
}
void
GlobalRouterLSA::SetLinkStateId (Ipv4Address addr)
GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
{
m_linkStateId = addr;
}
Ipv4Address
GlobalRouterLSA::GetAdvertisingRouter (void) const
GlobalRoutingLSA::GetAdvertisingRouter (void) const
{
return m_advertisingRtr;
}
void
GlobalRouterLSA::SetAdvertisingRouter (Ipv4Address addr)
GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
{
m_advertisingRtr = addr;
}
GlobalRouterLSA::SPFStatus
GlobalRouterLSA::GetStatus (void) const
void
GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
{
m_networkLSANetworkMask = mask;
}
Ipv4Mask
GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
{
return m_networkLSANetworkMask;
}
GlobalRoutingLSA::SPFStatus
GlobalRoutingLSA::GetStatus (void) const
{
return m_status;
}
uint32_t
GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
{
m_attachedRouters.push_back (addr);
return m_attachedRouters.size ();
}
uint32_t
GlobalRoutingLSA::GetNAttachedRouters (void) const
{
return m_attachedRouters.size ();
}
Ipv4Address
GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
{
uint32_t j = 0;
for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
i != m_attachedRouters.end ();
i++, j++)
{
if (j == n)
{
return *i;
}
}
NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
return Ipv4Address("0.0.0.0");
}
void
GlobalRouterLSA::SetStatus (GlobalRouterLSA::SPFStatus status)
GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
{
m_status = status;
}
void
GlobalRouterLSA::Print (std::ostream &os) const
GlobalRoutingLSA::Print (std::ostream &os) const
{
os << "m_linkStateId = " << m_linkStateId << std::endl <<
os << "m_lsType = " << m_lsType << std::endl <<
"m_linkStateId = " << m_linkStateId << std::endl <<
"m_advertisingRtr = " << m_advertisingRtr << std::endl;
for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
i != m_linkRecords.end ();
i++)
if (m_lsType == GlobalRoutingLSA::RouterLSA)
{
for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
i != m_linkRecords.end ();
i++)
{
GlobalRoutingLinkRecord *p = *i;
os << "----------" << std::endl;
os << "m_linkId = " << p->GetLinkId () << std::endl;
os << "m_linkData = " << p->GetLinkData () << std::endl;
}
}
else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
{
GlobalRouterLinkRecord *p = *i;
os << "----------" << std::endl;
os << "m_linkId = " << p->GetLinkId () << std::endl;
os << "m_linkData = " << p->GetLinkData () << std::endl;
os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask
<< std::endl;
for ( ListOfAttachedRouters_t::const_iterator i =
m_attachedRouters.begin ();
i != m_attachedRouters.end ();
i++)
{
Ipv4Address p = *i;
os << "attachedRouter = " << p << std::endl;
}
}
else
{
NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
}
}
std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa)
std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
{
lsa.Print (os);
return os;
@@ -350,7 +438,7 @@ GlobalRouter::ClearLSAs ()
{
NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA");
GlobalRouterLSA *p = *i;
GlobalRoutingLSA *p = *i;
delete p;
p = 0;
@@ -373,11 +461,16 @@ GlobalRouter::GetRouterId (void) const
uint32_t
GlobalRouter::DiscoverLSAs (void)
{
NS_DEBUG("GlobalRouter::DiscoverLSAs ()");
NS_DEBUG("GlobalRouter::DiscoverLSAs () for node " << m_node->GetId () );
NS_ASSERT_MSG(m_node,
"GlobalRouter::DiscoverLSAs (): <Node> interface not set");
ClearLSAs ();
// While building the router-LSA, keep a list of those NetDevices for
// which I am the designated router and need to later build a NetworkLSA
std::list<Ptr<NetDevice> > listOfDRInterfaces;
//
// 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
@@ -387,118 +480,252 @@ GlobalRouter::DiscoverLSAs (void)
NS_ASSERT_MSG(ipv4Local,
"GlobalRouter::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
// number of link records. This means that GetNumLSAs will actually always
// return exactly one.
// Each node originates a Router-LSA
//
GlobalRouterLSA *pLSA = new GlobalRouterLSA;
GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
pLSA->SetLinkStateId (m_routerId);
pLSA->SetAdvertisingRouter (m_routerId);
pLSA->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
//
// 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.
// ethernets, etc.).
//
uint32_t numDevices = m_node->GetNDevices();
NS_DEBUG("GlobalRouter::DiscoverLSAs (): numDevices = " << numDevices);
//
// Loop through the devices looking for those connected to a point-to-point
// channel.
//
for (uint32_t i = 0; i < numDevices; ++i)
{
Ptr<NetDevice> ndLocal = m_node->GetDevice(i);
if (!ndLocal->IsPointToPoint ())
if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
{
NS_DEBUG("GlobalRouter::DiscoverLSAs (): non-point-to-point device");
continue;
}
NS_DEBUG("GlobalRouter::DiscoverLSAs (): Point-to-point device");
NS_DEBUG("GlobalRouter::DiscoverLSAs (): broadcast link");
GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
//
// We need to determine whether we are on a transit or stub network
// If we find at least one more router on this channel, we are a transit
//
//
// Now, we have to find the Ipv4 interface whose netdevice is the one we
// 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, ndLocal);
//
// Now that we have the Ipv4 interface index, we can get the address and mask
// we need.
//
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
NS_DEBUG("Working with local address " << addrLocal);
uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
NS_DEBUG("Working with local address " << addrLocal);
//
// 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 = ndLocal->GetChannel();
Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
Ptr<Channel> ch = ndLocal->GetChannel();
uint32_t nDevices = ch->GetNDevices();
if (nDevices == 1)
{
// This is a stub broadcast interface
NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA stub broadcast link");
// XXX in future, need to consider if >1 includes other routers
plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
// Link ID is IP network number of attached network
plr->SetLinkId (addrLocal.CombineMask(maskLocal));
// Link Data is network mask; convert to Ipv4Address
Ipv4Address maskLocalAddr;
maskLocalAddr.Set(maskLocal.GetHostOrder ());
plr->SetLinkData (maskLocalAddr);
// Cost is interface's configured output cost (NOTYET)
plr->SetMetric (1);
pLSA->AddLinkRecord(plr);
plr = 0;
continue;
}
else
{
NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Broadcast link");
// multiple routers on a broadcast interface
// lowest IP address is designated router
plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
// Link ID is IP interface address of designated router
Ipv4Address desigRtr =
FindDesignatedRouterForLink (m_node, ndLocal);
if (desigRtr == addrLocal)
{
listOfDRInterfaces.push_back (ndLocal);
NS_DEBUG("GlobalRouter::DiscoverLSAs (): " <<
m_node->GetId () << " is a DR");
}
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);
pLSA->AddLinkRecord (plr);
plr = 0;
continue;
}
}
else if (ndLocal->IsPointToPoint () )
{
NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Point-to-point device");
//
// Now, we have to find the Ipv4 interface whose netdevice is the one we
// 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, ndLocal);
//
// Now that we have the Ipv4 interface index, we can get the address and mask
// we need.
//
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
NS_DEBUG("Working with local address " << addrLocal);
//
// 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 = 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.
//
Ptr<Node> nodeRemote = ndRemote->GetNode();
Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT_MSG(ipv4Remote,
"GlobalRouter::DiscoverLSAs (): QI for remote <Ipv4> failed");
Ptr<Node> nodeRemote = ndRemote->GetNode();
Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT_MSG(ipv4Remote,
"GlobalRouter::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<GlobalRouter> srRemote =
nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
NS_ASSERT_MSG(srRemote,
"GlobalRouter::DiscoverLSAs (): QI for remote <GlobalRouter> failed");
Ipv4Address rtrIdRemote = srRemote->GetRouterId();
NS_DEBUG("Working with remote router " << rtrIdRemote);
Ptr<GlobalRouter> srRemote =
nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
NS_ASSERT_MSG(srRemote,
"GlobalRouter::DiscoverLSAs():QI for remote <GlobalRouter> 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.
//
uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
//
// Now that we have the Ipv4 interface, we can get the (remote) address and
// mask we need.
//
Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
NS_DEBUG("Working with remote address " << addrRemote);
Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
NS_DEBUG("Working with remote address " << addrRemote);
//
// Now we can fill out the link records for this link. There are always two
// link records; the first is a point-to-point record describing the link and
// the second is a stub network record with the network number.
//
GlobalRouterLinkRecord *plr = new GlobalRouterLinkRecord;
plr->SetLinkType (GlobalRouterLinkRecord::PointToPoint);
plr->SetLinkId (rtrIdRemote);
plr->SetLinkData (addrLocal);
pLSA->AddLinkRecord(plr);
plr = 0;
GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
plr->SetLinkId (rtrIdRemote);
plr->SetLinkData (addrLocal);
pLSA->AddLinkRecord (plr);
plr = 0;
plr = new GlobalRoutingLinkRecord;
plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
plr->SetLinkId (addrRemote);
plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
pLSA->AddLinkRecord (plr);
plr = 0;
}
else
{
NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
}
plr = new GlobalRouterLinkRecord;
plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork);
plr->SetLinkId (addrRemote);
plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
pLSA->AddLinkRecord(plr);
plr = 0;
}
//
// The LSA goes on a list of LSAs in case we want to begin exporting other
// kinds of advertisements (than Router LSAs).
m_LSAs.push_back (pLSA);
NS_DEBUG(*pLSA);
// Now, determine whether we need to build a NetworkLSA
if (listOfDRInterfaces.size () > 0)
{
for (std::list<Ptr<NetDevice> >::iterator i = listOfDRInterfaces.begin ();
i != listOfDRInterfaces.end (); i++)
{
// Build one NetworkLSA for each interface that is a DR
Ptr<NetDevice> ndLocal = *i;
uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
pLSA->SetLinkStateId (addrLocal);
pLSA->SetAdvertisingRouter (m_routerId);
pLSA->SetNetworkLSANetworkMask (maskLocal);
pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
// Build list of AttachedRouters
Ptr<Channel> ch = ndLocal->GetChannel();
uint32_t nDevices = ch->GetNDevices();
NS_ASSERT (nDevices);
for (uint32_t i = 0; i < nDevices; i++)
{
Ptr<NetDevice> tempNd = ch->GetDevice (i);
NS_ASSERT (tempNd);
Ptr<Node> tempNode = tempNd->GetNode ();
uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT (tempIpv4);
Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
pLSA->AddAttachedRouter (tempAddr);
}
m_LSAs.push_back (pLSA);
NS_DEBUG(*pLSA);
}
}
return m_LSAs.size ();
}
Ipv4Address
GlobalRouter::FindDesignatedRouterForLink (Ptr<Node> node,
Ptr<NetDevice> ndLocal) const
{
uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal);
Ptr<Ipv4> ipv4Local = m_node->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT (ipv4Local);
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
Ptr<Channel> ch = ndLocal->GetChannel();
uint32_t nDevices = ch->GetNDevices();
NS_ASSERT (nDevices);
Ipv4Address lowest = addrLocal;
// iterate all NetDevices and return the lowest numbered IP address
for (uint32_t i = 0; i < nDevices; i++)
{
Ptr<NetDevice> tempNd = ch->GetDevice (i);
NS_ASSERT (tempNd);
Ptr<Node> tempNode = tempNd->GetNode ();
uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT (tempIpv4);
Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
if (tempAddr < addrLocal)
{
addrLocal = tempAddr;
}
}
return addrLocal;
}
uint32_t
GlobalRouter::GetNumLSAs (void) const
{
@@ -510,7 +737,7 @@ GlobalRouter::GetNumLSAs (void) const
// Get the nth link state advertisement from this router.
//
bool
GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
{
NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
//
@@ -525,7 +752,7 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
{
if (j == n)
{
GlobalRouterLSA *p = *i;
GlobalRoutingLSA *p = *i;
lsa = *p;
return true;
}

View File

@@ -31,16 +31,16 @@ namespace ns3 {
/**
* @brief A single link record for a link state advertisement.
*
* The GlobalRouterLinkRecord is modeled after the OSPF link record field of
* The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
* a Link State Advertisement. Right now we will only see two types of link
* records corresponding to a stub network and a point-to-point link (channel).
*/
class GlobalRouterLinkRecord
class GlobalRoutingLinkRecord
{
public:
/**
* @enum LinkType
* @brief Enumeration of the possible types of Global Router Link Records.
* @brief Enumeration of the possible types of Global Routing Link Records.
*
* These values are defined in the OSPF spec. We currently only use
* PointToPoint and StubNetwork types.
@@ -54,16 +54,16 @@ public:
};
/**
* @brief Construct an empty ("uninitialized") Global Router Link Record.
* @brief Construct an empty ("uninitialized") Global Routing Link Record.
*
* The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
* The Link Type is set to Unknown;
* The metric is set to 0.
*/
GlobalRouterLinkRecord ();
GlobalRoutingLinkRecord ();
/**
* Construct an initialized Global Router Link Record.
* Construct an initialized Global Routing Link Record.
*
* @param linkType The type of link record to construct.
* @param linkId The link ID for the record.
@@ -73,21 +73,21 @@ public:
* @see SetLinkId
* @see SetLinkData
*/
GlobalRouterLinkRecord (
GlobalRoutingLinkRecord (
LinkType linkType,
Ipv4Address linkId,
Ipv4Address linkData,
uint32_t metric);
/**
* @brief Destroy a Global Router Link Record.
* @brief Destroy a Global Routing Link Record.
*
* Currently does nothing. Here as a placeholder only.
*/
~GlobalRouterLinkRecord ();
~GlobalRoutingLinkRecord ();
/**
* Get the Link ID field of the Global Router Link Record.
* Get the Link ID field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
* of the neighboring router.
@@ -100,7 +100,7 @@ public:
Ipv4Address GetLinkId(void) const;
/**
* @brief Set the Link ID field of the Global Router Link Record.
* @brief Set the Link ID field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
* of the neighboring router.
@@ -113,7 +113,7 @@ public:
void SetLinkId(Ipv4Address addr);
/**
* @brief Get the Link Data field of the Global Router Link Record.
* @brief Get the Link Data field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
* address of the node of the local side of the link.
@@ -126,7 +126,7 @@ public:
Ipv4Address GetLinkData(void) const;
/**
* @brief Set the Link Data field of the Global Router Link Record.
* @brief Set the Link Data field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
* address of the node of the local side of the link.
@@ -139,29 +139,29 @@ public:
void SetLinkData(Ipv4Address addr);
/**
* @brief Get the Link Type field of the Global Router Link Record.
* @brief Get the Link Type field of the Global Routing Link Record.
*
* The Link Type describes the kind of link a given record represents. The
* values are defined by OSPF.
*
* @see LinkType
* @returns The LinkType of the current Global Router Link Record.
* @returns The LinkType of the current Global Routing Link Record.
*/
LinkType GetLinkType(void) const;
/**
* @brief Set the Link Type field of the Global Router Link Record.
* @brief Set the Link Type field of the Global Routing Link Record.
*
* The Link Type describes the kind of link a given record represents. The
* values are defined by OSPF.
*
* @see LinkType
* @param linkType The new LinkType for the current Global Router Link Record.
* @param linkType The new LinkType for the current Global Routing Link Record.
*/
void SetLinkType(LinkType linkType);
/**
* @brief Get the Metric Data field of the Global Router Link Record.
* @brief Get the Metric Data field of the Global Routing Link Record.
*
* The metric is an abstract cost associated with forwarding a packet across
* a link. A sum of metrics must have a well-defined meaning. That is, you
@@ -169,12 +169,12 @@ public:
* two hops relate to the cost of sending a packet); rather you should use
* something like delay.
*
* @returns The metric field of the Global Router Link Record.
* @returns The metric field of the Global Routing Link Record.
*/
uint32_t GetMetric(void) const;
/**
* @brief Set the Metric Data field of the Global Router Link Record.
* @brief Set the Metric Data field of the Global Routing Link Record.
*
* The metric is an abstract cost associated with forwarding a packet across
* a link. A sum of metrics must have a well-defined meaning. That is, you
@@ -182,7 +182,7 @@ public:
* two hops relate to the cost of sending a packet); rather you should use
* something like delay.
*
* @param metric The new metric for the current Global Router Link Record.
* @param metric The new metric for the current Global Routing Link Record.
*/
void SetMetric(uint32_t metric);
@@ -211,7 +211,7 @@ private:
Ipv4Address m_linkData; // for links to RouterLSA,
/**
* The type of the Global Router Link Record. Defined in the OSPF spec.
* The type of the Global Routing Link Record. Defined in the OSPF spec.
* We currently only use PointToPoint and StubNetwork types.
*/
LinkType m_linkType;
@@ -236,12 +236,24 @@ private:
* combined with a list of Link Records. Since it's global, there's
* no need for age or sequence number. See RFC 2328, Appendix A.
*/
class GlobalRouterLSA
class GlobalRoutingLSA
{
public:
/**
* @enum LSType
* @brief corresponds to LS type field of RFC 2328 OSPF LSA header
*/
enum LSType {
Unknown = 0, /**< Uninitialized Type */
RouterLSA,
NetworkLSA,
SummaryLSA,
SummaryLSA_ASBR,
ASExternalLSAs
};
/**
* @enum SPFStatus
* @brief Enumeration of the possible values of the status flag in the Router
* @brief Enumeration of the possible values of the status flag in the Routing
* Link State Advertisements.
*/
enum SPFStatus {
@@ -249,17 +261,16 @@ public:
LSA_SPF_CANDIDATE, /**< Vertex is in the SPF candidate queue */
LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */
};
/**
* @brief Create a blank Global Router Link State Advertisement.
* @brief Create a blank Global Routing Link State Advertisement.
*
* On completion Ipv4Address variables initialized to 0.0.0.0 and the
* list of Link State Records is empty.
*/
GlobalRouterLSA();
GlobalRoutingLSA();
/**
* @brief Create an initialized Global Router Link State Advertisement.
* @brief Create an initialized Global Routing Link State Advertisement.
*
* On completion the list of Link State Records is empty.
*
@@ -267,42 +278,42 @@ public:
* @param linkStateId The Ipv4Address for the link state ID field.
* @param advertisingRtr The Ipv4Address for the advertising router field.
*/
GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId,
GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId,
Ipv4Address advertisingRtr);
/**
* @brief Copy constructor for a Global Router Link State Advertisement.
* @brief Copy constructor for a Global Routing Link State Advertisement.
*
* Takes a piece of memory and constructs a semantically identical copy of
* the given LSA.
*
* @param lsa The existing LSA to be used as the source.
*/
GlobalRouterLSA (GlobalRouterLSA& lsa);
GlobalRoutingLSA (GlobalRoutingLSA& lsa);
/**
* @brief Destroy an existing Global Router Link State Advertisement.
* @brief Destroy an existing Global Routing Link State Advertisement.
*
* Any Global Router Link Records present in the list are freed.
* Any Global Routing Link Records present in the list are freed.
*/
~GlobalRouterLSA();
~GlobalRoutingLSA();
/**
* @brief Assignment operator for a Global Router Link State Advertisement.
* @brief Assignment operator for a Global Routing Link State Advertisement.
*
* Takes an existing Global Router Link State Advertisement and overwrites
* Takes an existing Global Routing Link State Advertisement and overwrites
* it to make a semantically identical copy of a given prototype LSA.
*
* If there are any Global Router Link Records present in the existing
* If there are any Global Routing Link Records present in the existing
* LSA, they are freed before the assignment happens.
*
* @param lsa The existing LSA to be used as the source.
* @returns Reference to the overwritten LSA.
*/
GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa);
GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
/**
* @brief Copy any Global Router Link Records in a given Global Router Link
* @brief Copy any Global Routing Link Records in a given Global Routing Link
* State Advertisement to the current LSA.
*
* Existing Link Records are not deleted -- this is a concatenation of Link
@@ -311,57 +322,66 @@ public:
* @see ClearLinkRecords ()
* @param lsa The LSA to copy the Link Records from.
*/
void CopyLinkRecords (const GlobalRouterLSA& lsa);
void CopyLinkRecords (const GlobalRoutingLSA& lsa);
/**
* @brief Add a given Global Router Link Record to the LSA.
* @brief Add a given Global Routing Link Record to the LSA.
*
* @param lr The Global Router Link Record to be added.
* @param lr The Global Routing Link Record to be added.
* @returns The number of link records in the list.
*/
uint32_t AddLinkRecord (GlobalRouterLinkRecord* lr);
uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
/**
* @brief Return the number of Global Router Link Records in the LSA.
* @brief Return the number of Global Routing Link Records in the LSA.
*
* @returns The number of link records in the list.
*/
uint32_t GetNLinkRecords (void) const;
/**
* @brief Return a pointer to the specified Global Router Link Record.
* @brief Return a pointer to the specified Global Routing Link Record.
*
* @param n The LSA number desired.
* @returns The number of link records in the list.
*/
GlobalRouterLinkRecord* GetLinkRecord (uint32_t n) const;
GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
/**
* @brief Release all of the Global Router Link Records present in the Global
* Router Link State Advertisement and make the list of link records empty.
* @brief Release all of the Global Routing Link Records present in the Global
* Routing Link State Advertisement and make the list of link records empty.
*/
void ClearLinkRecords(void);
/**
* @brief Check to see if the list of Global Router Link Records present in the
* Global Router Link State Advertisement is empty.
* @brief Check to see if the list of Global Routing Link Records present in the
* Global Routing Link State Advertisement is empty.
*
* @returns True if the list is empty, false otherwise.
*/
bool IsEmpty(void) const;
/**
* @brief Print the contents of the Global Router Link State Advertisement and
* any Global Router Link Records present in the list. Quite verbose.
* @brief Print the contents of the Global Routing Link State Advertisement and
* any Global Routing Link Records present in the list. Quite verbose.
*/
void Print (std::ostream &os) const;
/**
* @brief Return the LSType field of the LSA
*/
LSType GetLSType (void) const;
/**
* @brief Set the LS type field of the LSA
*/
void SetLSType (LSType typ);
/**
* @brief Get the Link State ID as defined by the OSPF spec. We always set it
* to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
* @returns The Ipv4Address stored as the link state ID.
*/
Ipv4Address GetLinkStateId (void) const;
@@ -371,7 +391,7 @@ public:
* to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
*/
void SetLinkStateId (Ipv4Address addr);
@@ -380,7 +400,7 @@ public:
* set it to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
* @returns The Ipv4Address stored as the advetising router.
*/
Ipv4Address GetAdvertisingRouter (void) const;
@@ -390,10 +410,47 @@ public:
* set it to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
*/
void SetAdvertisingRouter (Ipv4Address rtr);
/**
* @brief For a Network LSA, set the Network Mask field that precedes
* the list of attached routers.
*/
void SetNetworkLSANetworkMask (Ipv4Mask mask);
/**
* @brief For a Network LSA, get the Network Mask field that precedes
* the list of attached routers.
*
* @returns the NetworkLSANetworkMask
*/
Ipv4Mask GetNetworkLSANetworkMask (void) const;
/**
* @brief Add an attached router to the list in the NetworkLSA
*
* @param address The Ipv4Address of the interface on the network link
* @returns The number of addresses in the list.
*/
uint32_t AddAttachedRouter (Ipv4Address addr);
/**
* @brief Return the number of attached routers listed in the NetworkLSA
*
* @returns The number of attached routers.
*/
uint32_t GetNAttachedRouters (void) const;
/**
* @brief Return an Ipv4Address corresponding to the specified attached router
*
* @param n The attached router number desired (number in the list).
* @returns The Ipv4Address of the requested router
*/
Ipv4Address GetAttachedRouter (uint32_t n) const;
/**
* @brief Get the SPF status of the advertisement.
*
@@ -410,12 +467,17 @@ public:
void SetStatus (SPFStatus status);
private:
/**
* The type of the LSA. Each LSA type has a separate advertisement
* format.
*/
LSType m_lsType;
/**
* The Link State ID is defined by the OSPF spec. We always set it to the
* router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
*/
Ipv4Address m_linkStateId;
@@ -424,14 +486,14 @@ private:
* the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
* @see GlobalRouter::GetRouterId ()
* @see GlobalRouting::GetRouterId ()
*/
Ipv4Address m_advertisingRtr;
/**
* A convenience typedef to avoid too much writers cramp.
*/
typedef std::list<GlobalRouterLinkRecord*> ListOfLinkRecords_t;
typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
/**
* Each Link State Advertisement contains a number of Link Records that
@@ -441,10 +503,30 @@ private:
* m_linkRecords is an STL list container to hold the Link Records that have
* been discovered and prepared for the advertisement.
*
* @see GlobalRouter::DiscoverLSAs ()
* @see GlobalRouting::DiscoverLSAs ()
*/
ListOfLinkRecords_t m_linkRecords;
/**
* Each Network LSA contains the network mask of the attached network
*/
Ipv4Mask m_networkLSANetworkMask;
/**
* A convenience typedef to avoid too much writers cramp.
*/
typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
/**
* Each Network LSA contains a list of attached routers
*
* m_attachedRouters is an STL list container to hold the addresses that have
* been discovered and prepared for the advertisement.
*
* @see GlobalRouting::DiscoverLSAs ()
*/
ListOfAttachedRouters_t m_attachedRouters;
/**
* This is a tristate flag used internally in the SPF computation to mark
* if an SPFVertex (a data structure representing a vertex in the SPF tree
@@ -454,7 +536,7 @@ private:
SPFStatus m_status;
};
std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa);
std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
/**
* @brief An interface aggregated to a node to provide global routing info
@@ -496,7 +578,7 @@ public:
/**
* @brief Walk the connected channels, discover the adjacent routers and build
* the associated number of Global Router Link State Advertisements that
* the associated number of Global Routing Link State Advertisements that
* this router can export.
*
* This is a fairly expensive operation in that every time it is called
@@ -507,14 +589,14 @@ public:
* advertisements after a network topology change by calling DiscoverLSAs
* and then by reading those advertisements.
*
* @see GlobalRouterLSA
* @see GlobalRoutingLSA
* @see GlobalRouter::GetLSA ()
* @returns The number of Global Router Link State Advertisements.
* @returns The number of Global Routing Link State Advertisements.
*/
uint32_t DiscoverLSAs (void);
/**
* @brief Get the Number of Global Router Link State Advertisements that this
* @brief Get the Number of Global Routing Link State Advertisements that this
* router can export.
*
* To get meaningful information you must have previously called DiscoverLSAs.
@@ -522,19 +604,19 @@ public:
* GetLSA () to retrieve the actual advertisement.
*
* @see GlobalRouterLSA
* @see GlobalRouter::DiscoverLSAs ()
* @see GlobalRouter::GetLSA ()
* @returns The number of Global Router Link State Advertisements.
* @see GlobalRouting::DiscoverLSAs ()
* @see GlobalRouting::GetLSA ()
* @returns The number of Global Routing Link State Advertisements.
*/
uint32_t GetNumLSAs (void) const;
/**
* @brief Get a Global Router Link State Advertisements that this router has
* @brief Get a Global Routing Link State Advertisements that this router has
* said that it can export.
*
* This is a fairly inexpensive expensive operation in that the hard work
* was done in GetNumLSAs. We just copy the indicated Global Router Link
* State Advertisement into the requested GlobalRouterLSA object.
* was done in GetNumLSAs. We just copy the indicated Global Routing Link
* State Advertisement into the requested GlobalRoutingLSA object.
*
* You must call GlobalRouter::GetNumLSAs before calling this method in
* order to discover the adjacent routers and build the advertisements.
@@ -542,13 +624,13 @@ public:
* The parameter n (requested LSA number) must be in the range 0 to
* GetNumLSAs() - 1.
*
* @see GlobalRouterLSA
* @see GlobalRouter::GetNumLSAs ()
* @see GlobalRoutingLSA
* @see GlobalRouting::GetNumLSAs ()
* @param n The index number of the LSA you want to read.
* @param lsa The GlobalRouterLSA class to receive the LSA information.
* @param lsa The GlobalRoutingLSA class to receive the LSA information.
* @returns The number of Global Router Link State Advertisements.
*/
bool GetLSA (uint32_t n, GlobalRouterLSA &lsa) const;
bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
private:
virtual ~GlobalRouter ();
@@ -556,10 +638,12 @@ private:
Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
uint32_t FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd) const;
Ipv4Address FindDesignatedRouterForLink (Ptr<Node> node,
Ptr<NetDevice> ndLocal) const;
Ptr<Node> m_node;
typedef std::list<GlobalRouterLSA*> ListOfLSAs_t;
typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
ListOfLSAs_t m_LSAs;
Ipv4Address m_routerId;