branch merge
This commit is contained in:
199
examples/mixed-global-routing.cc
Normal file
199
examples/mixed-global-routing.cc
Normal 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 ();
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
@@ -133,7 +133,6 @@ CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
|
||||
|
||||
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
|
||||
EnableMulticast();
|
||||
EnablePointToPoint();
|
||||
|
||||
SetSendEnable (sendEnable);
|
||||
SetReceiveEnable (receiveEnable);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user