From 883d92940f66f365eb095023d947c8c06edac9b3 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 10 Aug 2007 13:33:45 -0700 Subject: [PATCH 1/2] global routing csma patch --- examples/mixed-global-routing.cc | 199 ++++++ examples/wscript | 4 + src/devices/csma/csma-net-device.cc | 1 - .../global-route-manager-impl.cc | 575 +++++++++++++----- .../global-route-manager-impl.h | 76 ++- .../global-routing/global-router-interface.cc | 481 +++++++++++---- .../global-routing/global-router-interface.h | 236 ++++--- 7 files changed, 1201 insertions(+), 371 deletions(-) create mode 100644 examples/mixed-global-routing.cc diff --git a/examples/mixed-global-routing.cc b/examples/mixed-global-routing.cc new file mode 100644 index 000000000..b3017e029 --- /dev/null +++ b/examples/mixed-global-routing.cc @@ -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 +#include +#include +#include + +#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 n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + Ptr n4 = Create (); + Ptr n5 = Create (); + Ptr n6 = Create (); + + // We create the channels first without any IP addressing information + Ptr channel0 = + PointToPointTopology::AddPointToPointLink ( + n0, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel1 = + PointToPointTopology::AddPointToPointLink ( + n1, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel2 = + PointToPointTopology::AddPointToPointLink ( + n5, n6, DataRate (1500000), MilliSeconds (10)); + + // We create the channels first without any IP addressing information + Ptr 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 ooff = Create ( + 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-- + // 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 (); +} diff --git a/examples/wscript b/examples/wscript index e7559756f..e5e771555 100644 --- a/examples/wscript +++ b/examples/wscript @@ -17,3 +17,7 @@ def build(bld): obj = bld.create_ns3_program('csma-packet-socket', ['csma', 'internet-node']) obj.source = 'csma-packet-socket.cc' + + obj = bld.create_ns3_program( 'mixed-global-routing', + ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd']) + obj.source = 'mixed-global-routing.cc' diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index a493fa12a..531bf7314 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.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); diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 142f613be..e78dfedf6 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -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 ). -// - 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 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 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 . 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 . 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 (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 , 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 (parent) to vertex (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 to . Think of it as // SPFGetLink. // - GlobalRouterLinkRecord *linkRemote = 0; + NS_ASSERT(l); + GlobalRoutingLinkRecord *linkRemote = 0; linkRemote = SPFGetNextLink (w, v, linkRemote); // // At this point, 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 @@ -739,16 +864,17 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( // 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 +882,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 +892,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 +900,16 @@ GlobalRouteManagerImpl::SPFGetNextLink ( // We're just checking to see if the link is actually the link from to // . // - 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 +980,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 +1025,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 +1063,18 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) // through its point-to-point links, adding a *host* route to the local IP // address (at the 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 +1167,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 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 >::iterator i = NodeList::Begin (); + for (; i != NodeList::End (); i++) + { + Ptr node = *i; + + Ptr rtr = + node->QueryInterface (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 = node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG (ipv4, + "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " + "QI for 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 +1325,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 +1344,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 +1378,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 >::iterator i = NodeList::Begin (); + for (; i != NodeList::End (); i++) + { + Ptr 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 rtr = + node->QueryInterface (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 = node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG (ipv4, + "GlobalRouteManagerImpl::SPFIntraAddTransit (): " + "QI for 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 = v->GetLSA ()->GetNetworkLSANetworkMask (); + Ipv4Address tempip = v->GetLSA ()->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 +1576,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 +1661,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); diff --git a/src/routing/global-routing/global-route-manager-impl.h b/src/routing/global-routing/global-route-manager-impl.h index 7979cb4a2..739e20592 100644 --- a/src/routing/global-routing/global-route-manager-impl.h +++ b/src/routing/global-routing/global-route-manager-impl.h @@ -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 LSDBMap_t; - typedef std::pair LSDBPair_t; + typedef std::map LSDBMap_t; + typedef std::pair 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 diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 778d91bcc..c057f9ddf 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -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 (): 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 > 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 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 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 ch = ndLocal->GetChannel(); - Ptr ndRemote = GetAdjacent(ndLocal, ch); + Ptr 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 ch = ndLocal->GetChannel(); + Ptr 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 nodeRemote = ndRemote->GetNode(); - Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4Remote, - "GlobalRouter::DiscoverLSAs (): QI for remote failed"); + Ptr nodeRemote = ndRemote->GetNode(); + Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4Remote, + "GlobalRouter::DiscoverLSAs (): QI for remote failed"); // // Per the OSPF spec, we're going to need the remote router ID, so we might as // well get it now. // - Ptr srRemote = - nodeRemote->QueryInterface (GlobalRouter::iid); - NS_ASSERT_MSG(srRemote, - "GlobalRouter::DiscoverLSAs (): QI for remote failed"); - Ipv4Address rtrIdRemote = srRemote->GetRouterId(); - NS_DEBUG("Working with remote router " << rtrIdRemote); + Ptr srRemote = + nodeRemote->QueryInterface (GlobalRouter::iid); + NS_ASSERT_MSG(srRemote, + "GlobalRouter::DiscoverLSAs():QI for remote 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 >::iterator i = listOfDRInterfaces.begin (); + i != listOfDRInterfaces.end (); i++) + { +// Build one NetworkLSA for each interface that is a DR + Ptr 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 ch = ndLocal->GetChannel(); + uint32_t nDevices = ch->GetNDevices(); + NS_ASSERT (nDevices); + for (uint32_t i = 0; i < nDevices; i++) + { + Ptr tempNd = ch->GetDevice (i); + NS_ASSERT (tempNd); + Ptr tempNode = tempNd->GetNode (); + uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); + Ptr tempIpv4 = tempNode->QueryInterface (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, + Ptr ndLocal) const +{ + uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); + Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); + NS_ASSERT (ipv4Local); + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + + Ptr 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 tempNd = ch->GetDevice (i); + NS_ASSERT (tempNd); + Ptr tempNode = tempNd->GetNode (); + uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); + Ptr tempIpv4 = tempNode->QueryInterface (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; } diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index 61351d34b..66f0c7543 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -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 ListOfLinkRecords_t; + typedef std::list 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 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 GetAdjacent(Ptr nd, Ptr ch) const; uint32_t FindIfIndexForDevice(Ptr node, Ptr nd) const; + Ipv4Address FindDesignatedRouterForLink (Ptr node, + Ptr ndLocal) const; Ptr m_node; - typedef std::list ListOfLSAs_t; + typedef std::list ListOfLSAs_t; ListOfLSAs_t m_LSAs; Ipv4Address m_routerId; From 915e34b32bc3068725c50d0db544f8d7ccd73017 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 12 Aug 2007 14:24:49 -0700 Subject: [PATCH 2/2] fix optimized build; remove old comment --- src/routing/global-routing/global-route-manager-impl.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index e78dfedf6..217513df8 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -860,9 +860,6 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( // Router Link Record we find that describes a point-to-point link from // to . If prev_link is not NULL, we return a Global Router Link Record // representing a possible *second* link from to . -// -// 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? // GlobalRoutingLinkRecord* GlobalRouteManagerImpl::SPFGetNextLink ( @@ -1450,8 +1447,8 @@ GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v) NS_ASSERT_MSG (lsa, "GlobalRouteManagerImpl::SPFIntraAddTransit (): " "Expected valid LSA in SPFVertex* v"); - Ipv4Mask tempmask = v->GetLSA ()->GetNetworkLSANetworkMask (); - Ipv4Address tempip = v->GetLSA ()->GetLinkStateId (); + Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask (); + Ipv4Address tempip = lsa->GetLinkStateId (); tempip = tempip.CombineMask (tempmask); ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingInterfaceId ());