--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mixed-global-routing.cc Sun Aug 12 22:43:25 2007 -0700
@@ -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 ();
+}
--- a/examples/wscript Sun Aug 12 22:41:24 2007 -0700
+++ b/examples/wscript Sun Aug 12 22:43:25 2007 -0700
@@ -22,3 +22,6 @@
['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'
--- a/src/devices/csma/csma-net-device.cc Sun Aug 12 22:41:24 2007 -0700
+++ b/src/devices/csma/csma-net-device.cc Sun Aug 12 22:43:25 2007 -0700
@@ -133,7 +133,6 @@
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
- EnablePointToPoint();
SetSendEnable (sendEnable);
SetReceiveEnable (receiveEnable);
--- a/src/routing/global-routing/global-route-manager-impl.cc Sun Aug 12 22:41:24 2007 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.cc Sun Aug 12 22:43:25 2007 -0700
@@ -48,8 +48,7 @@
{
}
-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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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::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 @@
// 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 ();
-
- NS_DEBUG ("SPFNext: Considering w_lsa " <<
- w_lsa->GetLinkStateId ());
+ if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ distance = v->GetDistanceFromRoot () + l->GetMetric ();
+ }
+ else
+ {
+ distance = v->GetDistanceFromRoot ();
+ }
- 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);
-//
+ NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// 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 @@
//
// 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 @@
// 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::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 @@
// 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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
//
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 @@
// 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 @@
// 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).
//
@@ -1026,6 +1165,80 @@
}
//
+// 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 ()
//
// This is where we are actually going to add the host routes to the routing
@@ -1109,7 +1322,7 @@
// 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 @@
//
// 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 @@
}
}
}
+ 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 @@
// 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 @@
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);
--- a/src/routing/global-routing/global-route-manager-impl.h Sun Aug 12 22:41:24 2007 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.h Sun Aug 12 22:43:25 2007 -0700
@@ -102,10 +102,10 @@
*
* @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 @@
* @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 @@
*
* @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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
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 @@
* 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 @@
* 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 @@
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
--- a/src/routing/global-routing/global-router-interface.cc Sun Aug 12 22:41:24 2007 -0700
+++ b/src/routing/global-routing/global-router-interface.cc Sun Aug 12 22:43:25 2007 -0700
@@ -28,21 +28,21 @@
// ---------------------------------------------------------------------------
//
-// 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 @@
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 @@
}
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 @@
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 @@
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 @@
{
NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA");
- GlobalRouterLSA *p = *i;
+ GlobalRoutingLSA *p = *i;
delete p;
p = 0;
@@ -373,11 +461,16 @@
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 @@
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 (): 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);
+ 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();
+ 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;
+ }
}
-
- NS_DEBUG("GlobalRouter::DiscoverLSAs (): Point-to-point device");
+ 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);
+ 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);
+ 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();
+ 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 GlobalRouterLinkRecord;
- plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork);
- plr->SetLinkId (addrRemote);
- plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
- 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");
+ }
+
}
//
// 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 @@
// 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 @@
{
if (j == n)
{
- GlobalRouterLSA *p = *i;
+ GlobalRoutingLSA *p = *i;
lsa = *p;
return true;
}
--- a/src/routing/global-routing/global-router-interface.h Sun Aug 12 22:41:24 2007 -0700
+++ b/src/routing/global-routing/global-router-interface.h Sun Aug 12 22:43:25 2007 -0700
@@ -31,16 +31,16 @@
/**
* @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 @@
};
/**
- * @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 @@
* @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 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
* 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 @@
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 @@
* 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 @@
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 @@
* @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 @@
* @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 @@
* 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 @@
* 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,11 +410,48 @@
* 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.
*
* @see SPFStatus
@@ -411,11 +468,16 @@
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 @@
* 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,11 +503,31 @@
* 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
* -- a router) is new, is a candidate for a shortest path, or is in its
@@ -454,7 +536,7 @@
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 @@
/**
* @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 @@
* 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 @@
* 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 @@
* 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 @@
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;