From 7fec46aecf3064b3a64b337e34d09302434b7ebd Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 20 Jun 2007 12:07:31 -0700 Subject: [PATCH 01/92] test --- SConstruct | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SConstruct b/SConstruct index 44f168c6b..95b3b2804 100644 --- a/SConstruct +++ b/SConstruct @@ -1,4 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +# +# +# import os.path import build From 89ea0a9911118c72db9a9ee2fc7b07536c34ac25 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 28 Jun 2007 14:29:46 -0700 Subject: [PATCH 02/92] test --- SConstruct | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SConstruct b/SConstruct index 95b3b2804..b52a16cf5 100644 --- a/SConstruct +++ b/SConstruct @@ -1,7 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -# -# -# + import os.path import build From b22e98aa017b2628e49228e0e9522be6afd00102 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 28 Jun 2007 14:39:56 -0700 Subject: [PATCH 03/92] test --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index b52a16cf5..aa77efa0d 100644 --- a/SConstruct +++ b/SConstruct @@ -1,5 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +# + import os.path import build From a5e90a8deae122ed11a1d62f255304f0b166f83e Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 28 Jun 2007 14:54:42 -0700 Subject: [PATCH 04/92] test --- SConstruct | 2 -- 1 file changed, 2 deletions(-) diff --git a/SConstruct b/SConstruct index aa77efa0d..b52a16cf5 100644 --- a/SConstruct +++ b/SConstruct @@ -1,7 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -# - import os.path import build From 58d341cea3bdbe69dd1478fd3b749ffe4418038f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 3 Jul 2007 12:43:39 -0700 Subject: [PATCH 05/92] test --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConstruct b/SConstruct index b52a16cf5..aa77efa0d 100644 --- a/SConstruct +++ b/SConstruct @@ -1,5 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +# + import os.path import build From 418275589cf5f4f19f38fc0493c1bf2ffa22969b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 5 Jul 2007 23:27:28 -0700 Subject: [PATCH 06/92] beginnings of static routing --- src/routing/static-router.cc | 38 ++++++++++++++++ src/routing/static-router.h | 85 ++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/routing/static-router.cc create mode 100644 src/routing/static-router.h diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc new file mode 100644 index 000000000..60ff0e189 --- /dev/null +++ b/src/routing/static-router.cc @@ -0,0 +1,38 @@ +/* -*- 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 + */ + +#include "ns3/debug.h" +#include "static-router.h" + +NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); + +namespace ns3 { + +const InterfaceId StaticRouter::iid = + MakeInterfaceId ("StaticRouter", Object::iid); + +StaticRouter::StaticRouter () +{ + SetInterfaceId (StaticRouter::iid); + NS_DEBUG("StaticRouter::StaticRouter ()"); +} + +StaticRouter::~StaticRouter () +{ + NS_DEBUG("StaticRouter::~StaticRouter ()"); +} + +} // namespace ns3 diff --git a/src/routing/static-router.h b/src/routing/static-router.h new file mode 100644 index 000000000..dcb14b570 --- /dev/null +++ b/src/routing/static-router.h @@ -0,0 +1,85 @@ +/* -*- 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 + */ +#ifndef STATIC_ROUTER_H +#define STATIC_ROUTER_H + +#include +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" + +namespace ns3 { + +// +// Roughly equivalent to a static incarnation of the OSPF link state header +// combined with a single Router-LSA Link Record. Since it's static, there's +// no need for age or sequence number. +// + +class StaticRouterLinkRecord +{ +public: + IpV4Address m_originator; // Router ID of this router + + enum LinkType { + PointToPoint = 1, + TransitNetwork, + StubNetwork, + VirtualLink + }; + + LinkType m_linkType; // What kind of link this is + + Ipv4Address m_linkId; // Neighbor's router ID + + union { + uint32_t m_interfaceIndex; // For unnumbered links + uint32_t m_networkMask; // For Stub Network (self) + } u; + + uint32_t m_metric; // Abstract cost of sending packets +}; + +// +// An interface aggregated to a node that provides static routing information +// to a global route manager. The presence of the interface indicates that +// the node is a router. The interface is the mechanism by which the router +// advertises its connections to neighboring routers. We're basically +// allowing the route manager to query for link state advertisements. +// + +class StaticRouter : public Object +{ +public: + static const InterfaceId iid; + StaticRouter (); + + void SetRouterId (IpV4Address routerId); + + uint32_t GetNumLinkRecords (void); + bool GetLinkRecord (uint32_t n, StaticRouterLinkRecord &lsa); + +protected: + virtual ~StaticRouter (); + + IpV4Address m_routerId; // Router ID of this router + +private: +}; + +} // namespace ns3 + +#endif /* STATIC_ROUTER_H */ From 4156e28d78834b2a877cb10d7b1f73954e70ca99 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 13:13:43 -0700 Subject: [PATCH 07/92] add example static routing script; a few changes to static-router LSAs --- SConstruct | 6 + examples/simple-static-routing.cc | 191 ++++++++++++++++++++++++++++++ src/routing/static-router.h | 73 +++++++----- 3 files changed, 239 insertions(+), 31 deletions(-) create mode 100644 examples/simple-static-routing.cc diff --git a/SConstruct b/SConstruct index aa77efa0d..4cc78440f 100644 --- a/SConstruct +++ b/SConstruct @@ -475,4 +475,10 @@ ns3.add(example_simple_p2p) example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications']) example_simple_p2p.add_source('simple-p2p.cc') +example_static_routing = build.Ns3Module('simple-static-routing', 'examples') +example_static_routing.set_executable() +ns3.add(example_static_routing) +example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications']) +example_static_routing.add_source('simple-static-routing.cc') + ns3.generate_dependencies() diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc new file mode 100644 index 000000000..9ad235b5e --- /dev/null +++ b/examples/simple-static-routing.cc @@ -0,0 +1,191 @@ +/* -*- 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 + * + * ns-2 simple.tcl script (ported from ns-2) + * Originally authored by Steve McCanne, 12/19/1996 + */ + +// Port of ns-2/tcl/ex/simple.tcl to ns-3 +// +// Network topology +// +// n0 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 -------------------------n3 +// / +// / 5 Mb/s, 2ms +// n1 +// +// - all links are p2p links with indicated one-way BW/delay +// - CBR/UDP flows from n0 to n3, and from n3 to n1 +// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "simple-p2p.tr" + +#include +#include +#include +#include + +#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/p2p-channel.h" +#include "ns3/p2p-net-device.h" +#include "ns3/mac-address.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/ipv4-route.h" +#include "ns3/p2p-topology.h" +#include "ns3/onoff-application.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"); +#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 Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + Bind ("Queue", "DropTailQueue"); + + Bind ("OnOffApplicationPacketSize", "210"); + Bind ("OnOffApplicationDataRate", "448kb/s"); + + //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); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = 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 ( + n2, n3, DataRate(1500000), MilliSeconds(10)); + + // 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, n2, Ipv4Address("10.1.3.1"), + n3, Ipv4Address("10.1.3.2")); + + // Finally, we add static routes. These three steps (Channel and + // NetDevice creation, IP Address assignment, and routing) are + // separated because there may be a need to postpone IP Address + // assignment (emulation) or modify to use dynamic routing + PointToPointTopology::AddIpv4Routes(n0, n2, channel0); + PointToPointTopology::AddIpv4Routes(n1, n2, channel1); + PointToPointTopology::AddIpv4Routes(n2, n3, channel2); + + + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s + Ptr ooff = Create ( + n0, + Ipv4Address("10.1.3.2"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); + + // Create a similar flow from n3 to n1, starting at time 1.1 seconds + ooff = Create ( + n3, + Ipv4Address("10.1.2.1"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.1)); + ooff->Stop (Seconds(10.0)); + + // Here, finish off packet routing configuration + // This will likely set by some global StaticRouting object in the future + Ptr ipv4; + ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); + ipv4 = n3->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-p2p.tr file + AsciiTrace asciitrace ("simple-p2p.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 ("simple-p2p.pcap"); + pcaptrace.TraceAllIp (); + + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/src/routing/static-router.h b/src/routing/static-router.h index dcb14b570..41ea45aea 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -23,16 +23,15 @@ namespace ns3 { -// -// Roughly equivalent to a static incarnation of the OSPF link state header -// combined with a single Router-LSA Link Record. Since it's static, there's -// no need for age or sequence number. -// - +/** + * \brief A single link record for a link state advertisement + * + */ class StaticRouterLinkRecord { public: - IpV4Address m_originator; // Router ID of this router + uint32_t m_linkId; + Ipv4Address m_linkData; enum LinkType { PointToPoint = 1, @@ -40,44 +39,56 @@ public: StubNetwork, VirtualLink }; + + uint32_t m_metric; +} - LinkType m_linkType; // What kind of link this is +/** + * \brief a Link State Advertisement (LSA) for a router, used in static routing + * + * Roughly equivalent to a static incarnation of the OSPF link state header + * combined with a list of Link Records. Since it's static, there's + * no need for age or sequence number. See RFC 2328, Appendix A. + */ +class StaticRouterLSA +{ +public: + enum LSType { + RouterLSA = 1, + NetworkLSA + } m_LSType; + uint32_t m_linkStateId; + Ipv4Address m_advertising_rtr; + uint32_t m_numLinks; - Ipv4Address m_linkId; // Neighbor's router ID - - union { - uint32_t m_interfaceIndex; // For unnumbered links - uint32_t m_networkMask; // For Stub Network (self) - } u; - - uint32_t m_metric; // Abstract cost of sending packets + typedef std::list type_listOfLinkRecords; + type_listOfLinkRecords m_listOfLinkRecords; + type_listOfLinkRecords::iterator m_iter; }; -// -// An interface aggregated to a node that provides static routing information -// to a global route manager. The presence of the interface indicates that -// the node is a router. The interface is the mechanism by which the router -// advertises its connections to neighboring routers. We're basically -// allowing the route manager to query for link state advertisements. -// - +/** + * \brief An interface aggregated to a node to provide static routing info + * + * An interface aggregated to a node that provides static routing information + * to a global route manager. The presence of the interface indicates that + * the node is a router. The interface is the mechanism by which the router + * advertises its connections to neighboring routers. We're basically + * allowing the route manager to query for link state advertisements. + */ class StaticRouter : public Object { public: static const InterfaceId iid; - StaticRouter (); + StaticRouter (Ptr node); - void SetRouterId (IpV4Address routerId); - - uint32_t GetNumLinkRecords (void); - bool GetLinkRecord (uint32_t n, StaticRouterLinkRecord &lsa); + uint32_t GetNumLSAs (void); + bool GetLSA (uint32_t n, StaticRouterLSA &lsa); protected: virtual ~StaticRouter (); - IpV4Address m_routerId; // Router ID of this router - private: + Ptr m_node; }; } // namespace ns3 From fdda9161fe86dcbba2ee6f62d57057716c67d1c0 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 14:19:40 -0700 Subject: [PATCH 08/92] a few fixes to the LSAs --- src/routing/static-router.h | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 41ea45aea..cf3bcfe9c 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -26,21 +26,34 @@ namespace ns3 { /** * \brief A single link record for a link state advertisement * + * For Type 3 link (Stub), */ class StaticRouterLinkRecord { public: - uint32_t m_linkId; - Ipv4Address m_linkData; + // + // For Type 1 link (PointToPoint), set m_linkId to Router ID of + // neighboring router. + // + // For Type 3 link (Stub), set m_linkId to neighbor's IP address + // + Ipv4Address m_linkId; + + // + // For Type 1 link (PointToPoint), set m_linkData to local IP address + // + // For Type 3 link (Stub), set m_linkData to mask 0xffffffff + // + Ipv4Address m_linkData; // for links to RouterLSA, enum LinkType { PointToPoint = 1, TransitNetwork, StubNetwork, VirtualLink - }; + } m_linkType; - uint32_t m_metric; + uint32_t m_metric; } /** @@ -53,14 +66,10 @@ public: class StaticRouterLSA { public: - enum LSType { - RouterLSA = 1, - NetworkLSA - } m_LSType; - uint32_t m_linkStateId; - Ipv4Address m_advertising_rtr; - uint32_t m_numLinks; + Ipv4Address m_linkStateId; // set to the NodeId + Ipv4Address m_advertising_rtr; // set to the NodeId + uint32_t m_numLinks; typedef std::list type_listOfLinkRecords; type_listOfLinkRecords m_listOfLinkRecords; type_listOfLinkRecords::iterator m_iter; From 59633b8ba6edf939aee03d7b4a7da395123922f9 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 14:47:01 -0700 Subject: [PATCH 09/92] remove p2p strings in simple-static-routing example --- examples/simple-static-routing.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 9ad235b5e..b1e40033f 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -29,13 +29,13 @@ // / 5 Mb/s, 2ms // n1 // -// - all links are p2p links with indicated one-way BW/delay +// - all links are point-to-point links with indicated one-way BW/delay // - CBR/UDP flows from n0 to n3, and from n3 to n1 // - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. // - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. // (i.e., DataRate of 448,000 bps) // - DropTail queues -// - Tracing of queues and packet receptions to file "simple-p2p.tr" +// - Tracing of queues and packet receptions to file "simple-static-routing.tr" #include #include @@ -173,8 +173,8 @@ int main (int argc, char *argv[]) ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); // Configure tracing of all enqueue, dequeue, and NetDevice receive events - // Trace output will be sent to the simple-p2p.tr file - AsciiTrace asciitrace ("simple-p2p.tr"); + // Trace output will be sent to the simple-static-routing.tr file + AsciiTrace asciitrace ("simple-static-routing.tr"); asciitrace.TraceAllQueues (); asciitrace.TraceAllNetDeviceRx (); @@ -182,7 +182,7 @@ int main (int argc, char *argv[]) // 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 ("simple-p2p.pcap"); + PcapTrace pcaptrace ("simple-static-routing.pcap"); pcaptrace.TraceAllIp (); Simulator::Run (); From 7979a013711d5a197ed5a9b9e7854c277ed86c7d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 6 Jul 2007 15:03:59 -0700 Subject: [PATCH 10/92] static routing --- examples/simple-static-routing.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 9ad235b5e..7e194c6a3 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -88,6 +88,11 @@ int main (int argc, char *argv[]) // instantiate, when the queue factory is invoked in the topology code Bind ("Queue", "DropTailQueue"); + // This bind tells the system to use global static routing. It results in + // a StaticRouter interface being aggregated to the internet nodes and the + // creation of a Route Manager component to oversee the route generation. + Bind ("DoStaticRouting", "true"); + Bind ("OnOffApplicationPacketSize", "210"); Bind ("OnOffApplicationDataRate", "448kb/s"); From 2f5acd74d97ef688fedfcc31e47dc7f955130c7a Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 6 Jul 2007 15:04:33 -0700 Subject: [PATCH 11/92] static routing --- src/internet-node/internet-node.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index 85a6a0dec..611b6c9a5 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -23,6 +23,8 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/net-device.h" +#include "ns3/routing-environment.h" +#include "ns3/static-router.h" #include "l3-demux.h" #include "ipv4-l4-demux.h" @@ -37,7 +39,6 @@ namespace ns3 { - InternetNode::InternetNode() { Construct (); @@ -76,9 +77,19 @@ InternetNode::Construct (void) Object::AddInterface (udpImpl); Object::AddInterface (l3Demux); Object::AddInterface (ipv4L4Demux); +// +// If static routing has been enabled via bind(), all nodes will have the +// capacity to participate in the global static routing scheme. The presence +// of the StaticRouter interface tells the route manager that it needs to +// ask a given node about any link state records that it may want to advertise. +// + if (RoutingEnvironment::StaticRoutingEnabled()) + { + Ptr staticRouter = Create (this); + Object::AddInterface (staticRouter); + } } - TraceResolver * InternetNode::DoCreateTraceResolver (TraceContext const &context) { From d0ff4c3306651bedfccdcfe64995c8b381406df7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 6 Jul 2007 15:05:47 -0700 Subject: [PATCH 12/92] static routing --- src/routing/static-router.cc | 4 +++- src/routing/static-router.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 60ff0e189..02b8fb95b 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -15,6 +15,7 @@ */ #include "ns3/debug.h" +#include "ns3/internet-node.h" #include "static-router.h" NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); @@ -24,7 +25,8 @@ namespace ns3 { const InterfaceId StaticRouter::iid = MakeInterfaceId ("StaticRouter", Object::iid); -StaticRouter::StaticRouter () +StaticRouter::StaticRouter (Ptr node) + : m_node(node) { SetInterfaceId (StaticRouter::iid); NS_DEBUG("StaticRouter::StaticRouter ()"); diff --git a/src/routing/static-router.h b/src/routing/static-router.h index cf3bcfe9c..234755aae 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -17,6 +17,7 @@ #define STATIC_ROUTER_H #include +#include #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/ipv4-address.h" @@ -54,7 +55,7 @@ public: } m_linkType; uint32_t m_metric; -} +}; /** * \brief a Link State Advertisement (LSA) for a router, used in static routing From 42bc462559411ecd1b08ed255e7d5e9edaf0d653 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 6 Jul 2007 15:06:26 -0700 Subject: [PATCH 13/92] static routing --- src/routing/routing-environment.cc | 39 ++++++++++++++++++++++++++++++ src/routing/routing-environment.h | 32 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/routing/routing-environment.cc create mode 100644 src/routing/routing-environment.h diff --git a/src/routing/routing-environment.cc b/src/routing/routing-environment.cc new file mode 100644 index 000000000..160bd8668 --- /dev/null +++ b/src/routing/routing-environment.cc @@ -0,0 +1,39 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * All rights reserved. + * + * 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 + */ + +#include "ns3/debug.h" +#include "ns3/default-value.h" + +#include "routing-environment.h" + +NS_DEBUG_COMPONENT_DEFINE ("RoutingEnvironment"); + +namespace ns3 { +namespace RoutingEnvironment { + +BooleanDefaultValue g_doStaticRoutingDefaultValue ("DoStaticRouting", + "Enable global static routing", false); + + bool +StaticRoutingEnabled(void) +{ + return g_doStaticRoutingDefaultValue.GetValue(); +} + +} // namespace RoutingEnvironment +} // namespace ns3 diff --git a/src/routing/routing-environment.h b/src/routing/routing-environment.h new file mode 100644 index 000000000..abf9da4d8 --- /dev/null +++ b/src/routing/routing-environment.h @@ -0,0 +1,32 @@ +/* -*- 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 + */ +#ifndef ROUTING_ENVIRONMENT_H +#define ROUTING_ENVIRONMENT_H + +#include +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" + +namespace ns3 { +namespace RoutingEnvironment { + +bool StaticRoutingEnabled(void); + +} // namespace RoutingEnvironment +} // namespace ns3 + +#endif /* ROUTING_ENVIRONMENT_H */ From 5a7dd756872ffe0f80684c9a9ec852314e41e207 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 6 Jul 2007 15:07:03 -0700 Subject: [PATCH 14/92] static routing --- SConstruct | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/SConstruct b/SConstruct index 4cc78440f..049711378 100644 --- a/SConstruct +++ b/SConstruct @@ -1,7 +1,5 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -# - import os.path import build @@ -47,8 +45,6 @@ for wscript in [ ns3.add_extra_dist('waf') ns3.add_extra_dist('waf.bat') - - # # The Core module # @@ -115,7 +111,7 @@ def config_core (env, config): core.add_config (config_core) # -# The Simu module +# The Simulator module # simu = build.Ns3Module('simulator', 'src/simulator') ns3.add(simu) @@ -178,7 +174,6 @@ def config_simulator (env, config): return retval simu.add_config (config_simulator) - # # The Common module # @@ -226,6 +221,9 @@ common.add_inst_headers([ 'data-rate.h', ]) +# +# The Node module +# node = build.Ns3Module ('node', 'src/node') ns3.add (node) node.add_deps (['core', 'common', 'simulator']) @@ -264,6 +262,9 @@ node.add_inst_headers ([ 'application.h', ]) +# +# The Applications module +# applications = build.Ns3Module ('applications', 'src/applications') ns3.add (applications) applications.add_deps (['node']) @@ -274,6 +275,9 @@ applications.add_inst_headers ([ 'onoff-application.h', ]) +# +# The Internet Node module +# inode = build.Ns3Module ('internet-node', 'src/internet-node') ns3.add (inode) inode.add_deps (['node']) @@ -339,8 +343,9 @@ inode.add_inst_headers ([ 'pcap-trace.h', ]) - - +# +# The Point-to-point module +# p2p = build.Ns3Module ('p2p', 'src/devices/p2p') ns3.add (p2p) p2p.add_deps (['node']) @@ -355,6 +360,22 @@ p2p.add_inst_headers ([ 'p2p-topology.h', ]) +# +# The Routing module +# +routing = build.Ns3Module('routing', 'src/routing') +routing.add_deps(['core']) +ns3.add(routing) +routing.add_sources([ + 'routing-environment.cc', + 'static-router.cc', + ]) +routing.add_headers ([ + ]) +routing.add_inst_headers([ + 'routing-environment.h', + 'static-router.h', + ]) # utils run_tests = build.Ns3Module('run-tests', 'utils') @@ -441,7 +462,7 @@ sample_test.add_source('main-test.cc') sample_simple = build.Ns3Module('sample-simple', 'samples') sample_simple.set_executable() ns3.add(sample_simple) -sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node']) +sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node', 'routing']) sample_simple.add_source('main-simple.cc') sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples') @@ -472,13 +493,13 @@ sample_component_manager.add_source('main-component-manager.cc') example_simple_p2p = build.Ns3Module('simple-p2p', 'examples') example_simple_p2p.set_executable() ns3.add(example_simple_p2p) -example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications']) +example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing']) example_simple_p2p.add_source('simple-p2p.cc') example_static_routing = build.Ns3Module('simple-static-routing', 'examples') example_static_routing.set_executable() ns3.add(example_static_routing) -example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications']) +example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing']) example_static_routing.add_source('simple-static-routing.cc') ns3.generate_dependencies() From 4d9b0f615783236d288ab41f8899616bd04e015b Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 16:21:50 -0700 Subject: [PATCH 15/92] Add routing dependency to inode in SConstruct --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 023e15517..a91b232cf 100644 --- a/SConstruct +++ b/SConstruct @@ -284,7 +284,7 @@ applications.add_inst_headers ([ # inode = build.Ns3Module ('internet-node', 'src/internet-node') ns3.add (inode) -inode.add_deps (['node']) +inode.add_deps (['node', 'routing']) inode.add_sources ([ 'internet-node.cc', 'l3-demux.cc', From 60685f35d8d91bfb4a3b531f2ba1f29c02ba40b0 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 16:44:58 -0700 Subject: [PATCH 16/92] Add static-route-manager scaffolding --- SConstruct | 2 ++ examples/simple-static-routing.cc | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/SConstruct b/SConstruct index a91b232cf..bd90edd57 100644 --- a/SConstruct +++ b/SConstruct @@ -373,12 +373,14 @@ ns3.add(routing) routing.add_sources([ 'routing-environment.cc', 'static-router.cc', + 'static-route-manager.cc', ]) routing.add_headers ([ ]) routing.add_inst_headers([ 'routing-environment.h', 'static-router.h', + 'static-route-manager.h', ]) # utils diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 1fc92fd04..50bc38a17 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -63,6 +63,7 @@ #include "ns3/ipv4-route.h" #include "ns3/p2p-topology.h" #include "ns3/onoff-application.h" +#include "ns3/static-route-manager.h" using namespace ns3; @@ -135,6 +136,10 @@ int main (int argc, char *argv[]) channel2, n2, Ipv4Address("10.1.3.1"), n3, Ipv4Address("10.1.3.2")); + // Here, we will use the StaticRoutingManager to build routes + Ptr route_manager = Create (); + + // XXX this goes away once static routing is in place // Finally, we add static routes. These three steps (Channel and // NetDevice creation, IP Address assignment, and routing) are // separated because there may be a need to postpone IP Address From 1194823a738d56addd24784313f376e7158168fa Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 16:57:35 -0700 Subject: [PATCH 17/92] Add more scaffolding --- examples/simple-static-routing.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 50bc38a17..86726f827 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -137,7 +137,11 @@ int main (int argc, char *argv[]) n3, Ipv4Address("10.1.3.2")); // Here, we will use the StaticRoutingManager to build routes - Ptr route_manager = Create (); + Ptr routeManager = Create (); + // The below functions might better be placed in some kind of + // Simulator::Initialization function (for further study) + routeManager->BuildStaticRoutingDatabase (); + routeManager->InitializeRoutes (); // XXX this goes away once static routing is in place // Finally, we add static routes. These three steps (Channel and From 3aa83b20ff3aed7bf41225f5cf1903f842e920ae Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 6 Jul 2007 17:13:49 -0700 Subject: [PATCH 18/92] include node.h --- src/routing/static-router.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 234755aae..27070888f 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -20,6 +20,7 @@ #include #include "ns3/object.h" #include "ns3/ptr.h" +#include "ns3/node.h" #include "ns3/ipv4-address.h" namespace ns3 { From 4d0e208a2e690bf2533625d85a8695d1a5de8614 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 8 Jul 2007 13:55:03 -0700 Subject: [PATCH 19/92] Add routing module to run_tests; add node module as dependency to routing --- SConstruct | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SConstruct b/SConstruct index bd90edd57..5fcd7d29b 100644 --- a/SConstruct +++ b/SConstruct @@ -368,7 +368,7 @@ p2p.add_inst_headers ([ # The Routing module # routing = build.Ns3Module('routing', 'src/routing') -routing.add_deps(['core']) +routing.add_deps(['core', 'node']) ns3.add(routing) routing.add_sources([ 'routing-environment.cc', @@ -387,7 +387,7 @@ routing.add_inst_headers([ run_tests = build.Ns3Module('run-tests', 'utils') ns3.add(run_tests) run_tests.set_executable() -run_tests.add_deps(['core', 'simulator', 'common']) +run_tests.add_deps(['core', 'simulator', 'common', 'routing']) run_tests.add_source('run-tests.cc') bench_object = build.Ns3Module('bench-object', 'utils') From 2447ea37ca70a3f5f3ae1e3d0c2a7c3c4785b11d Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 8 Jul 2007 13:55:39 -0700 Subject: [PATCH 20/92] Add Set methods to class Ipv4Address (like the non-default ctors) --- src/node/ipv4-address.cc | 11 +++++++++++ src/node/ipv4-address.h | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/node/ipv4-address.cc b/src/node/ipv4-address.cc index f8ff9f7a6..2973c1775 100644 --- a/src/node/ipv4-address.cc +++ b/src/node/ipv4-address.cc @@ -135,6 +135,17 @@ Ipv4Address::Ipv4Address (char const *address) m_address = AsciiToIpv4Host (address); } +void +Ipv4Address::Set (uint32_t address) +{ + m_address = address; +} +void +Ipv4Address::Set (char const *address) +{ + m_address = AsciiToIpv4Host (address); +} + bool Ipv4Address::IsEqual (Ipv4Address other) const { diff --git a/src/node/ipv4-address.h b/src/node/ipv4-address.h index dc834052a..b4a020380 100644 --- a/src/node/ipv4-address.h +++ b/src/node/ipv4-address.h @@ -49,6 +49,22 @@ public: */ Ipv4Address (char const *address); + /** + * input address is in host order. + * \param address The host order 32-bit address + */ + void Set (uint32_t address); + /** + * \brief Sets an Ipv4Address by parsing a the input C-string + * + * Input address is in format: + * hhh.xxx.xxx.lll + * where h is the high byte and l the + * low byte + * \param address C-string containing the address as described above + */ + void Set (char const *address); + /** * \brief Comparison operation between two Ipv4Addresses * \param other address to which to compare this address From 37783c34462d62ee681c681c70807c0f44b1b3cd Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 8 Jul 2007 15:12:50 -0700 Subject: [PATCH 21/92] Add ctor/dtor to StaticRouterLSA, add the Add() method to add link records, misc. cleanup --- src/routing/static-route-manager.cc | 105 ++++++++++++++++++++++++++++ src/routing/static-route-manager.h | 94 +++++++++++++++++++++++++ src/routing/static-router.cc | 24 +++++++ src/routing/static-router.h | 8 ++- 4 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 src/routing/static-route-manager.cc create mode 100644 src/routing/static-route-manager.h diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc new file mode 100644 index 000000000..f9e56a841 --- /dev/null +++ b/src/routing/static-route-manager.cc @@ -0,0 +1,105 @@ +/* -*- 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 + */ +#include +#include +#include "ns3/assert.h" +#include "ns3/fatal-error.h" +#include "ns3/debug.h" +#include "ns3/node-list.h" +#include "static-router.h" +#include "static-route-manager.h" + +NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); + +namespace ns3 { + +StaticRouteManager::StaticRouteManager () +{ +} + +StaticRouteManager::~StaticRouteManager () +{} + +void +StaticRouteManager::BuildStaticRoutingDatabase () +{ + // walk list of nodes. QI for StaticRouter interface. + // if node has a StaticRouter interface, grab the LSAs + // from it and stick them in the LSDB + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) + { + Ptr node = *i; + NS_DEBUG_UNCOND ("node="<< node->GetId () ); + } +} + +void +StaticRouteManager::InitializeRoutes () +{ + // For each node that is a static router (which can be determined by + // the presence of StaticRouter interface), run Dijkstra SPF calculation + // on the database rooted at that router, and populate the node + // forwarding tables +} + +} // namespace ns3 + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" + +namespace ns3 { + +class StaticRouteManagerTest : public Test { +public: + StaticRouteManagerTest (); + virtual ~StaticRouteManagerTest (); + virtual bool RunTests (void); +}; + +StaticRouteManagerTest::StaticRouteManagerTest () + : Test ("StaticRouteManager") +{ +} + +StaticRouteManagerTest::~StaticRouteManagerTest () +{} + +bool +StaticRouteManagerTest::RunTests (void) +{ + DebugComponentEnable("StaticRouteManager"); + bool ok = true; + StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord(); + lr1->m_linkId.Set(1); + lr1->m_linkData.Set(0xffffffff); + lr1->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr1->m_metric = 1; + StaticRouterLSA* lsa1 = new StaticRouterLSA(); + lsa1->m_linkStateId.Set(1); + lsa1->m_advertisingRtr.Set(1); + lsa1->Add(lr1); + + delete lsa1; + return ok; +} + +static StaticRouteManagerTest g_staticRouteManagerTest; + +} // namespace ns3 + +#endif diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h new file mode 100644 index 000000000..7b8ea5c74 --- /dev/null +++ b/src/routing/static-route-manager.h @@ -0,0 +1,94 @@ +/* -*- 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 + */ +#ifndef STATIC_ROUTE_MANAGER_H +#define STATIC_ROUTE_MANAGER_H + +#include +#include +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" + +namespace ns3 { + +/** + * \brief Vertex used in shortest path first (SPF) computations + * + * See RFC 2328, Section 16. + */ +class SPFVertex +{ +public: + enum VertexType { + VertexRouter = 1, + VertexNetwork + } m_vertexType; + + Ipv4Address m_vertexId; + + uint32_t m_distanceFromRoot; + + typedef std::list type_listOfSPFVertex; + type_listOfSPFVertex m_parents; + type_listOfSPFVertex m_children; + type_listOfSPFVertex::iterator m_iter; +}; + +/** + * \brief The Link State DataBase (LSDB) of a static router + */ +class StaticRouteManagerLSDB +{ +public: +}; + +/** + * \brief A global static router + * + * This singleton object can query interface each node in the system + * for a StaticRouter interface. For those nodes, it fetches one or + * more LSAs and stores them in a local database. Then, it + * can compute shortest paths on a per-node basis to all routers, and + * finally configure each of the node's forwarding tables. + * + * The design is guided by OSPFv2 RFC 2328 section 16.1.1 + * and quagga ospfd + */ +class StaticRouteManager : public Object +{ +public: + static const InterfaceId iid; + StaticRouteManager (); + /** + * \brief Build routing database by gathering LSA from each routing node + */ + virtual void BuildStaticRoutingDatabase(); + /** + * \brief Compute routes using Dijkstra SPF computation, and populate + * per-node forwarding tables + */ + virtual void InitializeRoutes(); + +protected: + virtual ~StaticRouteManager (); + +private: + StaticRouteManagerLSDB m_lsdb; +}; + +} // namespace ns3 + +#endif /* STATIC_ROUTE_MANAGER_H */ diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 02b8fb95b..5d35afc84 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -22,6 +22,30 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); namespace ns3 { +StaticRouterLSA::StaticRouterLSA () : m_linkStateId(0x66666666), + m_advertisingRtr(0x66666666), m_numLinks(0) +{ + NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); +} +StaticRouterLSA::~StaticRouterLSA () +{ + NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()"); + for (m_iter = m_listOfLinkRecords.begin(); + m_iter != m_listOfLinkRecords.end(); m_iter++) + { + NS_DEBUG_UNCOND("Deleting"); + StaticRouterLinkRecord* temp = *m_iter; + delete temp; + } +} + +uint32_t +StaticRouterLSA::Add (StaticRouterLinkRecord* lr) +{ + m_listOfLinkRecords.push_back (lr); + return m_listOfLinkRecords.size (); +} + const InterfaceId StaticRouter::iid = MakeInterfaceId ("StaticRouter", Object::iid); diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 27070888f..1a157c03b 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -67,14 +67,18 @@ public: */ class StaticRouterLSA { +public: + StaticRouterLSA(); + virtual ~StaticRouterLSA (); public: Ipv4Address m_linkStateId; // set to the NodeId - Ipv4Address m_advertising_rtr; // set to the NodeId + Ipv4Address m_advertisingRtr; // set to the NodeId uint32_t m_numLinks; - typedef std::list type_listOfLinkRecords; + typedef std::list type_listOfLinkRecords; type_listOfLinkRecords m_listOfLinkRecords; type_listOfLinkRecords::iterator m_iter; + uint32_t Add (StaticRouterLinkRecord* lr); }; /** From 9c3fa17ce21b9d69aae66488fd4a2c3f21ae7a6d Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 8 Jul 2007 15:17:45 -0700 Subject: [PATCH 22/92] Remove NS_DEBUG in destructor --- src/routing/static-router.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 5d35afc84..2edf15752 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -33,7 +33,6 @@ StaticRouterLSA::~StaticRouterLSA () for (m_iter = m_listOfLinkRecords.begin(); m_iter != m_listOfLinkRecords.end(); m_iter++) { - NS_DEBUG_UNCOND("Deleting"); StaticRouterLinkRecord* temp = *m_iter; delete temp; } From 849c347d2e31299f68cad14c9f7194e26d23ecd1 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 8 Jul 2007 15:30:17 -0700 Subject: [PATCH 23/92] Remove m_numLinks LSA member (redundant with list.size() method) --- src/routing/static-router.cc | 4 ++-- src/routing/static-router.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 2edf15752..7b9d8f143 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -22,8 +22,8 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); namespace ns3 { -StaticRouterLSA::StaticRouterLSA () : m_linkStateId(0x66666666), - m_advertisingRtr(0x66666666), m_numLinks(0) +StaticRouterLSA::StaticRouterLSA () : + m_linkStateId(0x66666666), m_advertisingRtr(0x66666666) { NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 1a157c03b..bacdfcf57 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -70,15 +70,15 @@ class StaticRouterLSA public: StaticRouterLSA(); virtual ~StaticRouterLSA (); + uint32_t Add (StaticRouterLinkRecord* lr); + public: Ipv4Address m_linkStateId; // set to the NodeId Ipv4Address m_advertisingRtr; // set to the NodeId - uint32_t m_numLinks; typedef std::list type_listOfLinkRecords; type_listOfLinkRecords m_listOfLinkRecords; type_listOfLinkRecords::iterator m_iter; - uint32_t Add (StaticRouterLinkRecord* lr); }; /** From dfb744bdf194d20440a14ddbb228b8de3ec62a69 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jul 2007 02:41:33 -0700 Subject: [PATCH 24/92] Fill out self-tests example --- src/routing/static-route-manager.cc | 115 ++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 7 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 6e9eb67a3..c327b1955 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -89,21 +89,122 @@ StaticRouteManagerTest::~StaticRouteManagerTest () bool StaticRouteManagerTest::RunTests (void) { - DebugComponentEnable("StaticRouteManager"); bool ok = true; -#if 0 + + // Build fake link state database; four routers (0-3), 3 point-to-point + // links + // + // n0 + // \ link 0 + // \ link 2 + // n2 -------------------------n3 + // / + // / link 1 + // n1 + // + // link0: 10.1.1.1/30, 10.1.1.2/30 + // link1: 10.1.2.1/30, 10.1.2.2/30 + // link2: 10.1.3.1/30, 10.1.3.2/30 + // + // Router 0 + StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord(); + lr0->m_linkId.Set(2); // router ID 0.0.0.2 + lr0->m_linkData.Set("10.1.1.1"); + lr0->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr0->m_metric = 1; StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord(); - lr1->m_linkId.Set(1); - lr1->m_linkData.Set(0xffffffff); - lr1->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr1->m_linkId.Set("10.1.1.1"); + lr1->m_linkData.Set("255.255.255.252"); + lr1->m_linkType = StaticRouterLinkRecord::StubNetwork; lr1->m_metric = 1; + StaticRouterLSA* lsa0 = new StaticRouterLSA(); + lsa0->m_linkStateId.Set(1); + lsa0->m_advertisingRtr.Set(1); + lsa0->AddLinkRecord(lr0); + lsa0->AddLinkRecord(lr1); + + // Router 1 + StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord(); + lr2->m_linkId.Set(2); // router ID 0.0.0.2 + lr2->m_linkData.Set("10.1.2.1"); + lr2->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr2->m_metric = 1; + StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord(); + lr3->m_linkId.Set("10.1.2.1"); + lr3->m_linkData.Set("255.255.255.252"); + lr3->m_linkType = StaticRouterLinkRecord::StubNetwork; + lr3->m_metric = 1; StaticRouterLSA* lsa1 = new StaticRouterLSA(); lsa1->m_linkStateId.Set(1); lsa1->m_advertisingRtr.Set(1); - lsa1->Add(lr1); + lsa1->AddLinkRecord(lr2); + lsa1->AddLinkRecord(lr3); + // Router 2 + StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord(); + lr4->m_linkId.Set("0.0.0.0"); + lr4->m_linkData.Set("10.1.1.2"); + lr4->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr4->m_metric = 1; + StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord(); + lr5->m_linkId.Set("10.1.1.2"); + lr5->m_linkData.Set("255.255.255.252"); + lr5->m_linkType = StaticRouterLinkRecord::StubNetwork; + lr5->m_metric = 1; + StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord(); + lr6->m_linkId.Set(1); + lr6->m_linkData.Set("10.1.2.2"); + lr6->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr6->m_metric = 1; + StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord(); + lr7->m_linkId.Set("10.1.2.2"); + lr7->m_linkData.Set("255.255.255.252"); + lr7->m_linkType = StaticRouterLinkRecord::StubNetwork; + lr7->m_metric = 1; + StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord(); + lr8->m_linkId.Set(3); + lr8->m_linkData.Set("10.1.3.2"); + lr8->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr8->m_metric = 1; + StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord(); + lr9->m_linkId.Set("10.1.3.2"); + lr9->m_linkData.Set("255.255.255.252"); + lr9->m_linkType = StaticRouterLinkRecord::StubNetwork; + lr9->m_metric = 1; + StaticRouterLSA* lsa2 = new StaticRouterLSA(); + lsa2->m_linkStateId.Set(2); + lsa2->m_advertisingRtr.Set(2); + lsa2->AddLinkRecord(lr4); + lsa2->AddLinkRecord(lr5); + lsa2->AddLinkRecord(lr6); + lsa2->AddLinkRecord(lr7); + lsa2->AddLinkRecord(lr8); + lsa2->AddLinkRecord(lr9); + + // Router 3 + StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord(); + lr10->m_linkId.Set(2); // router ID 0.0.0.2 + lr10->m_linkData.Set("10.1.2.1"); + lr10->m_linkType = StaticRouterLinkRecord::PointToPoint; + lr10->m_metric = 1; + StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord(); + lr11->m_linkId.Set("10.1.2.1"); + lr11->m_linkData.Set("255.255.255.252"); + lr11->m_linkType = StaticRouterLinkRecord::StubNetwork; + lr11->m_metric = 1; + StaticRouterLSA* lsa3 = new StaticRouterLSA(); + lsa3->m_linkStateId.Set(3); + lsa3->m_advertisingRtr.Set(3); + lsa3->AddLinkRecord(lr2); + lsa3->AddLinkRecord(lr3); + + // Add four LSAs to the database; XXX todo next + + delete lsa0; delete lsa1; -#endif + delete lsa2; + delete lsa3; + return ok; } From bd0cbfb5b80559613f84b66d96652fec62f1908c Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 9 Jul 2007 15:16:27 -0700 Subject: [PATCH 25/92] checkpoint --- examples/simple-static-routing.cc | 4 +- src/devices/p2p/p2p-channel.cc | 24 ++--- src/devices/p2p/p2p-channel.h | 4 +- src/node/channel.h | 27 +++-- src/routing/static-route-manager.cc | 9 ++ src/routing/static-router.cc | 161 +++++++++++++++++++++++++--- src/routing/static-router.h | 18 ++-- 7 files changed, 202 insertions(+), 45 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 86726f827..bb9dcf21e 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -42,6 +42,8 @@ #include #include +#include "ns3/debug.h" + #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" @@ -80,6 +82,7 @@ int main (int argc, char *argv[]) DebugComponentEnable("PointToPointChannel"); DebugComponentEnable("PointToPointNetDevice"); #endif + DebugComponentEnable("StaticRouter"); // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, @@ -152,7 +155,6 @@ int main (int argc, char *argv[]) PointToPointTopology::AddIpv4Routes(n1, n2, channel1); PointToPointTopology::AddIpv4Routes(n2, n3, channel2); - // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index 2833c8bb1..c91fe368c 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -1,8 +1,5 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2007 University of Washington - * All rights reserved. - * * 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; @@ -15,8 +12,6 @@ * 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 - * - * Author: Craig Dowell */ #include "p2p-channel.h" @@ -32,6 +27,7 @@ namespace ns3 { // // By default, you get a channel with the name "PointToPoint Channel" that // has an "infitely" fast transmission speed and zero delay. +// PointToPointChannel::PointToPointChannel() : Channel ("PointToPoint Channel"), @@ -91,7 +87,7 @@ PointToPointChannel::Attach(Ptr device) } } -bool + bool PointToPointChannel::TransmitStart(Packet& p, Ptr src) { NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << @@ -116,7 +112,7 @@ PointToPointChannel::TransmitStart(Packet& p, Ptr src) return true; } -bool + bool PointToPointChannel::TransmitEnd(Packet& p, Ptr src) { NS_DEBUG("PointToPointChannel::TransmitEnd (" << &p << ", " << src << ")"); @@ -144,7 +140,7 @@ PointToPointChannel::TransmitEnd(Packet& p, Ptr src) return true; } -void + void PointToPointChannel::PropagationCompleteEvent( Packet p, Ptr src) @@ -162,20 +158,25 @@ PointToPointChannel::PropagationCompleteEvent( m_link[wire].m_dst->Receive (p); } - -uint32_t + uint32_t PointToPointChannel::GetNDevices (void) const { return m_nDevices; } -Ptr + Ptr PointToPointChannel::GetDevice (uint32_t i) const { NS_ASSERT(i < 2); return m_link[i].m_src; } + Channel::ChannelType +PointToPointChannel::GetType (void) const +{ + return Channel::PointToPoint; +} + DataRate PointToPointChannel::GetDataRate (void) { @@ -188,5 +189,4 @@ PointToPointChannel::GetDelay (void) return m_delay; } - } // namespace ns3 diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 97a251177..6bd849741 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -1,7 +1,5 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2007 University of Washington - * * 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; @@ -96,6 +94,8 @@ public: virtual uint32_t GetNDevices (void) const; virtual Ptr GetDevice (uint32_t i) const; + virtual ChannelType GetType (void) const; + virtual DataRate GetDataRate (void); virtual Time GetDelay (void); diff --git a/src/node/channel.h b/src/node/channel.h index b2feb280b..0fa8d9656 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -1,7 +1,5 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2007 University of Washington - * * 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; @@ -14,11 +12,8 @@ * 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 - * - * Author: Craig Dowell - * - * Wed Feb 14 16:05:46 PST 2007 craigdo: Created */ + #ifndef CHANNEL_H #define CHANNEL_H @@ -41,6 +36,13 @@ class Channel : public Object { public: static const InterfaceId iid; + enum ChannelType + { + Unknown = 0, + PointToPoint, + Multipoint + }; + Channel (); Channel (std::string name); @@ -61,9 +63,18 @@ public: */ virtual Ptr GetDevice (uint32_t i) const = 0; + /** + * \returns the abstract type of this channel. Right now this is only + * PointToPoint (p2p) or Multipoint (Ethernet). + * + * This method must be implemented by subclasses. + */ + virtual ChannelType GetType (void) const = 0; + protected: - virtual ~Channel (); - std::string m_name; + virtual ~Channel (); + std::string m_name; + ChannelType m_channelType; private: }; diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index f9e56a841..6e9eb67a3 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -44,6 +44,13 @@ StaticRouteManager::BuildStaticRoutingDatabase () { Ptr node = *i; NS_DEBUG_UNCOND ("node="<< node->GetId () ); + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + NS_ASSERT_MSG(rtr, "QI for interface failed"); + + uint32_t numLSAs = rtr->GetNumLSAs(); + NS_DEBUG_UNCOND (numLSAs << "LSAs"); } } @@ -84,6 +91,7 @@ StaticRouteManagerTest::RunTests (void) { DebugComponentEnable("StaticRouteManager"); bool ok = true; +#if 0 StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord(); lr1->m_linkId.Set(1); lr1->m_linkData.Set(0xffffffff); @@ -95,6 +103,7 @@ StaticRouteManagerTest::RunTests (void) lsa1->Add(lr1); delete lsa1; +#endif return ok; } diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 7b9d8f143..6c8f0fc28 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -15,44 +15,61 @@ */ #include "ns3/debug.h" +#include "ns3/assert.h" +#include "ns3/channel.h" +#include "ns3/net-device.h" #include "ns3/internet-node.h" +#include "ns3/ipv4.h" #include "static-router.h" NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); namespace ns3 { -StaticRouterLSA::StaticRouterLSA () : - m_linkStateId(0x66666666), m_advertisingRtr(0x66666666) +StaticRouterLSA::StaticRouterLSA() + : + m_linkStateId("0.0.0.0"), + m_advertisingRtr("0.0.0.0"), + m_linkRecords() { NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } -StaticRouterLSA::~StaticRouterLSA () + +StaticRouterLSA::~StaticRouterLSA() { NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()"); - for (m_iter = m_listOfLinkRecords.begin(); - m_iter != m_listOfLinkRecords.end(); m_iter++) - { - StaticRouterLinkRecord* temp = *m_iter; - delete temp; - } + + for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + i != m_linkRecords.end (); + i++) + { + NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): free link record"); + + StaticRouterLinkRecord *p = *i; + delete p; + p = 0; + + *i = 0; + } + NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): clear list"); + m_linkRecords.clear(); } -uint32_t -StaticRouterLSA::Add (StaticRouterLinkRecord* lr) + uint32_t +StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr) { - m_listOfLinkRecords.push_back (lr); - return m_listOfLinkRecords.size (); + m_linkRecords.push_back (lr); + return m_linkRecords.size (); } const InterfaceId StaticRouter::iid = MakeInterfaceId ("StaticRouter", Object::iid); StaticRouter::StaticRouter (Ptr node) - : m_node(node) + : m_node(node), m_numLSAs(0) { - SetInterfaceId (StaticRouter::iid); NS_DEBUG("StaticRouter::StaticRouter ()"); + SetInterfaceId (StaticRouter::iid); } StaticRouter::~StaticRouter () @@ -60,4 +77,118 @@ StaticRouter::~StaticRouter () NS_DEBUG("StaticRouter::~StaticRouter ()"); } +// +// Return the number of Link State Advertisements this node has to advertise. +// + uint32_t +StaticRouter::GetNumLSAs (void) +{ + NS_DEBUG("StaticRouter::GetNumLSAs ()"); + NS_ASSERT_MSG(m_node, " interface not set"); +// +// 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 +// interfaces lives. +// + Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4, "QI for interface failed"); +// +// Now, we need to ask Ipv4 for the number of interfaces attached to this +// node. This isn't necessarily equal to the number of links to adjacent +// nodes (other routers); the number of interfaces may include interfaces +// connected to stub networks (e.g., ethernets, etc.). So we have to walk +// through the list of net devices and see if they are directly connected +// to another router. +// +// We'll start out at the maximum possible number of LSAs and reduce that +// number if we discover a link that's not actually connected to another +// router. +// + m_numLSAs = ipv4->GetNInterfaces(); + + NS_DEBUG("StaticRouter::GetNumLSAs (): m_numLSAs = " << m_numLSAs); + + for (uint32_t i = 0; i < m_numLSAs; ++i) + { + Ptr nd = ipv4->GetNetDevice(i); + Ptr ch = nd->GetChannel(); + + if (!nd->IsPointToPoint ()) + { + NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device"); + --m_numLSAs; + continue; + } + + NS_DEBUG("StaticRouter::GetNumLSAs (): point-to-point device"); +// +// Find the net device on the other end of the point-to-point channel. This +// is where our adjacent router is running. 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 and then ask the Ipv4 for the IP +// address. To do this, we have to get the interface index associated with +// that net device in order to find the correct interface on the adjacent node. +// + Ptr ndAdjacent = GetAdjacent(nd, ch); + uint32_t ifIndexAdjacent = ndAdjacent->GetIfIndex(); + Ptr nodeAdjacent = ndAdjacent->GetNode(); + Ptr ipv4Adjacent = nodeAdjacent->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4Adjacent, "QI for adjacent interface failed"); +// +// Okay, all of the preliminaries are done. We can get the IP address and +// net mask for the adjacent router. +// + Ipv4Address addrAdjacent = ipv4Adjacent->GetAddress(ifIndexAdjacent); + Ipv4Mask maskAdjacent = ipv4->GetNetworkMask(ifIndexAdjacent); + + NS_DEBUG("StaticRouter::GetNumLSAs (): Adjacent to " << addrAdjacent << + " & " << maskAdjacent); + } + + return m_numLSAs; +} + + bool +StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) +{ + return false; +} + + Ptr +StaticRouter::GetAdjacent(Ptr nd, Ptr ch) +{ +// +// Double-check that channel agrees with device that it's a point-to-point +// + NS_ASSERT(ch->GetType () == Channel::PointToPoint); + + uint32_t nDevices = ch->GetNDevices(); + NS_ASSERT_MSG(nDevices == 2, + "Point to point channel with other than two devices is not expected"); +// +// This is a point to point channel with two endpoints. Get both of them. +// + Ptr nd1 = ch->GetDevice(0); + Ptr nd2 = ch->GetDevice(1); +// +// One of the endpoints is going to be "us" -- that is the net device attached +// to the node on which we're running -- i.e., "nd". The other endpoint (the +// one to which we are connected via the channel) is the adjacent router. +// + if (nd1 == nd) + { + return nd2; + } + else if (nd2 == nd) + { + return nd1; + } + else + { + NS_ASSERT_MSG(0, + "Neither channel endpoint thinks it is connected to this net device"); + return 0; + } +} + } // namespace ns3 diff --git a/src/routing/static-router.h b/src/routing/static-router.h index bacdfcf57..9d2b4cc6a 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -21,6 +21,7 @@ #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/node.h" +#include "ns3/channel.h" #include "ns3/ipv4-address.h" namespace ns3 { @@ -69,16 +70,15 @@ class StaticRouterLSA { public: StaticRouterLSA(); - virtual ~StaticRouterLSA (); - uint32_t Add (StaticRouterLinkRecord* lr); + ~StaticRouterLSA(); + + uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); -public: Ipv4Address m_linkStateId; // set to the NodeId Ipv4Address m_advertisingRtr; // set to the NodeId - typedef std::list type_listOfLinkRecords; - type_listOfLinkRecords m_listOfLinkRecords; - type_listOfLinkRecords::iterator m_iter; + typedef std::list ListOfLinkRecords_t; + ListOfLinkRecords_t m_linkRecords; }; /** @@ -102,8 +102,12 @@ public: protected: virtual ~StaticRouter (); + Ptr m_node; + uint32_t m_numLSAs; + + Ptr GetAdjacent(Ptr nd, Ptr ch); + private: - Ptr m_node; }; } // namespace ns3 From 7ce874f5d00abfaedb18311a4dded46473480fa3 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 9 Jul 2007 22:03:41 -0700 Subject: [PATCH 26/92] checkpoint --- SConstruct | 2 +- src/routing/static-router.cc | 84 ++++++++++++++++++++++++++---------- src/routing/static-router.h | 1 + 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/SConstruct b/SConstruct index 5fcd7d29b..00a799f90 100644 --- a/SConstruct +++ b/SConstruct @@ -334,8 +334,8 @@ inode.add_headers ([ 'ipv4-end-point-demux.h', 'ipv4-end-point.h', 'ipv4-header.h', - 'udp-header.h', 'ipv4-interface.h', + 'udp-header.h', 'sgi-hashmap.h', 'udp-impl.h', ]) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 6c8f0fc28..94f393357 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -20,6 +20,7 @@ #include "ns3/net-device.h" #include "ns3/internet-node.h" #include "ns3/ipv4.h" +#include "ns3/ipv4-interface.h" #include "static-router.h" NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); @@ -90,8 +91,8 @@ StaticRouter::GetNumLSAs (void) // Ipv4 interface. This is where the information regarding the attached // interfaces lives. // - Ptr ipv4 = m_node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4, "QI for interface failed"); + Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4Local, "QI for interface failed"); // // Now, we need to ask Ipv4 for the number of interfaces attached to this // node. This isn't necessarily equal to the number of links to adjacent @@ -104,23 +105,40 @@ StaticRouter::GetNumLSAs (void) // number if we discover a link that's not actually connected to another // router. // - m_numLSAs = ipv4->GetNInterfaces(); - - NS_DEBUG("StaticRouter::GetNumLSAs (): m_numLSAs = " << m_numLSAs); - - for (uint32_t i = 0; i < m_numLSAs; ++i) + m_numLSAs = 0; + uint32_t numDevices = m_node->GetNDevices(); + NS_DEBUG("StaticRouter::GetNumLSAs (): numDevices = " << numDevices); +// +// Loop through the devices looking for those connected to a point-to-point +// channel. These are the ones that are used to route packets. +// + for (uint32_t i = 0; i < numDevices; ++i) { - Ptr nd = ipv4->GetNetDevice(i); - Ptr ch = nd->GetChannel(); + Ptr nd = m_node->GetDevice(i); if (!nd->IsPointToPoint ()) { NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device"); - --m_numLSAs; continue; } - NS_DEBUG("StaticRouter::GetNumLSAs (): point-to-point device"); + NS_DEBUG("StaticRouter::GetNumLSAs (): Point-to-point device"); +// +// Now, we have to find the Ipv4 interface whose netdevice is the one we +// just found. This is 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 its not +// exported so we had to whip up an equivalent. +// + uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, nd); +// +// 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); + + Ptr ch = nd->GetChannel(); // // Find the net device on the other end of the point-to-point channel. This // is where our adjacent router is running. The adjacent net device is @@ -129,20 +147,23 @@ StaticRouter::GetNumLSAs (void) // address. To do this, we have to get the interface index associated with // that net device in order to find the correct interface on the adjacent node. // - Ptr ndAdjacent = GetAdjacent(nd, ch); - uint32_t ifIndexAdjacent = ndAdjacent->GetIfIndex(); - Ptr nodeAdjacent = ndAdjacent->GetNode(); - Ptr ipv4Adjacent = nodeAdjacent->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4Adjacent, "QI for adjacent interface failed"); + Ptr ndRemote = GetAdjacent(nd, ch); + Ptr nodeRemote = ndRemote->GetNode(); + Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4Remote, "QI for remote interface failed"); // -// Okay, all of the preliminaries are done. We can get the IP address and -// net mask for the adjacent router. +// 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. // - Ipv4Address addrAdjacent = ipv4Adjacent->GetAddress(ifIndexAdjacent); - Ipv4Mask maskAdjacent = ipv4->GetNetworkMask(ifIndexAdjacent); - - NS_DEBUG("StaticRouter::GetNumLSAs (): Adjacent to " << addrAdjacent << - " & " << maskAdjacent); + uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote); +// +// Now that we have the Ipv4 interface, we can get the address and mask we +// need. +// + Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); + Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); + NS_DEBUG("Working with remote address " << addrRemote); + ++m_numLSAs; } return m_numLSAs; @@ -191,4 +212,21 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) } } + uint32_t +StaticRouter::FindIfIndexForDevice(Ptr node, Ptr nd) +{ + Ptr ipv4 = node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4, "QI for interface failed"); + for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i ) + { + if (ipv4->GetNetDevice(i) == nd) + { + return i; + } + } + + NS_ASSERT_MSG(0, "Cannot find interface for device"); + return 0; +} + } // namespace ns3 diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 9d2b4cc6a..a3d56001e 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -106,6 +106,7 @@ protected: uint32_t m_numLSAs; Ptr GetAdjacent(Ptr nd, Ptr ch); + uint32_t FindIfIndexForDevice(Ptr node, Ptr nd); private: }; From 5487c20beb541a80073f1313d57e80f91892d192 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 9 Jul 2007 22:12:58 -0700 Subject: [PATCH 27/92] forgot to remove a header include --- src/routing/static-router.cc | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 94f393357..b76565b9f 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -20,7 +20,6 @@ #include "ns3/net-device.h" #include "ns3/internet-node.h" #include "ns3/ipv4.h" -#include "ns3/ipv4-interface.h" #include "static-router.h" NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); @@ -137,17 +136,17 @@ StaticRouter::GetNumLSAs (void) Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); NS_DEBUG("Working with local address " << addrLocal); - +// +// Now, we're going to link to the remote net device on the other end of the +// point-to-point channel we know we have. This is where our adjacent router +// (to use OSPF lingo) is running. +// Ptr ch = nd->GetChannel(); -// -// Find the net device on the other end of the point-to-point channel. This -// is where our adjacent router is running. 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 and then ask the Ipv4 for the IP -// address. To do this, we have to get the interface index associated with -// that net device in order to find the correct interface on the adjacent node. -// Ptr ndRemote = GetAdjacent(nd, 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, "QI for remote interface failed"); @@ -157,8 +156,8 @@ StaticRouter::GetNumLSAs (void) // uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote); // -// Now that we have the Ipv4 interface, we can get the address and mask we -// need. +// 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); From 75070e1bfaa50da0afeed93904bcfbbba7ab3428 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jul 2007 22:21:01 -0700 Subject: [PATCH 28/92] Add LSDB functions --- src/routing/static-route-manager.cc | 51 ++++++++++++++++++++++++++++- src/routing/static-route-manager.h | 9 +++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index c327b1955..fc962fd95 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -25,6 +25,49 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { +StaticRouteManagerLSDB::~StaticRouteManagerLSDB() +{ + NS_DEBUG_UNCOND("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); + +#if 0 + for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + i != m_linkRecords.end (); + i++) + { + NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): free link record"); + + StaticRouterLinkRecord *p = *i; + delete p; + p = 0; + + *i = 0; + } +#endif + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear list"); + //m_linkRecords.clear(); +} + +void +StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) +{ + m_database.insert(LSDBPair_t(addr, lsa)); +} + +StaticRouterLSA* +StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) +{ + // Look up an LSA by its address + LSDBMap_t::iterator i; + for (i= m_database.begin(); i!= m_database.end(); i++) + { + //Ipv4Address temp = i->first; + if (i->first == addr) + { + return i->second; + } + } + return 0; +} StaticRouteManager::StaticRouteManager () { @@ -198,7 +241,13 @@ StaticRouteManagerTest::RunTests (void) lsa3->AddLinkRecord(lr2); lsa3->AddLinkRecord(lr3); - // Add four LSAs to the database; XXX todo next + // Test the database + StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); + srmlsdb->Insert(lsa0->m_linkStateId ,lsa0); + srmlsdb->Insert(lsa1->m_linkStateId ,lsa1); + srmlsdb->Insert(lsa2->m_linkStateId ,lsa2); + srmlsdb->Insert(lsa3->m_linkStateId ,lsa3); + NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); delete lsa0; delete lsa1; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 7b8ea5c74..120252c6b 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -18,9 +18,11 @@ #include #include +#include #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/ipv4-address.h" +#include "static-router.h" namespace ns3 { @@ -53,6 +55,13 @@ public: class StaticRouteManagerLSDB { public: + ~StaticRouteManagerLSDB (); + void Insert(Ipv4Address addr, StaticRouterLSA* lsa); + StaticRouterLSA* GetLSA (Ipv4Address addr); + + typedef std::map LSDBMap_t; + typedef std::pair LSDBPair_t; + LSDBMap_t m_database; }; /** From d07e17d85c022a5c8aab68946e4ce2ce21693485 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 9 Jul 2007 23:07:51 -0700 Subject: [PATCH 29/92] Add LSDB destructor --- src/routing/static-route-manager.cc | 48 +++++++++++++---------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index fc962fd95..3c3cf14d6 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -27,24 +27,17 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { StaticRouteManagerLSDB::~StaticRouteManagerLSDB() { - NS_DEBUG_UNCOND("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); -#if 0 - for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); - i != m_linkRecords.end (); - i++) - { - NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): free link record"); - - StaticRouterLinkRecord *p = *i; - delete p; - p = 0; - - *i = 0; + LSDBMap_t::iterator i; + for (i= m_database.begin(); i!= m_database.end(); i++) + { + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): free LSA"); + StaticRouterLSA* temp = i->second; + delete temp; } -#endif - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear list"); - //m_linkRecords.clear(); + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); + m_database.clear(); } void @@ -60,7 +53,6 @@ StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) { - //Ipv4Address temp = i->first; if (i->first == addr) { return i->second; @@ -161,8 +153,8 @@ StaticRouteManagerTest::RunTests (void) lr1->m_linkType = StaticRouterLinkRecord::StubNetwork; lr1->m_metric = 1; StaticRouterLSA* lsa0 = new StaticRouterLSA(); - lsa0->m_linkStateId.Set(1); - lsa0->m_advertisingRtr.Set(1); + lsa0->m_linkStateId.Set("0.0.0.0"); + lsa0->m_advertisingRtr.Set("0.0.0.0"); lsa0->AddLinkRecord(lr0); lsa0->AddLinkRecord(lr1); @@ -243,20 +235,22 @@ StaticRouteManagerTest::RunTests (void) // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); - srmlsdb->Insert(lsa0->m_linkStateId ,lsa0); - srmlsdb->Insert(lsa1->m_linkStateId ,lsa1); - srmlsdb->Insert(lsa2->m_linkStateId ,lsa2); - srmlsdb->Insert(lsa3->m_linkStateId ,lsa3); + srmlsdb->Insert(lsa0->m_linkStateId, lsa0); + srmlsdb->Insert(lsa1->m_linkStateId, lsa1); + srmlsdb->Insert(lsa2->m_linkStateId, lsa2); + srmlsdb->Insert(lsa3->m_linkStateId, lsa3); NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); - delete lsa0; - delete lsa1; - delete lsa2; - delete lsa3; + // This delete clears the LSDB, which clears the LSAs, which destroy + // the LinkRecords. + delete srmlsdb; + + // XXX next, calculate routes based on the manually created LSDB return ok; } +// Instantiate this class for the unit tests static StaticRouteManagerTest g_staticRouteManagerTest; } // namespace ns3 From 3640d302e11718ad6f61a4d656e28fd1bc74a00d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 01:28:19 -0700 Subject: [PATCH 30/92] checkpoint --- examples/simple-static-routing.cc | 2 +- src/routing/routing-environment.cc | 9 +- src/routing/routing-environment.h | 1 + src/routing/static-route-manager.cc | 13 +- src/routing/static-router.cc | 195 ++++++++++++++++++++++++---- src/routing/static-router.h | 28 +++- 6 files changed, 212 insertions(+), 36 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index bb9dcf21e..7a366f736 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -81,8 +81,8 @@ int main (int argc, char *argv[]) DebugComponentEnable("Channel"); DebugComponentEnable("PointToPointChannel"); DebugComponentEnable("PointToPointNetDevice"); -#endif DebugComponentEnable("StaticRouter"); +#endif // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, diff --git a/src/routing/routing-environment.cc b/src/routing/routing-environment.cc index 160bd8668..73e936ca8 100644 --- a/src/routing/routing-environment.cc +++ b/src/routing/routing-environment.cc @@ -29,11 +29,18 @@ namespace RoutingEnvironment { BooleanDefaultValue g_doStaticRoutingDefaultValue ("DoStaticRouting", "Enable global static routing", false); - bool + bool StaticRoutingEnabled(void) { return g_doStaticRoutingDefaultValue.GetValue(); } + uint32_t +AllocateRouterId(void) +{ + static uint32_t routerId = 0; + return ++routerId; +} + } // namespace RoutingEnvironment } // namespace ns3 diff --git a/src/routing/routing-environment.h b/src/routing/routing-environment.h index abf9da4d8..51ee61f2b 100644 --- a/src/routing/routing-environment.h +++ b/src/routing/routing-environment.h @@ -25,6 +25,7 @@ namespace ns3 { namespace RoutingEnvironment { bool StaticRoutingEnabled(void); +uint32_t AllocateRouterId(void); } // namespace RoutingEnvironment } // namespace ns3 diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 3c3cf14d6..393128967 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -85,7 +85,18 @@ StaticRouteManager::BuildStaticRoutingDatabase () NS_ASSERT_MSG(rtr, "QI for interface failed"); uint32_t numLSAs = rtr->GetNumLSAs(); - NS_DEBUG_UNCOND (numLSAs << "LSAs"); + NS_DEBUG_UNCOND ("Found " << numLSAs << " LSAs"); + + for (uint32_t j = 0; j < numLSAs; ++j) + { + StaticRouterLSA lsa; + rtr->GetLSA(j, lsa); + NS_DEBUG_UNCOND ("LSA " << j); + NS_DEBUG_UNCOND ("----------------------------------------"); + NS_DEBUG_UNCOND("m_linkStateId = " << lsa.m_linkStateId); + NS_DEBUG_UNCOND("m_advertisingRtr = " << lsa.m_advertisingRtr); + NS_DEBUG_UNCOND ("----------------------------------------"); + } } } diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index b76565b9f..fa72622e4 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -35,15 +35,57 @@ StaticRouterLSA::StaticRouterLSA() NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } +// +// Copy constructor for StaticRouterLSA +// +StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) + : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr) +{ + NS_DEBUG("StaticRouterLSA Copy Constructor"); + NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before copy"); + + for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin (); + i != lsa.m_linkRecords.end (); + i++) + { + StaticRouterLinkRecord *pSrc = *i; + StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; + pDst->m_linkId = pSrc->m_linkId; + pDst->m_linkData = pSrc->m_linkData; + m_linkRecords.push_back(pDst); + pDst = 0; + } +} + +// +// Assignment operator for StaticRouterLSA +// +// This uses the non-obvious trick of taking the source LSA passed by +// value instead of by reference. This causes the copy constructor to be +// invoked (where the real work is done -- see above). All we have to do +// here is to return the newly constructed LSA. +// + StaticRouterLSA& +StaticRouterLSA::operator= (StaticRouterLSA lsa) +{ + NS_DEBUG("StaticRouterLSA Operator ="); + return *this; +} + StaticRouterLSA::~StaticRouterLSA() { NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()"); + ClearLinkRecords (); +} + void +StaticRouterLSA::ClearLinkRecords(void) +{ for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); i != m_linkRecords.end (); i++) { - NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): free link record"); + NS_DEBUG("StaticRouterLSA::ClearLinkRecords (): free link record"); StaticRouterLinkRecord *p = *i; delete p; @@ -51,7 +93,7 @@ StaticRouterLSA::~StaticRouterLSA() *i = 0; } - NS_DEBUG("StaticRouterLSA::~StaticRouterLSA (): clear list"); + NS_DEBUG("StaticRouterLSA::ClearLinkRecords(): clear list"); m_linkRecords.clear(); } @@ -62,19 +104,77 @@ StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr) return m_linkRecords.size (); } + bool +StaticRouterLSA::IsEmpty (void) +{ + return m_linkRecords.size () == 0; +} + + void +StaticRouterLSA::Print (std::ostream &os) +{ + os << "m_linkStateId = " << m_linkStateId << std::endl << + "m_advertisingRtr = " << m_advertisingRtr << std::endl; + + for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + i != m_linkRecords.end (); + i++) + { + StaticRouterLinkRecord *p = *i; + os << "----------" << std::endl; + os << "m_linkId = " << p->m_linkId << std::endl; + os << "m_linkData = " << p->m_linkData << std::endl; + } +} + +std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa) +{ + lsa.Print (os); + return os; +} + const InterfaceId StaticRouter::iid = MakeInterfaceId ("StaticRouter", Object::iid); StaticRouter::StaticRouter (Ptr node) - : m_node(node), m_numLSAs(0) + : m_node(node), m_LSAs() { NS_DEBUG("StaticRouter::StaticRouter ()"); SetInterfaceId (StaticRouter::iid); + m_routerId.Set(RoutingEnvironment::AllocateRouterId()); } StaticRouter::~StaticRouter () { NS_DEBUG("StaticRouter::~StaticRouter ()"); + ClearLSAs(); +} + + void +StaticRouter::ClearLSAs () +{ + NS_DEBUG("StaticRouter::ClearLSAs ()"); + + for ( ListOfLSAs_t::iterator i = m_LSAs.begin (); + i != m_LSAs.end (); + i++) + { + NS_DEBUG("StaticRouter::ClearLSAs (): free LSA"); + + StaticRouterLSA *p = *i; + delete p; + p = 0; + + *i = 0; + } + NS_DEBUG("StaticRouter::ClearLSAs (): clear list"); + m_LSAs.clear(); +} + + Ipv4Address + StaticRouter::GetRouterId (void) +{ + return m_routerId; } // @@ -85,6 +185,7 @@ StaticRouter::GetNumLSAs (void) { NS_DEBUG("StaticRouter::GetNumLSAs ()"); NS_ASSERT_MSG(m_node, " interface not set"); + ClearLSAs (); // // 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 @@ -93,29 +194,24 @@ StaticRouter::GetNumLSAs (void) Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4Local, "QI for interface failed"); // -// Now, we need to ask Ipv4 for the number of interfaces attached to this -// node. This isn't necessarily equal to the number of links to adjacent -// nodes (other routers); the number of interfaces may include interfaces -// connected to stub networks (e.g., ethernets, etc.). So we have to walk -// through the list of net devices and see if they are directly connected -// to another router. +// 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. // -// We'll start out at the maximum possible number of LSAs and reduce that -// number if we discover a link that's not actually connected to another -// router. -// - m_numLSAs = 0; uint32_t numDevices = m_node->GetNDevices(); NS_DEBUG("StaticRouter::GetNumLSAs (): numDevices = " << numDevices); // // Loop through the devices looking for those connected to a point-to-point -// channel. These are the ones that are used to route packets. +// channel. // for (uint32_t i = 0; i < numDevices; ++i) { - Ptr nd = m_node->GetDevice(i); + Ptr ndLocal = m_node->GetDevice(i); - if (!nd->IsPointToPoint ()) + if (!ndLocal->IsPointToPoint ()) { NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device"); continue; @@ -124,11 +220,11 @@ StaticRouter::GetNumLSAs (void) NS_DEBUG("StaticRouter::GetNumLSAs (): Point-to-point device"); // // Now, we have to find the Ipv4 interface whose netdevice is the one we -// just found. This is 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 its not +// 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, nd); + uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal); // // Now that we have the Ipv4 interface index, we can get the address and mask // we need. @@ -137,12 +233,12 @@ StaticRouter::GetNumLSAs (void) Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); NS_DEBUG("Working with local address " << addrLocal); // -// Now, we're going to link to the remote net device on the other end of the -// point-to-point channel we know we have. This is where our adjacent router -// (to use OSPF lingo) is running. +// 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 = nd->GetChannel(); - Ptr ndRemote = GetAdjacent(nd, ch); + 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. @@ -151,6 +247,15 @@ StaticRouter::GetNumLSAs (void) Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4Remote, "QI for remote interface 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 (StaticRouter::iid); + NS_ASSERT_MSG(srRemote, "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. // @@ -162,15 +267,51 @@ StaticRouter::GetNumLSAs (void) Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); NS_DEBUG("Working with remote address " << addrRemote); - ++m_numLSAs; +// +// Now we can fill out the link state advertisement for this link. +// + StaticRouterLSA *pLSA = new StaticRouterLSA; + pLSA->m_linkStateId = m_routerId; + pLSA->m_advertisingRtr = m_routerId; + + StaticRouterLinkRecord *plr = new StaticRouterLinkRecord; + plr->m_linkType = StaticRouterLinkRecord::PointToPoint; + plr->m_linkId = rtrIdRemote; + plr->m_linkData = addrLocal; + pLSA->AddLinkRecord(plr); + plr = 0; + + plr = new StaticRouterLinkRecord; + plr->m_linkType = StaticRouterLinkRecord::StubNetwork; + plr->m_linkId = addrRemote; + plr->m_linkData.Set(maskRemote.GetHostOrder()); // Frown + pLSA->AddLinkRecord(plr); + plr = 0; + + m_LSAs.push_back (pLSA); + NS_DEBUG(*pLSA); } - return m_numLSAs; + return m_LSAs.size (); } bool StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) { + NS_ASSERT_MSG(lsa.IsEmpty(), "Must pass empty LSA"); + + ListOfLSAs_t::iterator i = m_LSAs.begin (); + uint32_t j = 0; + + for (; i != m_LSAs.end (); i++, j++) + { + if (j == n) + { + StaticRouterLSA *p = *i; + lsa = *p; + return true; + } + } return false; } diff --git a/src/routing/static-router.h b/src/routing/static-router.h index a3d56001e..5ed6b3e79 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -23,6 +23,7 @@ #include "ns3/node.h" #include "ns3/channel.h" #include "ns3/ipv4-address.h" +#include "ns3/routing-environment.h" namespace ns3 { @@ -70,17 +71,26 @@ class StaticRouterLSA { public: StaticRouterLSA(); + StaticRouterLSA (StaticRouterLSA& lsa); ~StaticRouterLSA(); - uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); + StaticRouterLSA& operator= (StaticRouterLSA lsa); - Ipv4Address m_linkStateId; // set to the NodeId - Ipv4Address m_advertisingRtr; // set to the NodeId + uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); + void ClearLinkRecords(void); + bool IsEmpty(void); + + void Print (std::ostream &os); + + Ipv4Address m_linkStateId; + Ipv4Address m_advertisingRtr; typedef std::list ListOfLinkRecords_t; ListOfLinkRecords_t m_linkRecords; }; +std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); + /** * \brief An interface aggregated to a node to provide static routing info * @@ -96,18 +106,24 @@ public: static const InterfaceId iid; StaticRouter (Ptr node); + Ipv4Address GetRouterId(void); uint32_t GetNumLSAs (void); bool GetLSA (uint32_t n, StaticRouterLSA &lsa); protected: virtual ~StaticRouter (); - - Ptr m_node; - uint32_t m_numLSAs; + void ClearLSAs (void); Ptr GetAdjacent(Ptr nd, Ptr ch); uint32_t FindIfIndexForDevice(Ptr node, Ptr nd); + Ptr m_node; + + typedef std::list ListOfLSAs_t; + ListOfLSAs_t m_LSAs; + + Ipv4Address m_routerId; + private: }; From 0068da44d43dc44e53d496281ed1408a2488e174 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 09:31:07 -0700 Subject: [PATCH 31/92] first working router --- src/routing/static-route-manager.cc | 6 ++---- src/routing/static-router.cc | 28 +++++++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 393128967..9c7097b02 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -92,10 +92,8 @@ StaticRouteManager::BuildStaticRoutingDatabase () StaticRouterLSA lsa; rtr->GetLSA(j, lsa); NS_DEBUG_UNCOND ("LSA " << j); - NS_DEBUG_UNCOND ("----------------------------------------"); - NS_DEBUG_UNCOND("m_linkStateId = " << lsa.m_linkStateId); - NS_DEBUG_UNCOND("m_advertisingRtr = " << lsa.m_advertisingRtr); - NS_DEBUG_UNCOND ("----------------------------------------"); + NS_DEBUG_UNCOND ("----------------------------"); + NS_DEBUG_UNCOND(lsa); } } } diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index fa72622e4..6f48a0f36 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -35,9 +35,6 @@ StaticRouterLSA::StaticRouterLSA() NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } -// -// Copy constructor for StaticRouterLSA -// StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr) { @@ -57,18 +54,27 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) } } -// -// Assignment operator for StaticRouterLSA -// -// This uses the non-obvious trick of taking the source LSA passed by -// value instead of by reference. This causes the copy constructor to be -// invoked (where the real work is done -- see above). All we have to do -// here is to return the newly constructed LSA. -// StaticRouterLSA& StaticRouterLSA::operator= (StaticRouterLSA lsa) { NS_DEBUG("StaticRouterLSA Operator ="); + NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before assignment"); + + m_linkStateId = lsa.m_linkStateId; + m_advertisingRtr = lsa.m_advertisingRtr; + + for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin (); + i != lsa.m_linkRecords.end (); + i++) + { + StaticRouterLinkRecord *pSrc = *i; + StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; + pDst->m_linkId = pSrc->m_linkId; + pDst->m_linkData = pSrc->m_linkData; + m_linkRecords.push_back(pDst); + pDst = 0; + } + return *this; } From dc80efa426602d8dd2ad4764bddf5289b9abad5a Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 10:56:27 -0700 Subject: [PATCH 32/92] convert LSDB to class SPFVertex --- src/routing/static-route-manager.cc | 182 +++++++++++++++++++++++++--- src/routing/static-route-manager.h | 16 ++- 2 files changed, 177 insertions(+), 21 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 9c7097b02..228d57078 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -25,6 +25,13 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { + +SPFVertex::~SPFVertex () +{ + delete m_lsa; +} + + StaticRouteManagerLSDB::~StaticRouteManagerLSDB() { NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); @@ -32,8 +39,8 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) { - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): free LSA"); - StaticRouterLSA* temp = i->second; + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB():free vertex"); + SPFVertex* temp = i->second; delete temp; } NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); @@ -41,13 +48,13 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() } void -StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) +StaticRouteManagerLSDB::Insert(Ipv4Address addr, SPFVertex* vertex) { - m_database.insert(LSDBPair_t(addr, lsa)); + m_database.insert(LSDBPair_t(addr, vertex)); } -StaticRouterLSA* -StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) +SPFVertex* +StaticRouteManagerLSDB::GetVertex (Ipv4Address addr) { // Look up an LSA by its address LSDBMap_t::iterator i; @@ -98,15 +105,148 @@ StaticRouteManager::BuildStaticRoutingDatabase () } } -void -StaticRouteManager::InitializeRoutes () -{ // For each node that is a static router (which can be determined by // the presence of StaticRouter interface), run Dijkstra SPF calculation // on the database rooted at that router, and populate the node // forwarding tables + // +void +StaticRouteManager::InitializeRoutes () +{ +// This function parallels RFC2328, Section 16.1.1, and quagga ospfd +// +// This calculation yields the set of intra-area routes associated +// with an area (called hereafter Area A). A router calculates the +// shortest-path tree using itself as the root. The formation +// of the shortest path tree is done here in two stages. In the +// first stage, only links between routers and transit networks are +// considered. Using the Dijkstra algorithm, a tree is formed from +// this subset of the link state database. In the second stage, +// leaves are added to the tree by considering the links to stub +// networks. + +// The area's link state database is represented as a directed graph. +// The graph's vertices are routers, transit networks and stub networks. +// The first stage of the procedure (i.e., the Dijkstra algorithm) +// can now be summarized as follows. At each iteration of the +// algorithm, there is a list of candidate vertices. Paths from +// the root to these vertices have been found, but not necessarily +// the shortest ones. However, the paths to the candidate vertex +// that is closest to the root are guaranteed to be shortest; this +// vertex is added to the shortest-path tree, removed from the +// candidate list, and its adjacent vertices are examined for +// possible addition to/modification of the candidate list. The +// algorithm then iterates again. It terminates when the candidate +// list becomes empty. + + // For each node that is a router in the topology + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) + { + Ptr node = *i; + NS_DEBUG_UNCOND ("node="<< node->GetId () ); + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + NS_ASSERT_MSG(rtr, "QI for interface failed"); + if (rtr && rtr->GetNumLSAs () ) + { + SPFCalculate(); + } + } } + +// quagga ospf_spf_next +void +StaticRouteManager::SPFNext() +{ + // if LSA == Router_LSA, examine links + // a) if link to stub, skip + // b) W is transit +} + +void +StaticRouteManager::SPFCalculate() +{ + NS_DEBUG("StaticRouteManager::SPFCalculate ()"); + /* + * struct pqueue* candidate; + * struct vertex* v; + */ + // Initialize the shortest-path tree to only the router doing the + // calculation. + // + +#if 0 + ospf_spf_init (area); + v = area->spf; + + + /* Create a new heap for the candidates. */ + candidate = pqueue_create(); + candidate->cmp = cmp; + candidate->update = update_stat; + + /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the + * * spanning tree. */ + *(v->stat) = LSA_SPF_IN_SPFTREE; + + /* Set Area A's TransitCapability to FALSE. */ + area->transit = OSPF_TRANSIT_FALSE; + area->shortcut_capability = 1; + + for (;;) + { + /* RFC2328 16.1. (2). */ + ospf_spf_next (v, area, candidate); + + /* RFC2328 16.1. (3). */ + /* If at this step the candidate list is empty, the shortest- + * path tree (of transit vertices) has been completely built and + * this stage of the procedure terminates. */ + if (candidate->size == 0) + break; + + /* Otherwise, choose the vertex belonging to the candidate list + * that is closest to the root, and add it to the shortest-path + * tree (removing it from the candidate list in the + * process). */ + /* Extract from the candidates the node with the lower key. */ + v = (struct vertex *) pqueue_dequeue (candidate); + /* Update stat field in vertex. */ + *(v->stat) = LSA_SPF_IN_SPFTREE; + + ospf_vertex_add_parent (v); + /* Note that when there is a choice of vertices closest to the + * root, network vertices must be chosen before router vertices + * in order to necessarily find all equal-cost paths. */ + /* We don't do this at this moment, we should add the treatment + * above codes. -- kunihiro. */ + + /* RFC2328 16.1. (4). */ + if (v->type == OSPF_VERTEX_ROUTER) + ospf_intra_add_router (new_rtrs, v, area); + else + ospf_intra_add_transit (new_table, v, area); + + /* RFC2328 16.1. (5). */ + /* Iterate the algorithm by returning to Step 2. */ + + } /* end loop until no more candidate vertices */ + + /* Second stage of SPF calculation procedure's */ + ospf_spf_process_stubs (area, area->spf, new_table); + + /* Free candidate queue. */ + pqueue_delete (candidate); + +#endif + + +} + + } // namespace ns3 #ifdef RUN_SELF_TESTS @@ -242,16 +382,26 @@ StaticRouteManagerTest::RunTests (void) lsa3->AddLinkRecord(lr2); lsa3->AddLinkRecord(lr3); + // Create four vertices to store these four LSAs + SPFVertex* v0 = new SPFVertex (); + v0->m_lsa = lsa0; + SPFVertex* v1 = new SPFVertex (); + v1->m_lsa = lsa1; + SPFVertex* v2 = new SPFVertex (); + v2->m_lsa = lsa2; + SPFVertex* v3 = new SPFVertex (); + v3->m_lsa = lsa3; + // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); - srmlsdb->Insert(lsa0->m_linkStateId, lsa0); - srmlsdb->Insert(lsa1->m_linkStateId, lsa1); - srmlsdb->Insert(lsa2->m_linkStateId, lsa2); - srmlsdb->Insert(lsa3->m_linkStateId, lsa3); - NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); + srmlsdb->Insert(lsa0->m_linkStateId, v0); + srmlsdb->Insert(lsa1->m_linkStateId, v1); + srmlsdb->Insert(lsa2->m_linkStateId, v2); + srmlsdb->Insert(lsa3->m_linkStateId, v3); + NS_ASSERT(v2 == srmlsdb->GetVertex(lsa2->m_linkStateId)); - // This delete clears the LSDB, which clears the LSAs, which destroy - // the LinkRecords. + // This delete clears the LSDB, which clears the vertices, which deletes + // the matching LSAs, which destroys the LinkRecords. delete srmlsdb; // XXX next, calculate routes based on the manually created LSDB diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 120252c6b..1d4ce0c1e 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -34,6 +34,8 @@ namespace ns3 { class SPFVertex { public: + ~SPFVertex(); + enum VertexType { VertexRouter = 1, VertexNetwork @@ -41,12 +43,14 @@ public: Ipv4Address m_vertexId; - uint32_t m_distanceFromRoot; + StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes typedef std::list type_listOfSPFVertex; type_listOfSPFVertex m_parents; type_listOfSPFVertex m_children; type_listOfSPFVertex::iterator m_iter; + + uint32_t m_distanceFromRoot; }; /** @@ -56,11 +60,11 @@ class StaticRouteManagerLSDB { public: ~StaticRouteManagerLSDB (); - void Insert(Ipv4Address addr, StaticRouterLSA* lsa); - StaticRouterLSA* GetLSA (Ipv4Address addr); + void Insert(Ipv4Address addr, SPFVertex* vertex); + SPFVertex* GetVertex (Ipv4Address addr); - typedef std::map LSDBMap_t; - typedef std::pair LSDBPair_t; + typedef std::map LSDBMap_t; + typedef std::pair LSDBPair_t; LSDBMap_t m_database; }; @@ -96,6 +100,8 @@ protected: private: StaticRouteManagerLSDB m_lsdb; + void SPFCalculate (); + void SPFNext (); }; } // namespace ns3 From 71d55ebf18e431a56564fe487a6c9e0752fdea25 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 11:29:08 -0700 Subject: [PATCH 33/92] more plumbing around SPFCalculate() --- src/routing/static-route-manager.cc | 49 ++++++++++++++++++++++++----- src/routing/static-route-manager.h | 15 +++++++-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 228d57078..867baeadd 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -68,12 +68,24 @@ StaticRouteManagerLSDB::GetVertex (Ipv4Address addr) return 0; } -StaticRouteManager::StaticRouteManager () +StaticRouteManager::StaticRouteManager () { + m_lsdb = new StaticRouteManagerLSDB (); } StaticRouteManager::~StaticRouteManager () -{} +{ + if (m_lsdb) + delete m_lsdb; +} + +void +StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) +{ + if (m_lsdb) + delete m_lsdb; + m_lsdb = lsdb; +} void StaticRouteManager::BuildStaticRoutingDatabase () @@ -113,6 +125,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () void StaticRouteManager::InitializeRoutes () { + NS_DEBUG_UNCOND("StaticRouteManager::InitializeRoutes ()"); // This function parallels RFC2328, Section 16.1.1, and quagga ospfd // // This calculation yields the set of intra-area routes associated @@ -151,7 +164,7 @@ StaticRouteManager::InitializeRoutes () NS_ASSERT_MSG(rtr, "QI for interface failed"); if (rtr && rtr->GetNumLSAs () ) { - SPFCalculate(); + SPFCalculate(rtr->GetRouterId ()); } } } @@ -166,8 +179,16 @@ StaticRouteManager::SPFNext() // b) W is transit } +// quagga ospf_spf_calculate void -StaticRouteManager::SPFCalculate() +StaticRouteManager::DebugSPFCalculate(Ipv4Address root) +{ + SPFCalculate(root); +} + +// quagga ospf_spf_calculate +void +StaticRouteManager::SPFCalculate(Ipv4Address root) { NS_DEBUG("StaticRouteManager::SPFCalculate ()"); /* @@ -385,12 +406,20 @@ StaticRouteManagerTest::RunTests (void) // Create four vertices to store these four LSAs SPFVertex* v0 = new SPFVertex (); v0->m_lsa = lsa0; + v0->m_vertexType = SPFVertex::VertexRouter; + v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v1 = new SPFVertex (); v1->m_lsa = lsa1; + v0->m_vertexType = SPFVertex::VertexRouter; + v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v2 = new SPFVertex (); v2->m_lsa = lsa2; + v0->m_vertexType = SPFVertex::VertexRouter; + v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v3 = new SPFVertex (); v3->m_lsa = lsa3; + v0->m_vertexType = SPFVertex::VertexRouter; + v0->m_distanceFromRoot = 0xffffffff; // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); @@ -400,11 +429,15 @@ StaticRouteManagerTest::RunTests (void) srmlsdb->Insert(lsa3->m_linkStateId, v3); NS_ASSERT(v2 == srmlsdb->GetVertex(lsa2->m_linkStateId)); - // This delete clears the LSDB, which clears the vertices, which deletes - // the matching LSAs, which destroys the LinkRecords. - delete srmlsdb; - // XXX next, calculate routes based on the manually created LSDB + StaticRouteManager* srm = new StaticRouteManager(); + srm->DebugUseLsdb (srmlsdb); + srm->DebugSPFCalculate(lsa0->m_linkStateId); // node n0 + + // This delete clears the srm, which deletes the LSDB, which clears + // all of the vertices, which each destroy the matching LSAs, which each + // destroys the attached LinkRecords. + delete srm; return ok; } diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 1d4ce0c1e..6e0ac608f 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -95,12 +95,21 @@ public: */ virtual void InitializeRoutes(); -protected: + /** + * \brief Debugging routine; allow client code to supply a pre-built LSDB + */ + void DebugUseLsdb (StaticRouteManagerLSDB*); + /** + * \brief Debugging routine; call the core SPF from the unit tests + */ + void DebugSPFCalculate (Ipv4Address root); + virtual ~StaticRouteManager (); +protected: private: - StaticRouteManagerLSDB m_lsdb; - void SPFCalculate (); + StaticRouteManagerLSDB* m_lsdb; + void SPFCalculate (Ipv4Address root); void SPFNext (); }; From 05d649ef54db2ec8fafb007dbeab020dfedb072c Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 12:38:51 -0700 Subject: [PATCH 34/92] doxygen --- src/routing/static-router.cc | 25 +++++- src/routing/static-router.h | 152 ++++++++++++++++++++++++++++++++--- 2 files changed, 161 insertions(+), 16 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 6f48a0f36..6f1fd245b 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -55,7 +55,7 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) } StaticRouterLSA& -StaticRouterLSA::operator= (StaticRouterLSA lsa) +StaticRouterLSA::operator= (StaticRouterLSA& lsa) { NS_DEBUG("StaticRouterLSA Operator ="); NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before assignment"); @@ -274,7 +274,10 @@ StaticRouter::GetNumLSAs (void) Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); NS_DEBUG("Working with remote address " << addrRemote); // -// Now we can fill out the link state advertisement for this link. +// Now we can fill out the link state advertisement 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. // StaticRouterLSA *pLSA = new StaticRouterLSA; pLSA->m_linkStateId = m_routerId; @@ -301,11 +304,18 @@ StaticRouter::GetNumLSAs (void) return m_LSAs.size (); } +// +// Get the nth link state advertisement from this router. +// bool StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) { NS_ASSERT_MSG(lsa.IsEmpty(), "Must pass empty LSA"); - +// +// All of the work was done in GetNumLSAs. All we have to do here is to +// walk the list of link state advertisements created there and return the +// one the client is interested in. +// ListOfLSAs_t::iterator i = m_LSAs.begin (); uint32_t j = 0; @@ -318,9 +328,14 @@ StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) return true; } } + return false; } +// +// Link through the given channel and find the net device that's on the +// other end. This only makes sense with a point-to-point channel. +// Ptr StaticRouter::GetAdjacent(Ptr nd, Ptr ch) { @@ -358,6 +373,10 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) } } +// +// Given a node and a net device, find the IPV4 interface index that +// corresponds to that net device. +// uint32_t StaticRouter::FindIfIndexForDevice(Ptr node, Ptr nd) { diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 5ed6b3e79..0d0cd09ac 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -28,7 +28,11 @@ namespace ns3 { /** - * \brief A single link record for a link state advertisement + * \brief A single link record for a link state advertisement. + * + * The StaticRouterLinkRecord 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). * * For Type 3 link (Stub), */ @@ -49,14 +53,24 @@ public: // For Type 3 link (Stub), set m_linkData to mask 0xffffffff // Ipv4Address m_linkData; // for links to RouterLSA, - + /** + * Enumeration of the possible types of Static Router Link Records. These + * are defined in the OSPF spec. We currently only use PointToPoint and + * StubNetwork types. + */ enum LinkType { - PointToPoint = 1, - TransitNetwork, - StubNetwork, - VirtualLink + PointToPoint = 1, /**< Record representing a point to point channel */ + TransitNetwork, /**< Unused -- for future OSPF compatibility */ + StubNetwork, /**< Record represents a leaf node network */ + VirtualLink /**< Unused -- for future OSPF compatibility */ } m_linkType; - + /** + * An abstract cost associated with forwarding a packet across a link. + * A sum of metrics must have a well-defined meaning. That is, you shouldn't + * use bandwidth as a metric (how does the sum of the bandwidth of two hops + * relate to the cost of sending a packet); rather you should use something + * like delay. + */ uint32_t m_metric; }; @@ -70,19 +84,77 @@ public: class StaticRouterLSA { public: + /** + * Create a blank Static Router Link State Advertisement. On completion, + * any Ipv4Address variables initialized to 0.0.0.0 and the list of Link + * State Records is empty. + */ StaticRouterLSA(); + /** + * Copy constructor for a Static Router 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. + */ StaticRouterLSA (StaticRouterLSA& lsa); + /** + * Destroy an existing Static Router Link State Advertisement. Any Static + * router Link Records present in the list are freed. + */ ~StaticRouterLSA(); - - StaticRouterLSA& operator= (StaticRouterLSA lsa); - + /** + * Assignment operator for a Static Router Link State Advertisement. + * Takes an existing Static Router Link State Advertisement and overwrites + * it to make a semantically identical copy of a given prototype LSA. + * + * If there are any Static Router 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. + */ + StaticRouterLSA& operator= (StaticRouterLSA& lsa); + /** + * Add a given Static Router Link Record to a given Static Router Link + * State Advertisement. + * + * @param lr The Static Router Link Record to be added. + * @returns The number of link records in the list. + */ uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); + /** + * Release all of the Static Router Link Records present in the Static + * Router Link State Advertisement and make the list of link records empty. + */ void ClearLinkRecords(void); + /** + * Check to see of the list of Static Router Link Records present in the + * Static Router Link State Advertisement is empty. + * + * @returns True if the list is empty, false otherwise. + */ bool IsEmpty(void); - + /** + * Print the contents of the Static Router Link State Advertisement and + * any Static Router Link Records present in the list. Quite verbose. + */ void Print (std::ostream &os); - + /** + * 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 StaticRouter::GetRouterId () + */ Ipv4Address m_linkStateId; + /** + * The Advertising Router is defined by the OSPF spec. We always set it to + * the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () + * @see StaticRouter::GetRouterId () + */ Ipv4Address m_advertisingRtr; typedef std::list ListOfLinkRecords_t; @@ -103,11 +175,65 @@ std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); class StaticRouter : public Object { public: + /** + * The Interface ID of the Static Router interface. + * + * @see Object::QueryInterface () + */ static const InterfaceId iid; + /** + * Create a Static Router class and aggregate its interface onto the Node + * provided. + * + * @param lsa The existing Node onto which this router will be aggregated. + */ StaticRouter (Ptr node); - + /** + * Get the Router ID associated with this Static Router. The Router IDs + * are allocated in the RoutingEnvironment -- one per Router, starting at + * 0.0.0.1 and incrementing with each instantiation of a router. + * + * @see RoutingEnvironment::AllocateRouterId () + * @returns The Router ID associated with the Static Router. + */ Ipv4Address GetRouterId(void); + /** + * Get the Number of Static Router Link State Advertisements that this + * router can export. + * + * This is a fairly expensive operation in that every time it is called + * the current list of LSAs is built by walking connected point-to-point + * channels and peeking into adjacent IPV4 stacks to get address information. + * This is done to allow for limited dymanics of the Static Routing + * environment. By that we mean that you can discover new link state + * advertisements after a network topology change by calling GetNumLSAs and + * then by reading those advertisements. + * + * @see StaticRouterLSA + * @see StaticRouter::GetLSA () + * @returns The number of Static Router Link State Advertisements. + */ uint32_t GetNumLSAs (void); + /** + * Get a Static Router 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 Static Router Link + * State Advertisement into the requested StaticRouterLSA object. + * + * You must call StaticRouter::GetNumLSAs before calling this method in + * order to discover the adjacent routers and build the advertisements. + * GetNumLSAs will return the number of LSAs this router advertises. + * The parameter n (requested LSA number) must be in the range 0 to + * GetNumLSAs() - 1. + * + * @see StaticRouterLSA + * @see StaticRouter::GetNumLSAs () + * @param n The index number of the LSA you want to read. + * @param lsa The StaticRouterLSA class to receive the LSA information. + * @returns The number of Static Router Link State Advertisements. + */ bool GetLSA (uint32_t n, StaticRouterLSA &lsa); protected: From b10355c846476624088a60ed4329f9635d4eec44 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 13:01:43 -0700 Subject: [PATCH 35/92] made GetNumLSAs cheap, added DiscoverLSAs as expensive call. --- src/routing/static-route-manager.cc | 8 ++++++-- src/routing/static-router.cc | 20 ++++++++++++++------ src/routing/static-router.h | 24 +++++++++++++++++++----- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 867baeadd..cecd0d9cf 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -102,8 +102,12 @@ StaticRouteManager::BuildStaticRoutingDatabase () Ptr rtr = node->QueryInterface (StaticRouter::iid); NS_ASSERT_MSG(rtr, "QI for interface failed"); - - uint32_t numLSAs = rtr->GetNumLSAs(); +// +// Should call DiscoverLSAs () before trying to use any routing info or to +// update LSAs. Subsequently you may use GetNumLSAs(). If you call +// GetNumLSAs () before calling DiscoverLSAs () will get zero as the number. +// + uint32_t numLSAs = rtr->DiscoverLSAs(); NS_DEBUG_UNCOND ("Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 6f1fd245b..f8ff27657 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -184,12 +184,13 @@ StaticRouter::ClearLSAs () } // -// Return the number of Link State Advertisements this node has to advertise. +// Go out and discover any adjacent routers and build the Link State +// Advertisements that reflect them and their associated networks. // uint32_t -StaticRouter::GetNumLSAs (void) +StaticRouter::DiscoverLSAs (void) { - NS_DEBUG("StaticRouter::GetNumLSAs ()"); + NS_DEBUG("StaticRouter::DiscoverLSAs ()"); NS_ASSERT_MSG(m_node, " interface not set"); ClearLSAs (); // @@ -208,7 +209,7 @@ StaticRouter::GetNumLSAs (void) // a point-to-point channel. // uint32_t numDevices = m_node->GetNDevices(); - NS_DEBUG("StaticRouter::GetNumLSAs (): numDevices = " << numDevices); + NS_DEBUG("StaticRouter::DiscoverLSAs (): numDevices = " << numDevices); // // Loop through the devices looking for those connected to a point-to-point // channel. @@ -219,11 +220,11 @@ StaticRouter::GetNumLSAs (void) if (!ndLocal->IsPointToPoint ()) { - NS_DEBUG("StaticRouter::GetNumLSAs (): non-point-to-point device"); + NS_DEBUG("StaticRouter::DiscoverLSAs (): non-point-to-point device"); continue; } - NS_DEBUG("StaticRouter::GetNumLSAs (): Point-to-point device"); + NS_DEBUG("StaticRouter::DiscoverLSAs (): 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 @@ -304,6 +305,13 @@ StaticRouter::GetNumLSAs (void) return m_LSAs.size (); } + uint32_t +StaticRouter::GetNumLSAs (void) +{ + NS_DEBUG("StaticRouter::GetNumLSAs ()"); + return m_LSAs.size (); +} + // // Get the nth link state advertisement from this router. // diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 0d0cd09ac..f3273c311 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -185,7 +185,7 @@ public: * Create a Static Router class and aggregate its interface onto the Node * provided. * - * @param lsa The existing Node onto which this router will be aggregated. + * @param node The existing Node onto which this router will be aggregated. */ StaticRouter (Ptr node); /** @@ -198,21 +198,35 @@ public: */ Ipv4Address GetRouterId(void); /** - * Get the Number of Static Router Link State Advertisements that this - * router can export. + * Walk the connected channels, discover the adjacent routers and build + * the associated number of Static Router Link State Advertisements that + * this router can export. * * This is a fairly expensive operation in that every time it is called * the current list of LSAs is built by walking connected point-to-point * channels and peeking into adjacent IPV4 stacks to get address information. * This is done to allow for limited dymanics of the Static Routing * environment. By that we mean that you can discover new link state - * advertisements after a network topology change by calling GetNumLSAs and - * then by reading those advertisements. + * advertisements after a network topology change by calling DiscoverLSAs + * and then by reading those advertisements. * * @see StaticRouterLSA * @see StaticRouter::GetLSA () * @returns The number of Static Router Link State Advertisements. */ + uint32_t DiscoverLSAs (void); + /** + * Get the Number of Static Router Link State Advertisements that this + * router can export. To get meaningful information you must have + * previously called DiscoverLSAs. After you know how many LSAs are + * present in the router, you may call GetLSA () to retrieve the actual + * advertisement. + * + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @see StaticRouter::GetLSA () + * @returns The number of Static Router Link State Advertisements. + */ uint32_t GetNumLSAs (void); /** * Get a Static Router Link State Advertisements that this router has said From 0fc2f3d86d64e4b34d08c7c7b83801549d6fe76a Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 13:28:07 -0700 Subject: [PATCH 36/92] SPFVertex constructor --- src/routing/static-route-manager.cc | 13 +++++++++++++ src/routing/static-route-manager.h | 8 +++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 867baeadd..b7bb13f3f 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -15,6 +15,7 @@ */ #include #include +#include #include "ns3/assert.h" #include "ns3/fatal-error.h" #include "ns3/debug.h" @@ -26,6 +27,15 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { +SPFVertex::SPFVertex () : + m_vertexType(VertexUnknown), + m_vertexId("255.255.255.255"), + m_lsa(0), + m_distanceFromRoot(SPF_INFINITY), + m_stat(false) +{ +} + SPFVertex::~SPFVertex () { delete m_lsa; @@ -191,6 +201,9 @@ void StaticRouteManager::SPFCalculate(Ipv4Address root) { NS_DEBUG("StaticRouteManager::SPFCalculate ()"); + // Make a priority queue of int using a vector container + // priority_queue, less > pq; + //priority_queue, less > candidate; /* * struct pqueue* candidate; * struct vertex* v; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 6e0ac608f..861da5c13 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -26,6 +26,8 @@ namespace ns3 { +const uint32_t SPF_INFINITY = 0xffffffff; + /** * \brief Vertex used in shortest path first (SPF) computations * @@ -34,10 +36,12 @@ namespace ns3 { class SPFVertex { public: + SPFVertex(); ~SPFVertex(); enum VertexType { - VertexRouter = 1, + VertexUnknown = 0, + VertexRouter, VertexNetwork } m_vertexType; @@ -51,6 +55,8 @@ public: type_listOfSPFVertex::iterator m_iter; uint32_t m_distanceFromRoot; + + bool m_stat; // true if LSA is in SPF tree already }; /** From 42019fca7cd22d6e662865b92f82d0ee25d62fc3 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 13:34:23 -0700 Subject: [PATCH 37/92] Initialize LSDB for SPF runs --- src/routing/static-route-manager.cc | 31 ++++++++++++++++++++++++----- src/routing/static-route-manager.h | 5 +++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index b7bb13f3f..ed8c68c3d 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -41,6 +41,14 @@ SPFVertex::~SPFVertex () delete m_lsa; } +void +SPFVertex::Initialize () +{ + m_distanceFromRoot = SPF_INFINITY; + m_stat = false; + // XXX previous = 0 +} + StaticRouteManagerLSDB::~StaticRouteManagerLSDB() { @@ -48,7 +56,7 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) - { + { NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB():free vertex"); SPFVertex* temp = i->second; delete temp; @@ -57,6 +65,19 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() m_database.clear(); } +void +StaticRouteManagerLSDB::Initialize() +{ + NS_DEBUG("StaticRouteManagerLSDB::Initialize ()"); + + LSDBMap_t::iterator i; + for (i= m_database.begin(); i!= m_database.end(); i++) + { + SPFVertex* temp = i->second; + temp->Initialize(); + } +} + void StaticRouteManagerLSDB::Insert(Ipv4Address addr, SPFVertex* vertex) { @@ -201,6 +222,10 @@ void StaticRouteManager::SPFCalculate(Ipv4Address root) { NS_DEBUG("StaticRouteManager::SPFCalculate ()"); + + // The SPFVertex objects may have state from a previous computation + m_lsdb->Initialize(); + // Make a priority queue of int using a vector container // priority_queue, less > pq; //priority_queue, less > candidate; @@ -420,19 +445,15 @@ StaticRouteManagerTest::RunTests (void) SPFVertex* v0 = new SPFVertex (); v0->m_lsa = lsa0; v0->m_vertexType = SPFVertex::VertexRouter; - v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v1 = new SPFVertex (); v1->m_lsa = lsa1; v0->m_vertexType = SPFVertex::VertexRouter; - v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v2 = new SPFVertex (); v2->m_lsa = lsa2; v0->m_vertexType = SPFVertex::VertexRouter; - v0->m_distanceFromRoot = 0xffffffff; SPFVertex* v3 = new SPFVertex (); v3->m_lsa = lsa3; v0->m_vertexType = SPFVertex::VertexRouter; - v0->m_distanceFromRoot = 0xffffffff; // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 861da5c13..84b1a2e29 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -38,6 +38,7 @@ class SPFVertex public: SPFVertex(); ~SPFVertex(); + void Initialize (); enum VertexType { VertexUnknown = 0, @@ -68,6 +69,10 @@ public: ~StaticRouteManagerLSDB (); void Insert(Ipv4Address addr, SPFVertex* vertex); SPFVertex* GetVertex (Ipv4Address addr); + /** + * \brief Set all SPFVertex to an initialized state, for SPF computation + */ + void Initialize (); typedef std::map LSDBMap_t; typedef std::pair LSDBPair_t; From 3adfd850c723b812ae1a2aba55ebcf7e4efde345 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 13:39:54 -0700 Subject: [PATCH 38/92] Initialize SPFCalculate --- src/routing/static-route-manager.cc | 35 +++++++++-------------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index ed8c68c3d..888892b1c 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -225,36 +225,23 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // The SPFVertex objects may have state from a previous computation m_lsdb->Initialize(); + SPFVertex* v; - // Make a priority queue of int using a vector container - // priority_queue, less > pq; - //priority_queue, less > candidate; - /* - * struct pqueue* candidate; - * struct vertex* v; - */ + // Make a priority queue of int using a vector container + // priority_queue, less > pq; + // + //priority_queue candidate; + // // Initialize the shortest-path tree to only the router doing the // calculation. // + v= m_lsdb->GetVertex(root); + // Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the + // spanning tree. + v->m_distanceFromRoot = 0; + v->m_stat = true; #if 0 - ospf_spf_init (area); - v = area->spf; - - - /* Create a new heap for the candidates. */ - candidate = pqueue_create(); - candidate->cmp = cmp; - candidate->update = update_stat; - - /* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the - * * spanning tree. */ - *(v->stat) = LSA_SPF_IN_SPFTREE; - - /* Set Area A's TransitCapability to FALSE. */ - area->transit = OSPF_TRANSIT_FALSE; - area->shortcut_capability = 1; - for (;;) { /* RFC2328 16.1. (2). */ From 40e70fc6e9d3cc16408cb13bfe5fb89f02f003b5 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 13:58:13 -0700 Subject: [PATCH 39/92] Dummy test node for unit testing --- src/routing/static-route-manager.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 8deb95337..61c5af8c0 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -305,6 +305,28 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) namespace ns3 { +class StaticRouterTestNode : public Node +{ +public: + StaticRouterTestNode(); + +private: + virtual void DoAddDevice (Ptr device) const {}; + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); +}; + +StaticRouterTestNode::StaticRouterTestNode () +{ +// Ptr ipv4 = Create (this); +} + +TraceResolver* +StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) +{ + return 0; +} + + class StaticRouteManagerTest : public Test { public: StaticRouteManagerTest (); @@ -454,6 +476,9 @@ StaticRouteManagerTest::RunTests (void) srmlsdb->Insert(lsa3->m_linkStateId, v3); NS_ASSERT(v2 == srmlsdb->GetVertex(lsa2->m_linkStateId)); + // We need a dummy node to populate the routing tables + Ptr n2 = Create (); + // XXX next, calculate routes based on the manually created LSDB StaticRouteManager* srm = new StaticRouteManager(); srm->DebugUseLsdb (srmlsdb); From a2acacebe03ebfe9aeba75ac0eb25644df71db5d Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 15:03:39 -0700 Subject: [PATCH 40/92] Iterate link records (16.1(2)) --- src/routing/static-route-manager.cc | 84 ++++++++++++++++++++++++----- src/routing/static-route-manager.h | 4 +- src/routing/static-router.cc | 2 + 3 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 61c5af8c0..aab5bd88f 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -78,6 +78,16 @@ StaticRouteManagerLSDB::Initialize() } } +void +StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) +{ + SPFVertex* temp = new SPFVertex (); + temp->m_lsa = lsa; + temp->m_vertexType = SPFVertex::VertexRouter; + temp->m_vertexId = lsa->m_linkStateId; + m_database.insert(LSDBPair_t(addr, temp)); +} + void StaticRouteManagerLSDB::Insert(Ipv4Address addr, SPFVertex* vertex) { @@ -143,11 +153,12 @@ StaticRouteManager::BuildStaticRoutingDatabase () for (uint32_t j = 0; j < numLSAs; ++j) { - StaticRouterLSA lsa; - rtr->GetLSA(j, lsa); + StaticRouterLSA* lsa = new StaticRouterLSA (); + rtr->GetLSA(j, *lsa); NS_DEBUG_UNCOND ("LSA " << j); NS_DEBUG_UNCOND ("----------------------------"); - NS_DEBUG_UNCOND(lsa); + NS_DEBUG_UNCOND (*lsa); + m_lsdb->Insert (lsa->m_linkStateId, lsa); } } } @@ -192,7 +203,6 @@ StaticRouteManager::InitializeRoutes () for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { Ptr node = *i; - NS_DEBUG_UNCOND ("node="<< node->GetId () ); Ptr rtr = node->QueryInterface (StaticRouter::iid); @@ -206,12 +216,49 @@ StaticRouteManager::InitializeRoutes () // quagga ospf_spf_next +// RFC2328 Section 16.1 (2). +// v is on the SPF tree. Examine the links in v's LSA. Update the list +// of candidates with any vertices not already on the list. If a lower-cost +// path is found to a vertex already on the candidate list, store the new cost. +// +// +// void -StaticRouteManager::SPFNext() +StaticRouteManager::SPFNext(SPFVertex* v /*,candidate */) { - // if LSA == Router_LSA, examine links - // a) if link to stub, skip - // b) W is transit + if (v->m_vertexType == SPFVertex::VertexRouter) + { + // Always true for now, since all our LSAs are RouterLSAs + if (true) + { + NS_DEBUG_UNCOND("Examining " << v->m_vertexId << "'s link records"); + for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = + v->m_lsa->m_linkRecords.begin(); + i != v->m_lsa->m_linkRecords.end(); + 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. + StaticRouterLinkRecord* temp = *i; + if (temp->m_linkType == StaticRouterLinkRecord::StubNetwork) + { + NS_DEBUG_UNCOND("Found a Stub record to " << temp->m_linkId); + continue; + } + if (temp->m_linkType == StaticRouterLinkRecord::PointToPoint) + { + // Lookup the LSA (vertex) for the neighbor + SPFVertex* w = m_lsdb->GetVertex(temp->m_linkId); + NS_DEBUG_UNCOND("Found a P2P record from " << + v->m_vertexId << " to " << w->m_vertexId); + continue; + } + } + } + } + NS_DEBUG_UNCOND(""); } // quagga ospf_spf_calculate @@ -225,7 +272,7 @@ StaticRouteManager::DebugSPFCalculate(Ipv4Address root) void StaticRouteManager::SPFCalculate(Ipv4Address root) { - NS_DEBUG("StaticRouteManager::SPFCalculate ()"); + NS_DEBUG_UNCOND("StaticRouteManager::SPFCalculate ()"); // The SPFVertex objects may have state from a previous computation m_lsdb->Initialize(); @@ -242,11 +289,18 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) v= m_lsdb->GetVertex(root); // Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the // spanning tree. + NS_ASSERT(v); v->m_distanceFromRoot = 0; v->m_stat = true; + + // Add all other vertices to the candidate list -#if 0 for (;;) + { + SPFNext(v /*,candidate */); + break; + } +#if 0 { /* RFC2328 16.1. (2). */ ospf_spf_next (v, area, candidate); @@ -458,15 +512,19 @@ StaticRouteManagerTest::RunTests (void) SPFVertex* v0 = new SPFVertex (); v0->m_lsa = lsa0; v0->m_vertexType = SPFVertex::VertexRouter; + v0->m_vertexId = lsa0->m_linkStateId; SPFVertex* v1 = new SPFVertex (); v1->m_lsa = lsa1; - v0->m_vertexType = SPFVertex::VertexRouter; + v1->m_vertexType = SPFVertex::VertexRouter; + v1->m_vertexId = lsa1->m_linkStateId; SPFVertex* v2 = new SPFVertex (); v2->m_lsa = lsa2; - v0->m_vertexType = SPFVertex::VertexRouter; + v2->m_vertexType = SPFVertex::VertexRouter; + v2->m_vertexId = lsa2->m_linkStateId; SPFVertex* v3 = new SPFVertex (); v3->m_lsa = lsa3; - v0->m_vertexType = SPFVertex::VertexRouter; + v3->m_vertexType = SPFVertex::VertexRouter; + v3->m_vertexId = lsa3->m_linkStateId; // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 84b1a2e29..0ab536350 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -68,6 +68,7 @@ class StaticRouteManagerLSDB public: ~StaticRouteManagerLSDB (); void Insert(Ipv4Address addr, SPFVertex* vertex); + void Insert(Ipv4Address addr, StaticRouterLSA* lsa); SPFVertex* GetVertex (Ipv4Address addr); /** * \brief Set all SPFVertex to an initialized state, for SPF computation @@ -116,12 +117,13 @@ public: void DebugSPFCalculate (Ipv4Address root); virtual ~StaticRouteManager (); + protected: private: StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); - void SPFNext (); + void SPFNext (SPFVertex*/*,candidate */); }; } // namespace ns3 diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index f8ff27657..4bacbda64 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -49,6 +49,7 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; pDst->m_linkId = pSrc->m_linkId; pDst->m_linkData = pSrc->m_linkData; + pDst->m_linkType = pSrc->m_linkType; m_linkRecords.push_back(pDst); pDst = 0; } @@ -71,6 +72,7 @@ StaticRouterLSA::operator= (StaticRouterLSA& lsa) StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; pDst->m_linkId = pSrc->m_linkId; pDst->m_linkData = pSrc->m_linkData; + pDst->m_linkType = pSrc->m_linkType; m_linkRecords.push_back(pDst); pDst = 0; } From 711276e62b09ea173b7fa87a41508802b4dc4508 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 17:35:44 -0700 Subject: [PATCH 41/92] SPFVertex Priority Queue --- src/routing/static-route-manager.cc | 23 ++++++++++++++++++++++- src/routing/static-route-manager.h | 13 +++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index aab5bd88f..4a4739c4d 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -49,7 +49,6 @@ SPFVertex::Initialize () // XXX previous = 0 } - StaticRouteManagerLSDB::~StaticRouteManagerLSDB() { NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); @@ -401,6 +400,28 @@ StaticRouteManagerTest::RunTests (void) { bool ok = true; + SPFVertexPriorityQueue candidate; // <---------------- + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = new SPFVertex; + v->m_distanceFromRoot = rand () % 100; + candidate.push (v); // <---------------- + } + + uint32_t lastDistance = 0; + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = candidate.top (); // <---------------- + candidate.pop (); // <---------------- + if (v->m_distanceFromRoot < lastDistance) + { + ok = false; + } + lastDistance = v->m_distanceFromRoot; + } + // Build fake link state database; four routers (0-3), 3 point-to-point // links // diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 0ab536350..81669804f 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "ns3/object.h" #include "ns3/ptr.h" @@ -58,8 +59,20 @@ public: uint32_t m_distanceFromRoot; bool m_stat; // true if LSA is in SPF tree already + + struct Greater : public std::binary_function< SPFVertex*, SPFVertex*, bool> + { + bool operator()(const SPFVertex *v1, const SPFVertex *v2) const + { + return v1->m_distanceFromRoot > v2->m_distanceFromRoot; + } + }; }; +typedef std::vector SPFVector_t; +typedef std::priority_queue + SPFVertexPriorityQueue; + /** * \brief The Link State DataBase (LSDB) of a static router */ From 4e86f62a6445c99cc70f34e22aa1cce765cc4d2b Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 17:56:46 -0700 Subject: [PATCH 42/92] end of day checkin --- src/routing/static-route-manager.cc | 52 +++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 4a4739c4d..2449b6979 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -246,12 +246,50 @@ StaticRouteManager::SPFNext(SPFVertex* v /*,candidate */) NS_DEBUG_UNCOND("Found a Stub record to " << temp->m_linkId); 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 (temp->m_linkType == StaticRouterLinkRecord::PointToPoint) { // Lookup the LSA (vertex) for the neighbor SPFVertex* w = m_lsdb->GetVertex(temp->m_linkId); + NS_ASSERT(w); NS_DEBUG_UNCOND("Found a P2P record from " << v->m_vertexId << " to " << w->m_vertexId); + // (c) If vertex W is already on the shortest-path tree, + // examine the next link in the LSA. + if (w->m_stat == true) + { + 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. + +// uint32_t distance = v->m_distanceFromRoot + temp->m_metric; + + // Here, W is either already in candidate list or not + + // if (not in candidate list) + // ospf_nexthop_calculation() + // priority_queue.enqueu() + // else + // get vertex from candidates list + // if (w->distance < distance) + // continue; // not a shorter path + // else if (w->distance > distance) + // Found a lower-cost path to W. + // * nexthop_calculation is conditional, if it finds + // * valid nexthop it will call spf_add_parents, which + // * will flush the old parents + // */ + // if (ospf_nexthop_calculation (area, v, w, l, distance)) + // /* Decrease the key of the node in the heap, + // * re-sort the heap. */ + // trickle_down (w_lsa->stat, candidate); + // continue; } } @@ -293,17 +331,14 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) v->m_stat = true; // Add all other vertices to the candidate list + // XXX todo for (;;) { - SPFNext(v /*,candidate */); - break; - } + // RFC2328 16.1. (2). + SPFNext(v /*,candidate */); + #if 0 - { - /* RFC2328 16.1. (2). */ - ospf_spf_next (v, area, candidate); - /* RFC2328 16.1. (3). */ /* If at this step the candidate list is empty, the shortest- * path tree (of transit vertices) has been completely built and @@ -345,6 +380,9 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) pqueue_delete (candidate); #endif + break; + } + } From e47dd4f054e8fc0e6c33f651cfc7f24c56311efc Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 17:59:11 -0700 Subject: [PATCH 43/92] One RouterLSA per node --- src/routing/static-router.cc | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 4bacbda64..48a697a5e 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -203,6 +203,15 @@ StaticRouter::DiscoverLSAs (void) Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4Local, "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. +// + StaticRouterLSA *pLSA = new StaticRouterLSA; + pLSA->m_linkStateId = m_routerId; + pLSA->m_advertisingRtr = m_routerId; +// // 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., @@ -277,15 +286,10 @@ StaticRouter::DiscoverLSAs (void) Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); NS_DEBUG("Working with remote address " << addrRemote); // -// Now we can fill out the link state advertisement 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. +// 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. // - StaticRouterLSA *pLSA = new StaticRouterLSA; - pLSA->m_linkStateId = m_routerId; - pLSA->m_advertisingRtr = m_routerId; - StaticRouterLinkRecord *plr = new StaticRouterLinkRecord; plr->m_linkType = StaticRouterLinkRecord::PointToPoint; plr->m_linkId = rtrIdRemote; @@ -299,11 +303,12 @@ StaticRouter::DiscoverLSAs (void) plr->m_linkData.Set(maskRemote.GetHostOrder()); // Frown pLSA->AddLinkRecord(plr); plr = 0; - - m_LSAs.push_back (pLSA); - NS_DEBUG(*pLSA); } - +// +// 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); return m_LSAs.size (); } From d57291777f7c9d6f67f03f0ee54b0582181bd88e Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 10 Jul 2007 22:17:25 -0700 Subject: [PATCH 44/92] minor tweaks --- src/routing/static-router.cc | 30 ++++++++++-------------------- src/routing/static-router.h | 9 +++++++++ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 48a697a5e..b1a470feb 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -38,32 +38,24 @@ StaticRouterLSA::StaticRouterLSA() StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr) { - NS_DEBUG("StaticRouterLSA Copy Constructor"); - NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before copy"); - - for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin (); - i != lsa.m_linkRecords.end (); - i++) - { - StaticRouterLinkRecord *pSrc = *i; - StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; - pDst->m_linkId = pSrc->m_linkId; - pDst->m_linkData = pSrc->m_linkData; - pDst->m_linkType = pSrc->m_linkType; - m_linkRecords.push_back(pDst); - pDst = 0; - } + NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty in its constructor!"); + CopyLinkRecords (lsa); } StaticRouterLSA& StaticRouterLSA::operator= (StaticRouterLSA& lsa) { - NS_DEBUG("StaticRouterLSA Operator ="); - NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty before assignment"); - m_linkStateId = lsa.m_linkStateId; m_advertisingRtr = lsa.m_advertisingRtr; + ClearLinkRecords (); + CopyLinkRecords (lsa); + return *this; +} + + void +StaticRouterLSA::CopyLinkRecords (StaticRouterLSA& lsa) +{ for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin (); i != lsa.m_linkRecords.end (); i++) @@ -76,8 +68,6 @@ StaticRouterLSA::operator= (StaticRouterLSA& lsa) m_linkRecords.push_back(pDst); pDst = 0; } - - return *this; } StaticRouterLSA::~StaticRouterLSA() diff --git a/src/routing/static-router.h b/src/routing/static-router.h index f3273c311..d65e4e165 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -115,6 +115,15 @@ public: * @returns Reference to the overwritten LSA. */ StaticRouterLSA& operator= (StaticRouterLSA& lsa); + /** + * Copy any Static Router Link Records in a given Static Router Link + * State Advertisement to the current LSA. Existing Link Records are not + * deleted -- this is a concatenation of Link Records. + * + * @see ClearLinkRecords () + * @param lsa The LSA to copy the Link Records from. + */ + void CopyLinkRecords (StaticRouterLSA& lsa); /** * Add a given Static Router Link Record to a given Static Router Link * State Advertisement. From 8168ddcb400a1cbd0ecdd31fa98865aa3d55e0a0 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 10 Jul 2007 23:10:18 -0700 Subject: [PATCH 45/92] Add candidate list (priority queue) --- src/routing/static-route-manager.cc | 26 ++++++++++++-------------- src/routing/static-route-manager.h | 9 +++++++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 2449b6979..a0161656c 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -32,7 +32,7 @@ SPFVertex::SPFVertex () : m_vertexId("255.255.255.255"), m_lsa(0), m_distanceFromRoot(SPF_INFINITY), - m_stat(false) + m_stat(LSA_SPF_NOT_EXPLORED) { } @@ -45,7 +45,7 @@ void SPFVertex::Initialize () { m_distanceFromRoot = SPF_INFINITY; - m_stat = false; + m_stat = LSA_SPF_NOT_EXPLORED; // XXX previous = 0 } @@ -223,7 +223,7 @@ StaticRouteManager::InitializeRoutes () // // void -StaticRouteManager::SPFNext(SPFVertex* v /*,candidate */) +StaticRouteManager::SPFNext(SPFVertex* v, SPFVertexPriorityQueue& candidate) { if (v->m_vertexType == SPFVertex::VertexRouter) { @@ -258,7 +258,7 @@ StaticRouteManager::SPFNext(SPFVertex* v /*,candidate */) v->m_vertexId << " to " << w->m_vertexId); // (c) If vertex W is already on the shortest-path tree, // examine the next link in the LSA. - if (w->m_stat == true) + if (w->m_stat == LSA_SPF_IN_SPFTREE) { continue; } @@ -268,7 +268,7 @@ StaticRouteManager::SPFNext(SPFVertex* v /*,candidate */) // shortest path to vertex V and the advertised cost of // the link between vertices V and W. -// uint32_t distance = v->m_distanceFromRoot + temp->m_metric; + //uint32_t distance = v->m_distanceFromRoot + temp->m_metric; // Here, W is either already in candidate list or not @@ -315,10 +315,12 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) m_lsdb->Initialize(); SPFVertex* v; - // Make a priority queue of int using a vector container - // priority_queue, less > pq; + // The candidate queue is a priority queue of SPFVertex objects, with + // the top of the queue being the closest vertex in terms of + // distanceFromRoot. Initially, this queue is empty. // - //priority_queue candidate; + SPFVertexPriorityQueue candidate; + NS_ASSERT(candidate.size() == 0); // // Initialize the shortest-path tree to only the router doing the // calculation. @@ -328,16 +330,12 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // spanning tree. NS_ASSERT(v); v->m_distanceFromRoot = 0; - v->m_stat = true; + v->m_stat = LSA_SPF_IN_SPFTREE; - // Add all other vertices to the candidate list - // XXX todo - for (;;) { // RFC2328 16.1. (2). - SPFNext(v /*,candidate */); - + SPFNext(v , candidate); #if 0 /* RFC2328 16.1. (3). */ /* If at this step the candidate list is empty, the shortest- diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 81669804f..6e63aa5f0 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -29,6 +29,8 @@ namespace ns3 { const uint32_t SPF_INFINITY = 0xffffffff; +const int LSA_SPF_NOT_EXPLORED = -1; +const int LSA_SPF_IN_SPFTREE = -2; /** * \brief Vertex used in shortest path first (SPF) computations * @@ -51,6 +53,8 @@ public: StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes + // XXX not sure exactly what data structure is needed here + // need to keep track of previous vertex typedef std::list type_listOfSPFVertex; type_listOfSPFVertex m_parents; type_listOfSPFVertex m_children; @@ -58,7 +62,8 @@ public: uint32_t m_distanceFromRoot; - bool m_stat; // true if LSA is in SPF tree already + // If stat >= 0, stat is LSA position in candidates heap + int m_stat; struct Greater : public std::binary_function< SPFVertex*, SPFVertex*, bool> { @@ -136,7 +141,7 @@ protected: private: StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); - void SPFNext (SPFVertex*/*,candidate */); + void SPFNext (SPFVertex*, SPFVertexPriorityQueue&); }; } // namespace ns3 From 9dc9be484f7484ffe1627c120550f57da0db2f90 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 11 Jul 2007 13:18:01 -0700 Subject: [PATCH 46/92] candidate queue --- SConstruct | 10 ++- samples/main-candidate-queue.cc | 91 +++++++++++++++++++ src/routing/candidate-queue.cc | 151 ++++++++++++++++++++++++++++++++ src/routing/candidate-queue.h | 50 +++++++++++ src/routing/static-router.cc | 2 +- src/routing/static-router.h | 24 ++--- 6 files changed, 314 insertions(+), 14 deletions(-) create mode 100644 samples/main-candidate-queue.cc create mode 100644 src/routing/candidate-queue.cc create mode 100644 src/routing/candidate-queue.h diff --git a/SConstruct b/SConstruct index 00a799f90..111358020 100644 --- a/SConstruct +++ b/SConstruct @@ -374,6 +374,7 @@ routing.add_sources([ 'routing-environment.cc', 'static-router.cc', 'static-route-manager.cc', + 'candidate-queue.cc', ]) routing.add_headers ([ ]) @@ -381,6 +382,7 @@ routing.add_inst_headers([ 'routing-environment.h', 'static-router.h', 'static-route-manager.h', + 'candidate-queue.h', ]) # utils @@ -429,7 +431,6 @@ ns3.add(sample_packet_printer) sample_packet_printer.add_deps (['common', 'internet-node']) sample_packet_printer.add_source('main-packet-printer.cc') - sample_callback = build.Ns3Module('sample-callback', 'samples') sample_callback.set_executable() ns3.add(sample_callback) @@ -502,6 +503,13 @@ ns3.add(sample_component_manager) sample_component_manager.add_deps(['core']) sample_component_manager.add_source('main-component-manager.cc') +sample_candidate_queue = build.Ns3Module('sample-candidate-queue', 'samples') +sample_candidate_queue.set_executable() +ns3.add(sample_candidate_queue) +sample_candidate_queue.add_deps(['core']) +sample_candidate_queue.add_deps(['routing']) +sample_candidate_queue.add_source('main-candidate-queue.cc') + # examples example_simple_p2p = build.Ns3Module('simple-p2p', 'examples') example_simple_p2p.set_executable() diff --git a/samples/main-candidate-queue.cc b/samples/main-candidate-queue.cc new file mode 100644 index 000000000..7708b8c0f --- /dev/null +++ b/samples/main-candidate-queue.cc @@ -0,0 +1,91 @@ +/* -*- 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 + */ + +#include "ns3/debug.h" +#include "ns3/assert.h" +#include "ns3/candidate-queue.h" + +using namespace ns3; + + int +main (int argc, char *argv[]) +{ + NS_DEBUG_UNCOND("Candidate Queue Test"); + +#if 0 + DebugComponentEnable("CandidateQueue"); +#endif + + CandidateQueue candidate; + NS_ASSERT(candidate.Size () == 0); + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = new SPFVertex; + v->m_distanceFromRoot = rand () % 100; + candidate.Push (v); + } + + uint32_t lastDistance = 0; + bool ok = true; + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = candidate.Top (); + candidate.Pop (); + if (v->m_distanceFromRoot < lastDistance) + { + ok = false; + NS_ASSERT(0); + } + lastDistance = v->m_distanceFromRoot; + } + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = new SPFVertex; + v->m_distanceFromRoot = rand () % 100; + candidate.Push (v); + } + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = candidate.Fetch (i); + if (v) { + v->m_distanceFromRoot = rand () % 100; + } + } + + candidate.Reorder (); + + lastDistance = 0; + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = candidate.Top (); + candidate.Pop (); + if (v->m_distanceFromRoot < lastDistance) + { + ok = false; + NS_ASSERT(0); + } + lastDistance = v->m_distanceFromRoot; + } + + NS_ASSERT(candidate.Size () == 0); + + return 0; +} diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc new file mode 100644 index 000000000..a4b29802c --- /dev/null +++ b/src/routing/candidate-queue.cc @@ -0,0 +1,151 @@ +/* -*- 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 + */ + +#include "ns3/debug.h" +#include "ns3/assert.h" +#include "candidate-queue.h" + +NS_DEBUG_COMPONENT_DEFINE ("CandidateQueue"); + +namespace ns3 { + +CandidateQueue::CandidateQueue() + : m_candidates () +{ + NS_DEBUG("CandidateQueue::CandidateQueue ()"); +} + +CandidateQueue::~CandidateQueue() +{ + NS_DEBUG("CandidateQueue::~CandidateQueue ()"); + Clear (); +} + + void +CandidateQueue::Clear (void) +{ + NS_DEBUG("CandidateQueue::Clear ()"); + + while (!m_candidates.empty ()) + { + Pop (); + } +} + + + void +CandidateQueue::Push (SPFVertex *vNew) +{ + NS_DEBUG("CandidateQueue::Push (" << vNew << ")"); + + CandidateList_t::iterator i = m_candidates.begin (); + + for (; i != m_candidates.end (); i++) + { + SPFVertex *v = *i; + if (vNew->m_distanceFromRoot < v->m_distanceFromRoot) + { + break; + } + } + m_candidates.insert(i, vNew); +} + + void +CandidateQueue::Pop (void) +{ + NS_DEBUG("CandidateQueue::Pop ()"); + + if (m_candidates.empty ()) + { + return; + } + + SPFVertex *v = m_candidates.front (); + m_candidates.pop_front (); + delete v; + v = 0; +} + + SPFVertex * +CandidateQueue::Top (void) +{ + NS_DEBUG("CandidateQueue::Top ()"); + + if (m_candidates.empty ()) + { + return 0; + } + + return m_candidates.front (); +} + + bool +CandidateQueue::Empty (void) +{ + NS_DEBUG("CandidateQueue::Empty ()"); + + return m_candidates.empty (); +} + + uint32_t +CandidateQueue::Size (void) +{ + NS_DEBUG("CandidateQueue::Size ()"); + + return m_candidates.size (); +} + + + SPFVertex * +CandidateQueue::Fetch (uint32_t m_distanceFromRoot) +{ + NS_DEBUG("CandidateQueue::Fetch ()"); + + CandidateList_t::iterator i = m_candidates.begin (); + + for (; i != m_candidates.end (); i++) + { + SPFVertex *v = *i; + if (v->m_distanceFromRoot == m_distanceFromRoot) + { + return v; + } + } + + return 0; +} + + void +CandidateQueue::Reorder (void) +{ + NS_DEBUG("CandidateQueue::Reorder ()"); + + std::list temp; + + while (!m_candidates.empty ()) { + SPFVertex *v = m_candidates.front (); + m_candidates.pop_front (); + temp.push_back(v); + } + + while (!temp.empty ()) { + Push (temp.front ()); + temp.pop_front (); + } +} + +} // namespace ns3 diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h new file mode 100644 index 000000000..e04bd4651 --- /dev/null +++ b/src/routing/candidate-queue.h @@ -0,0 +1,50 @@ +/* -*- 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 + */ + +#ifndef CANDIDATE_QUEUE_H +#define CANDIDATE_QUEUE_H + +#include +#include +#include "static-route-manager.h" + +namespace ns3 { + +class CandidateQueue +{ +public: + CandidateQueue (); + virtual ~CandidateQueue (); + + void Clear (void); + void Push (SPFVertex *v); + void Pop (void); + SPFVertex* Top (void); + bool Empty (void); + uint32_t Size (void); + SPFVertex* Fetch (uint32_t key); + void Reorder (void); + +protected: + typedef std::list CandidateList_t; + CandidateList_t m_candidates; + +private: +}; + +} // namespace ns3 + +#endif /* CANDIDATE_QUEUE_H */ diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index b1a470feb..528a1500f 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -170,7 +170,7 @@ StaticRouter::ClearLSAs () } Ipv4Address - StaticRouter::GetRouterId (void) +StaticRouter::GetRouterId (void) { return m_routerId; } diff --git a/src/routing/static-router.h b/src/routing/static-router.h index d65e4e165..bda6cc04a 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -13,6 +13,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef STATIC_ROUTER_H #define STATIC_ROUTER_H @@ -39,19 +40,18 @@ namespace ns3 { class StaticRouterLinkRecord { public: - // - // For Type 1 link (PointToPoint), set m_linkId to Router ID of - // neighboring router. - // - // For Type 3 link (Stub), set m_linkId to neighbor's IP address - // +// +// For Type 1 link (PointToPoint), set m_linkId to Router ID of +// neighboring router. +// +// For Type 3 link (Stub), set m_linkId to neighbor's IP address +// Ipv4Address m_linkId; - - // - // For Type 1 link (PointToPoint), set m_linkData to local IP address - // - // For Type 3 link (Stub), set m_linkData to mask 0xffffffff - // +// +// For Type 1 link (PointToPoint), set m_linkData to local IP address +// +// For Type 3 link (Stub), set m_linkData to mask 0xffffffff +// Ipv4Address m_linkData; // for links to RouterLSA, /** * Enumeration of the possible types of Static Router Link Records. These From 248122670f13282034382d6323b8c9698c866853 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 16:45:19 -0700 Subject: [PATCH 47/92] Adjust candidate queue implementation: rename Fetch to Find, and make Find based on m_vertexId --- samples/main-candidate-queue.cc | 4 +++- src/routing/candidate-queue.cc | 6 +++--- src/routing/candidate-queue.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/samples/main-candidate-queue.cc b/samples/main-candidate-queue.cc index 7708b8c0f..ca111f0dc 100644 --- a/samples/main-candidate-queue.cc +++ b/samples/main-candidate-queue.cc @@ -61,13 +61,15 @@ main (int argc, char *argv[]) candidate.Push (v); } +#if 0 for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.Fetch (i); + SPFVertex *v = candidate.Find (i); if (v) { v->m_distanceFromRoot = rand () % 100; } } +#endif candidate.Reorder (); diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc index a4b29802c..7b5f9ba96 100644 --- a/src/routing/candidate-queue.cc +++ b/src/routing/candidate-queue.cc @@ -111,16 +111,16 @@ CandidateQueue::Size (void) SPFVertex * -CandidateQueue::Fetch (uint32_t m_distanceFromRoot) +CandidateQueue::Find (const Ipv4Address addr) { - NS_DEBUG("CandidateQueue::Fetch ()"); + NS_DEBUG("CandidateQueue::Find ()"); CandidateList_t::iterator i = m_candidates.begin (); for (; i != m_candidates.end (); i++) { SPFVertex *v = *i; - if (v->m_distanceFromRoot == m_distanceFromRoot) + if (v->m_vertexId == addr) { return v; } diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index e04bd4651..5d266e7c5 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -35,7 +35,7 @@ public: SPFVertex* Top (void); bool Empty (void); uint32_t Size (void); - SPFVertex* Fetch (uint32_t key); + SPFVertex* Find (const Ipv4Address addr); void Reorder (void); protected: From 9424ed96695195c11db1a55daaa3cd8c199be0cf Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 17:13:11 -0700 Subject: [PATCH 48/92] Make LSDB back into a storage for LSAs --- src/routing/static-route-manager.cc | 71 ++++++++++------------------- src/routing/static-route-manager.h | 9 ++-- 2 files changed, 28 insertions(+), 52 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index a0161656c..7bc6b2f5e 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -56,14 +56,15 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) { - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB():free vertex"); - SPFVertex* temp = i->second; + NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB():free LSA"); + StaticRouterLSA* temp = i->second; delete temp; } NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); m_database.clear(); } +#if 0 void StaticRouteManagerLSDB::Initialize() { @@ -72,29 +73,20 @@ StaticRouteManagerLSDB::Initialize() LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) { - SPFVertex* temp = i->second; + StaticRouterLSA* temp = i->second; temp->Initialize(); } } +#endif void StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) { - SPFVertex* temp = new SPFVertex (); - temp->m_lsa = lsa; - temp->m_vertexType = SPFVertex::VertexRouter; - temp->m_vertexId = lsa->m_linkStateId; - m_database.insert(LSDBPair_t(addr, temp)); + m_database.insert(LSDBPair_t(addr, lsa)); } -void -StaticRouteManagerLSDB::Insert(Ipv4Address addr, SPFVertex* vertex) -{ - m_database.insert(LSDBPair_t(addr, vertex)); -} - -SPFVertex* -StaticRouteManagerLSDB::GetVertex (Ipv4Address addr) +StaticRouterLSA* +StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) { // Look up an LSA by its address LSDBMap_t::iterator i; @@ -252,16 +244,18 @@ StaticRouteManager::SPFNext(SPFVertex* v, SPFVertexPriorityQueue& candidate) if (temp->m_linkType == StaticRouterLinkRecord::PointToPoint) { // Lookup the LSA (vertex) for the neighbor - SPFVertex* w = m_lsdb->GetVertex(temp->m_linkId); - NS_ASSERT(w); + StaticRouterLSA* w_lsa = m_lsdb->GetLSA(temp->m_linkId); + NS_ASSERT(w_lsa); NS_DEBUG_UNCOND("Found a P2P record from " << - v->m_vertexId << " to " << w->m_vertexId); + v->m_vertexId << " to " << w_lsa->m_linkStateId); +#if 0 // (c) If vertex W is already on the shortest-path tree, // examine the next link in the LSA. if (w->m_stat == LSA_SPF_IN_SPFTREE) { continue; } +#endif // (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) @@ -311,8 +305,6 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) { NS_DEBUG_UNCOND("StaticRouteManager::SPFCalculate ()"); - // The SPFVertex objects may have state from a previous computation - m_lsdb->Initialize(); SPFVertex* v; // The candidate queue is a priority queue of SPFVertex objects, with @@ -325,10 +317,12 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // Initialize the shortest-path tree to only the router doing the // calculation. // - v= m_lsdb->GetVertex(root); + v= new SPFVertex(); + v->m_vertexType = SPFVertex::VertexRouter; + v->m_vertexId = root; + v-> m_lsa = m_lsdb->GetLSA(root); // Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the // spanning tree. - NS_ASSERT(v); v->m_distanceFromRoot = 0; v->m_stat = LSA_SPF_IN_SPFTREE; @@ -565,31 +559,13 @@ StaticRouteManagerTest::RunTests (void) lsa3->AddLinkRecord(lr2); lsa3->AddLinkRecord(lr3); - // Create four vertices to store these four LSAs - SPFVertex* v0 = new SPFVertex (); - v0->m_lsa = lsa0; - v0->m_vertexType = SPFVertex::VertexRouter; - v0->m_vertexId = lsa0->m_linkStateId; - SPFVertex* v1 = new SPFVertex (); - v1->m_lsa = lsa1; - v1->m_vertexType = SPFVertex::VertexRouter; - v1->m_vertexId = lsa1->m_linkStateId; - SPFVertex* v2 = new SPFVertex (); - v2->m_lsa = lsa2; - v2->m_vertexType = SPFVertex::VertexRouter; - v2->m_vertexId = lsa2->m_linkStateId; - SPFVertex* v3 = new SPFVertex (); - v3->m_lsa = lsa3; - v3->m_vertexType = SPFVertex::VertexRouter; - v3->m_vertexId = lsa3->m_linkStateId; - // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); - srmlsdb->Insert(lsa0->m_linkStateId, v0); - srmlsdb->Insert(lsa1->m_linkStateId, v1); - srmlsdb->Insert(lsa2->m_linkStateId, v2); - srmlsdb->Insert(lsa3->m_linkStateId, v3); - NS_ASSERT(v2 == srmlsdb->GetVertex(lsa2->m_linkStateId)); + srmlsdb->Insert(lsa0->m_linkStateId, lsa0); + srmlsdb->Insert(lsa1->m_linkStateId, lsa1); + srmlsdb->Insert(lsa2->m_linkStateId, lsa2); + srmlsdb->Insert(lsa3->m_linkStateId, lsa3); + NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); // We need a dummy node to populate the routing tables Ptr n2 = Create (); @@ -600,8 +576,7 @@ StaticRouteManagerTest::RunTests (void) srm->DebugSPFCalculate(lsa0->m_linkStateId); // node n0 // This delete clears the srm, which deletes the LSDB, which clears - // all of the vertices, which each destroy the matching LSAs, which each - // destroys the attached LinkRecords. + // all of the LSAs, which each destroys the attached LinkRecords. delete srm; return ok; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 6e63aa5f0..42fa7ee16 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -85,16 +85,17 @@ class StaticRouteManagerLSDB { public: ~StaticRouteManagerLSDB (); - void Insert(Ipv4Address addr, SPFVertex* vertex); void Insert(Ipv4Address addr, StaticRouterLSA* lsa); - SPFVertex* GetVertex (Ipv4Address addr); + StaticRouterLSA* GetLSA (Ipv4Address addr); /** * \brief Set all SPFVertex to an initialized state, for SPF computation */ +#if 0 void Initialize (); +#endif - typedef std::map LSDBMap_t; - typedef std::pair LSDBPair_t; + typedef std::map LSDBMap_t; + typedef std::pair LSDBPair_t; LSDBMap_t m_database; }; From 9ff955496e4bea66691961e123256cf70c8dad87 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 17:31:43 -0700 Subject: [PATCH 49/92] Replace SPFVertexPriorityQueue with CandidateQueue --- src/routing/static-route-manager.cc | 15 ++++++++------- src/routing/static-route-manager.h | 17 ++++------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 7bc6b2f5e..b68432ca0 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -22,6 +22,7 @@ #include "ns3/node-list.h" #include "static-router.h" #include "static-route-manager.h" +#include "candidate-queue.h" NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); @@ -215,7 +216,7 @@ StaticRouteManager::InitializeRoutes () // // void -StaticRouteManager::SPFNext(SPFVertex* v, SPFVertexPriorityQueue& candidate) +StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) { if (v->m_vertexType == SPFVertex::VertexRouter) { @@ -311,8 +312,8 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // the top of the queue being the closest vertex in terms of // distanceFromRoot. Initially, this queue is empty. // - SPFVertexPriorityQueue candidate; - NS_ASSERT(candidate.size() == 0); + CandidateQueue candidate; + NS_ASSERT(candidate.Size() == 0); // // Initialize the shortest-path tree to only the router doing the // calculation. @@ -430,21 +431,21 @@ StaticRouteManagerTest::RunTests (void) { bool ok = true; - SPFVertexPriorityQueue candidate; // <---------------- + CandidateQueue candidate; // <---------------- for (int i = 0; i < 100; ++i) { SPFVertex *v = new SPFVertex; v->m_distanceFromRoot = rand () % 100; - candidate.push (v); // <---------------- + candidate.Push (v); // <---------------- } uint32_t lastDistance = 0; for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.top (); // <---------------- - candidate.pop (); // <---------------- + SPFVertex *v = candidate.Top (); // <---------------- + candidate.Pop (); // <---------------- if (v->m_distanceFromRoot < lastDistance) { ok = false; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 42fa7ee16..e9e94997b 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -31,6 +31,9 @@ const uint32_t SPF_INFINITY = 0xffffffff; const int LSA_SPF_NOT_EXPLORED = -1; const int LSA_SPF_IN_SPFTREE = -2; + +class CandidateQueue; + /** * \brief Vertex used in shortest path first (SPF) computations * @@ -64,20 +67,8 @@ public: // If stat >= 0, stat is LSA position in candidates heap int m_stat; - - struct Greater : public std::binary_function< SPFVertex*, SPFVertex*, bool> - { - bool operator()(const SPFVertex *v1, const SPFVertex *v2) const - { - return v1->m_distanceFromRoot > v2->m_distanceFromRoot; - } - }; }; -typedef std::vector SPFVector_t; -typedef std::priority_queue - SPFVertexPriorityQueue; - /** * \brief The Link State DataBase (LSDB) of a static router */ @@ -142,7 +133,7 @@ protected: private: StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); - void SPFNext (SPFVertex*, SPFVertexPriorityQueue&); + void SPFNext (SPFVertex*, CandidateQueue&); }; } // namespace ns3 From 33a0cc37598a58628b8352428f858727a4f9014b Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 22:37:48 -0700 Subject: [PATCH 50/92] move m_stat flag to LSA --- src/routing/static-route-manager.cc | 19 ++++++++++--------- src/routing/static-route-manager.h | 5 ----- src/routing/static-router.cc | 8 ++++++-- src/routing/static-router.h | 8 ++++++++ 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index b68432ca0..1a681764e 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -32,8 +32,7 @@ SPFVertex::SPFVertex () : m_vertexType(VertexUnknown), m_vertexId("255.255.255.255"), m_lsa(0), - m_distanceFromRoot(SPF_INFINITY), - m_stat(LSA_SPF_NOT_EXPLORED) + m_distanceFromRoot(SPF_INFINITY) { } @@ -46,7 +45,6 @@ void SPFVertex::Initialize () { m_distanceFromRoot = SPF_INFINITY; - m_stat = LSA_SPF_NOT_EXPLORED; // XXX previous = 0 } @@ -244,19 +242,18 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // network-LSA) in Area A's link state database. if (temp->m_linkType == StaticRouterLinkRecord::PointToPoint) { - // Lookup the LSA (vertex) for the neighbor + // Lookup the vertex W's LSA StaticRouterLSA* w_lsa = m_lsdb->GetLSA(temp->m_linkId); NS_ASSERT(w_lsa); NS_DEBUG_UNCOND("Found a P2P record from " << v->m_vertexId << " to " << w_lsa->m_linkStateId); -#if 0 // (c) If vertex W is already on the shortest-path tree, // examine the next link in the LSA. - if (w->m_stat == LSA_SPF_IN_SPFTREE) + if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_IN_SPFTREE) { + NS_DEBUG("LSA "<< w_lsa->m_linkStateId << " in SPF"); continue; } -#endif // (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) @@ -267,7 +264,12 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // Here, W is either already in candidate list or not - // if (not in candidate list) +#if 0 + if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + { + SPFVertex* w = new SPFVertex(w_lsa); +#endif + // ospf_nexthop_calculation() // priority_queue.enqueu() // else @@ -325,7 +327,6 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the // spanning tree. v->m_distanceFromRoot = 0; - v->m_stat = LSA_SPF_IN_SPFTREE; for (;;) { diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index e9e94997b..0b0cc4c5d 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -29,9 +29,6 @@ namespace ns3 { const uint32_t SPF_INFINITY = 0xffffffff; -const int LSA_SPF_NOT_EXPLORED = -1; -const int LSA_SPF_IN_SPFTREE = -2; - class CandidateQueue; /** @@ -65,8 +62,6 @@ public: uint32_t m_distanceFromRoot; - // If stat >= 0, stat is LSA position in candidates heap - int m_stat; }; /** diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 528a1500f..e0bceb40a 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -30,13 +30,15 @@ StaticRouterLSA::StaticRouterLSA() : m_linkStateId("0.0.0.0"), m_advertisingRtr("0.0.0.0"), - m_linkRecords() + m_linkRecords(), + m_stat(StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) - : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr) + : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr), + m_stat(lsa.m_stat) { NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty in its constructor!"); CopyLinkRecords (lsa); @@ -47,6 +49,7 @@ StaticRouterLSA::operator= (StaticRouterLSA& lsa) { m_linkStateId = lsa.m_linkStateId; m_advertisingRtr = lsa.m_advertisingRtr; + m_stat = lsa.m_stat; ClearLinkRecords (); CopyLinkRecords (lsa); @@ -201,6 +204,7 @@ StaticRouter::DiscoverLSAs (void) StaticRouterLSA *pLSA = new StaticRouterLSA; pLSA->m_linkStateId = m_routerId; pLSA->m_advertisingRtr = m_routerId; + pLSA->m_stat = StaticRouterLSA::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) diff --git a/src/routing/static-router.h b/src/routing/static-router.h index bda6cc04a..3c1c50514 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -168,6 +168,14 @@ public: typedef std::list ListOfLinkRecords_t; ListOfLinkRecords_t m_linkRecords; + + // this is a tristate flag used internally in the SPF computation + enum SPFStatus { + LSA_SPF_NOT_EXPLORED = 0, + LSA_SPF_IN_SPFTREE, + LSA_SPF_IN_CANDIDATE_QUEUE + } m_stat; + }; std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); From e0399adca9e5aaafea706fe8d7a09d66e696c6b6 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 22:54:47 -0700 Subject: [PATCH 51/92] Non-default constructor for SPFVertex --- src/routing/static-route-manager.cc | 18 +++++++++++------- src/routing/static-route-manager.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 1a681764e..8bada0079 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -36,9 +36,17 @@ SPFVertex::SPFVertex () : { } +SPFVertex::SPFVertex (StaticRouterLSA* lsa) : + m_vertexType(VertexRouter), + m_vertexId(lsa->m_linkStateId), + m_lsa(lsa), + m_distanceFromRoot(SPF_INFINITY) +{ +} + + SPFVertex::~SPFVertex () { - delete m_lsa; } void @@ -320,12 +328,8 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // Initialize the shortest-path tree to only the router doing the // calculation. // - v= new SPFVertex(); - v->m_vertexType = SPFVertex::VertexRouter; - v->m_vertexId = root; - v-> m_lsa = m_lsdb->GetLSA(root); - // Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the - // spanning tree. + v= new SPFVertex(m_lsdb->GetLSA(root)); + // This vertex is the root of the SPF tree v->m_distanceFromRoot = 0; for (;;) diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 0b0cc4c5d..4734619ce 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -40,6 +40,7 @@ class SPFVertex { public: SPFVertex(); + SPFVertex(StaticRouterLSA*); ~SPFVertex(); void Initialize (); From 534ab7a0305c059ffba2d2ccab694314741e5026 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Wed, 11 Jul 2007 23:43:09 -0700 Subject: [PATCH 52/92] finish SPFNext logic; add declaration for NexthopCalculation --- src/routing/static-route-manager.cc | 87 ++++++++++++++++++++--------- src/routing/static-route-manager.h | 2 + src/routing/static-router.h | 2 +- 3 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 8bada0079..f91f9bc9c 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -224,6 +224,10 @@ StaticRouteManager::InitializeRoutes () void StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) { + SPFVertex* w = 0; + StaticRouterLSA* w_lsa = 0; + uint32_t distance = 0; + if (v->m_vertexType == SPFVertex::VertexRouter) { // Always true for now, since all our LSAs are RouterLSAs @@ -239,19 +243,19 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // link in V's LSA. Links to stub networks will be // considered in the second stage of the shortest path // calculation. - StaticRouterLinkRecord* temp = *i; - if (temp->m_linkType == StaticRouterLinkRecord::StubNetwork) + StaticRouterLinkRecord* l = *i; + if (l->m_linkType == StaticRouterLinkRecord::StubNetwork) { - NS_DEBUG_UNCOND("Found a Stub record to " << temp->m_linkId); + NS_DEBUG_UNCOND("Found a Stub record to " << l->m_linkId); 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 (temp->m_linkType == StaticRouterLinkRecord::PointToPoint) + if (l->m_linkType == StaticRouterLinkRecord::PointToPoint) { // Lookup the vertex W's LSA - StaticRouterLSA* w_lsa = m_lsdb->GetLSA(temp->m_linkId); + w_lsa = m_lsdb->GetLSA(l->m_linkId); NS_ASSERT(w_lsa); NS_DEBUG_UNCOND("Found a P2P record from " << v->m_vertexId << " to " << w_lsa->m_linkStateId); @@ -267,42 +271,75 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // 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. - - //uint32_t distance = v->m_distanceFromRoot + temp->m_metric; + distance = v->m_distanceFromRoot + l->m_metric; // Here, W is either already in candidate list or not - -#if 0 if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { - SPFVertex* w = new SPFVertex(w_lsa); -#endif - - // ospf_nexthop_calculation() - // priority_queue.enqueu() - // else - // get vertex from candidates list - // if (w->distance < distance) - // continue; // not a shorter path - // else if (w->distance > distance) + w = new SPFVertex(w_lsa); + // Calculate nexthop to W + if (SPFNexthopCalculation(v, w, l, distance)) + { + w_lsa->m_stat = StaticRouterLSA::LSA_SPF_CANDIDATE; + candidate.Push(w); + } + } + } else if (w_lsa->m_stat == + StaticRouterLSA::LSA_SPF_CANDIDATE) + { + //Get the vertex from candidates + w = candidate.Find(w_lsa->m_linkStateId); + if (w->m_distanceFromRoot < distance) + { + continue; // not a shorter path + } + // equal to + else if (w->m_distanceFromRoot == distance) + { + // Do nothing-- not doing equal-cost multipath + } + else + { // Found a lower-cost path to W. // * nexthop_calculation is conditional, if it finds // * valid nexthop it will call spf_add_parents, which // * will flush the old parents // */ - // if (ospf_nexthop_calculation (area, v, w, l, distance)) + if (SPFNexthopCalculation(v, w, l, distance)) + { // /* Decrease the key of the node in the heap, // * re-sort the heap. */ - // trickle_down (w_lsa->stat, candidate); - // - continue; - } - } + candidate.Reorder(); + } + } + } // point-to-point + } // for loop } } NS_DEBUG_UNCOND(""); } +/* 16.1.1. Calculate nexthop from root through V (parent) to + * vertex W (destination), with given distance from root->W. + * + * The link must be supplied if V is the root vertex. In all other cases + * it may be NULL. + * + * Note that this function may fail, hence the state of the destination + * vertex, W, should /not/ be modified in a dependent manner until + * this function returns. This function will update the W vertex with the + * provided distance as appropriate. + */ +int +StaticRouteManager::SPFNexthopCalculation ( + SPFVertex* v, + SPFVertex* w, + StaticRouterLinkRecord* l, + uint32_t distance) +{ + return 1; +} + // quagga ospf_spf_calculate void StaticRouteManager::DebugSPFCalculate(Ipv4Address root) diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 4734619ce..6edf37e17 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -130,6 +130,8 @@ private: StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); void SPFNext (SPFVertex*, CandidateQueue&); + int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, + StaticRouterLinkRecord* l, uint32_t distance); }; } // namespace ns3 diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 3c1c50514..c863ddc90 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -173,7 +173,7 @@ public: enum SPFStatus { LSA_SPF_NOT_EXPLORED = 0, LSA_SPF_IN_SPFTREE, - LSA_SPF_IN_CANDIDATE_QUEUE + LSA_SPF_CANDIDATE } m_stat; }; From 9f44a9d6a4a76469f9bfb6cc87f3e7041f0f24cf Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 12 Jul 2007 10:47:12 -0700 Subject: [PATCH 53/92] dox for candidate queue --- src/routing/candidate-queue.cc | 2 - src/routing/candidate-queue.h | 109 ++++++++++++++++++++++++++++++++- src/routing/static-router.h | 8 +++ 3 files changed, 115 insertions(+), 4 deletions(-) diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc index 7b5f9ba96..bec333936 100644 --- a/src/routing/candidate-queue.cc +++ b/src/routing/candidate-queue.cc @@ -45,7 +45,6 @@ CandidateQueue::Clear (void) } } - void CandidateQueue::Push (SPFVertex *vNew) { @@ -109,7 +108,6 @@ CandidateQueue::Size (void) return m_candidates.size (); } - SPFVertex * CandidateQueue::Find (const Ipv4Address addr) { diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index 5d266e7c5..c5bfb3c39 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -23,19 +23,112 @@ namespace ns3 { +/** + * \brief a Candidate Queue used in static routing. + * + * The CandidateQueue is used in the OSPF shortest path computations. It + * is a priority queue used to store candidates for the shortest path to a + * given network. + * + * The queue holds Shortest Path First Vertex pointers and orders them + * according to the lowest value of the field m_distanceFromRoot. Remaining + * vertices are ordered according to increasing distance. This implements a + * priority queue. + * + * Although a STL priority_queue almost does what we want, the requirement + * for a Find () operation, the dynamic nature of the data and the derived + * requirement for a Reorder () operation led us to implement this simple + * enhanced priority queue. + */ class CandidateQueue { public: + /** + * Create an empty SPF Candidate Queue. + * + * @see SPFVertex + */ CandidateQueue (); + /** + * Destroy an SPF Candidate Queue and release any resources held by the + * contents. + * + * @see SPFVertex + */ virtual ~CandidateQueue (); - + /** + * Empty the Candidate Queue and release all of the resources associated + * with the Shortest Path First Vertex pointers in the queue. + * + * @see SPFVertex + */ void Clear (void); - void Push (SPFVertex *v); + /** + * Push a Shortest Path First Vertex pointer onto the queue according to the + * priority scheme. + * + * On completion, the top of the queue will hold the Shortest Path First + * Vertex pointer that points to a vertex having lowest value of the field + * m_distanceFromRoot. Remaining vertices are ordered according to + * increasing distance. + * + * @see SPFVertex + * @param vNew The Shortest Path First Vertex to add to the queue. + */ + void Push (SPFVertex *vNew); + /** + * Pop the Shortest Path First Vertex pointer at the top of the queue and + * release the resources associated with the vertex. + * + * @see SPFVertex + * @see Top () + */ void Pop (void); + /** + * Return the Shortest Path First Vertex pointer at the top of the queue. + * This method does not pop the SPFVertex* off of the queue, it simply + * returns the pointer. + * + * @see SPFVertex + * @see Pop () + * @returns The Shortest Path First Vertex pointer at the top of the queue. + */ SPFVertex* Top (void); + /** + * Test the Candidate Queue to determine if it is empty. + * + * @returns True if the queue is empty, false otherwise. + */ bool Empty (void); + /** + * Return the number of Shortest Path First Vertex pointers presently + * stored in the Candidate Queue. + * + * @see SPFVertex + * @returns The number of SPFVertex* pointers in the Candidate Queue. + */ uint32_t Size (void); + /** + * Searches the Candidate Queue for a Shortest Path First Vertex pointer + * that points to a vertex having the given IP address. + * + * @see SPFVertex + * @param addr The IP address to search for. + * @returns The SPFVertex* pointer corresponding to the given IP address. + */ SPFVertex* Find (const Ipv4Address addr); + /** + * Reorders the Candidate Queue according to the priority scheme. On + * completion, the top of the queue will hold the Shortest Path First + * Vertex pointer that points to a vertex having lowest value of the field + * m_distanceFromRoot. Remaining vertices are ordered according to + * increasing distance. + * + * This method is provided in case the values of m_distanceFromRoot change + * during the routing calculations. + * + * @see SPFVertex + */ void Reorder (void); protected: @@ -43,6 +136,18 @@ protected: CandidateList_t m_candidates; private: + /** + * Candidate Queue copy construction is disallowed (not implemented) to + * prevent the compiler from slipping in incorrect versions that don't + * properly deal with deep copies. + */ + CandidateQueue (CandidateQueue& sr); + /** + * Candidate Queue assignment operator is disallowed (not implemented) to + * prevent the compiler from slipping in incorrect versions that don't + * properly deal with deep copies. + */ + CandidateQueue& operator= (CandidateQueue& sr); }; } // namespace ns3 diff --git a/src/routing/static-router.h b/src/routing/static-router.h index c863ddc90..1d7bf2ab3 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -282,6 +282,14 @@ protected: Ipv4Address m_routerId; private: + /** + * Static Router copy construction is disallowed. + */ + StaticRouter (StaticRouter& sr); + /** + * Static Router copy assignment operator is disallowed. + */ + StaticRouter& operator= (StaticRouter& sr); }; } // namespace ns3 From 6361dd3f6e89b56d9520c64f813243d2c77350b9 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Thu, 12 Jul 2007 11:05:23 -0700 Subject: [PATCH 54/92] Initial logic for SPFNexthopCalculation --- src/routing/static-route-manager.cc | 86 +++++++++++++++++++---------- src/routing/static-route-manager.h | 17 +++--- 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index f91f9bc9c..5fb613790 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -32,7 +32,10 @@ SPFVertex::SPFVertex () : m_vertexType(VertexUnknown), m_vertexId("255.255.255.255"), m_lsa(0), - m_distanceFromRoot(SPF_INFINITY) + m_parent(0), + m_children(), + m_distanceFromRoot(SPF_INFINITY), + m_root_oif(SPF_INFINITY) { } @@ -40,7 +43,10 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : m_vertexType(VertexRouter), m_vertexId(lsa->m_linkStateId), m_lsa(lsa), - m_distanceFromRoot(SPF_INFINITY) + m_parent(0), + m_children(), + m_distanceFromRoot(SPF_INFINITY), + m_root_oif(SPF_INFINITY) { } @@ -49,13 +55,6 @@ SPFVertex::~SPFVertex () { } -void -SPFVertex::Initialize () -{ - m_distanceFromRoot = SPF_INFINITY; - // XXX previous = 0 -} - StaticRouteManagerLSDB::~StaticRouteManagerLSDB() { NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); @@ -107,7 +106,7 @@ StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) return 0; } -StaticRouteManager::StaticRouteManager () +StaticRouteManager::StaticRouteManager () : m_spfroot(0) { m_lsdb = new StaticRouteManagerLSDB (); } @@ -321,14 +320,8 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) /* 16.1.1. Calculate nexthop from root through V (parent) to * vertex W (destination), with given distance from root->W. - * - * The link must be supplied if V is the root vertex. In all other cases - * it may be NULL. - * - * Note that this function may fail, hence the state of the destination - * vertex, W, should /not/ be modified in a dependent manner until - * this function returns. This function will update the W vertex with the - * provided distance as appropriate. + * + * This greatly simplified from quagga */ int StaticRouteManager::SPFNexthopCalculation ( @@ -337,6 +330,21 @@ StaticRouteManager::SPFNexthopCalculation ( StaticRouterLinkRecord* l, uint32_t distance) { + if (v == m_spfroot) + { + // parent of w is the root itself + // calculate the interfaceid of the router that corresponds + // to link l between v and w and store it in w->m_root_oif + // This root_oif is then used when installing host routes for the + // destinations covered by this vertex + } + else + { + // Inherit the root_oif from the current parent + w->m_root_oif = v->m_root_oif; + } + w->m_distanceFromRoot = distance; + w->m_parent = v; return 1; } @@ -353,7 +361,9 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) { NS_DEBUG_UNCOND("StaticRouteManager::SPFCalculate ()"); - SPFVertex* v; + SPFVertex *v; + + // Query Interface for the IPv4-route interface // The candidate queue is a priority queue of SPFVertex objects, with // the top of the queue being the closest vertex in terms of @@ -368,17 +378,17 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) v= new SPFVertex(m_lsdb->GetLSA(root)); // This vertex is the root of the SPF tree v->m_distanceFromRoot = 0; + m_spfroot= v; for (;;) { // RFC2328 16.1. (2). SPFNext(v , candidate); -#if 0 /* RFC2328 16.1. (3). */ /* If at this step the candidate list is empty, the shortest- * path tree (of transit vertices) has been completely built and * this stage of the procedure terminates. */ - if (candidate->size == 0) + if (candidate.Size() == 0) break; /* Otherwise, choose the vertex belonging to the candidate list @@ -386,17 +396,21 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) * tree (removing it from the candidate list in the * process). */ /* Extract from the candidates the node with the lower key. */ - v = (struct vertex *) pqueue_dequeue (candidate); + v = candidate.Top(); + candidate.Pop(); /* Update stat field in vertex. */ - *(v->stat) = LSA_SPF_IN_SPFTREE; - - ospf_vertex_add_parent (v); + v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; + SPFVertexAddParent(v); +#if 0 /* Note that when there is a choice of vertices closest to the * root, network vertices must be chosen before router vertices * in order to necessarily find all equal-cost paths. */ /* We don't do this at this moment, we should add the treatment * above codes. -- kunihiro. */ + +INSTALL HOST ROUTES HERE + /* RFC2328 16.1. (4). */ if (v->type == OSPF_VERTEX_ROUTER) ospf_intra_add_router (new_rtrs, v, area); @@ -413,15 +427,29 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) /* Free candidate queue. */ pqueue_delete (candidate); - + #endif + break; } - - - + DeleteSPFVertexChain(m_spfroot); + m_spfroot = 0; } +// Add a vertex to the list of children in each of its parents. +void +StaticRouteManager::SPFVertexAddParent(SPFVertex* v) +{ +} + +void +StaticRouteManager::DeleteSPFVertexChain(SPFVertex* spfroot) +{ + // spfroot is the root of all SPFVertex created during the SPF process + // each vertex has a number of children + // Recursively, delete all of the SPFVertex children of each SPFVertex + // then delete root itself +} } // namespace ns3 diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 6edf37e17..fbde872e9 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -42,7 +42,6 @@ public: SPFVertex(); SPFVertex(StaticRouterLSA*); ~SPFVertex(); - void Initialize (); enum VertexType { VertexUnknown = 0, @@ -54,14 +53,15 @@ public: StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes - // XXX not sure exactly what data structure is needed here - // need to keep track of previous vertex - typedef std::list type_listOfSPFVertex; - type_listOfSPFVertex m_parents; - type_listOfSPFVertex m_children; - type_listOfSPFVertex::iterator m_iter; + // need to keep track of current parent vertex + SPFVertex* m_parent; + // m_children lists the leaves from your SPF tree + typedef std::list t_listOfSPFVertex; + t_listOfSPFVertex m_children; + t_listOfSPFVertex::iterator m_SPFVertexIter; uint32_t m_distanceFromRoot; + uint32_t m_root_oif; }; @@ -127,11 +127,14 @@ public: protected: private: + SPFVertex* m_spfroot; StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); void SPFNext (SPFVertex*, CandidateQueue&); int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, StaticRouterLinkRecord* l, uint32_t distance); + void SPFVertexAddParent(SPFVertex* v); + void DeleteSPFVertexChain(SPFVertex* spfroot); }; } // namespace ns3 From ba94df76e1cf4872abb28357170f6312cd26a431 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Thu, 12 Jul 2007 11:41:59 -0700 Subject: [PATCH 55/92] Finish function prototypes --- src/routing/static-route-manager.cc | 60 +++++++++++++++++++++-------- src/routing/static-route-manager.h | 4 ++ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 5fb613790..d33b8c15b 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -337,6 +337,10 @@ StaticRouteManager::SPFNexthopCalculation ( // to link l between v and w and store it in w->m_root_oif // This root_oif is then used when installing host routes for the // destinations covered by this vertex + // + // Find the outgoing interface on v corresponding to the link l + // between v and w + w->m_root_oif = FindOutgoingInterface(v,w,l); } else { @@ -348,6 +352,20 @@ StaticRouteManager::SPFNexthopCalculation ( return 1; } +uint32_t +StaticRouteManager::FindOutgoingInterface ( + SPFVertex* v, + SPFVertex* w, + StaticRouterLinkRecord* l + ) +{ + // Using the Ipv4 public APIs of a node, find the outgoing + // interface ID corresponding to the link l between vertex v and w + // where v is the root of the tree + return 0; +} + + // quagga ospf_spf_calculate void StaticRouteManager::DebugSPFCalculate(Ipv4Address root) @@ -363,7 +381,6 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) SPFVertex *v; - // Query Interface for the IPv4-route interface // The candidate queue is a priority queue of SPFVertex objects, with // the top of the queue being the closest vertex in terms of @@ -401,52 +418,63 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) /* Update stat field in vertex. */ v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; SPFVertexAddParent(v); -#if 0 /* Note that when there is a choice of vertices closest to the * root, network vertices must be chosen before router vertices * in order to necessarily find all equal-cost paths. */ /* We don't do this at this moment, we should add the treatment * above codes. -- kunihiro. */ - -INSTALL HOST ROUTES HERE - /* RFC2328 16.1. (4). */ - if (v->type == OSPF_VERTEX_ROUTER) - ospf_intra_add_router (new_rtrs, v, area); - else - ospf_intra_add_transit (new_table, v, area); + SPFIntraAddRouter (v); /* RFC2328 16.1. (5). */ /* Iterate the algorithm by returning to Step 2. */ } /* end loop until no more candidate vertices */ +#ifdef NOTYET /* Second stage of SPF calculation procedure's */ ospf_spf_process_stubs (area, area->spf, new_table); - - /* Free candidate queue. */ - pqueue_delete (candidate); - #endif - break; - } DeleteSPFVertexChain(m_spfroot); m_spfroot = 0; } +void +StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) +{ + + // This vertex has just been added to the SPF tree + // - the vertex should have a valid m_root_oid corresponding + // to the outgoing interface on the root router of the tree + // that corresponds to the path to it + // - the vertex has an m_lsa field that has a number of link + // records. For each point to point record, the m_linkData + // is a destination IP address to which we add a host route + // + + // Therefore, this routine's logic should be: + // i) obtain the ipv4-route interface of the node corresponding + // to m_spfroot (vertex) + // i.e. Query Interface for the IPv4-route interface + // ii) for each point-to-point link in v->m_lsa + // ipv4-route::AddHostRouteTo(m_linkData, m_root_oid); +} + // Add a vertex to the list of children in each of its parents. void StaticRouteManager::SPFVertexAddParent(SPFVertex* v) { + // For now, only one parent (not doing equal-cost multipath) + v->m_parent->m_children.push_back(v); } void StaticRouteManager::DeleteSPFVertexChain(SPFVertex* spfroot) { // spfroot is the root of all SPFVertex created during the SPF process - // each vertex has a number of children + // each vertex has a list of children // Recursively, delete all of the SPFVertex children of each SPFVertex // then delete root itself } diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index fbde872e9..ac7eb9f07 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -135,6 +135,10 @@ private: StaticRouterLinkRecord* l, uint32_t distance); void SPFVertexAddParent(SPFVertex* v); void DeleteSPFVertexChain(SPFVertex* spfroot); + uint32_t FindOutgoingInterface(SPFVertex* v, SPFVertex* w, + StaticRouterLinkRecord* l); + void SPFIntraAddRouter(SPFVertex* v); + }; } // namespace ns3 From be74b3dca89a4033c7c4ad49e97f470a4f8e0740 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 12 Jul 2007 22:15:59 -0700 Subject: [PATCH 56/92] implement SPFIntraAddRouter --- src/routing/static-route-manager.cc | 89 +++++++++++++++++++++++++++-- src/routing/static-route-manager.h | 2 +- src/routing/static-router.cc | 48 +++++++++++++--- src/routing/static-router.h | 16 +++++- 4 files changed, 138 insertions(+), 17 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index d33b8c15b..e68a85719 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -20,6 +20,7 @@ #include "ns3/fatal-error.h" #include "ns3/debug.h" #include "ns3/node-list.h" +#include "ns3/ipv4.h" #include "static-router.h" #include "static-route-manager.h" #include "candidate-queue.h" @@ -352,6 +353,10 @@ StaticRouteManager::SPFNexthopCalculation ( return 1; } +// +// Figure out which interface that the node represented by v will want to use +// to send packets to the node represented by w over the link represented by l +// uint32_t StaticRouteManager::FindOutgoingInterface ( SPFVertex* v, @@ -359,6 +364,12 @@ StaticRouteManager::FindOutgoingInterface ( StaticRouterLinkRecord* l ) { + NS_ASSERT_MSG(v == m_spfroot, + "StaticRouterManager""FindOutgoingInterface (): " + "The node of interest must be the root node"); + + // want interface that v uses to send packets + // Using the Ipv4 public APIs of a node, find the outgoing // interface ID corresponding to the link l between vertex v and w // where v is the root of the tree @@ -444,7 +455,6 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) void StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) { - // This vertex has just been added to the SPF tree // - the vertex should have a valid m_root_oid corresponding // to the outgoing interface on the root router of the tree @@ -460,6 +470,75 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) // i.e. Query Interface for the IPv4-route interface // ii) for each point-to-point link in v->m_lsa // ipv4-route::AddHostRouteTo(m_linkData, m_root_oid); + + NS_ASSERT_MSG(m_spfroot, + "StaticRouteManager::SPFIntraAddRouter (): Root pointer not set"); + + Ipv4Address routerId = m_spfroot->m_vertexId; + + std::vector >::iterator i = NodeList::Begin(); + for (; i != NodeList::End(); i++) + { + Ptr node = *i; + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + NS_ASSERT_MSG(rtr, + "StaticRouteManager::SPFIntraAddRouter (): " + "QI for interface failed"); + + if (rtr->GetRouterId () == routerId) + { + NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + "setting routes for node " << node->GetId ()); + + Ptr ipv4 = node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4, + "StaticRouteManager::SPFIntraAddRouter (): " + "QI for interface failed"); + + StaticRouterLSA *lsa = v->m_lsa; + NS_ASSERT_MSG(lsa, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected valid LSA in SPFVertex* v"); + + uint32_t nLinkRecords = lsa->GetNLinkRecords (); + + NS_ASSERT_MSG((nLinkRecords & 1) == 0, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected exen number of Link Records"); + + for (uint32_t j = 0; j < nLinkRecords; j += 2) + { + StaticRouterLinkRecord *lrp2p = lsa->GetLinkRecord (j); + NS_ASSERT_MSG( + lrp2p->m_linkType == StaticRouterLinkRecord::PointToPoint, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected PointToPoint Link Record"); + + StaticRouterLinkRecord *lrstub = lsa->GetLinkRecord (j + 1); + NS_ASSERT_MSG( + lrstub->m_linkType == StaticRouterLinkRecord::StubNetwork, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected StubNetwork Link Record"); +// +// BUGBUG +// +// Where does the next hop address come from? +// + NS_ASSERT_MSG(false, "BUGBUG"); + + NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + "Add route to " << lrp2p->m_linkData << + " using next hop " << lrp2p->m_linkData << + " via interface " << v->m_root_oif); + + ipv4->AddHostRouteTo(lrp2p->m_linkData, lrp2p->m_linkData, + v->m_root_oif); + } + break; + } + } } // Add a vertex to the list of children in each of its parents. @@ -529,21 +608,21 @@ StaticRouteManagerTest::RunTests (void) { bool ok = true; - CandidateQueue candidate; // <---------------- + CandidateQueue candidate; for (int i = 0; i < 100; ++i) { SPFVertex *v = new SPFVertex; v->m_distanceFromRoot = rand () % 100; - candidate.Push (v); // <---------------- + candidate.Push (v); } uint32_t lastDistance = 0; for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.Top (); // <---------------- - candidate.Pop (); // <---------------- + SPFVertex *v = candidate.Top (); + candidate.Pop (); if (v->m_distanceFromRoot < lastDistance) { ok = false; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index ac7eb9f07..85a96a71a 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -49,7 +49,7 @@ public: VertexNetwork } m_vertexType; - Ipv4Address m_vertexId; + Ipv4Address m_vertexId; // router id StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index e0bceb40a..81bbee2a6 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -40,7 +40,8 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr), m_stat(lsa.m_stat) { - NS_ASSERT_MSG(IsEmpty(), "The LSA must be empty in its constructor!"); + NS_ASSERT_MSG(IsEmpty(), + "StaticRouterLSA::StaticRouterLSA (): Non-empty LSA in constructor"); CopyLinkRecords (lsa); } @@ -105,6 +106,30 @@ StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr) return m_linkRecords.size (); } + uint32_t +StaticRouterLSA::GetNLinkRecords (void) +{ + return m_linkRecords.size (); +} + + StaticRouterLinkRecord * +StaticRouterLSA::GetLinkRecord (uint32_t n) +{ + uint32_t j = 0; + for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + i != m_linkRecords.end (); + i++, j++) + { + if (j == n) + { + return *i; + } + } + NS_ASSERT_MSG(false, "StaticRouterLSA::GetLinkRecord (): invalid index"); + return 0; +} + + bool StaticRouterLSA::IsEmpty (void) { @@ -186,7 +211,9 @@ StaticRouter::GetRouterId (void) StaticRouter::DiscoverLSAs (void) { NS_DEBUG("StaticRouter::DiscoverLSAs ()"); - NS_ASSERT_MSG(m_node, " interface not set"); + NS_ASSERT_MSG(m_node, + "StaticRouter::DiscoverLSAs (): interface not set"); + ClearLSAs (); // // We're aggregated to a node. We need to ask the node for a pointer to its @@ -194,7 +221,8 @@ StaticRouter::DiscoverLSAs (void) // interfaces lives. // Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4Local, "QI for interface failed"); + NS_ASSERT_MSG(ipv4Local, + "StaticRouter::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 @@ -257,14 +285,16 @@ StaticRouter::DiscoverLSAs (void) // Ptr nodeRemote = ndRemote->GetNode(); Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4Remote, "QI for remote interface failed"); + NS_ASSERT_MSG(ipv4Remote, + "StaticRouter::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 (StaticRouter::iid); - NS_ASSERT_MSG(srRemote, "QI for remote failed"); + NS_ASSERT_MSG(srRemote, + "StaticRouter::DiscoverLSAs (): QI for remote failed"); Ipv4Address rtrIdRemote = srRemote->GetRouterId(); NS_DEBUG("Working with remote router " << rtrIdRemote); // @@ -319,7 +349,7 @@ StaticRouter::GetNumLSAs (void) bool StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) { - NS_ASSERT_MSG(lsa.IsEmpty(), "Must pass empty LSA"); + NS_ASSERT_MSG(lsa.IsEmpty(), "StaticRouter::GetLSA (): Must pass empty LSA"); // // All of the work was done in GetNumLSAs. All we have to do here is to // walk the list of link state advertisements created there and return the @@ -355,7 +385,7 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) uint32_t nDevices = ch->GetNDevices(); NS_ASSERT_MSG(nDevices == 2, - "Point to point channel with other than two devices is not expected"); + "StaticRouter::GetAdjacent (): Channel with other than two devices"); // // This is a point to point channel with two endpoints. Get both of them. // @@ -376,8 +406,8 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) } else { - NS_ASSERT_MSG(0, - "Neither channel endpoint thinks it is connected to this net device"); + NS_ASSERT_MSG(false, + "StaticRouter::GetAdjacent (): Wrong or confused channel?"); return 0; } } diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 1d7bf2ab3..b6331021a 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -125,13 +125,25 @@ public: */ void CopyLinkRecords (StaticRouterLSA& lsa); /** - * Add a given Static Router Link Record to a given Static Router Link - * State Advertisement. + * Add a given Static Router Link Record to the LSA. * * @param lr The Static Router Link Record to be added. * @returns The number of link records in the list. */ uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); + /** + * Return the number of Static Router Link Records in the LSA. + * + * @returns The number of link records in the list. + */ + uint32_t GetNLinkRecords (void); + /** + * Return a pointer to the specified Static Router Link Record. + * + * @param n The LSA number desired. + * @returns The number of link records in the list. + */ + StaticRouterLinkRecord* GetLinkRecord (uint32_t n); /** * Release all of the Static Router Link Records present in the Static * Router Link State Advertisement and make the list of link records empty. From 3e0167a9e9752afa0d555198ee21dcc745e1ef88 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 13 Jul 2007 12:21:48 -0700 Subject: [PATCH 57/92] delete vertices, fix candidate queue pop/top semantics --- src/routing/candidate-queue.cc | 11 ++--- src/routing/candidate-queue.h | 8 ++-- src/routing/static-route-manager.cc | 68 +++++++++++++---------------- src/routing/static-route-manager.h | 1 - 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc index bec333936..b45af7ac2 100644 --- a/src/routing/candidate-queue.cc +++ b/src/routing/candidate-queue.cc @@ -41,7 +41,9 @@ CandidateQueue::Clear (void) while (!m_candidates.empty ()) { - Pop (); + SPFVertex *p = Pop (); + delete p; + p = 0; } } @@ -63,20 +65,19 @@ CandidateQueue::Push (SPFVertex *vNew) m_candidates.insert(i, vNew); } - void + SPFVertex * CandidateQueue::Pop (void) { NS_DEBUG("CandidateQueue::Pop ()"); if (m_candidates.empty ()) { - return; + return 0; } SPFVertex *v = m_candidates.front (); m_candidates.pop_front (); - delete v; - v = 0; + return v; } SPFVertex * diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index c5bfb3c39..146de707c 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -77,13 +77,15 @@ public: */ void Push (SPFVertex *vNew); /** - * Pop the Shortest Path First Vertex pointer at the top of the queue and - * release the resources associated with the vertex. + * Pop the Shortest Path First Vertex pointer at the top of the queue. + * The caller is given the responsiblity for releasing the resources + * associated with the vertex. * * @see SPFVertex * @see Top () + * @returns The Shortest Path First Vertex pointer at the top of the queue. */ - void Pop (void); + SPFVertex* Pop (void); /** * Return the Shortest Path First Vertex pointer at the top of the queue. * This method does not pop the SPFVertex* off of the queue, it simply diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index e68a85719..2aa2a857e 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -51,9 +51,18 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : { } - SPFVertex::~SPFVertex () { + for ( t_listOfSPFVertex::iterator i = m_children.begin (); + i != m_children.end (); + i++) + { + SPFVertex *p = *i; + delete p; + p = 0; + *i = 0; + } + m_children.clear(); } StaticRouteManagerLSDB::~StaticRouteManagerLSDB() @@ -89,7 +98,7 @@ StaticRouteManagerLSDB::Initialize() void StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) { - m_database.insert(LSDBPair_t(addr, lsa)); + m_database.insert(LSDBPair_t(addr, lsa)); } StaticRouterLSA* @@ -153,8 +162,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () { StaticRouterLSA* lsa = new StaticRouterLSA (); rtr->GetLSA(j, *lsa); - NS_DEBUG_UNCOND ("LSA " << j); - NS_DEBUG_UNCOND ("----------------------------"); + NS_DEBUG_UNCOND ("*** LSA " << j); NS_DEBUG_UNCOND (*lsa); m_lsdb->Insert (lsa->m_linkStateId, lsa); } @@ -424,8 +432,7 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) * tree (removing it from the candidate list in the * process). */ /* Extract from the candidates the node with the lower key. */ - v = candidate.Top(); - candidate.Pop(); + v = candidate.Pop(); /* Update stat field in vertex. */ v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; SPFVertexAddParent(v); @@ -448,7 +455,7 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) ospf_spf_process_stubs (area, area->spf, new_table); #endif - DeleteSPFVertexChain(m_spfroot); + delete m_spfroot; m_spfroot = 0; } @@ -508,33 +515,26 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) "StaticRouteManager::SPFIntraAddRouter (): " "Expected exen number of Link Records"); - for (uint32_t j = 0; j < nLinkRecords; j += 2) + for (uint32_t j = 0; j < nLinkRecords; ++j) { - StaticRouterLinkRecord *lrp2p = lsa->GetLinkRecord (j); - NS_ASSERT_MSG( - lrp2p->m_linkType == StaticRouterLinkRecord::PointToPoint, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected PointToPoint Link Record"); - - StaticRouterLinkRecord *lrstub = lsa->GetLinkRecord (j + 1); - NS_ASSERT_MSG( - lrstub->m_linkType == StaticRouterLinkRecord::StubNetwork, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected StubNetwork Link Record"); + StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); + if (lr->m_linkType != StaticRouterLinkRecord::PointToPoint) + { + continue; + } // -// BUGBUG +// BUGBUG This is not right. Need to find the next hop interface correctly // -// Where does the next hop address come from? -// - NS_ASSERT_MSG(false, "BUGBUG"); + NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + "BUGBUG incorrect next hope calculation"); NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " - "Add route to " << lrp2p->m_linkData << - " using next hop " << lrp2p->m_linkData << + "Add route to " << lr->m_linkData << + " using next hop " << lr->m_linkData << " via interface " << v->m_root_oif); - ipv4->AddHostRouteTo(lrp2p->m_linkData, lrp2p->m_linkData, - v->m_root_oif); + ipv4->AddHostRouteTo(lr->m_linkData, + lr->m_linkData, v->m_root_oif); } break; } @@ -549,15 +549,6 @@ StaticRouteManager::SPFVertexAddParent(SPFVertex* v) v->m_parent->m_children.push_back(v); } -void -StaticRouteManager::DeleteSPFVertexChain(SPFVertex* spfroot) -{ - // spfroot is the root of all SPFVertex created during the SPF process - // each vertex has a list of children - // Recursively, delete all of the SPFVertex children of each SPFVertex - // then delete root itself -} - } // namespace ns3 #ifdef RUN_SELF_TESTS @@ -621,12 +612,13 @@ StaticRouteManagerTest::RunTests (void) for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.Top (); - candidate.Pop (); + SPFVertex *v = candidate.Pop (); if (v->m_distanceFromRoot < lastDistance) { ok = false; } + delete v; + v = 0; lastDistance = v->m_distanceFromRoot; } diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 85a96a71a..d0cb28aa7 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -62,7 +62,6 @@ public: uint32_t m_distanceFromRoot; uint32_t m_root_oif; - }; /** From c4ee764dd83399e5c1cde4b47aa5096917514f43 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 13 Jul 2007 13:33:56 -0700 Subject: [PATCH 58/92] Debugged; works --- examples/simple-static-routing.cc | 10 +- src/routing/routing-environment.cc | 2 +- src/routing/static-route-manager.cc | 400 +++++++++++++++++----------- src/routing/static-route-manager.h | 13 +- src/routing/static-router.h | 4 +- 5 files changed, 253 insertions(+), 176 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 7a366f736..71fc00044 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -82,6 +82,7 @@ int main (int argc, char *argv[]) DebugComponentEnable("PointToPointChannel"); DebugComponentEnable("PointToPointNetDevice"); DebugComponentEnable("StaticRouter"); + DebugComponentEnable("StaticRouteManager"); #endif // Set up some default values for the simulation. Use the Bind() @@ -146,15 +147,6 @@ int main (int argc, char *argv[]) routeManager->BuildStaticRoutingDatabase (); routeManager->InitializeRoutes (); - // XXX this goes away once static routing is in place - // Finally, we add static routes. These three steps (Channel and - // NetDevice creation, IP Address assignment, and routing) are - // separated because there may be a need to postpone IP Address - // assignment (emulation) or modify to use dynamic routing - PointToPointTopology::AddIpv4Routes(n0, n2, channel0); - PointToPointTopology::AddIpv4Routes(n1, n2, channel1); - PointToPointTopology::AddIpv4Routes(n2, n3, channel2); - // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( diff --git a/src/routing/routing-environment.cc b/src/routing/routing-environment.cc index 73e936ca8..33eeafbe5 100644 --- a/src/routing/routing-environment.cc +++ b/src/routing/routing-environment.cc @@ -39,7 +39,7 @@ StaticRoutingEnabled(void) AllocateRouterId(void) { static uint32_t routerId = 0; - return ++routerId; + return routerId++; } } // namespace RoutingEnvironment diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 2aa2a857e..8b72927d8 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -36,7 +36,8 @@ SPFVertex::SPFVertex () : m_parent(0), m_children(), m_distanceFromRoot(SPF_INFINITY), - m_root_oif(SPF_INFINITY) + m_rootOif(SPF_INFINITY), + m_nextHop("0.0.0.0") { } @@ -47,22 +48,14 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : m_parent(0), m_children(), m_distanceFromRoot(SPF_INFINITY), - m_root_oif(SPF_INFINITY) + m_rootOif(SPF_INFINITY), + m_nextHop("0.0.0.0") { } + SPFVertex::~SPFVertex () { - for ( t_listOfSPFVertex::iterator i = m_children.begin (); - i != m_children.end (); - i++) - { - SPFVertex *p = *i; - delete p; - p = 0; - *i = 0; - } - m_children.clear(); } StaticRouteManagerLSDB::~StaticRouteManagerLSDB() @@ -80,7 +73,6 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB() m_database.clear(); } -#if 0 void StaticRouteManagerLSDB::Initialize() { @@ -90,20 +82,21 @@ StaticRouteManagerLSDB::Initialize() for (i= m_database.begin(); i!= m_database.end(); i++) { StaticRouterLSA* temp = i->second; - temp->Initialize(); + temp->m_stat = StaticRouterLSA::LSA_SPF_NOT_EXPLORED; } } -#endif void StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) { + NS_DEBUG("StaticRouteManagerLSDB::Insert ()"); m_database.insert(LSDBPair_t(addr, lsa)); } StaticRouterLSA* StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) { + NS_DEBUG("StaticRouteManagerLSDB::GetLSA ()"); // Look up an LSA by its address LSDBMap_t::iterator i; for (i= m_database.begin(); i!= m_database.end(); i++) @@ -123,6 +116,8 @@ StaticRouteManager::StaticRouteManager () : m_spfroot(0) StaticRouteManager::~StaticRouteManager () { + NS_DEBUG("StaticRouteManager::~StaticRouteManager ()"); + if (m_lsdb) delete m_lsdb; } @@ -138,73 +133,74 @@ StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) void StaticRouteManager::BuildStaticRoutingDatabase () { - // walk list of nodes. QI for StaticRouter interface. + NS_DEBUG("StaticRouteManager::BuildStaticRoutingDatabase()"); + + // Walk the list of nodes. QI for StaticRouter interface. // if node has a StaticRouter interface, grab the LSAs // from it and stick them in the LSDB typedef std::vector < Ptr >::iterator Iterator; for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { Ptr node = *i; - NS_DEBUG_UNCOND ("node="<< node->GetId () ); Ptr rtr = node->QueryInterface (StaticRouter::iid); NS_ASSERT_MSG(rtr, "QI for interface failed"); -// -// Should call DiscoverLSAs () before trying to use any routing info or to -// update LSAs. Subsequently you may use GetNumLSAs(). If you call -// GetNumLSAs () before calling DiscoverLSAs () will get zero as the number. -// + + // You must call DiscoverLSAs () before trying to use any + // routing info or to update LSAs. Subsequently you may use + // GetNumLSAs(). If you call GetNumLSAs () before calling + // DiscoverLSAs () will get zero as the number. uint32_t numLSAs = rtr->DiscoverLSAs(); - NS_DEBUG_UNCOND ("Found " << numLSAs << " LSAs"); + NS_DEBUG ("Discover LSAs: Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) { StaticRouterLSA* lsa = new StaticRouterLSA (); rtr->GetLSA(j, *lsa); - NS_DEBUG_UNCOND ("*** LSA " << j); - NS_DEBUG_UNCOND (*lsa); + NS_DEBUG ("LSA " << j); + NS_DEBUG ("----------------------------"); + NS_DEBUG (*lsa); m_lsdb->Insert (lsa->m_linkStateId, lsa); } } } - // For each node that is a static router (which can be determined by - // the presence of StaticRouter interface), run Dijkstra SPF calculation - // on the database rooted at that router, and populate the node - // forwarding tables - // +// For each node that is a static router (which can be determined by +// the presence of StaticRouter interface), run Dijkstra SPF calculation +// on the database rooted at that router, and populate the node +// forwarding tables void StaticRouteManager::InitializeRoutes () { - NS_DEBUG_UNCOND("StaticRouteManager::InitializeRoutes ()"); -// This function parallels RFC2328, Section 16.1.1, and quagga ospfd -// -// This calculation yields the set of intra-area routes associated -// with an area (called hereafter Area A). A router calculates the -// shortest-path tree using itself as the root. The formation -// of the shortest path tree is done here in two stages. In the -// first stage, only links between routers and transit networks are -// considered. Using the Dijkstra algorithm, a tree is formed from -// this subset of the link state database. In the second stage, -// leaves are added to the tree by considering the links to stub -// networks. + NS_DEBUG("StaticRouteManager::InitializeRoutes ()"); + // This function parallels RFC2328, Section 16.1.1, and quagga ospfd + // + // This calculation yields the set of intra-area routes associated + // with an area (called hereafter Area A). A router calculates the + // shortest-path tree using itself as the root. The formation + // of the shortest path tree is done here in two stages. In the + // first stage, only links between routers and transit networks are + // considered. Using the Dijkstra algorithm, a tree is formed from + // this subset of the link state database. In the second stage, + // leaves are added to the tree by considering the links to stub + // networks. -// The area's link state database is represented as a directed graph. -// The graph's vertices are routers, transit networks and stub networks. -// The first stage of the procedure (i.e., the Dijkstra algorithm) -// can now be summarized as follows. At each iteration of the -// algorithm, there is a list of candidate vertices. Paths from -// the root to these vertices have been found, but not necessarily -// the shortest ones. However, the paths to the candidate vertex -// that is closest to the root are guaranteed to be shortest; this -// vertex is added to the shortest-path tree, removed from the -// candidate list, and its adjacent vertices are examined for -// possible addition to/modification of the candidate list. The -// algorithm then iterates again. It terminates when the candidate -// list becomes empty. + // The area's link state database is represented as a directed graph. + // The graph's vertices are routers, transit networks and stub networks. + // The first stage of the procedure (i.e., the Dijkstra algorithm) + // can now be summarized as follows. At each iteration of the + // algorithm, there is a list of candidate vertices. Paths from + // the root to these vertices have been found, but not necessarily + // the shortest ones. However, the paths to the candidate vertex + // that is closest to the root are guaranteed to be shortest; this + // vertex is added to the shortest-path tree, removed from the + // candidate list, and its adjacent vertices are examined for + // possible addition to/modification of the candidate list. The + // algorithm then iterates again. It terminates when the candidate + // list becomes empty. - // For each node that is a router in the topology + // Iterate for each node that is a router in the topology typedef std::vector < Ptr >::iterator Iterator; for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { @@ -221,14 +217,11 @@ StaticRouteManager::InitializeRoutes () } -// quagga ospf_spf_next +// Derived from quagga ospf_spf_next() // RFC2328 Section 16.1 (2). // v is on the SPF tree. Examine the links in v's LSA. Update the list // of candidates with any vertices not already on the list. If a lower-cost // path is found to a vertex already on the candidate list, store the new cost. -// -// -// void StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) { @@ -236,12 +229,14 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) StaticRouterLSA* w_lsa = 0; uint32_t distance = 0; + NS_DEBUG("StaticRouteManager::SPFNext ()"); if (v->m_vertexType == SPFVertex::VertexRouter) { // Always true for now, since all our LSAs are RouterLSAs if (true) { - NS_DEBUG_UNCOND("Examining " << v->m_vertexId << "'s link records"); + NS_DEBUG ("SPFNext: Examining " << v->m_vertexId << "'s " << + v->m_lsa->m_linkRecords.size() << " link records"); for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = v->m_lsa->m_linkRecords.begin(); i != v->m_lsa->m_linkRecords.end(); @@ -254,7 +249,8 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) StaticRouterLinkRecord* l = *i; if (l->m_linkType == StaticRouterLinkRecord::StubNetwork) { - NS_DEBUG_UNCOND("Found a Stub record to " << l->m_linkId); + NS_DEBUG("SPFNext: Found a Stub record to " + << l->m_linkId); continue; } // (b) Otherwise, W is a transit vertex (router or transit @@ -265,13 +261,14 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // Lookup the vertex W's LSA w_lsa = m_lsdb->GetLSA(l->m_linkId); NS_ASSERT(w_lsa); - NS_DEBUG_UNCOND("Found a P2P record from " << + NS_DEBUG("SPFNext: Found a P2P record from " << v->m_vertexId << " to " << w_lsa->m_linkStateId); // (c) If vertex W is already on the shortest-path tree, // examine the next link in the LSA. if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_IN_SPFTREE) { - NS_DEBUG("LSA "<< w_lsa->m_linkStateId << " in SPF"); + NS_DEBUG("SPFNext: Skipping-> LSA "<< + w_lsa->m_linkStateId << " already in SPF tree"); continue; } // (d) Calculate the link state cost D of the resulting path @@ -281,15 +278,19 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // the link between vertices V and W. distance = v->m_distanceFromRoot + l->m_metric; + NS_DEBUG("SPFNext: Considering w_lsa " << + w_lsa->m_linkStateId); // Here, W is either already in candidate list or not if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { - w = new SPFVertex(w_lsa); + w = new SPFVertex(w_lsa); // Calculate nexthop to W if (SPFNexthopCalculation(v, w, l, distance)) { w_lsa->m_stat = StaticRouterLSA::LSA_SPF_CANDIDATE; candidate.Push(w); + NS_DEBUG("SPFNext: Pushing " << w->m_vertexId + << ", parent vertexId: " << v->m_vertexId); } } } else if (w_lsa->m_stat == @@ -308,30 +309,29 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) } else { - // Found a lower-cost path to W. - // * nexthop_calculation is conditional, if it finds - // * valid nexthop it will call spf_add_parents, which - // * will flush the old parents - // */ + // Found a lower-cost path to W. + // nexthop_calculation is conditional, if it finds + // valid nexthop it will call spf_add_parents, which + // will flush the old parents if (SPFNexthopCalculation(v, w, l, distance)) { - // /* Decrease the key of the node in the heap, - // * re-sort the heap. */ - candidate.Reorder(); - } + // Decrease the key of the node in the heap, + // re-sort the heap. + candidate.Reorder(); + } } } // point-to-point } // for loop } } - NS_DEBUG_UNCOND(""); } -/* 16.1.1. Calculate nexthop from root through V (parent) to - * vertex W (destination), with given distance from root->W. - * - * This greatly simplified from quagga - */ +// Derived from quagga ospf_next_hop_calculation() +// 16.1.1. Calculate nexthop from root through V (parent) to +// vertex W (destination), with given distance from root->W. +// +// For now, this is greatly simplified from the quagga code +// int StaticRouteManager::SPFNexthopCalculation ( SPFVertex* v, @@ -339,48 +339,91 @@ StaticRouteManager::SPFNexthopCalculation ( StaticRouterLinkRecord* l, uint32_t distance) { + NS_DEBUG("StaticRouteManager::SPFNexthopCalculation ()"); if (v == m_spfroot) { // parent of w is the root itself // calculate the interfaceid of the router that corresponds - // to link l between v and w and store it in w->m_root_oif - // This root_oif is then used when installing host routes for the - // destinations covered by this vertex + // to link l between v and w and store it in w->m_rootOif + // This rootOif is then used when installing host routes for the + // destinations covered by this vertex. Store also the next hop + // IP address. // // Find the outgoing interface on v corresponding to the link l // between v and w - w->m_root_oif = FindOutgoingInterface(v,w,l); + if (w->m_vertexType == SPFVertex::VertexRouter) + { + // l is a link from v to w + // l2 will be a link from w to v + StaticRouterLinkRecord *l2 = 0; + l2 = SPFGetNextLink(w,v,l2); + w->m_nextHop = l2->m_linkData; + // Find interface corresponding to link's IP address + w->m_rootOif = FindOutgoingInterfaceId(l->m_linkData); + + NS_DEBUG("SPFNexthopCalculation: Next hop from " << + v->m_vertexId << " to " << w->m_vertexId << + " goes through next hop " << w->m_nextHop << + " via outgoing interface " << w->m_rootOif); + } } else { - // Inherit the root_oif from the current parent - w->m_root_oif = v->m_root_oif; + // Inherit the rootOif and nextHop from the current parent + w->m_rootOif = v->m_rootOif; + w->m_nextHop = v->m_nextHop; } w->m_distanceFromRoot = distance; w->m_parent = v; return 1; } +// Derived from quagga ospf_get_next_link +// Find the next link after prev_link from v to w. If prev_link is +// NULL, return the first link from v to w. Ignore stub and virtual links; +// these link types will never be returned. // -// Figure out which interface that the node represented by v will want to use -// to send packets to the node represented by w over the link represented by l -// -uint32_t -StaticRouteManager::FindOutgoingInterface ( +StaticRouterLinkRecord* +StaticRouteManager::SPFGetNextLink( SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* l + StaticRouterLinkRecord* prev_link ) { - NS_ASSERT_MSG(v == m_spfroot, - "StaticRouterManager""FindOutgoingInterface (): " - "The node of interest must be the root node"); - - // want interface that v uses to send packets - - // Using the Ipv4 public APIs of a node, find the outgoing - // interface ID corresponding to the link l between vertex v and w - // where v is the root of the tree + NS_DEBUG("StaticRouteManager::SPFGetNextLink ()"); + bool skip = true; + StaticRouterLinkRecord* l; + if (prev_link == 0) + { + skip = false; + } + + for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = + v->m_lsa->m_linkRecords.begin(); + i != v->m_lsa->m_linkRecords.end(); + i++ ) + { + l = *i; + if (l->m_linkType != StaticRouterLinkRecord::PointToPoint) + { + continue; + } + if (l->m_linkId == w->m_vertexId) { + NS_DEBUG("SPFGetNextLink: Found matching link l: linkId=" << + l->m_linkId << " linkData=" << l->m_linkData); + if (skip == false) + { + NS_DEBUG("SPFGetNextLink: Returning the found link"); + return l; + } + else + { + NS_DEBUG("SPFGetNextLink: Skipping the found link"); + skip = false; + continue; + } + } + } return 0; } @@ -396,10 +439,11 @@ StaticRouteManager::DebugSPFCalculate(Ipv4Address root) void StaticRouteManager::SPFCalculate(Ipv4Address root) { - NS_DEBUG_UNCOND("StaticRouteManager::SPFCalculate ()"); + NS_DEBUG("StaticRouteManager::SPFCalculate ()"); SPFVertex *v; + m_lsdb->Initialize (); // The candidate queue is a priority queue of SPFVertex objects, with // the top of the queue being the closest vertex in terms of @@ -415,50 +459,88 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // This vertex is the root of the SPF tree v->m_distanceFromRoot = 0; m_spfroot= v; + v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; for (;;) { // RFC2328 16.1. (2). SPFNext(v , candidate); - /* RFC2328 16.1. (3). */ - /* If at this step the candidate list is empty, the shortest- - * path tree (of transit vertices) has been completely built and - * this stage of the procedure terminates. */ + + // RFC2328 16.1. (3). + // If at this step the candidate list is empty, the shortest- + // path tree (of transit vertices) has been completely built and + // this stage of the procedure terminates. if (candidate.Size() == 0) break; - - /* Otherwise, choose the vertex belonging to the candidate list - * that is closest to the root, and add it to the shortest-path - * tree (removing it from the candidate list in the - * process). */ - /* Extract from the candidates the node with the lower key. */ - v = candidate.Pop(); - /* Update stat field in vertex. */ + // Otherwise, choose the vertex belonging to the candidate list + // that is closest to the root, and add it to the shortest-path + // tree (removing it from the candidate list in the + // process). + // Extract from the candidates the node with the lower key. + v = candidate.Top(); + candidate.Pop(); + // Update stat field in vertex. + NS_DEBUG("SPFCalculate: Popping vertex" << v->m_vertexId); v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; SPFVertexAddParent(v); - /* Note that when there is a choice of vertices closest to the - * root, network vertices must be chosen before router vertices - * in order to necessarily find all equal-cost paths. */ - /* We don't do this at this moment, we should add the treatment - * above codes. -- kunihiro. */ + // Note that when there is a choice of vertices closest to the + // root, network vertices must be chosen before router vertices + // in order to necessarily find all equal-cost paths. + // We don't do this at this moment, we should add the treatment + // above codes. -- kunihiro. - /* RFC2328 16.1. (4). */ + // RFC2328 16.1. (4). SPFIntraAddRouter (v); - /* RFC2328 16.1. (5). */ - /* Iterate the algorithm by returning to Step 2. */ + // RFC2328 16.1. (5). + // Iterate the algorithm by returning to Step 2. + } // end loop until no more candidate vertices - } /* end loop until no more candidate vertices */ + // Second stage of SPF calculation procedure's + // NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); -#ifdef NOTYET - /* Second stage of SPF calculation procedure's */ - ospf_spf_process_stubs (area, area->spf, new_table); -#endif - - delete m_spfroot; + DeleteSPFVertexChain(m_spfroot); m_spfroot = 0; } +// XXX this should probably be a method on Ipv4 +uint32_t +StaticRouteManager::FindOutgoingInterfaceId(Ipv4Address a) +{ + + Ipv4Address routerId = m_spfroot->m_vertexId; + + std::vector >::iterator i = NodeList::Begin(); + for (; i != NodeList::End(); i++) + { + Ptr node = *i; + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + NS_ASSERT_MSG(rtr, + "StaticRouteManager::SPFIntraAddRouter (): " + "QI for interface failed"); + if (rtr->GetRouterId () == routerId) + { + Ptr ipv4 = node->QueryInterface (Ipv4::iid); + NS_ASSERT_MSG(ipv4, + "StaticRouteManager::SPFIntraAddRouter (): " + "QI for interface failed"); + for (uint32_t i = 0; i < ipv4->GetNInterfaces(); i++) + { + if (ipv4->GetAddress (i) == a) { + NS_DEBUG("FindOutgoingInterfaceId: Interface match for " << a); + return i; + } + } + } + } + return 0; +} + +// derived from quagga ospf_intra_add_router() +// +// This is where we add host routes to the routing tables void StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) { @@ -470,13 +552,6 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) // records. For each point to point record, the m_linkData // is a destination IP address to which we add a host route // - - // Therefore, this routine's logic should be: - // i) obtain the ipv4-route interface of the node corresponding - // to m_spfroot (vertex) - // i.e. Query Interface for the IPv4-route interface - // ii) for each point-to-point link in v->m_lsa - // ipv4-route::AddHostRouteTo(m_linkData, m_root_oid); NS_ASSERT_MSG(m_spfroot, "StaticRouteManager::SPFIntraAddRouter (): Root pointer not set"); @@ -496,7 +571,7 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) if (rtr->GetRouterId () == routerId) { - NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " "setting routes for node " << node->GetId ()); Ptr ipv4 = node->QueryInterface (Ipv4::iid); @@ -515,32 +590,33 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) "StaticRouteManager::SPFIntraAddRouter (): " "Expected exen number of Link Records"); - for (uint32_t j = 0; j < nLinkRecords; ++j) + for (uint32_t j = 0; j < nLinkRecords; j += 2) { - StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); - if (lr->m_linkType != StaticRouterLinkRecord::PointToPoint) - { - continue; - } -// -// BUGBUG This is not right. Need to find the next hop interface correctly -// - NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " - "BUGBUG incorrect next hope calculation"); + StaticRouterLinkRecord *lrp2p = lsa->GetLinkRecord (j); + NS_ASSERT_MSG( + lrp2p->m_linkType == StaticRouterLinkRecord::PointToPoint, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected PointToPoint Link Record"); - NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " - "Add route to " << lr->m_linkData << - " using next hop " << lr->m_linkData << - " via interface " << v->m_root_oif); + StaticRouterLinkRecord *lrstub = lsa->GetLinkRecord (j + 1); + NS_ASSERT_MSG( + lrstub->m_linkType == StaticRouterLinkRecord::StubNetwork, + "StaticRouteManager::SPFIntraAddRouter (): " + "Expected StubNetwork Link Record"); + + NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " + "Add route to " << lrp2p->m_linkData << + " using next hop " << v->m_nextHop << + " via interface " << v->m_rootOif); - ipv4->AddHostRouteTo(lr->m_linkData, - lr->m_linkData, v->m_root_oif); + ipv4->AddHostRouteTo(lrp2p->m_linkData, v->m_nextHop, + v->m_rootOif); } - break; } } } +// Derived from quagga ospf_vertex_add_parents() // Add a vertex to the list of children in each of its parents. void StaticRouteManager::SPFVertexAddParent(SPFVertex* v) @@ -549,6 +625,15 @@ StaticRouteManager::SPFVertexAddParent(SPFVertex* v) v->m_parent->m_children.push_back(v); } +void +StaticRouteManager::DeleteSPFVertexChain(SPFVertex* spfroot) +{ + // spfroot is the root of all SPFVertex created during the SPF process + // each vertex has a list of children + // Recursively, delete all of the SPFVertex children of each SPFVertex + // then delete root itself +} + } // namespace ns3 #ifdef RUN_SELF_TESTS @@ -612,13 +697,12 @@ StaticRouteManagerTest::RunTests (void) for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.Pop (); + SPFVertex *v = candidate.Top (); + candidate.Pop (); if (v->m_distanceFromRoot < lastDistance) { ok = false; } - delete v; - v = 0; lastDistance = v->m_distanceFromRoot; } diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index d0cb28aa7..40105d464 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -61,7 +61,9 @@ public: t_listOfSPFVertex::iterator m_SPFVertexIter; uint32_t m_distanceFromRoot; - uint32_t m_root_oif; + uint32_t m_rootOif; + Ipv4Address m_nextHop; + }; /** @@ -74,11 +76,9 @@ public: void Insert(Ipv4Address addr, StaticRouterLSA* lsa); StaticRouterLSA* GetLSA (Ipv4Address addr); /** - * \brief Set all SPFVertex to an initialized state, for SPF computation + * \brief Set all LSA flags to an initialized state, for SPF computation */ -#if 0 void Initialize (); -#endif typedef std::map LSDBMap_t; typedef std::pair LSDBPair_t; @@ -134,9 +134,10 @@ private: StaticRouterLinkRecord* l, uint32_t distance); void SPFVertexAddParent(SPFVertex* v); void DeleteSPFVertexChain(SPFVertex* spfroot); - uint32_t FindOutgoingInterface(SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* l); + StaticRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, + StaticRouterLinkRecord* prev_link); void SPFIntraAddRouter(SPFVertex* v); + uint32_t FindOutgoingInterfaceId(Ipv4Address a); }; diff --git a/src/routing/static-router.h b/src/routing/static-router.h index b6331021a..4f777e484 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -184,8 +184,8 @@ public: // this is a tristate flag used internally in the SPF computation enum SPFStatus { LSA_SPF_NOT_EXPLORED = 0, - LSA_SPF_IN_SPFTREE, - LSA_SPF_CANDIDATE + LSA_SPF_CANDIDATE, + LSA_SPF_IN_SPFTREE } m_stat; }; From 420fb5f6ccfb94084b11e3c84a770de03273b54f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 13 Jul 2007 13:46:01 -0700 Subject: [PATCH 59/92] merge probs --- src/routing/static-route-manager.cc | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 8b72927d8..e06cceeec 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -518,13 +518,13 @@ StaticRouteManager::FindOutgoingInterfaceId(Ipv4Address a) Ptr rtr = node->QueryInterface (StaticRouter::iid); NS_ASSERT_MSG(rtr, - "StaticRouteManager::SPFIntraAddRouter (): " + "StaticRouteManager::FindOutgoingInterfaceId (): " "QI for interface failed"); if (rtr->GetRouterId () == routerId) { Ptr ipv4 = node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4, - "StaticRouteManager::SPFIntraAddRouter (): " + "StaticRouteManager::FindOutgoingInterfaceId (): " "QI for interface failed"); for (uint32_t i = 0; i < ipv4->GetNInterfaces(); i++) { @@ -592,24 +592,21 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) for (uint32_t j = 0; j < nLinkRecords; j += 2) { - StaticRouterLinkRecord *lrp2p = lsa->GetLinkRecord (j); - NS_ASSERT_MSG( - lrp2p->m_linkType == StaticRouterLinkRecord::PointToPoint, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected PointToPoint Link Record"); + StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); + if (lr->m_linkType != StaticRouterLinkRecord::PointToPoint) + { + continue; + } - StaticRouterLinkRecord *lrstub = lsa->GetLinkRecord (j + 1); - NS_ASSERT_MSG( - lrstub->m_linkType == StaticRouterLinkRecord::StubNetwork, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected StubNetwork Link Record"); - - NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " - "Add route to " << lrp2p->m_linkData << + NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + "BUGBUG incorrect next hope calculation"); + + NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + "Add route to " << lr->m_linkData << " using next hop " << v->m_nextHop << " via interface " << v->m_rootOif); - ipv4->AddHostRouteTo(lrp2p->m_linkData, v->m_nextHop, + ipv4->AddHostRouteTo(lr->m_linkData, v->m_nextHop, v->m_rootOif); } } From e1c4bbed1d6ba78cf58295b556e2c7f054858bbc Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 13 Jul 2007 13:49:10 -0700 Subject: [PATCH 60/92] remove debug prints --- src/routing/static-route-manager.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index e06cceeec..4eb432a09 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -598,10 +598,7 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) continue; } - NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " - "BUGBUG incorrect next hope calculation"); - - NS_DEBUG_UNCOND("StaticRouteManager::SPFIntraAddRouter (): " + NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " "Add route to " << lr->m_linkData << " using next hop " << v->m_nextHop << " via interface " << v->m_rootOif); From 65faee4e7be298ae29d6cc8aae4b8900f7d1d16f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 13 Jul 2007 14:05:12 -0700 Subject: [PATCH 61/92] fix merge problem that lost candidate queue changes --- src/routing/static-route-manager.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 4eb432a09..3e8e43fd7 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -477,8 +477,7 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // tree (removing it from the candidate list in the // process). // Extract from the candidates the node with the lower key. - v = candidate.Top(); - candidate.Pop(); + v = candidate.Pop(); // Update stat field in vertex. NS_DEBUG("SPFCalculate: Popping vertex" << v->m_vertexId); v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; @@ -691,13 +690,14 @@ StaticRouteManagerTest::RunTests (void) for (int i = 0; i < 100; ++i) { - SPFVertex *v = candidate.Top (); - candidate.Pop (); + SPFVertex *v = candidate.Pop (); if (v->m_distanceFromRoot < lastDistance) { ok = false; } lastDistance = v->m_distanceFromRoot; + delete v; + v = 0; } // Build fake link state database; four routers (0-3), 3 point-to-point From 57b34480191abedb4b8e7a7ba998d8c30c4abc6c Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 13 Jul 2007 14:21:44 -0700 Subject: [PATCH 62/92] Check for static routing flag before instantiating a StaticRouteManager --- examples/simple-static-routing.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 71fc00044..55200e7af 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -140,12 +140,12 @@ int main (int argc, char *argv[]) channel2, n2, Ipv4Address("10.1.3.1"), n3, Ipv4Address("10.1.3.2")); - // Here, we will use the StaticRoutingManager to build routes - Ptr routeManager = Create (); - // The below functions might better be placed in some kind of - // Simulator::Initialization function (for further study) - routeManager->BuildStaticRoutingDatabase (); - routeManager->InitializeRoutes (); + if (RoutingEnvironment::StaticRoutingEnabled()) + { + Ptr routeManager = Create (); + routeManager->BuildStaticRoutingDatabase (); + routeManager->InitializeRoutes (); + } // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s From 2065013a0434ceca85b66dda9181199d5dd4af77 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 13 Jul 2007 14:22:40 -0700 Subject: [PATCH 63/92] Small readme for the routing --- README.routing | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 README.routing diff --git a/README.routing b/README.routing new file mode 100644 index 000000000..7b5166f5c --- /dev/null +++ b/README.routing @@ -0,0 +1,93 @@ +Routing overview, mid-July + +This is a proposal to add global static routing to ns-3 + +The previously announced roadmap: +* July 15: Support IPv4 static routing with PointToPoint numbered links +* August 15: Extend IPv4 static routing to Ethernet (shared links), add static multicast forwarding over Ethernet and PointToPoint +* Sept 15: Add static multicast forwarding over wireless interface + +This would provide the first bullet above. + +Note: This is orthogonal to Gustavo's OLSR code, but could also exist +as a static routing protocol in the framework that he proposes; right now, +this just writes directly into the existing Ipv4 routing API + +1. Code: + +- source code is in a routing module src/routing/ +- an example script is in examples/simple-static-routing.cc +- StaticRouteManager is added in the run-tests unit tests + +2. Approach + +Static routing is used to automatically populate the forwarding tables +in a topology without running a dynamic routing protocol or asking +the user to manually enter routes themselves. + +A single object (StaticRouteManager) is responsible for populating +the static routes on each node, using the public Ipv4 API of that node. +It queries each node in the topology for a "staticRouter" interface. +If found, it uses the API of that interface to obtain a "link state +advertisement (LSA)" for the router. Link State Advertisements +are used in OSPF routing, and we follow their formatting. + +The StaticRouteManager populates a link state database with LSAs +gathered from the entire topology. Then, for each router in the topology, +the StaticRouteManager executes the OSPF shortest path first (SPF) +computation on the database, and populates the routing tables on each +node. + +This computation is initiated during the pre-simulation phase (after +topology and IP addressing has been done) with the following lines of code, +presently: + Ptr routeManager = Create (); + routeManager->BuildStaticRoutingDatabase (); + routeManager->InitializeRoutes (); + +The quagga (http://www.quagga.net) OSPF implementation was used as the +basis for the routing computation logic. +One benefit of following an existing OSPF SPF implementation is that +OSPF already has defined link state advertisements for all common +types of network links: +- point-to-point (serial links) +- point-to-multipoint (Frame Relay, ad hoc wireless) +- non-broadcast multiple access (ATM) +- broadcast (Ethernet) +Therefore, we think that enabling these other link types will be more +straightforward now that the underlying OSPF SPF framework is in place. + +Presently, we can handle IPv4 point-to-point, numbered links, and we do +not do equal-cost multipath. + +3. Bootstrapping + +Static routing can be enabled using a DoStaticRouting flag in the +default value system: + Bind ("DoStaticRouting", "true"); +This bind tells the system to use global static routing. It results in +a StaticRouter interface being aggregated to the internet nodes and the +creation of a Route Manager component to oversee the route generation. + +If this flag is true, when an InternetNode is created, it will aggregate +a routing interface to it. + if (RoutingEnvironment::StaticRoutingEnabled()) + { + Ptr staticRouter = Create (this); + Object::AddInterface (staticRouter); + } +this flag is also tested before creating a StaticRouteManager object. + +4. Some open issues + +- how transparent vs. explicit the enabling of static routing should be +(e.g., if we have a higher layer Inversion-of-Control framework, do these +static routing functions exist in some kind of Init() or Presimulate() +method?) +- whether to add some kind of flag in an InternetNode that is equivalent +to /proc/sys/net/ipv4/ip_forward , so that every InternetNode is not +necessarily a router. +- whether to continue to write to the existing IPv4 API or load a static +router component into the node like Gustavo's OLSR +- whether to make a single global forwarding table instead of distributing +it among all the routers From 2f2b10d22b1413ea69bccd55f3f3039d4cc914f4 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 13 Jul 2007 14:35:24 -0700 Subject: [PATCH 64/92] remove inappropriate assertions that popped when routing disabled --- src/routing/static-route-manager.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 3e8e43fd7..3c37389cf 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -145,7 +145,11 @@ StaticRouteManager::BuildStaticRoutingDatabase () Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG(rtr, "QI for interface failed"); + + if (!rtr) + { + continue; + } // You must call DiscoverLSAs () before trying to use any // routing info or to update LSAs. Subsequently you may use @@ -208,7 +212,7 @@ StaticRouteManager::InitializeRoutes () Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG(rtr, "QI for interface failed"); + if (rtr && rtr->GetNumLSAs () ) { SPFCalculate(rtr->GetRouterId ()); From 2684031ff2824a6dc4cb57c4762141a07eccb774 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 15 Jul 2007 22:47:58 -0700 Subject: [PATCH 65/92] Fix SPFVertex destructor; make unit tests succeed again --- src/routing/static-route-manager.cc | 28 ++++++++++++++-------------- src/routing/static-route-manager.h | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 3c37389cf..62dfc5136 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -56,6 +56,16 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : SPFVertex::~SPFVertex () { + for ( t_listOfSPFVertex::iterator i = m_children.begin (); + i != m_children.end (); + i++) + { + SPFVertex *p = *i; + delete p; + p = 0; + *i = 0; + } + m_children.clear(); } StaticRouteManagerLSDB::~StaticRouteManagerLSDB() @@ -502,7 +512,7 @@ StaticRouteManager::SPFCalculate(Ipv4Address root) // Second stage of SPF calculation procedure's // NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); - DeleteSPFVertexChain(m_spfroot); + delete m_spfroot; m_spfroot = 0; } @@ -622,15 +632,6 @@ StaticRouteManager::SPFVertexAddParent(SPFVertex* v) v->m_parent->m_children.push_back(v); } -void -StaticRouteManager::DeleteSPFVertexChain(SPFVertex* spfroot) -{ - // spfroot is the root of all SPFVertex created during the SPF process - // each vertex has a list of children - // Recursively, delete all of the SPFVertex children of each SPFVertex - // then delete root itself -} - } // namespace ns3 #ifdef RUN_SELF_TESTS @@ -819,12 +820,11 @@ StaticRouteManagerTest::RunTests (void) srmlsdb->Insert(lsa3->m_linkStateId, lsa3); NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); - // We need a dummy node to populate the routing tables - Ptr n2 = Create (); - // XXX next, calculate routes based on the manually created LSDB StaticRouteManager* srm = new StaticRouteManager(); - srm->DebugUseLsdb (srmlsdb); + srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB + // Note-- this will succeed without any nodes in the topology + // because the NodeList is empty srm->DebugSPFCalculate(lsa0->m_linkStateId); // node n0 // This delete clears the srm, which deletes the LSDB, which clears diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 40105d464..2f47d0b40 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -133,7 +133,6 @@ private: int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, StaticRouterLinkRecord* l, uint32_t distance); void SPFVertexAddParent(SPFVertex* v); - void DeleteSPFVertexChain(SPFVertex* spfroot); StaticRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, StaticRouterLinkRecord* prev_link); void SPFIntraAddRouter(SPFVertex* v); From 510d2346118f24d6d98089ccee7b00a528389204 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 16 Jul 2007 16:59:23 -0700 Subject: [PATCH 66/92] checkpoint --- src/routing/static-route-manager.cc | 307 +++++++++++++++++++--------- 1 file changed, 210 insertions(+), 97 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 62dfc5136..322548faf 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -53,7 +53,6 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : { } - SPFVertex::~SPFVertex () { for ( t_listOfSPFVertex::iterator i = m_children.begin (); @@ -129,7 +128,9 @@ StaticRouteManager::~StaticRouteManager () NS_DEBUG("StaticRouteManager::~StaticRouteManager ()"); if (m_lsdb) - delete m_lsdb; + { + delete m_lsdb; + } } void @@ -140,14 +141,22 @@ StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) m_lsdb = lsdb; } +// +// In order to build the routing database, we need to walk the list of nodes +// in the system and look for those that support the StaticRouter interface. +// These routers will export a number of Link State Advertisements (LSAs) +// that describe the links and networks that are "adjacent" (i.e., that are +// on the other side of a point-to-point link). We take these LSAs and put +// add them to the Link State DataBase (LSDB) from which the routes will +// ultimately be computed. +// void StaticRouteManager::BuildStaticRoutingDatabase () { NS_DEBUG("StaticRouteManager::BuildStaticRoutingDatabase()"); - - // Walk the list of nodes. QI for StaticRouter interface. - // if node has a StaticRouter interface, grab the LSAs - // from it and stick them in the LSDB +// +// Walk the list of nodes looking for the StaticRouter Interface. +// typedef std::vector < Ptr >::iterator Iterator; for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { @@ -155,74 +164,96 @@ StaticRouteManager::BuildStaticRoutingDatabase () Ptr rtr = node->QueryInterface (StaticRouter::iid); - +// +// Ignore nodes that aren't participating in routing. +// if (!rtr) { continue; } - - // You must call DiscoverLSAs () before trying to use any - // routing info or to update LSAs. Subsequently you may use - // GetNumLSAs(). If you call GetNumLSAs () before calling - // DiscoverLSAs () will get zero as the number. +// +// You must call DiscoverLSAs () before trying to use any routing info or to +// update LSAs. DiscoverLSAs () drives the process of discovering routes in +// the StaticRouter. Afterward, you may use GetNumLSAs (), which is a very +// computationally inexpensive call. If you call GetNumLSAs () before calling +// DiscoverLSAs () will get zero as the number since no routes have been +// found. +// uint32_t numLSAs = rtr->DiscoverLSAs(); NS_DEBUG ("Discover LSAs: Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) { StaticRouterLSA* lsa = new StaticRouterLSA (); +// +// This is the call to actually fetch a Link State Advertisement from the +// router. +// rtr->GetLSA(j, *lsa); NS_DEBUG ("LSA " << j); - NS_DEBUG ("----------------------------"); NS_DEBUG (*lsa); +// +// Write the newly discovered link state advertisement to the database. +// m_lsdb->Insert (lsa->m_linkStateId, lsa); } } } -// For each node that is a static router (which can be determined by -// the presence of StaticRouter interface), run Dijkstra SPF calculation -// on the database rooted at that router, and populate the node -// forwarding tables +// +// For each node that is a static router (which is determined by the presence +// of an aggregated StaticRouter interface), run the Dijkstra SPF calculation +// on the database rooted at that router, and populate the node forwarding +// tables. +// +// This function parallels RFC2328, Section 16.1.1, and quagga ospfd +// +// This calculation yields the set of intra-area routes associated +// with an area (called hereafter Area A). A router calculates the +// shortest-path tree using itself as the root. The formation +// of the shortest path tree is done here in two stages. In the +// first stage, only links between routers and transit networks are +// considered. Using the Dijkstra algorithm, a tree is formed from +// this subset of the link state database. In the second stage, +// leaves are added to the tree by considering the links to stub +// networks. +// +// The area's link state database is represented as a directed graph. +// The graph's vertices are routers, transit networks and stub networks. +// +// The first stage of the procedure (i.e., the Dijkstra algorithm) +// can now be summarized as follows. At each iteration of the +// algorithm, there is a list of candidate vertices. Paths from +// the root to these vertices have been found, but not necessarily +// the shortest ones. However, the paths to the candidate vertex +// that is closest to the root are guaranteed to be shortest; this +// vertex is added to the shortest-path tree, removed from the +// candidate list, and its adjacent vertices are examined for +// possible addition to/modification of the candidate list. The +// algorithm then iterates again. It terminates when the candidate +// list becomes empty. +// void StaticRouteManager::InitializeRoutes () { NS_DEBUG("StaticRouteManager::InitializeRoutes ()"); - // This function parallels RFC2328, Section 16.1.1, and quagga ospfd - // - // This calculation yields the set of intra-area routes associated - // with an area (called hereafter Area A). A router calculates the - // shortest-path tree using itself as the root. The formation - // of the shortest path tree is done here in two stages. In the - // first stage, only links between routers and transit networks are - // considered. Using the Dijkstra algorithm, a tree is formed from - // this subset of the link state database. In the second stage, - // leaves are added to the tree by considering the links to stub - // networks. - - // The area's link state database is represented as a directed graph. - // The graph's vertices are routers, transit networks and stub networks. - // The first stage of the procedure (i.e., the Dijkstra algorithm) - // can now be summarized as follows. At each iteration of the - // algorithm, there is a list of candidate vertices. Paths from - // the root to these vertices have been found, but not necessarily - // the shortest ones. However, the paths to the candidate vertex - // that is closest to the root are guaranteed to be shortest; this - // vertex is added to the shortest-path tree, removed from the - // candidate list, and its adjacent vertices are examined for - // possible addition to/modification of the candidate list. The - // algorithm then iterates again. It terminates when the candidate - // list becomes empty. - - // Iterate for each node that is a router in the topology +// +// Walk the list of nodes in the system. +// typedef std::vector < Ptr >::iterator Iterator; for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) { Ptr node = *i; - +// +// Look for the StaticRouter interface that indicates that the node is +// participating in routing. +// Ptr rtr = node->QueryInterface (StaticRouter::iid); - +// +// if the node has a static router interface, then run the static routing +// algorithms. +// if (rtr && rtr->GetNumLSAs () ) { SPFCalculate(rtr->GetRouterId ()); @@ -230,12 +261,19 @@ StaticRouteManager::InitializeRoutes () } } - -// Derived from quagga ospf_spf_next() -// RFC2328 Section 16.1 (2). -// v is on the SPF tree. Examine the links in v's LSA. Update the list -// of candidates with any vertices not already on the list. If a lower-cost -// path is found to a vertex already on the candidate list, store the new cost. +// +// This method is derived from quagga ospf_spf_next(). See RFC2328 Section +// 16.1 (2) for further details. +// +// We're passed a parameter that is a vertex which is already in the SPF +// tree. A vertex represents a router node. We also get a reference to the +// SPF candidate queue, which is a priority queue containing the shortest paths +// to the networks we know about. +// +// We examine the links in v's LSA and update the listof candidates with any +// vertices not already on the list. If a lower-cost path is found to a +// vertex already on the candidate list, store the new (lower) cost. +// void StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) { @@ -246,20 +284,27 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) NS_DEBUG("StaticRouteManager::SPFNext ()"); if (v->m_vertexType == SPFVertex::VertexRouter) { - // Always true for now, since all our LSAs are RouterLSAs +// +// Always true for now, since all our LSAs are RouterLSAs. +// if (true) { NS_DEBUG ("SPFNext: Examining " << v->m_vertexId << "'s " << v->m_lsa->m_linkRecords.size() << " link records"); +// +// Walk the list of link records in the link state advertisemnt associated with +// the "current" router (represented by vertex ). +// for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = v->m_lsa->m_linkRecords.begin(); i != v->m_lsa->m_linkRecords.end(); 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. +// +// (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. +// StaticRouterLinkRecord* l = *i; if (l->m_linkType == StaticRouterLinkRecord::StubNetwork) { @@ -267,41 +312,67 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) << l->m_linkId); 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. +// +// (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->m_linkType == StaticRouterLinkRecord::PointToPoint) { - // Lookup the vertex W's LSA +// +// Lookup the link state advertisement of the new link -- we call it in +// the link state database. +// w_lsa = m_lsdb->GetLSA(l->m_linkId); NS_ASSERT(w_lsa); NS_DEBUG("SPFNext: Found a P2P record from " << v->m_vertexId << " to " << w_lsa->m_linkStateId); - // (c) If vertex W is already on the shortest-path tree, - // examine the next link in the LSA. +// +// (c) If vertex W is already on the shortest-path tree, examine the next +// link in the LSA. +// +// 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->m_stat == StaticRouterLSA::LSA_SPF_IN_SPFTREE) { NS_DEBUG("SPFNext: Skipping-> LSA "<< w_lsa->m_linkStateId << " 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. +// +// The link is to a router we haven't dealt with yet. +// +// (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->m_distanceFromRoot + l->m_metric; NS_DEBUG("SPFNext: Considering w_lsa " << w_lsa->m_linkStateId); - // Here, W is either already in candidate list or not + if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { +// +// If we havent yet considered the link represented by we have to create +// a new SPFVertex to represent it. +// 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 things0 find the next hop address to send +// packets destined fo this network to, and also find the outbound interface +// used to forward the packets. +// if (SPFNexthopCalculation(v, w, l, distance)) { w_lsa->m_stat = StaticRouterLSA::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->m_vertexId << ", parent vertexId: " << v->m_vertexId); @@ -310,39 +381,58 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) } else if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_CANDIDATE) { - //Get the vertex from candidates +// +// 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 +// distance metric. +// +// So, locate the vertex in the candidate queue and take a look at the +// distance. w = candidate.Find(w_lsa->m_linkStateId); if (w->m_distanceFromRoot < distance) { - continue; // not a shorter path +// +// This is not a shorter path, so don't do anything. +// + continue; } - // equal to else if (w->m_distanceFromRoot == distance) { - // Do nothing-- not doing equal-cost multipath +// +// This path is one with an equal cost. Do nothing for now -- we're not doing +// equal-cost multipath cases yet. +// } else { - // Found a lower-cost path to W. - // nexthop_calculation is conditional, if it finds - // valid nexthop it will call spf_add_parents, which - // will flush the old parents +// +// 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 +// (vertex ) +// +// 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)) { - // Decrease the key of the node in the heap, - // re-sort the heap. +// +// 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 } } } -// Derived from quagga ospf_next_hop_calculation() -// 16.1.1. Calculate nexthop from root through V (parent) to -// vertex W (destination), with given distance from root->W. +// +// This method is derived from quagga ospf_next_hop_calculation() 16.1.1. +// +// Calculate the nexthop from the root through V (parent) to vertex W +// (destination), with given distance from root->W. // // For now, this is greatly simplified from the quagga code // @@ -354,25 +444,42 @@ StaticRouteManager::SPFNexthopCalculation ( uint32_t distance) { NS_DEBUG("StaticRouteManager::SPFNexthopCalculation ()"); +// +// If we're calculating the next hop information from a node (v) that is the +// root, then we need to store the information needed to forward to the +// given network (w). We need to know the interface ID to use to forward the +// packets, and we need to know the IP address of the router to which we need +// to send the packets (the next hop address). +// if (v == m_spfroot) { - // parent of w is the root itself - // calculate the interfaceid of the router that corresponds - // to link l between v and w and store it in w->m_rootOif - // This rootOif is then used when installing host routes for the - // destinations covered by this vertex. Store also the next hop - // IP address. - // - // Find the outgoing interface on v corresponding to the link l - // between v and w +// +// We're going from the root to a vertex representing a router ... +// if (w->m_vertexType == SPFVertex::VertexRouter) { - // l is a link from v to w - // l2 will be a link from w to v +// +// We need to find both sides of the link we're examining. We are considering +// a link "from" vertex v "to" vertex w over the link represented by the link +// record l. We have the information from the perspective of v, now we need +// to get the information from the perspective of w, specifically the point +// to point link record describing the link from w to v. +// StaticRouterLinkRecord *l2 = 0; l2 = SPFGetNextLink(w,v,l2); +// +// At this point, is the link record from to ; and is the +// link record from to . The next hop address of the destination is +// the link data field of the static router link record (which is the local IP +// address in the case of a point-to-point link). This means that in order to +// get to the network w, you send packets to the other side of the point-to- +// point link -- the router on that network. +// w->m_nextHop = l2->m_linkData; - // Find interface corresponding to link's IP address +// +// Now find the interface corresponding to the point to point link's IP +// address. +// w->m_rootOif = FindOutgoingInterfaceId(l->m_linkData); NS_DEBUG("SPFNexthopCalculation: Next hop from " << @@ -383,10 +490,16 @@ StaticRouteManager::SPFNexthopCalculation ( } else { - // Inherit the rootOif and nextHop from the current parent +// +// If we're calculating the next hop information from a node (v) that is +// *not* the root, then we need to "inherit" the information needed to +// forward from the parent (who will have inherited, ultimately, from the +// root. +// w->m_rootOif = v->m_rootOif; w->m_nextHop = v->m_nextHop; } + w->m_distanceFromRoot = distance; w->m_parent = v; return 1; From 04e59f26b9efb04571da7e670e52acae79d99134 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jul 2007 12:17:17 -0700 Subject: [PATCH 67/92] checkpoint documentation --- src/routing/static-route-manager.cc | 679 +++++++++++++++++----------- 1 file changed, 405 insertions(+), 274 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 322548faf..508f53831 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -13,6 +13,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include #include #include @@ -30,26 +31,26 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { SPFVertex::SPFVertex () : - m_vertexType(VertexUnknown), - m_vertexId("255.255.255.255"), - m_lsa(0), - m_parent(0), - m_children(), - m_distanceFromRoot(SPF_INFINITY), - m_rootOif(SPF_INFINITY), - m_nextHop("0.0.0.0") + m_vertexType (VertexUnknown), + m_vertexId ("255.255.255.255"), + m_lsa (0), + m_parent (0), + m_children (), + m_distanceFromRoot (SPF_INFINITY), + m_rootOif (SPF_INFINITY), + m_nextHop ("0.0.0.0") { } SPFVertex::SPFVertex (StaticRouterLSA* lsa) : - m_vertexType(VertexRouter), - m_vertexId(lsa->m_linkStateId), - m_lsa(lsa), - m_parent(0), - m_children(), - m_distanceFromRoot(SPF_INFINITY), - m_rootOif(SPF_INFINITY), - m_nextHop("0.0.0.0") + m_vertexType (VertexRouter), + m_vertexId (lsa->m_linkStateId), + m_lsa (lsa), + m_parent (0), + m_children (), + m_distanceFromRoot (SPF_INFINITY), + m_rootOif (SPF_INFINITY), + m_nextHop ("0.0.0.0") { } @@ -64,31 +65,31 @@ SPFVertex::~SPFVertex () p = 0; *i = 0; } - m_children.clear(); + m_children.clear (); } -StaticRouteManagerLSDB::~StaticRouteManagerLSDB() +StaticRouteManagerLSDB::~StaticRouteManagerLSDB () { - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); LSDBMap_t::iterator i; - for (i= m_database.begin(); i!= m_database.end(); i++) + for (i= m_database.begin (); i!= m_database.end (); i++) { - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB():free LSA"); + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ():free LSA"); StaticRouterLSA* temp = i->second; delete temp; } - NS_DEBUG("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); - m_database.clear(); + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); + m_database.clear (); } void -StaticRouteManagerLSDB::Initialize() +StaticRouteManagerLSDB::Initialize () { - NS_DEBUG("StaticRouteManagerLSDB::Initialize ()"); + NS_DEBUG ("StaticRouteManagerLSDB::Initialize ()"); LSDBMap_t::iterator i; - for (i= m_database.begin(); i!= m_database.end(); i++) + for (i= m_database.begin (); i!= m_database.end (); i++) { StaticRouterLSA* temp = i->second; temp->m_stat = StaticRouterLSA::LSA_SPF_NOT_EXPLORED; @@ -96,19 +97,19 @@ StaticRouteManagerLSDB::Initialize() } void -StaticRouteManagerLSDB::Insert(Ipv4Address addr, StaticRouterLSA* lsa) +StaticRouteManagerLSDB::Insert (Ipv4Address addr, StaticRouterLSA* lsa) { - NS_DEBUG("StaticRouteManagerLSDB::Insert ()"); - m_database.insert(LSDBPair_t(addr, lsa)); + NS_DEBUG ("StaticRouteManagerLSDB::Insert ()"); + m_database.insert (LSDBPair_t (addr, lsa)); } StaticRouterLSA* StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) { - NS_DEBUG("StaticRouteManagerLSDB::GetLSA ()"); + NS_DEBUG ("StaticRouteManagerLSDB::GetLSA ()"); // Look up an LSA by its address LSDBMap_t::iterator i; - for (i= m_database.begin(); i!= m_database.end(); i++) + for (i= m_database.begin (); i!= m_database.end (); i++) { if (i->first == addr) { @@ -118,14 +119,14 @@ StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) return 0; } -StaticRouteManager::StaticRouteManager () : m_spfroot(0) +StaticRouteManager::StaticRouteManager () : m_spfroot (0) { m_lsdb = new StaticRouteManagerLSDB (); } StaticRouteManager::~StaticRouteManager () { - NS_DEBUG("StaticRouteManager::~StaticRouteManager ()"); + NS_DEBUG ("StaticRouteManager::~StaticRouteManager ()"); if (m_lsdb) { @@ -153,12 +154,12 @@ StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) void StaticRouteManager::BuildStaticRoutingDatabase () { - NS_DEBUG("StaticRouteManager::BuildStaticRoutingDatabase()"); + NS_DEBUG ("StaticRouteManager::BuildStaticRoutingDatabase()"); // // Walk the list of nodes looking for the StaticRouter Interface. // typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) { Ptr node = *i; @@ -179,7 +180,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () // DiscoverLSAs () will get zero as the number since no routes have been // found. // - uint32_t numLSAs = rtr->DiscoverLSAs(); + uint32_t numLSAs = rtr->DiscoverLSAs (); NS_DEBUG ("Discover LSAs: Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) @@ -189,7 +190,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () // This is the call to actually fetch a Link State Advertisement from the // router. // - rtr->GetLSA(j, *lsa); + rtr->GetLSA (j, *lsa); NS_DEBUG ("LSA " << j); NS_DEBUG (*lsa); // @@ -236,12 +237,12 @@ StaticRouteManager::BuildStaticRoutingDatabase () void StaticRouteManager::InitializeRoutes () { - NS_DEBUG("StaticRouteManager::InitializeRoutes ()"); + NS_DEBUG ("StaticRouteManager::InitializeRoutes ()"); // // Walk the list of nodes in the system. // typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin(); i != NodeList::End(); i++) + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) { Ptr node = *i; // @@ -256,13 +257,13 @@ StaticRouteManager::InitializeRoutes () // if (rtr && rtr->GetNumLSAs () ) { - SPFCalculate(rtr->GetRouterId ()); + SPFCalculate (rtr->GetRouterId ()); } } } // -// This method is derived from quagga ospf_spf_next(). See RFC2328 Section +// This method is derived from quagga ospf_spf_next (). See RFC2328 Section // 16.1 (2) for further details. // // We're passed a parameter that is a vertex which is already in the SPF @@ -270,35 +271,35 @@ StaticRouteManager::InitializeRoutes () // SPF candidate queue, which is a priority queue containing the shortest paths // to the networks we know about. // -// We examine the links in v's LSA and update the listof candidates with any +// We examine the links in v's LSA and update the list of candidates with any // vertices not already on the list. If a lower-cost path is found to a // vertex already on the candidate list, store the new (lower) cost. // void -StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) +StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) { SPFVertex* w = 0; StaticRouterLSA* w_lsa = 0; uint32_t distance = 0; - NS_DEBUG("StaticRouteManager::SPFNext ()"); - if (v->m_vertexType == SPFVertex::VertexRouter) - { + NS_DEBUG ("StaticRouteManager::SPFNext ()"); // // Always true for now, since all our LSAs are RouterLSAs. // + if (v->m_vertexType == SPFVertex::VertexRouter) + { if (true) { NS_DEBUG ("SPFNext: Examining " << v->m_vertexId << "'s " << - v->m_lsa->m_linkRecords.size() << " link records"); + v->m_lsa->m_linkRecords.size () << " link records"); // -// Walk the list of link records in the link state advertisemnt associated with -// the "current" router (represented by vertex ). +// Walk the list of link records in the link state advertisement associated +// with the "current" router (represented by vertex ). // - for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = - v->m_lsa->m_linkRecords.begin(); - i != v->m_lsa->m_linkRecords.end(); - i++ ) + for (StaticRouterLSA::ListOfLinkRecords_t::iterator i = + v->m_lsa->m_linkRecords.begin (); + i != v->m_lsa->m_linkRecords.end (); + i++) { // // (a) If this is a link to a stub network, examine the next link in V's LSA. @@ -308,7 +309,7 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) StaticRouterLinkRecord* l = *i; if (l->m_linkType == StaticRouterLinkRecord::StubNetwork) { - NS_DEBUG("SPFNext: Found a Stub record to " + NS_DEBUG ("SPFNext: Found a Stub record to " << l->m_linkId); continue; } @@ -323,9 +324,9 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // Lookup the link state advertisement of the new link -- we call it in // the link state database. // - w_lsa = m_lsdb->GetLSA(l->m_linkId); - NS_ASSERT(w_lsa); - NS_DEBUG("SPFNext: Found a P2P record from " << + w_lsa = m_lsdb->GetLSA (l->m_linkId); + NS_ASSERT (w_lsa); + NS_DEBUG ("SPFNext: Found a P2P record from " << v->m_vertexId << " to " << w_lsa->m_linkStateId); // // (c) If vertex W is already on the shortest-path tree, examine the next @@ -336,7 +337,7 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_IN_SPFTREE) { - NS_DEBUG("SPFNext: Skipping-> LSA "<< + NS_DEBUG ("SPFNext: Skipping-> LSA "<< w_lsa->m_linkStateId << " already in SPF tree"); continue; } @@ -350,7 +351,7 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // distance = v->m_distanceFromRoot + l->m_metric; - NS_DEBUG("SPFNext: Considering w_lsa " << + NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->m_linkStateId); if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) @@ -359,22 +360,22 @@ StaticRouteManager::SPFNext(SPFVertex* v, CandidateQueue& candidate) // If we havent yet considered the link represented by we have to create // a new SPFVertex to represent it. // - w = new SPFVertex(w_lsa); + w = new SPFVertex (w_lsa); // // We need to figure out how to actually get to the new router represented -// by . This will (among other things0 find the next hop address to send -// packets destined fo this network to, and also find the outbound interface +// 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)) + if (SPFNexthopCalculation (v, w, l, distance)) { w_lsa->m_stat = StaticRouterLSA::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->m_vertexId + candidate.Push (w); + NS_DEBUG ("SPFNext: Pushing " << w->m_vertexId << ", parent vertexId: " << v->m_vertexId); } } @@ -388,7 +389,7 @@ StaticRouteManager::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->m_linkStateId); + w = candidate.Find (w_lsa->m_linkStateId); if (w->m_distanceFromRoot < distance) { // @@ -413,26 +414,27 @@ StaticRouteManager::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(); + candidate.Reorder (); } } - } // point-to-point + } // point-to-point } // for loop } - } + } } // // This method is derived from quagga ospf_next_hop_calculation() 16.1.1. // -// Calculate the nexthop from the root through V (parent) to vertex W -// (destination), with given distance from root->W. +// 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. // // For now, this is greatly simplified from the quagga code // @@ -443,46 +445,73 @@ StaticRouteManager::SPFNexthopCalculation ( StaticRouterLinkRecord* l, uint32_t distance) { - NS_DEBUG("StaticRouteManager::SPFNexthopCalculation ()"); + NS_DEBUG ("StaticRouteManager::SPFNexthopCalculation ()"); // -// If we're calculating the next hop information from a node (v) that is the -// root, then we need to store the information needed to forward to the -// given network (w). We need to know the interface ID to use to forward the -// packets, and we need to know the IP address of the router to which we need -// to send the packets (the next hop address). +// 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 +// calculating the routes. +// +// There are two distinct cases for calculating the next hop information. +// First, if we're considering a hop from the root to an "adjacent" network +// (one that is on the other side of a point-to-point link connected to the +// root), then we need to store the information needed to forward down that +// link. The second case is if the network is not directly adjacent. In that +// case we need to use the forwarding information from the vertex on the path +// to the destination that is directly adjacent [node 1] in both cases of the +// diagram below. +// +// (1) [root] -> [point-to-point] -> [node 1] +// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2] +// +// We call the propagation of next hop information down vertices of a path +// "inheriting" the next hop information. +// +// The point-to-point link information is only useful in this calculation when +// we are examining the root node. // if (v == m_spfroot) { // -// We're going from the root to a vertex representing a router ... -// +// In this case is the root node, which means it is the starting point +// for the packets forwarded by that node. This also means that the next hop +// address of packets headed for some arbitrary off-network destination must +// be the destination at the other end of one of the links off of the root +// node if this root node is a router. We then need to see if this node +// is a router. +// if (w->m_vertexType == SPFVertex::VertexRouter) { // -// We need to find both sides of the link we're examining. We are considering -// a link "from" vertex v "to" vertex w over the link represented by the link -// record l. We have the information from the perspective of v, now we need -// to get the information from the perspective of w, specifically the point -// to point link record describing the link from w to v. +// In the case of point-to-point links, the link data field (m_linkData) of a +// Static Router Link Record contains the local IP address. If we look at the +// link record describing the link from the perspecive of (the remote +// node from the viewpoint of ) back to the root node, we can discover the +// IP address of the router to which is adjacent. This is a distinguished +// address -- the next hop address to get from to and all networks +// accessed through that path. // - StaticRouterLinkRecord *l2 = 0; - l2 = SPFGetNextLink(w,v,l2); + StaticRouterLinkRecord *linkRemote = 0; + linkRemote = SPFGetNextLink (w, v, linkRemote); // -// At this point, is the link record from to ; and is the -// link record from to . The next hop address of the destination is -// the link data field of the static router link record (which is the local IP -// address in the case of a point-to-point link). This means that in order to -// get to the network w, you send packets to the other side of the point-to- -// point link -- the router on that network. -// - w->m_nextHop = l2->m_linkData; +// At this point, is the Static Router Link Record describing the point- +// to point link from to from the perspective of ; and +// is the Static Router Link Record describing that same link from the +// perspective of (back to ). Now we can just copy the next hop +// address from the m_linkData member variable. // -// Now find the interface corresponding to the point to point link's IP -// address. +// The next hop member variable we put in has the sense "in order to get +// to the network represented by vertex , you have to send the packet to +// the next hop address specified in w->nextHop. // - w->m_rootOif = FindOutgoingInterfaceId(l->m_linkData); + w->m_nextHop = linkRemote->m_linkData; +// +// Now find the outgoing interface corresponding to the point to point link +// from the perspective of -- remember that is the link "from" +// "to" . +// + w->m_rootOif = FindOutgoingInterfaceId (l->m_linkData); - NS_DEBUG("SPFNexthopCalculation: Next hop from " << + NS_DEBUG ("SPFNexthopCalculation: Next hop from " << v->m_vertexId << " to " << w->m_vertexId << " goes through next hop " << w->m_nextHop << " via outgoing interface " << w->m_rootOif); @@ -493,63 +522,112 @@ StaticRouteManager::SPFNexthopCalculation ( // // If we're calculating the next hop information from a node (v) that is // *not* the root, then we need to "inherit" the information needed to -// forward from the parent (who will have inherited, ultimately, from the -// root. +// forward the packet from the vertex closer to the root. That is, we'll +// still send packets to the next hop address of the router adjacent to the +// root on the path toward . +// +// Above, when we were considering the root node, we calculated the next hop +// address and outgoing interface required to get off of the root network. +// At this point, we are further away from the root network along one of the +// (shortest) paths. So the next hop and outoing interface remain the same +// (are inherited). // - w->m_rootOif = v->m_rootOif; w->m_nextHop = v->m_nextHop; + w->m_rootOif = v->m_rootOif; } - +// +// In all cases, we need valid values for the distance metric and a parent. +// w->m_distanceFromRoot = distance; w->m_parent = v; + return 1; } -// Derived from quagga ospf_get_next_link -// Find the next link after prev_link from v to w. If prev_link is -// NULL, return the first link from v to w. Ignore stub and virtual links; -// these link types will never be returned. +// +// This method is derived from quagga ospf_get_next_link () +// +// First search the Static Router Link Records of vertex for one +// representing a point-to point link to vertex . +// +// What is done depends on prev_link. Contrary to appearances, prev_link just +// acts as a flag here. If prev_link is NULL, we return the first Static +// Router Link Record we find that describes a point-to-point link from +// to . If prev_link is not NULL, we return a Static Router Link Record +// representing a possible *second* link from to . +// +// BUGBUG This seems to be a bug? Shouldn't this function look for any link +// records after pre_link and not just after the first? // StaticRouterLinkRecord* -StaticRouteManager::SPFGetNextLink( +StaticRouteManager::SPFGetNextLink ( SPFVertex* v, SPFVertex* w, StaticRouterLinkRecord* prev_link ) { - NS_DEBUG("StaticRouteManager::SPFGetNextLink ()"); + NS_DEBUG ("StaticRouteManager::SPFGetNextLink ()"); + bool skip = true; StaticRouterLinkRecord* l; +// +// If prev_link is 0, we are really looking for the first link, not the next +// link. +// if (prev_link == 0) { skip = false; } - - for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = - v->m_lsa->m_linkRecords.begin(); - i != v->m_lsa->m_linkRecords.end(); - i++ ) +// +// Iterate through the Static Router Link Records advertised by the vertex +// looking for records representing the point-to-point links off of this +// vertex. +// + for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = + v->m_lsa->m_linkRecords.begin (); + i != v->m_lsa->m_linkRecords.end (); + i++ ) { - l = *i; - if (l->m_linkType != StaticRouterLinkRecord::PointToPoint) + l = *i; + if (l->m_linkType != StaticRouterLinkRecord::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 +// connects from the perspective of in this case. The vertex ID is also +// set to the router ID (using the link state advertisement of a router node). +// We're just checking to see if the link is actually the link from to +// . +// + if (l->m_linkId == w->m_vertexId) { + NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId=" << + l->m_linkId << " linkData=" << l->m_linkData); +// +// If skip is false, don't (not too surprisingly) skip the link found -- it's +// the one we're interested in. That's either because we didn't pass in a +// previous link, and we're interested in the first one, or because we've +// skipped a previous link and moved forward to the next (which is then the +// one we want). +// + if (skip == false) { + NS_DEBUG ("SPFGetNextLink: Returning the found link"); + return l; + } + else + { +// +// Skip is true and we've found a link from to . We want the next one. +// Setting skip to false gets us the next point-to-point static router link +// record in the LSA from . +// + NS_DEBUG ("SPFGetNextLink: Skipping the found link"); + skip = false; continue; } - if (l->m_linkId == w->m_vertexId) { - NS_DEBUG("SPFGetNextLink: Found matching link l: linkId=" << - l->m_linkId << " linkData=" << l->m_linkData); - if (skip == false) - { - NS_DEBUG("SPFGetNextLink: Returning the found link"); - return l; - } - else - { - NS_DEBUG("SPFGetNextLink: Skipping the found link"); - skip = false; - continue; - } - } + } } return 0; } @@ -557,105 +635,158 @@ StaticRouteManager::SPFGetNextLink( // quagga ospf_spf_calculate void -StaticRouteManager::DebugSPFCalculate(Ipv4Address root) +StaticRouteManager::DebugSPFCalculate (Ipv4Address root) { - SPFCalculate(root); + SPFCalculate (root); } // quagga ospf_spf_calculate void -StaticRouteManager::SPFCalculate(Ipv4Address root) +StaticRouteManager::SPFCalculate (Ipv4Address root) { - NS_DEBUG("StaticRouteManager::SPFCalculate ()"); + NS_DEBUG ("StaticRouteManager::SPFCalculate ()"); SPFVertex *v; - +// +// Initialize the Link State Database. +// m_lsdb->Initialize (); - - // The candidate queue is a priority queue of SPFVertex objects, with - // the top of the queue being the closest vertex in terms of - // distanceFromRoot. Initially, this queue is empty. - // +// +// The candidate queue is a priority queue of SPFVertex objects, with the top +// of the queue being the closest vertex in terms of distance from the root +// of the tree. Initially, this queue is empty. +// CandidateQueue candidate; - NS_ASSERT(candidate.Size() == 0); - // - // Initialize the shortest-path tree to only the router doing the - // calculation. - // - v= new SPFVertex(m_lsdb->GetLSA(root)); - // This vertex is the root of the SPF tree + NS_ASSERT(candidate.Size () == 0); +// +// Initialize the shortest-path tree to only contain the router doing the +// calculation. Each router (and corresponding network) is a vertex in the +// shortest path first (SPF) tree. +// + v = new SPFVertex (m_lsdb->GetLSA (root)); +// +// This vertex is the root of the SPF tree and it is distance 0 from the root. +// We also mark this vertex as being in the SPF tree. +// + m_spfroot= v; v->m_distanceFromRoot = 0; - m_spfroot= v; v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; for (;;) { - // RFC2328 16.1. (2). - SPFNext(v , candidate); - - // RFC2328 16.1. (3). - // If at this step the candidate list is empty, the shortest- - // path tree (of transit vertices) has been completely built and - // this stage of the procedure terminates. - if (candidate.Size() == 0) - break; - // Otherwise, choose the vertex belonging to the candidate list - // that is closest to the root, and add it to the shortest-path - // tree (removing it from the candidate list in the - // process). - // Extract from the candidates the node with the lower key. - v = candidate.Pop(); - // Update stat field in vertex. - NS_DEBUG("SPFCalculate: Popping vertex" << v->m_vertexId); +// +// The operations we need to do are given in the OSPF RFC which we reference +// as we go along. +// +// RFC2328 16.1. (2). +// +// We examine the Static Router Link Records in the Link State +// Advertisements of the current vertex. If there are any point-to-point +// links to unexplored adjacent vertices we add them to the tree and update +// the distance and next hop information on how to get there. We also add +// the new vertices to the candidate queue (the priority queue ordered by +// shortest path). If the new vertices represent shorter paths, we use them +// and update the path cost. +// + SPFNext (v, candidate); +// +// RFC2328 16.1. (3). +// +// If at this step the candidate list is empty, the shortest-path tree (of +// transit vertices) has been completely built and this stage of the +// procedure terminates. +// + if (candidate.Size () == 0) + { + break; + } +// +// Choose the vertex belonging to the candidate list that is closest to the +// root, and add it to the shortest-path tree (removing it from the candidate +// list in the process). +// +// Recall that in the previous step, we created SPFVertex structures for each +// of the routers found in the Static Router Link Records and added tehm to +// the candidate list. +// + v = candidate.Pop (); + NS_DEBUG ("SPFCalculate: Popped vertex" << v->m_vertexId); +// +// Update the status field of the vertex to indicate that it is in the SPF +// tree. +// v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; - SPFVertexAddParent(v); - // Note that when there is a choice of vertices closest to the - // root, network vertices must be chosen before router vertices - // in order to necessarily find all equal-cost paths. - // We don't do this at this moment, we should add the treatment - // above codes. -- kunihiro. - - // RFC2328 16.1. (4). +// +// 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 +// children of that parent vertex. In the next hop calculation called during +// SPFNext, the parent pointer was set but the vertex has been orphaned up +// to now. +// + SPFVertexAddParent (v); +// +// Note that when there is a choice of vertices closest to the root, network +// vertices must be chosen before router vertices in order to necessarily +// find all equal-cost paths. We don't do this at this moment, we should add +// the treatment above codes. -- kunihiro. +// +// +// RFC2328 16.1. (4). +// +// This is the method that actually adds the routes. It'll walk the list +// of nodes in the system, looking for the node corresponding to the router +// ID of the root of the tree -- that is the router we're building the routes +// for. It looks for the Ipv4 interface of that node and remembers it. So +// we are always adding routes to that one node at the root of the SPF tree. +// +// We have a pointer to a vertex in the SPF tree. For each of the +// point-to-point Static Router Link Records of that vertex, we add a route +// using the existing next hop and outbound interface information we have +// already calculated. +// SPFIntraAddRouter (v); - - // RFC2328 16.1. (5). - // Iterate the algorithm by returning to Step 2. - } // end loop until no more candidate vertices - - // Second stage of SPF calculation procedure's - // NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); - +// +// RFC2328 16.1. (5). +// +// Iterate the algorithm by returning to Step 2 until there are no more +// candidate vertices. +// + } +// +// Second stage of SPF calculation procedure's +// NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); +// delete m_spfroot; m_spfroot = 0; } // XXX this should probably be a method on Ipv4 uint32_t -StaticRouteManager::FindOutgoingInterfaceId(Ipv4Address a) +StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) { Ipv4Address routerId = m_spfroot->m_vertexId; - std::vector >::iterator i = NodeList::Begin(); - for (; i != NodeList::End(); i++) + std::vector >::iterator i = NodeList::Begin (); + for (; i != NodeList::End (); i++) { Ptr node = *i; Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG(rtr, + NS_ASSERT_MSG (rtr, "StaticRouteManager::FindOutgoingInterfaceId (): " "QI for interface failed"); if (rtr->GetRouterId () == routerId) { Ptr ipv4 = node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4, + NS_ASSERT_MSG (ipv4, "StaticRouteManager::FindOutgoingInterfaceId (): " "QI for interface failed"); - for (uint32_t i = 0; i < ipv4->GetNInterfaces(); i++) + for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++) { if (ipv4->GetAddress (i) == a) { - NS_DEBUG("FindOutgoingInterfaceId: Interface match for " << a); + NS_DEBUG ("FindOutgoingInterfaceId: Interface match for " << a); return i; } } @@ -664,11 +795,11 @@ StaticRouteManager::FindOutgoingInterfaceId(Ipv4Address a) return 0; } -// derived from quagga ospf_intra_add_router() +// derived from quagga ospf_intra_add_router () // // This is where we add host routes to the routing tables void -StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) +StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) { // This vertex has just been added to the SPF tree // - the vertex should have a valid m_root_oid corresponding @@ -679,42 +810,42 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) // is a destination IP address to which we add a host route // - NS_ASSERT_MSG(m_spfroot, + NS_ASSERT_MSG (m_spfroot, "StaticRouteManager::SPFIntraAddRouter (): Root pointer not set"); Ipv4Address routerId = m_spfroot->m_vertexId; - std::vector >::iterator i = NodeList::Begin(); - for (; i != NodeList::End(); i++) + std::vector >::iterator i = NodeList::Begin (); + for (; i != NodeList::End (); i++) { Ptr node = *i; Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG(rtr, + NS_ASSERT_MSG (rtr, "StaticRouteManager::SPFIntraAddRouter (): " "QI for interface failed"); if (rtr->GetRouterId () == routerId) { - NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " + NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " "setting routes for node " << node->GetId ()); Ptr ipv4 = node->QueryInterface (Ipv4::iid); - NS_ASSERT_MSG(ipv4, + NS_ASSERT_MSG (ipv4, "StaticRouteManager::SPFIntraAddRouter (): " "QI for interface failed"); StaticRouterLSA *lsa = v->m_lsa; - NS_ASSERT_MSG(lsa, + NS_ASSERT_MSG (lsa, "StaticRouteManager::SPFIntraAddRouter (): " "Expected valid LSA in SPFVertex* v"); uint32_t nLinkRecords = lsa->GetNLinkRecords (); - NS_ASSERT_MSG((nLinkRecords & 1) == 0, + NS_ASSERT_MSG ((nLinkRecords & 1) == 0, "StaticRouteManager::SPFIntraAddRouter (): " - "Expected exen number of Link Records"); + "Expected even number of Link Records"); for (uint32_t j = 0; j < nLinkRecords; j += 2) { @@ -724,25 +855,25 @@ StaticRouteManager::SPFIntraAddRouter(SPFVertex* v) continue; } - NS_DEBUG("StaticRouteManager::SPFIntraAddRouter (): " + NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " "Add route to " << lr->m_linkData << " using next hop " << v->m_nextHop << " via interface " << v->m_rootOif); - ipv4->AddHostRouteTo(lr->m_linkData, v->m_nextHop, + ipv4->AddHostRouteTo (lr->m_linkData, v->m_nextHop, v->m_rootOif); } } } } -// Derived from quagga ospf_vertex_add_parents() +// Derived from quagga ospf_vertex_add_parents () // Add a vertex to the list of children in each of its parents. void -StaticRouteManager::SPFVertexAddParent(SPFVertex* v) +StaticRouteManager::SPFVertexAddParent (SPFVertex* v) { // For now, only one parent (not doing equal-cost multipath) - v->m_parent->m_children.push_back(v); + v->m_parent->m_children.push_back (v); } } // namespace ns3 @@ -756,7 +887,7 @@ namespace ns3 { class StaticRouterTestNode : public Node { public: - StaticRouterTestNode(); + StaticRouterTestNode (); private: virtual void DoAddDevice (Ptr device) const {}; @@ -834,111 +965,111 @@ StaticRouteManagerTest::RunTests (void) // link2: 10.1.3.1/30, 10.1.3.2/30 // // Router 0 - StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord(); - lr0->m_linkId.Set(2); // router ID 0.0.0.2 - lr0->m_linkData.Set("10.1.1.1"); + StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord (); + lr0->m_linkId.Set (2); // router ID 0.0.0.2 + lr0->m_linkData.Set ("10.1.1.1"); lr0->m_linkType = StaticRouterLinkRecord::PointToPoint; lr0->m_metric = 1; - StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord(); - lr1->m_linkId.Set("10.1.1.1"); - lr1->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord (); + lr1->m_linkId.Set ("10.1.1.1"); + lr1->m_linkData.Set ("255.255.255.252"); lr1->m_linkType = StaticRouterLinkRecord::StubNetwork; lr1->m_metric = 1; - StaticRouterLSA* lsa0 = new StaticRouterLSA(); - lsa0->m_linkStateId.Set("0.0.0.0"); - lsa0->m_advertisingRtr.Set("0.0.0.0"); - lsa0->AddLinkRecord(lr0); - lsa0->AddLinkRecord(lr1); + StaticRouterLSA* lsa0 = new StaticRouterLSA (); + lsa0->m_linkStateId.Set ("0.0.0.0"); + lsa0->m_advertisingRtr.Set ("0.0.0.0"); + lsa0->AddLinkRecord (lr0); + lsa0->AddLinkRecord (lr1); // Router 1 - StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord(); - lr2->m_linkId.Set(2); // router ID 0.0.0.2 - lr2->m_linkData.Set("10.1.2.1"); + StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord (); + lr2->m_linkId.Set (2); // router ID 0.0.0.2 + lr2->m_linkData.Set ("10.1.2.1"); lr2->m_linkType = StaticRouterLinkRecord::PointToPoint; lr2->m_metric = 1; - StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord(); - lr3->m_linkId.Set("10.1.2.1"); - lr3->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord (); + lr3->m_linkId.Set ("10.1.2.1"); + lr3->m_linkData.Set ("255.255.255.252"); lr3->m_linkType = StaticRouterLinkRecord::StubNetwork; lr3->m_metric = 1; - StaticRouterLSA* lsa1 = new StaticRouterLSA(); - lsa1->m_linkStateId.Set(1); - lsa1->m_advertisingRtr.Set(1); - lsa1->AddLinkRecord(lr2); - lsa1->AddLinkRecord(lr3); + StaticRouterLSA* lsa1 = new StaticRouterLSA (); + lsa1->m_linkStateId.Set (1); + lsa1->m_advertisingRtr.Set (1); + lsa1->AddLinkRecord (lr2); + lsa1->AddLinkRecord (lr3); // Router 2 - StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord(); - lr4->m_linkId.Set("0.0.0.0"); - lr4->m_linkData.Set("10.1.1.2"); + StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord (); + lr4->m_linkId.Set ("0.0.0.0"); + lr4->m_linkData.Set ("10.1.1.2"); lr4->m_linkType = StaticRouterLinkRecord::PointToPoint; lr4->m_metric = 1; - StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord(); - lr5->m_linkId.Set("10.1.1.2"); - lr5->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord (); + lr5->m_linkId.Set ("10.1.1.2"); + lr5->m_linkData.Set ("255.255.255.252"); lr5->m_linkType = StaticRouterLinkRecord::StubNetwork; lr5->m_metric = 1; - StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord(); - lr6->m_linkId.Set(1); - lr6->m_linkData.Set("10.1.2.2"); + StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord (); + lr6->m_linkId.Set (1); + lr6->m_linkData.Set ("10.1.2.2"); lr6->m_linkType = StaticRouterLinkRecord::PointToPoint; lr6->m_metric = 1; - StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord(); - lr7->m_linkId.Set("10.1.2.2"); - lr7->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord (); + lr7->m_linkId.Set ("10.1.2.2"); + lr7->m_linkData.Set ("255.255.255.252"); lr7->m_linkType = StaticRouterLinkRecord::StubNetwork; lr7->m_metric = 1; - StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord(); - lr8->m_linkId.Set(3); - lr8->m_linkData.Set("10.1.3.2"); + StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord (); + lr8->m_linkId.Set (3); + lr8->m_linkData.Set ("10.1.3.2"); lr8->m_linkType = StaticRouterLinkRecord::PointToPoint; lr8->m_metric = 1; - StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord(); - lr9->m_linkId.Set("10.1.3.2"); - lr9->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord (); + lr9->m_linkId.Set ("10.1.3.2"); + lr9->m_linkData.Set ("255.255.255.252"); lr9->m_linkType = StaticRouterLinkRecord::StubNetwork; lr9->m_metric = 1; - StaticRouterLSA* lsa2 = new StaticRouterLSA(); - lsa2->m_linkStateId.Set(2); - lsa2->m_advertisingRtr.Set(2); - lsa2->AddLinkRecord(lr4); - lsa2->AddLinkRecord(lr5); - lsa2->AddLinkRecord(lr6); - lsa2->AddLinkRecord(lr7); - lsa2->AddLinkRecord(lr8); - lsa2->AddLinkRecord(lr9); + StaticRouterLSA* lsa2 = new StaticRouterLSA (); + lsa2->m_linkStateId.Set (2); + lsa2->m_advertisingRtr.Set (2); + lsa2->AddLinkRecord (lr4); + lsa2->AddLinkRecord (lr5); + lsa2->AddLinkRecord (lr6); + lsa2->AddLinkRecord (lr7); + lsa2->AddLinkRecord (lr8); + lsa2->AddLinkRecord (lr9); // Router 3 - StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord(); - lr10->m_linkId.Set(2); // router ID 0.0.0.2 - lr10->m_linkData.Set("10.1.2.1"); + StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord (); + lr10->m_linkId.Set (2); // router ID 0.0.0.2 + lr10->m_linkData.Set ("10.1.2.1"); lr10->m_linkType = StaticRouterLinkRecord::PointToPoint; lr10->m_metric = 1; - StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord(); - lr11->m_linkId.Set("10.1.2.1"); - lr11->m_linkData.Set("255.255.255.252"); + StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord (); + lr11->m_linkId.Set ("10.1.2.1"); + lr11->m_linkData.Set ("255.255.255.252"); lr11->m_linkType = StaticRouterLinkRecord::StubNetwork; lr11->m_metric = 1; - StaticRouterLSA* lsa3 = new StaticRouterLSA(); - lsa3->m_linkStateId.Set(3); - lsa3->m_advertisingRtr.Set(3); - lsa3->AddLinkRecord(lr2); - lsa3->AddLinkRecord(lr3); + StaticRouterLSA* lsa3 = new StaticRouterLSA (); + lsa3->m_linkStateId.Set (3); + lsa3->m_advertisingRtr.Set (3); + lsa3->AddLinkRecord (lr2); + lsa3->AddLinkRecord (lr3); // Test the database - StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB(); - srmlsdb->Insert(lsa0->m_linkStateId, lsa0); - srmlsdb->Insert(lsa1->m_linkStateId, lsa1); - srmlsdb->Insert(lsa2->m_linkStateId, lsa2); - srmlsdb->Insert(lsa3->m_linkStateId, lsa3); - NS_ASSERT(lsa2 == srmlsdb->GetLSA(lsa2->m_linkStateId)); + StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB (); + srmlsdb->Insert (lsa0->m_linkStateId, lsa0); + srmlsdb->Insert (lsa1->m_linkStateId, lsa1); + srmlsdb->Insert (lsa2->m_linkStateId, lsa2); + srmlsdb->Insert (lsa3->m_linkStateId, lsa3); + NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->m_linkStateId)); // XXX next, calculate routes based on the manually created LSDB - StaticRouteManager* srm = new StaticRouteManager(); + StaticRouteManager* srm = new StaticRouteManager (); srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB // Note-- this will succeed without any nodes in the topology // because the NodeList is empty - srm->DebugSPFCalculate(lsa0->m_linkStateId); // node n0 + srm->DebugSPFCalculate (lsa0->m_linkStateId); // node n0 // This delete clears the srm, which deletes the LSDB, which clears // all of the LSAs, which each destroys the attached LinkRecords. From 76223227ba572b5f2d142259be2e385467776491 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 17 Jul 2007 11:02:14 +0100 Subject: [PATCH 68/92] Allow compiling the 'routing' module and example with WAF --- examples/wscript | 1 + src/internet-node/wscript | 2 +- src/routing/wscript | 25 +++++++++++++++++++++++++ src/wscript | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/routing/wscript diff --git a/examples/wscript b/examples/wscript index f535ea93f..6e8fea84d 100644 --- a/examples/wscript +++ b/examples/wscript @@ -10,4 +10,5 @@ def build(bld): return obj obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node']) + obj = create_ns_prog('simple-static-routing', 'simple-static-routing.cc', deps=['p2p', 'internet-node', 'routing']) diff --git a/src/internet-node/wscript b/src/internet-node/wscript index 806861fd3..ef922b3b1 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -9,7 +9,7 @@ def build(bld): obj = bld.create_obj('cpp', 'shlib') obj.name = 'ns3-internet-node' obj.target = obj.name - obj.uselib_local = ['ns3-node', 'ns3-applications'] + obj.uselib_local = ['ns3-node', 'ns3-applications', 'ns3-routing'] obj.source = [ 'internet-node.cc', 'l3-demux.cc', diff --git a/src/routing/wscript b/src/routing/wscript new file mode 100644 index 000000000..79f8c2b21 --- /dev/null +++ b/src/routing/wscript @@ -0,0 +1,25 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def configure(conf): + conf.env.append_value('NS3_MODULES', 'ns3-routing') + + +def build(bld): + module = bld.create_obj('cpp', 'shlib') + module.name = 'ns3-routing' + module.target = module.name + module.uselib_local = ['ns3-node'] + module.source = [ + 'routing-environment.cc', + 'static-router.cc', + 'static-route-manager.cc', + 'candidate-queue.cc', + ] + + headers = bld.create_obj('ns3header') + headers.source = [ + 'routing-environment.h', + 'static-router.h', + 'static-route-manager.h', + 'candidate-queue.h', + ] diff --git a/src/wscript b/src/wscript index 2e2349f10..33032283b 100644 --- a/src/wscript +++ b/src/wscript @@ -17,6 +17,7 @@ all_modules = [ 'internet-node', 'devices/p2p', 'applications', + 'routing', ] From f8616ba0b506fe41a0b0bf965f83e958d2e99527 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 17 Jul 2007 22:20:48 -0700 Subject: [PATCH 69/92] routing documentation --- src/routing/static-route-manager.cc | 220 ++++++++++++++++++++++------ 1 file changed, 172 insertions(+), 48 deletions(-) diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 508f53831..e6142fa03 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -489,6 +489,10 @@ StaticRouteManager::SPFNexthopCalculation ( // IP address of the router to which is adjacent. This is a distinguished // address -- the next hop address to get from to and all networks // accessed through that path. +// +// SPFGetNextLink () is a little odd. used in this way it is just going to +// return the link record describing the link from to . Think of it as +// SPFGetLink. // StaticRouterLinkRecord *linkRemote = 0; linkRemote = SPFGetNextLink (w, v, linkRemote); @@ -500,8 +504,8 @@ StaticRouteManager::SPFNexthopCalculation ( // address from the m_linkData member variable. // // The next hop member variable we put in has the sense "in order to get -// to the network represented by vertex , you have to send the packet to -// the next hop address specified in w->nextHop. +// from the root node to the host represented by vertex , you have to send +// the packet to the next hop address specified in w->m_nextHop. // w->m_nextHop = linkRemote->m_linkData; // @@ -632,8 +636,9 @@ StaticRouteManager::SPFGetNextLink ( return 0; } - -// quagga ospf_spf_calculate +// +// Used for unit tests. +// void StaticRouteManager::DebugSPFCalculate (Ipv4Address root) { @@ -644,7 +649,8 @@ StaticRouteManager::DebugSPFCalculate (Ipv4Address root) void StaticRouteManager::SPFCalculate (Ipv4Address root) { - NS_DEBUG ("StaticRouteManager::SPFCalculate ()"); + NS_DEBUG ("StaticRouteManager::SPFCalculate (): " + "root = " << root); SPFVertex *v; // @@ -710,7 +716,7 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // the candidate list. // v = candidate.Pop (); - NS_DEBUG ("SPFCalculate: Popped vertex" << v->m_vertexId); + NS_DEBUG ("SPFCalculate: Popped vertex " << v->m_vertexId); // // Update the status field of the vertex to indicate that it is in the SPF // tree. @@ -730,19 +736,28 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // find all equal-cost paths. We don't do this at this moment, we should add // the treatment above codes. -- kunihiro. // -// // RFC2328 16.1. (4). // // This is the method that actually adds the routes. It'll walk the list // of nodes in the system, looking for the node corresponding to the router // ID of the root of the tree -- that is the router we're building the routes // for. It looks for the Ipv4 interface of that node and remembers it. So -// we are always adding routes to that one node at the root of the SPF tree. +// we are only actually adding routes to that one node at the root of the SPF +// tree. // -// We have a pointer to a vertex in the SPF tree. For each of the -// point-to-point Static Router Link Records of that vertex, we add a route -// using the existing next hop and outbound interface information we have -// already calculated. +// We're going to pop of a pointer to every vertex in the tree except the +// root in order of distance from the root. For each of the vertices, we call +// SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the +// point-to-point Static Router Link Records (the links to nodes adjacent to +// the node represented by the vertex). We add a link to the IP address +// specified by the m_linkData field of each of those link records. This will +// be the *local* IP address associated with the interface attached to the +// link. We use the outbound interface and next hop information present in +// the vertex . +// +// To summarize, we're going to look at the node represented by and loop +// 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); // @@ -755,18 +770,37 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // // Second stage of SPF calculation procedure's // NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); +// +// We're all done setting the routing information for the node at the root of +// the SPF tree. Delete all of the vertices and corresponding resources. Go +// possibly do it again for the next router. // delete m_spfroot; m_spfroot = 0; } +// // XXX this should probably be a method on Ipv4 +// +// Return the interface index corresponding to a given IP address +// uint32_t StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) { - +// +// 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->m_vertexId; - +// +// 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++) { @@ -774,81 +808,147 @@ StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG (rtr, - "StaticRouteManager::FindOutgoingInterfaceId (): " - "QI for interface failed"); +// +// If the node doesn't have a StaticRouter 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, "StaticRouteManager::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) == a) { - NS_DEBUG ("FindOutgoingInterfaceId: Interface match for " << a); - return i; - } + if (ipv4->GetAddress (i) == a) + { + NS_DEBUG ("StaticRouteManager::FindOutgoingInterfaceId (): " + "Interface match for " << a); + return i; + } } } - } + } +// +// Couldn't find it. +// return 0; } -// derived from quagga ospf_intra_add_router () // -// This is where we add host routes to the routing tables +// 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 +// tables of the individual nodes. +// +// The vertex passed as a parameter has just been added to the SPF tree. +// This vertex must have a valid m_root_oid, corresponding to the outgoing +// interface on the root router of the tree that is the first hop on the path +// to the vertex. The vertex must also have a next hop address, corresponding +// to the next hop on the path to the vertex. The vertex has an m_lsa field +// that has some number of link records. For each point to point link record, +// the m_linkData is the local IP address of the link. This corresponds to +// a destination IP address, reachable from the root, to which we add a host +// route. +// void StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) { - // This vertex has just been added to the SPF tree - // - the vertex should have a valid m_root_oid corresponding - // to the outgoing interface on the root router of the tree - // that corresponds to the path to it - // - the vertex has an m_lsa field that has a number of link - // records. For each point to point record, the m_linkData - // is a destination IP address to which we add a host route - // + NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter ()"); NS_ASSERT_MSG (m_spfroot, "StaticRouteManager::SPFIntraAddRouter (): 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->m_vertexId; + NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter ():" + "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 StaticRouter interface, so we need +// to QI for that interface. If there's no StaticRouter interface, the node +// in question cannot be the router we want, so we continue. +// Ptr rtr = node->QueryInterface (StaticRouter::iid); - NS_ASSERT_MSG (rtr, - "StaticRouteManager::SPFIntraAddRouter (): " - "QI for interface failed"); + if (rtr == 0) + { + 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. +// if (rtr->GetRouterId () == routerId) { NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " "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, "StaticRouteManager::SPFIntraAddRouter (): " "QI for interface failed"); - +// +// Get the Static Router Link State Advertisement from the vertex we're +// adding the routes to. The LSA will have a number of attached Static 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. +// StaticRouterLSA *lsa = v->m_lsa; NS_ASSERT_MSG (lsa, "StaticRouteManager::SPFIntraAddRouter (): " "Expected valid LSA in SPFVertex* v"); uint32_t nLinkRecords = lsa->GetNLinkRecords (); - - NS_ASSERT_MSG ((nLinkRecords & 1) == 0, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected even number of Link Records"); - +// +// Iterate through the link records on the vertex to which we're going to add +// routes. To make sure we're being clear, we're going to add routing table +// entries to the tables on the node corresping to the root of the SPF tree. +// These entries will have routes to the IP addresses we find from looking at +// the local side of the point-to-point links found on the node described by +// the vertex . +// for (uint32_t j = 0; j < nLinkRecords; j += 2) { +// +// We are only concerned about point-to-point links +// StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); if (lr->m_linkType != StaticRouterLinkRecord::PointToPoint) { @@ -856,19 +956,44 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) } NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " - "Add route to " << lr->m_linkData << + " Node " << node->GetId () << + " add route to " << lr->m_linkData << " using next hop " << v->m_nextHop << " via interface " << v->m_rootOif); - +// +// Here's why we did all of that work. We're going to add a host route to the +// host address found in the m_linkData field of the point-to-point link +// record. In the case of a point-to-point link, this is the local IP address +// of the node connected to the link. Each of these point-to-point links +// will correspond to a local interface that has an IP address to which +// the node at the root of the SPF tree can send packets. The vertex +// (corresponding to the node that has these links and interfaces) has +// an m_nextHop address precalculated for us that is the address to which the +// root node should send packets to be forwarded to these IP addresses. +// Similarly, the vertex has an m_rootOif (outbound interface index) to +// which the packets should be send for forwarding. +// ipv4->AddHostRouteTo (lr->m_linkData, v->m_nextHop, v->m_rootOif); } } +// +// We've found the node and added the routes. Don't need to search forward +// for another node we'll never find. +// + return; } } // Derived from quagga ospf_vertex_add_parents () -// Add a vertex to the list of children in each of its parents. +// +// This is a somewhat oddly named method (blame quagga). Although you might +// expect it to add a parent *to* something, it actually adds a vertex +// to the list of children *in* each of its parents. +// +// Given a pointer to a vertex, it links back to the vertex's parent that it +// already has set and adds itself to that vertex's list of children. +// void StaticRouteManager::SPFVertexAddParent (SPFVertex* v) { @@ -905,7 +1030,6 @@ StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) return 0; } - class StaticRouteManagerTest : public Test { public: StaticRouteManagerTest (); From 0921355a74d64ff5ce071ee4dc9f994c593227ca Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jul 2007 14:35:06 -0700 Subject: [PATCH 70/92] General cleanup -- const correctness, encapsulation, documentation, etc. --- src/routing/candidate-queue.cc | 10 +- src/routing/candidate-queue.h | 8 +- src/routing/static-route-manager.cc | 241 ++++++++------- src/routing/static-router.cc | 208 ++++++++++--- src/routing/static-router.h | 459 ++++++++++++++++++++-------- 5 files changed, 637 insertions(+), 289 deletions(-) diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc index b45af7ac2..d34e49855 100644 --- a/src/routing/candidate-queue.cc +++ b/src/routing/candidate-queue.cc @@ -81,7 +81,7 @@ CandidateQueue::Pop (void) } SPFVertex * -CandidateQueue::Top (void) +CandidateQueue::Top (void) const { NS_DEBUG("CandidateQueue::Top ()"); @@ -94,7 +94,7 @@ CandidateQueue::Top (void) } bool -CandidateQueue::Empty (void) +CandidateQueue::Empty (void) const { NS_DEBUG("CandidateQueue::Empty ()"); @@ -102,7 +102,7 @@ CandidateQueue::Empty (void) } uint32_t -CandidateQueue::Size (void) +CandidateQueue::Size (void) const { NS_DEBUG("CandidateQueue::Size ()"); @@ -110,11 +110,11 @@ CandidateQueue::Size (void) } SPFVertex * -CandidateQueue::Find (const Ipv4Address addr) +CandidateQueue::Find (const Ipv4Address addr) const { NS_DEBUG("CandidateQueue::Find ()"); - CandidateList_t::iterator i = m_candidates.begin (); + CandidateList_t::const_iterator i = m_candidates.begin (); for (; i != m_candidates.end (); i++) { diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index 146de707c..e9c985287 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -95,13 +95,13 @@ public: * @see Pop () * @returns The Shortest Path First Vertex pointer at the top of the queue. */ - SPFVertex* Top (void); + SPFVertex* Top (void) const; /** * Test the Candidate Queue to determine if it is empty. * * @returns True if the queue is empty, false otherwise. */ - bool Empty (void); + bool Empty (void) const; /** * Return the number of Shortest Path First Vertex pointers presently * stored in the Candidate Queue. @@ -109,7 +109,7 @@ public: * @see SPFVertex * @returns The number of SPFVertex* pointers in the Candidate Queue. */ - uint32_t Size (void); + uint32_t Size (void) const; /** * Searches the Candidate Queue for a Shortest Path First Vertex pointer * that points to a vertex having the given IP address. @@ -118,7 +118,7 @@ public: * @param addr The IP address to search for. * @returns The SPFVertex* pointer corresponding to the given IP address. */ - SPFVertex* Find (const Ipv4Address addr); + SPFVertex* Find (const Ipv4Address addr) const; /** * Reorders the Candidate Queue according to the priority scheme. On * completion, the top of the queue will hold the Shortest Path First diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index e6142fa03..5e4aece04 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -44,7 +44,7 @@ SPFVertex::SPFVertex () : SPFVertex::SPFVertex (StaticRouterLSA* lsa) : m_vertexType (VertexRouter), - m_vertexId (lsa->m_linkStateId), + m_vertexId (lsa->GetLinkStateId ()), m_lsa (lsa), m_parent (0), m_children (), @@ -92,7 +92,7 @@ StaticRouteManagerLSDB::Initialize () for (i= m_database.begin (); i!= m_database.end (); i++) { StaticRouterLSA* temp = i->second; - temp->m_stat = StaticRouterLSA::LSA_SPF_NOT_EXPLORED; + temp->SetStatus (StaticRouterLSA::LSA_SPF_NOT_EXPLORED); } } @@ -196,7 +196,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () // // Write the newly discovered link state advertisement to the database. // - m_lsdb->Insert (lsa->m_linkStateId, lsa); + m_lsdb->Insert (lsa->GetLinkStateId (), lsa); } } } @@ -291,26 +291,23 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) if (true) { NS_DEBUG ("SPFNext: Examining " << v->m_vertexId << "'s " << - v->m_lsa->m_linkRecords.size () << " link records"); + v->m_lsa->GetNLinkRecords () << " link records"); // // Walk the list of link records in the link state advertisement associated // with the "current" router (represented by vertex ). // - for (StaticRouterLSA::ListOfLinkRecords_t::iterator i = - v->m_lsa->m_linkRecords.begin (); - i != v->m_lsa->m_linkRecords.end (); - i++) + for (uint32_t i = 0; i < v->m_lsa->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. // - StaticRouterLinkRecord* l = *i; - if (l->m_linkType == StaticRouterLinkRecord::StubNetwork) + StaticRouterLinkRecord *l = v->m_lsa->GetLinkRecord (i); + if (l->GetLinkType () == StaticRouterLinkRecord::StubNetwork) { - NS_DEBUG ("SPFNext: Found a Stub record to " - << l->m_linkId); + NS_DEBUG ("SPFNext: Found a Stub record to " << + l->GetLinkId ()); continue; } // @@ -318,16 +315,16 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // the vertex W's LSA (router-LSA or network-LSA) in Area A's link state // database. // - if (l->m_linkType == StaticRouterLinkRecord::PointToPoint) + if (l->GetLinkType () == StaticRouterLinkRecord::PointToPoint) { // // Lookup the link state advertisement of the new link -- we call it in // the link state database. // - w_lsa = m_lsdb->GetLSA (l->m_linkId); + w_lsa = m_lsdb->GetLSA (l->GetLinkId ()); NS_ASSERT (w_lsa); NS_DEBUG ("SPFNext: Found a P2P record from " << - v->m_vertexId << " to " << w_lsa->m_linkStateId); + v->m_vertexId << " to " << w_lsa->GetLinkStateId ()); // // (c) If vertex W is already on the shortest-path tree, examine the next // link in the LSA. @@ -335,10 +332,11 @@ StaticRouteManager::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->m_stat == StaticRouterLSA::LSA_SPF_IN_SPFTREE) + if (w_lsa->GetStatus () == + StaticRouterLSA::LSA_SPF_IN_SPFTREE) { NS_DEBUG ("SPFNext: Skipping-> LSA "<< - w_lsa->m_linkStateId << " already in SPF tree"); + w_lsa->GetLinkStateId () << " already in SPF tree"); continue; } // @@ -349,12 +347,13 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // calculated) shortest path to vertex V and the advertised cost of the link // between vertices V and W. // - distance = v->m_distanceFromRoot + l->m_metric; + distance = v->m_distanceFromRoot + l->GetMetric (); NS_DEBUG ("SPFNext: Considering w_lsa " << - w_lsa->m_linkStateId); + w_lsa->GetLinkStateId ()); - if (w_lsa->m_stat == StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + if (w_lsa->GetStatus () == + StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { // // If we havent yet considered the link represented by we have to create @@ -369,7 +368,8 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // if (SPFNexthopCalculation (v, w, l, distance)) { - w_lsa->m_stat = StaticRouterLSA::LSA_SPF_CANDIDATE; + w_lsa->SetStatus ( + StaticRouterLSA::LSA_SPF_CANDIDATE); // // Push this new vertex onto the priority queue (ordered by distance from the // root node). @@ -379,8 +379,8 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) << ", parent vertexId: " << v->m_vertexId); } } - } else if (w_lsa->m_stat == - StaticRouterLSA::LSA_SPF_CANDIDATE) + } else if (w_lsa->GetStatus () == + StaticRouterLSA::LSA_SPF_CANDIDATE) { // // We have already considered the link represented by . What wse have to @@ -389,7 +389,7 @@ StaticRouteManager::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->m_linkStateId); + w = candidate.Find (w_lsa->GetLinkStateId ()); if (w->m_distanceFromRoot < distance) { // @@ -507,13 +507,13 @@ StaticRouteManager::SPFNexthopCalculation ( // from the root node to the host represented by vertex , you have to send // the packet to the next hop address specified in w->m_nextHop. // - w->m_nextHop = linkRemote->m_linkData; + w->m_nextHop = linkRemote->GetLinkData (); // // Now find the outgoing interface corresponding to the point to point link // from the perspective of -- remember that is the link "from" // "to" . // - w->m_rootOif = FindOutgoingInterfaceId (l->m_linkData); + w->m_rootOif = FindOutgoingInterfaceId (l->GetLinkData ()); NS_DEBUG ("SPFNexthopCalculation: Next hop from " << v->m_vertexId << " to " << w->m_vertexId << @@ -587,13 +587,10 @@ StaticRouteManager::SPFGetNextLink ( // looking for records representing the point-to-point links off of this // vertex. // - for ( StaticRouterLSA::ListOfLinkRecords_t::iterator i = - v->m_lsa->m_linkRecords.begin (); - i != v->m_lsa->m_linkRecords.end (); - i++ ) + for (uint32_t i = 0; i < v->m_lsa->GetNLinkRecords (); ++i) { - l = *i; - if (l->m_linkType != StaticRouterLinkRecord::PointToPoint) + l = v->m_lsa->GetLinkRecord (i); + if (l->GetLinkType () != StaticRouterLinkRecord::PointToPoint) { continue; } @@ -605,9 +602,9 @@ StaticRouteManager::SPFGetNextLink ( // We're just checking to see if the link is actually the link from to // . // - if (l->m_linkId == w->m_vertexId) { - NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId=" << - l->m_linkId << " linkData=" << l->m_linkData); + if (l->GetLinkId () == w->m_vertexId) { + 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 // the one we're interested in. That's either because we didn't pass in a @@ -676,7 +673,7 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // m_spfroot= v; v->m_distanceFromRoot = 0; - v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; + v->m_lsa->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); for (;;) { @@ -721,7 +718,7 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // Update the status field of the vertex to indicate that it is in the SPF // tree. // - v->m_lsa->m_stat = StaticRouterLSA::LSA_SPF_IN_SPFTREE; + v->m_lsa->SetStatus (StaticRouterLSA::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 @@ -950,14 +947,14 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) // We are only concerned about point-to-point links // StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); - if (lr->m_linkType != StaticRouterLinkRecord::PointToPoint) + if (lr->GetLinkType () != StaticRouterLinkRecord::PointToPoint) { continue; } NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " " Node " << node->GetId () << - " add route to " << lr->m_linkData << + " add route to " << lr->GetLinkData () << " using next hop " << v->m_nextHop << " via interface " << v->m_rootOif); // @@ -973,7 +970,7 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) // Similarly, the vertex has an m_rootOif (outbound interface index) to // which the packets should be send for forwarding. // - ipv4->AddHostRouteTo (lr->m_linkData, v->m_nextHop, + ipv4->AddHostRouteTo (lr->GetLinkData (), v->m_nextHop, v->m_rootOif); } } @@ -1089,73 +1086,83 @@ StaticRouteManagerTest::RunTests (void) // link2: 10.1.3.1/30, 10.1.3.2/30 // // Router 0 - StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord (); - lr0->m_linkId.Set (2); // router ID 0.0.0.2 - lr0->m_linkData.Set ("10.1.1.1"); - lr0->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr0->m_metric = 1; - StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord (); - lr1->m_linkId.Set ("10.1.1.1"); - lr1->m_linkData.Set ("255.255.255.252"); - lr1->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr1->m_metric = 1; + StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", // router ID 0.0.0.2 + "10.1.1.1", // local ID + 1); // metric + + StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.1.1", + "255.255.255.252", + 1); + StaticRouterLSA* lsa0 = new StaticRouterLSA (); - lsa0->m_linkStateId.Set ("0.0.0.0"); - lsa0->m_advertisingRtr.Set ("0.0.0.0"); + lsa0->SetLinkStateId ("0.0.0.0"); + lsa0->SetAdvertisingRouter ("0.0.0.0"); lsa0->AddLinkRecord (lr0); lsa0->AddLinkRecord (lr1); // Router 1 - StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord (); - lr2->m_linkId.Set (2); // router ID 0.0.0.2 - lr2->m_linkData.Set ("10.1.2.1"); - lr2->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr2->m_metric = 1; - StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord (); - lr3->m_linkId.Set ("10.1.2.1"); - lr3->m_linkData.Set ("255.255.255.252"); - lr3->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr3->m_metric = 1; + StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + + StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + StaticRouterLSA* lsa1 = new StaticRouterLSA (); - lsa1->m_linkStateId.Set (1); - lsa1->m_advertisingRtr.Set (1); + lsa1->SetLinkStateId ("0.0.0.1"); + lsa1->SetAdvertisingRouter ("0.0.0.1"); lsa1->AddLinkRecord (lr2); lsa1->AddLinkRecord (lr3); // Router 2 - StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord (); - lr4->m_linkId.Set ("0.0.0.0"); - lr4->m_linkData.Set ("10.1.1.2"); - lr4->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr4->m_metric = 1; - StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord (); - lr5->m_linkId.Set ("10.1.1.2"); - lr5->m_linkData.Set ("255.255.255.252"); - lr5->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr5->m_metric = 1; - StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord (); - lr6->m_linkId.Set (1); - lr6->m_linkData.Set ("10.1.2.2"); - lr6->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr6->m_metric = 1; - StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord (); - lr7->m_linkId.Set ("10.1.2.2"); - lr7->m_linkData.Set ("255.255.255.252"); - lr7->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr7->m_metric = 1; - StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord (); - lr8->m_linkId.Set (3); - lr8->m_linkData.Set ("10.1.3.2"); - lr8->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr8->m_metric = 1; - StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord (); - lr9->m_linkId.Set ("10.1.3.2"); - lr9->m_linkData.Set ("255.255.255.252"); - lr9->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr9->m_metric = 1; + StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.0", + "10.1.1.2", + 1); + + StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.1.2", + "255.255.255.252", + 1); + + StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.1", + "10.1.2.2", + 1); + + StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.2", + "255.255.255.252", + 1); + + StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.3", + "10.1.3.2", + 1); + + StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.3.2", + "255.255.255.252", + 1); + StaticRouterLSA* lsa2 = new StaticRouterLSA (); - lsa2->m_linkStateId.Set (2); - lsa2->m_advertisingRtr.Set (2); + lsa2->SetLinkStateId ("0.0.0.2"); + lsa2->SetAdvertisingRouter ("0.0.0.2"); lsa2->AddLinkRecord (lr4); lsa2->AddLinkRecord (lr5); lsa2->AddLinkRecord (lr6); @@ -1164,36 +1171,38 @@ StaticRouteManagerTest::RunTests (void) lsa2->AddLinkRecord (lr9); // Router 3 - StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord (); - lr10->m_linkId.Set (2); // router ID 0.0.0.2 - lr10->m_linkData.Set ("10.1.2.1"); - lr10->m_linkType = StaticRouterLinkRecord::PointToPoint; - lr10->m_metric = 1; - StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord (); - lr11->m_linkId.Set ("10.1.2.1"); - lr11->m_linkData.Set ("255.255.255.252"); - lr11->m_linkType = StaticRouterLinkRecord::StubNetwork; - lr11->m_metric = 1; + StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + + StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + StaticRouterLSA* lsa3 = new StaticRouterLSA (); - lsa3->m_linkStateId.Set (3); - lsa3->m_advertisingRtr.Set (3); - lsa3->AddLinkRecord (lr2); - lsa3->AddLinkRecord (lr3); + lsa3->SetLinkStateId ("0.0.0.3"); + lsa3->SetAdvertisingRouter ("0.0.0.3"); + lsa3->AddLinkRecord (lr10); + lsa3->AddLinkRecord (lr11); // Test the database StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB (); - srmlsdb->Insert (lsa0->m_linkStateId, lsa0); - srmlsdb->Insert (lsa1->m_linkStateId, lsa1); - srmlsdb->Insert (lsa2->m_linkStateId, lsa2); - srmlsdb->Insert (lsa3->m_linkStateId, lsa3); - NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->m_linkStateId)); + srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0); + srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1); + srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2); + srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3); + NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ())); // XXX next, calculate routes based on the manually created LSDB StaticRouteManager* srm = new StaticRouteManager (); srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB // Note-- this will succeed without any nodes in the topology // because the NodeList is empty - srm->DebugSPFCalculate (lsa0->m_linkStateId); // node n0 + srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 // This delete clears the srm, which deletes the LSDB, which clears // all of the LSAs, which each destroys the attached LinkRecords. diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index 81bbee2a6..b70d865e1 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -26,19 +26,120 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); namespace ns3 { +StaticRouterLinkRecord::StaticRouterLinkRecord () +: + m_linkId ("0.0.0.0"), + m_linkData ("0.0.0.0"), + m_linkType (Unknown), + m_metric (0) +{ + NS_DEBUG("StaticRouterLinkRecord::StaticRouterLinkRecord ()"); +} + +StaticRouterLinkRecord::StaticRouterLinkRecord ( + LinkType linkType, + Ipv4Address linkId, + Ipv4Address linkData, + uint32_t metric) +: + m_linkId (linkId), + m_linkData (linkData), + m_linkType (linkType), + m_metric (metric) +{ + NS_DEBUG("StaticRouterLinkRecord::StaticRouterLinkRecord (" << + linkType << ", " << linkId << ", " << linkData << ", " << metric << ")"); +} + +StaticRouterLinkRecord::~StaticRouterLinkRecord () +{ + NS_DEBUG("StaticRouterLinkRecord::~StaticRouterLinkRecord ()"); +} + + Ipv4Address +StaticRouterLinkRecord::GetLinkId (void) const +{ + NS_DEBUG("StaticRouterLinkRecord::GetLinkId ()"); + return m_linkId; +} + + void +StaticRouterLinkRecord::SetLinkId (Ipv4Address addr) +{ + NS_DEBUG("StaticRouterLinkRecord::SetLinkId ()"); + m_linkId = addr; +} + + Ipv4Address +StaticRouterLinkRecord::GetLinkData (void) const +{ + NS_DEBUG("StaticRouterLinkRecord::GetLinkData ()"); + return m_linkData; +} + + void +StaticRouterLinkRecord::SetLinkData (Ipv4Address addr) +{ + NS_DEBUG("StaticRouterLinkRecord::SetLinkData ()"); + m_linkData = addr; +} + + StaticRouterLinkRecord::LinkType +StaticRouterLinkRecord::GetLinkType (void) const +{ + NS_DEBUG("StaticRouterLinkRecord::GetLinkType ()"); + return m_linkType; +} + + void +StaticRouterLinkRecord::SetLinkType ( + StaticRouterLinkRecord::LinkType linkType) +{ + NS_DEBUG("StaticRouterLinkRecord::SetLinkType ()"); + m_linkType = linkType; +} + + uint32_t +StaticRouterLinkRecord::GetMetric (void) const +{ + NS_DEBUG("StaticRouterLinkRecord::GetMetric ()"); + return m_metric; +} + + void +StaticRouterLinkRecord::SetMetric (uint32_t metric) +{ + NS_DEBUG("StaticRouterLinkRecord::SetMetric ()"); + m_metric = metric; +} + StaticRouterLSA::StaticRouterLSA() : m_linkStateId("0.0.0.0"), m_advertisingRtr("0.0.0.0"), m_linkRecords(), - m_stat(StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + m_status(StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); } +StaticRouterLSA::StaticRouterLSA ( + StaticRouterLSA::SPFStatus status, + Ipv4Address linkStateId, + Ipv4Address advertisingRtr) +: + m_linkStateId(linkStateId), + m_advertisingRtr(advertisingRtr), + m_linkRecords(), + m_status(status) +{ + NS_DEBUG("StaticRouterLSA::StaticRouterLSA (" << status << ", " << + linkStateId << ", " << advertisingRtr << ")"); +} + StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr), - m_stat(lsa.m_stat) + m_status(lsa.m_status) { NS_ASSERT_MSG(IsEmpty(), "StaticRouterLSA::StaticRouterLSA (): Non-empty LSA in constructor"); @@ -46,11 +147,11 @@ StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) } StaticRouterLSA& -StaticRouterLSA::operator= (StaticRouterLSA& lsa) +StaticRouterLSA::operator= (const StaticRouterLSA& lsa) { m_linkStateId = lsa.m_linkStateId; m_advertisingRtr = lsa.m_advertisingRtr; - m_stat = lsa.m_stat; + m_status = lsa.m_status; ClearLinkRecords (); CopyLinkRecords (lsa); @@ -58,17 +159,19 @@ StaticRouterLSA::operator= (StaticRouterLSA& lsa) } void -StaticRouterLSA::CopyLinkRecords (StaticRouterLSA& lsa) +StaticRouterLSA::CopyLinkRecords (const StaticRouterLSA& lsa) { - for ( ListOfLinkRecords_t::iterator i = lsa.m_linkRecords.begin (); - i != lsa.m_linkRecords.end (); - i++) + for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin (); + i != lsa.m_linkRecords.end (); + i++) { StaticRouterLinkRecord *pSrc = *i; StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; - pDst->m_linkId = pSrc->m_linkId; - pDst->m_linkData = pSrc->m_linkData; - pDst->m_linkType = pSrc->m_linkType; + + pDst->SetLinkType (pSrc->GetLinkType ()); + pDst->SetLinkId (pSrc->GetLinkId ()); + pDst->SetLinkData (pSrc->GetLinkData ()); + m_linkRecords.push_back(pDst); pDst = 0; } @@ -107,16 +210,16 @@ StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr) } uint32_t -StaticRouterLSA::GetNLinkRecords (void) +StaticRouterLSA::GetNLinkRecords (void) const { return m_linkRecords.size (); } StaticRouterLinkRecord * -StaticRouterLSA::GetLinkRecord (uint32_t n) +StaticRouterLSA::GetLinkRecord (uint32_t n) const { uint32_t j = 0; - for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); i != m_linkRecords.end (); i++, j++) { @@ -129,27 +232,62 @@ StaticRouterLSA::GetLinkRecord (uint32_t n) return 0; } - bool -StaticRouterLSA::IsEmpty (void) +StaticRouterLSA::IsEmpty (void) const { return m_linkRecords.size () == 0; } + Ipv4Address +StaticRouterLSA::GetLinkStateId (void) const +{ + return m_linkStateId; +} + + void +StaticRouterLSA::SetLinkStateId (Ipv4Address addr) +{ + m_linkStateId = addr; +} + + Ipv4Address +StaticRouterLSA::GetAdvertisingRouter (void) const +{ + return m_advertisingRtr; +} + + void +StaticRouterLSA::SetAdvertisingRouter (Ipv4Address addr) +{ + m_advertisingRtr = addr; +} + + StaticRouterLSA::SPFStatus +StaticRouterLSA::GetStatus (void) const +{ + return m_status; +} + + void +StaticRouterLSA::SetStatus (StaticRouterLSA::SPFStatus status) +{ + m_status = status; +} + void -StaticRouterLSA::Print (std::ostream &os) +StaticRouterLSA::Print (std::ostream &os) const { os << "m_linkStateId = " << m_linkStateId << std::endl << "m_advertisingRtr = " << m_advertisingRtr << std::endl; - for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); + for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); i != m_linkRecords.end (); i++) { StaticRouterLinkRecord *p = *i; os << "----------" << std::endl; - os << "m_linkId = " << p->m_linkId << std::endl; - os << "m_linkData = " << p->m_linkData << std::endl; + os << "m_linkId = " << p->GetLinkId () << std::endl; + os << "m_linkData = " << p->GetLinkData () << std::endl; } } @@ -198,7 +336,7 @@ StaticRouter::ClearLSAs () } Ipv4Address -StaticRouter::GetRouterId (void) +StaticRouter::GetRouterId (void) const { return m_routerId; } @@ -230,9 +368,9 @@ StaticRouter::DiscoverLSAs (void) // return exactly one. // StaticRouterLSA *pLSA = new StaticRouterLSA; - pLSA->m_linkStateId = m_routerId; - pLSA->m_advertisingRtr = m_routerId; - pLSA->m_stat = StaticRouterLSA::LSA_SPF_NOT_EXPLORED; + pLSA->SetLinkStateId (m_routerId); + pLSA->SetAdvertisingRouter (m_routerId); + pLSA->SetStatus (StaticRouterLSA::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) @@ -315,16 +453,16 @@ StaticRouter::DiscoverLSAs (void) // the second is a stub network record with the network number. // StaticRouterLinkRecord *plr = new StaticRouterLinkRecord; - plr->m_linkType = StaticRouterLinkRecord::PointToPoint; - plr->m_linkId = rtrIdRemote; - plr->m_linkData = addrLocal; + plr->SetLinkType (StaticRouterLinkRecord::PointToPoint); + plr->SetLinkId (rtrIdRemote); + plr->SetLinkData (addrLocal); pLSA->AddLinkRecord(plr); plr = 0; plr = new StaticRouterLinkRecord; - plr->m_linkType = StaticRouterLinkRecord::StubNetwork; - plr->m_linkId = addrRemote; - plr->m_linkData.Set(maskRemote.GetHostOrder()); // Frown + plr->SetLinkType (StaticRouterLinkRecord::StubNetwork); + plr->SetLinkId (addrRemote); + plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown pLSA->AddLinkRecord(plr); plr = 0; } @@ -337,7 +475,7 @@ StaticRouter::DiscoverLSAs (void) } uint32_t -StaticRouter::GetNumLSAs (void) +StaticRouter::GetNumLSAs (void) const { NS_DEBUG("StaticRouter::GetNumLSAs ()"); return m_LSAs.size (); @@ -347,7 +485,7 @@ StaticRouter::GetNumLSAs (void) // Get the nth link state advertisement from this router. // bool -StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) +StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) const { NS_ASSERT_MSG(lsa.IsEmpty(), "StaticRouter::GetLSA (): Must pass empty LSA"); // @@ -355,7 +493,7 @@ StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) // walk the list of link state advertisements created there and return the // one the client is interested in. // - ListOfLSAs_t::iterator i = m_LSAs.begin (); + ListOfLSAs_t::const_iterator i = m_LSAs.begin (); uint32_t j = 0; for (; i != m_LSAs.end (); i++, j++) @@ -376,7 +514,7 @@ StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) // other end. This only makes sense with a point-to-point channel. // Ptr -StaticRouter::GetAdjacent(Ptr nd, Ptr ch) +StaticRouter::GetAdjacent(Ptr nd, Ptr ch) const { // // Double-check that channel agrees with device that it's a point-to-point @@ -417,7 +555,7 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) // corresponds to that net device. // uint32_t -StaticRouter::FindIfIndexForDevice(Ptr node, Ptr nd) +StaticRouter::FindIfIndexForDevice(Ptr node, Ptr nd) const { Ptr ipv4 = node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4, "QI for interface failed"); diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 4f777e484..f1e5252b0 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -1,3 +1,4 @@ + /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * This program is free software; you can redistribute it and/or modify @@ -34,42 +35,163 @@ namespace ns3 { * The StaticRouterLinkRecord 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). - * - * For Type 3 link (Stub), */ class StaticRouterLinkRecord { public: -// -// For Type 1 link (PointToPoint), set m_linkId to Router ID of -// neighboring router. -// -// For Type 3 link (Stub), set m_linkId to neighbor's IP address -// - Ipv4Address m_linkId; -// -// For Type 1 link (PointToPoint), set m_linkData to local IP address -// -// For Type 3 link (Stub), set m_linkData to mask 0xffffffff -// - Ipv4Address m_linkData; // for links to RouterLSA, /** * Enumeration of the possible types of Static Router Link Records. These * are defined in the OSPF spec. We currently only use PointToPoint and * StubNetwork types. */ enum LinkType { - PointToPoint = 1, /**< Record representing a point to point channel */ + Unknown = 0, /**< Uninitialized Link Record */ + PointToPoint, /**< Record representing a point to point channel */ TransitNetwork, /**< Unused -- for future OSPF compatibility */ StubNetwork, /**< Record represents a leaf node network */ VirtualLink /**< Unused -- for future OSPF compatibility */ - } m_linkType; + }; /** - * An abstract cost associated with forwarding a packet across a link. - * A sum of metrics must have a well-defined meaning. That is, you shouldn't - * use bandwidth as a metric (how does the sum of the bandwidth of two hops - * relate to the cost of sending a packet); rather you should use something - * like delay. + * Construct an empty ("uninitialized") Static Router 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. + */ + StaticRouterLinkRecord (); + /** + * Construct a fully uninitialized Static Router Link Record. + * + * @param linkType The type of link record to construct. + * @param linkId The link ID for the record. + * @param linkData The link data field for the record. + * @param metric The metric field for the record. + * @see LinkType + * @see SetLinkId + * @see SetLinkData + */ + StaticRouterLinkRecord ( + LinkType linkType, + Ipv4Address linkId, + Ipv4Address linkData, + uint32_t metric); + /** + * Destroy a Static Router Link Record. + * + * Currently does nothing. Here as a placeholder only. + */ + ~StaticRouterLinkRecord (); + /** + * Get the Link ID field of the Static Router Link Record. + * + * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID + * of the neighboring router. + * + * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent + * neighbor's IP address + */ + Ipv4Address GetLinkId(void) const; + /** + * Set the Link ID field of the Static Router Link Record. + * + * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID + * of the neighboring router. + * + * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent + * neighbor's IP address + */ + void SetLinkId(Ipv4Address addr); + /** + * Get the Link Data field of the Static Router 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. + * + * For an OSPF type 3 link (StubNetwork), the Link Data will be the + * network mask + */ + Ipv4Address GetLinkData(void) const; + /** + * Set the Link Data field of the Static Router 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. + * + * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the + * network mask + */ + void SetLinkData(Ipv4Address addr); + /** + * Get the Link Type field of the Static Router Link Record. + * + * The Link Type describes the kind of link a given record represents. The + * values are defined by OSPF. + * + * @see LinkType + */ + LinkType GetLinkType(void) const; + /** + * Set the Link Type field of the Static Router Link Record. + * + * The Link Type describes the kind of link a given record represents. The + * values are defined by OSPF. + * + * @see LinkType + */ + void SetLinkType(LinkType linkType); + /** + * Get the Metric Data field of the Static Router 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 + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of + * two hops relate to the cost of sending a packet); rather you should use + * something like delay. + */ + uint32_t GetMetric(void) const; + /** + * Set the Metric Data field of the Static Router 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 + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of + * two hops relate to the cost of sending a packet); rather you should use + * something like delay. + */ + void SetMetric(uint32_t metric); + +private: + /** + * m_linkId and m_linkData are defined by OSPF to have different meanings + * depending on the type of link a given link records represents. They work + * together. + * + * For Type 1 link (PointToPoint), set m_linkId to Router ID of + * neighboring router. + * + * For Type 3 link (Stub), set m_linkId to neighbor's IP address + */ + Ipv4Address m_linkId; + /** + * m_linkId and m_linkData are defined by OSPF to have different meanings + * depending on the type of link a given link records represents. They work + * together. + * + * For Type 1 link (PointToPoint), set m_linkData to local IP address + * + * For Type 3 link (Stub), set m_linkData to mask + */ + Ipv4Address m_linkData; // for links to RouterLSA, + + LinkType m_linkType; + /** + * The metric for a given link. + * + * A metric is abstract cost associated with forwarding a packet across a + * link. A sum of metrics must have a well-defined meaning. That is, you + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth + * of two hops relate to the cost of sending a packet); rather you should + * use something like delay. */ uint32_t m_metric; }; @@ -84,110 +206,189 @@ public: class StaticRouterLSA { public: - /** - * Create a blank Static Router Link State Advertisement. On completion, - * any Ipv4Address variables initialized to 0.0.0.0 and the list of Link - * State Records is empty. - */ - StaticRouterLSA(); - /** - * Copy constructor for a Static Router 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. - */ - StaticRouterLSA (StaticRouterLSA& lsa); - /** - * Destroy an existing Static Router Link State Advertisement. Any Static - * router Link Records present in the list are freed. - */ - ~StaticRouterLSA(); - /** - * Assignment operator for a Static Router Link State Advertisement. - * Takes an existing Static Router Link State Advertisement and overwrites - * it to make a semantically identical copy of a given prototype LSA. - * - * If there are any Static Router 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. - */ - StaticRouterLSA& operator= (StaticRouterLSA& lsa); - /** - * Copy any Static Router Link Records in a given Static Router Link - * State Advertisement to the current LSA. Existing Link Records are not - * deleted -- this is a concatenation of Link Records. - * - * @see ClearLinkRecords () - * @param lsa The LSA to copy the Link Records from. - */ - void CopyLinkRecords (StaticRouterLSA& lsa); - /** - * Add a given Static Router Link Record to the LSA. - * - * @param lr The Static Router Link Record to be added. - * @returns The number of link records in the list. - */ - uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); - /** - * Return the number of Static Router Link Records in the LSA. - * - * @returns The number of link records in the list. - */ - uint32_t GetNLinkRecords (void); - /** - * Return a pointer to the specified Static Router Link Record. - * - * @param n The LSA number desired. - * @returns The number of link records in the list. - */ - StaticRouterLinkRecord* GetLinkRecord (uint32_t n); - /** - * Release all of the Static Router Link Records present in the Static - * Router Link State Advertisement and make the list of link records empty. - */ - void ClearLinkRecords(void); - /** - * Check to see of the list of Static Router Link Records present in the - * Static Router Link State Advertisement is empty. - * - * @returns True if the list is empty, false otherwise. - */ - bool IsEmpty(void); - /** - * Print the contents of the Static Router Link State Advertisement and - * any Static Router Link Records present in the list. Quite verbose. - */ - void Print (std::ostream &os); - /** - * 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 StaticRouter::GetRouterId () - */ - Ipv4Address m_linkStateId; - /** - * The Advertising Router is defined by the OSPF spec. We always set it to - * the router ID of the router making the advertisement. - * - * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () - */ - Ipv4Address m_advertisingRtr; - - typedef std::list ListOfLinkRecords_t; - ListOfLinkRecords_t m_linkRecords; - - // this is a tristate flag used internally in the SPF computation +/** + * Enumeration of the possible values of the status flag in the Router Link + * State Advertisements. + */ enum SPFStatus { - LSA_SPF_NOT_EXPLORED = 0, - LSA_SPF_CANDIDATE, - LSA_SPF_IN_SPFTREE - } m_stat; + LSA_SPF_NOT_EXPLORED = 0, /**< New vertex not yet considered */ + LSA_SPF_CANDIDATE, /**< Vertex is in the SPF candidate queue */ + LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */ + }; +/** + * Create a blank Static Router Link State Advertisement. On completion, + * any Ipv4Address variables initialized to 0.0.0.0 and the list of Link + * State Records is empty. + */ + StaticRouterLSA(); +/** + * Create an initialized Static Router Link State Advertisement. On + * completion the list of Link State Records is empty. + * + * @param status The status to of the new LSA. + * @param linkStateId The Ipv4Address for the link state ID field. + * @param advertisingRouter The Ipv4Address for the advertising router field. + */ + StaticRouterLSA(SPFStatus status, Ipv4Address linkStateId, + Ipv4Address advertisingRtr); +/** + * Copy constructor for a Static Router 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. + */ + StaticRouterLSA (StaticRouterLSA& lsa); +/** + * Destroy an existing Static Router Link State Advertisement. Any Static + * router Link Records present in the list are freed. + */ + ~StaticRouterLSA(); +/** + * Assignment operator for a Static Router Link State Advertisement. + * Takes an existing Static Router Link State Advertisement and overwrites + * it to make a semantically identical copy of a given prototype LSA. + * + * If there are any Static Router 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. + */ + StaticRouterLSA& operator= (const StaticRouterLSA& lsa); +/** + * Copy any Static Router Link Records in a given Static Router Link + * State Advertisement to the current LSA. Existing Link Records are not + * deleted -- this is a concatenation of Link Records. + * + * @see ClearLinkRecords () + * @param lsa The LSA to copy the Link Records from. + */ + void CopyLinkRecords (const StaticRouterLSA& lsa); +/** + * Add a given Static Router Link Record to the LSA. + * + * @param lr The Static Router Link Record to be added. + * @returns The number of link records in the list. + */ + uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); +/** + * Return the number of Static Router Link Records in the LSA. + * + * @returns The number of link records in the list. + */ + uint32_t GetNLinkRecords (void) const; +/** + * Return a pointer to the specified Static Router Link Record. + * + * @param n The LSA number desired. + * @returns The number of link records in the list. + */ + StaticRouterLinkRecord* GetLinkRecord (uint32_t n) const; +/** + * Release all of the Static Router Link Records present in the Static + * Router Link State Advertisement and make the list of link records empty. + */ + void ClearLinkRecords(void); +/** + * Check to see of the list of Static Router Link Records present in the + * Static Router Link State Advertisement is empty. + * + * @returns True if the list is empty, false otherwise. + */ + bool IsEmpty(void) const; +/** + * Print the contents of the Static Router Link State Advertisement and + * any Static Router Link Records present in the list. Quite verbose. + */ + void Print (std::ostream &os) const; +/** + * 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 StaticRouter::GetRouterId () + * @returns The Ipv4Address stored as the link state ID. + */ + Ipv4Address GetLinkStateId (void) const; +/** + * Set 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 StaticRouter::GetRouterId () + */ + void SetLinkStateId (Ipv4Address addr); +/** + * Get the Advertising Router as defined by the OSPF spec. We always set + * it to the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () + * @see StaticRouter::GetRouterId () + * @returns The Ipv4Address stored as the advetising router. + */ + Ipv4Address GetAdvertisingRouter (void) const; +/** + * Set the Advertising Router as defined by the OSPF spec. We always set + * it to the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () + * @see StaticRouter::GetRouterId () + */ + void SetAdvertisingRouter (Ipv4Address rtr); +/** + * Get the SPF status of the advertisement. + * + * @see SPFStatus + * @returns The SPFStatus of the LSA. + */ + SPFStatus GetStatus (void) const; +/** + * Set the SPF status of the advertisement + * + * @see SPFStatus + */ + void SetStatus (SPFStatus status); +private: +/** + * 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 StaticRouter::GetRouterId () + */ + Ipv4Address m_linkStateId; +/** + * The Advertising Router is defined by the OSPF spec. We always set it to + * the router ID of the router making the advertisement. + * + * @see RoutingEnvironment::AllocateRouterId () + * @see StaticRouter::GetRouterId () + */ + Ipv4Address m_advertisingRtr; +/** + * A convenience typedef to avoid too much writers cramp. + */ + typedef std::list ListOfLinkRecords_t; +/** + * Each Link State Advertisement contains a number of Link Records that + * describe the kinds of links that are attached to a given node. We + * consider PointToPoint and StubNetwork links. + * + * m_linkRecords is an STL list container to hold the Link Records that have + * been discovered and prepared for the advertisement. + * + * @see StaticRouter::DiscoverLSAs () + */ + ListOfLinkRecords_t m_linkRecords; +/** + * 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 + * proper position in the tree. + */ + SPFStatus m_status; }; std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); @@ -225,7 +426,7 @@ public: * @see RoutingEnvironment::AllocateRouterId () * @returns The Router ID associated with the Static Router. */ - Ipv4Address GetRouterId(void); + Ipv4Address GetRouterId (void) const; /** * Walk the connected channels, discover the adjacent routers and build * the associated number of Static Router Link State Advertisements that @@ -256,7 +457,7 @@ public: * @see StaticRouter::GetLSA () * @returns The number of Static Router Link State Advertisements. */ - uint32_t GetNumLSAs (void); + uint32_t GetNumLSAs (void) const; /** * Get a Static Router Link State Advertisements that this router has said * that it can export. @@ -277,14 +478,14 @@ public: * @param lsa The StaticRouterLSA class to receive the LSA information. * @returns The number of Static Router Link State Advertisements. */ - bool GetLSA (uint32_t n, StaticRouterLSA &lsa); + bool GetLSA (uint32_t n, StaticRouterLSA &lsa) const; protected: virtual ~StaticRouter (); void ClearLSAs (void); - Ptr GetAdjacent(Ptr nd, Ptr ch); - uint32_t FindIfIndexForDevice(Ptr node, Ptr nd); + Ptr GetAdjacent(Ptr nd, Ptr ch) const; + uint32_t FindIfIndexForDevice(Ptr node, Ptr nd) const; Ptr m_node; From e3283739ce619a225d7f54e90c774d2c3e63e9c6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 18 Jul 2007 16:57:54 -0700 Subject: [PATCH 71/92] general cleanup of routing --- SConstruct | 7 - samples/main-candidate-queue.cc | 93 ------- src/routing/candidate-queue.cc | 4 +- src/routing/static-route-manager.cc | 242 +++++++++++++---- src/routing/static-route-manager.h | 79 +++++- src/routing/static-router.h | 405 ++++++++++++++-------------- 6 files changed, 459 insertions(+), 371 deletions(-) delete mode 100644 samples/main-candidate-queue.cc diff --git a/SConstruct b/SConstruct index 111358020..8d8468c27 100644 --- a/SConstruct +++ b/SConstruct @@ -503,13 +503,6 @@ ns3.add(sample_component_manager) sample_component_manager.add_deps(['core']) sample_component_manager.add_source('main-component-manager.cc') -sample_candidate_queue = build.Ns3Module('sample-candidate-queue', 'samples') -sample_candidate_queue.set_executable() -ns3.add(sample_candidate_queue) -sample_candidate_queue.add_deps(['core']) -sample_candidate_queue.add_deps(['routing']) -sample_candidate_queue.add_source('main-candidate-queue.cc') - # examples example_simple_p2p = build.Ns3Module('simple-p2p', 'examples') example_simple_p2p.set_executable() diff --git a/samples/main-candidate-queue.cc b/samples/main-candidate-queue.cc deleted file mode 100644 index ca111f0dc..000000000 --- a/samples/main-candidate-queue.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/debug.h" -#include "ns3/assert.h" -#include "ns3/candidate-queue.h" - -using namespace ns3; - - int -main (int argc, char *argv[]) -{ - NS_DEBUG_UNCOND("Candidate Queue Test"); - -#if 0 - DebugComponentEnable("CandidateQueue"); -#endif - - CandidateQueue candidate; - NS_ASSERT(candidate.Size () == 0); - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = new SPFVertex; - v->m_distanceFromRoot = rand () % 100; - candidate.Push (v); - } - - uint32_t lastDistance = 0; - bool ok = true; - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = candidate.Top (); - candidate.Pop (); - if (v->m_distanceFromRoot < lastDistance) - { - ok = false; - NS_ASSERT(0); - } - lastDistance = v->m_distanceFromRoot; - } - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = new SPFVertex; - v->m_distanceFromRoot = rand () % 100; - candidate.Push (v); - } - -#if 0 - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = candidate.Find (i); - if (v) { - v->m_distanceFromRoot = rand () % 100; - } - } -#endif - - candidate.Reorder (); - - lastDistance = 0; - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = candidate.Top (); - candidate.Pop (); - if (v->m_distanceFromRoot < lastDistance) - { - ok = false; - NS_ASSERT(0); - } - lastDistance = v->m_distanceFromRoot; - } - - NS_ASSERT(candidate.Size () == 0); - - return 0; -} diff --git a/src/routing/candidate-queue.cc b/src/routing/candidate-queue.cc index d34e49855..67bec63b1 100644 --- a/src/routing/candidate-queue.cc +++ b/src/routing/candidate-queue.cc @@ -57,7 +57,7 @@ CandidateQueue::Push (SPFVertex *vNew) for (; i != m_candidates.end (); i++) { SPFVertex *v = *i; - if (vNew->m_distanceFromRoot < v->m_distanceFromRoot) + if (vNew->GetDistanceFromRoot () < v->GetDistanceFromRoot ()) { break; } @@ -119,7 +119,7 @@ CandidateQueue::Find (const Ipv4Address addr) const for (; i != m_candidates.end (); i++) { SPFVertex *v = *i; - if (v->m_vertexId == addr) + if (v->GetVertexId() == addr) { return v; } diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 5e4aece04..408f2a91d 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -34,11 +34,11 @@ SPFVertex::SPFVertex () : m_vertexType (VertexUnknown), m_vertexId ("255.255.255.255"), m_lsa (0), - m_parent (0), - m_children (), m_distanceFromRoot (SPF_INFINITY), m_rootOif (SPF_INFINITY), - m_nextHop ("0.0.0.0") + m_nextHop ("0.0.0.0"), + m_parent (0), + m_children () { } @@ -46,19 +46,19 @@ SPFVertex::SPFVertex (StaticRouterLSA* lsa) : m_vertexType (VertexRouter), m_vertexId (lsa->GetLinkStateId ()), m_lsa (lsa), - m_parent (0), - m_children (), m_distanceFromRoot (SPF_INFINITY), m_rootOif (SPF_INFINITY), - m_nextHop ("0.0.0.0") + m_nextHop ("0.0.0.0"), + m_parent (0), + m_children () { } SPFVertex::~SPFVertex () { - for ( t_listOfSPFVertex::iterator i = m_children.begin (); - i != m_children.end (); - i++) + for ( ListOfSPFVertex_t::iterator i = m_children.begin (); + i != m_children.end (); + i++) { SPFVertex *p = *i; delete p; @@ -68,6 +68,128 @@ SPFVertex::~SPFVertex () m_children.clear (); } + void +SPFVertex::SetVertexType (SPFVertex::VertexType type) +{ + m_vertexType = type; +} + + SPFVertex::VertexType +SPFVertex::GetVertexType (void) const +{ + return m_vertexType; +} + + void +SPFVertex::SetVertexId (Ipv4Address id) +{ + m_vertexId = id; +} + + Ipv4Address +SPFVertex::GetVertexId (void) const +{ + return m_vertexId; +} + + void +SPFVertex::SetLSA (StaticRouterLSA* lsa) +{ + m_lsa = lsa; +} + + StaticRouterLSA* +SPFVertex::GetLSA (void) const +{ + return m_lsa; +} + + void +SPFVertex::SetDistanceFromRoot (uint32_t distance) +{ + m_distanceFromRoot = distance; +} + + uint32_t +SPFVertex::GetDistanceFromRoot (void) const +{ + return m_distanceFromRoot; +} + + void +SPFVertex::SetOutgoingInterfaceId (uint32_t id) +{ + m_rootOif = id; +} + + uint32_t +SPFVertex::GetOutgoingInterfaceId (void) const +{ + return m_rootOif; +} + + void +SPFVertex::SetNextHop (Ipv4Address nextHop) +{ + m_nextHop = nextHop; +} + + Ipv4Address +SPFVertex::GetNextHop (void) const +{ + return m_nextHop; +} + + void +SPFVertex::SetParent (SPFVertex* parent) +{ + m_parent = parent; +} + + SPFVertex* +SPFVertex::GetParent (void) const +{ + return m_parent; +} + + uint32_t +SPFVertex::GetNChildren (void) const +{ + return m_children.size (); +} + + SPFVertex* +SPFVertex::GetChild (uint32_t n) const +{ + uint32_t j = 0; + + for ( ListOfSPFVertex_t::const_iterator i = m_children.begin (); + i != m_children.end (); + i++, j++) + { + if (j == n) + { + return *i; + } + } + NS_ASSERT_MSG(false, "Index out of range."); + return 0; +} + + uint32_t +SPFVertex::AddChild (SPFVertex* child) +{ + m_children.push_back (child); + return m_children.size (); +} + +StaticRouteManagerLSDB::StaticRouteManagerLSDB () +: + m_database () +{ + NS_DEBUG ("StaticRouteManagerLSDB::StaticRouteManagerLSDB ()"); +} + StaticRouteManagerLSDB::~StaticRouteManagerLSDB () { NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); @@ -286,24 +408,24 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // // Always true for now, since all our LSAs are RouterLSAs. // - if (v->m_vertexType == SPFVertex::VertexRouter) + if (v->GetVertexType () == SPFVertex::VertexRouter) { if (true) { - NS_DEBUG ("SPFNext: Examining " << v->m_vertexId << "'s " << - v->m_lsa->GetNLinkRecords () << " link records"); + 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->m_lsa->GetNLinkRecords (); ++i) + 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. // - StaticRouterLinkRecord *l = v->m_lsa->GetLinkRecord (i); + StaticRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); if (l->GetLinkType () == StaticRouterLinkRecord::StubNetwork) { NS_DEBUG ("SPFNext: Found a Stub record to " << @@ -324,7 +446,7 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) w_lsa = m_lsdb->GetLSA (l->GetLinkId ()); NS_ASSERT (w_lsa); NS_DEBUG ("SPFNext: Found a P2P record from " << - v->m_vertexId << " to " << w_lsa->GetLinkStateId ()); + v->GetVertexId () << " to " << w_lsa->GetLinkStateId ()); // // (c) If vertex W is already on the shortest-path tree, examine the next // link in the LSA. @@ -347,7 +469,7 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // calculated) shortest path to vertex V and the advertised cost of the link // between vertices V and W. // - distance = v->m_distanceFromRoot + l->GetMetric (); + distance = v->GetDistanceFromRoot () + l->GetMetric (); NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ()); @@ -375,8 +497,9 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // root node). // candidate.Push (w); - NS_DEBUG ("SPFNext: Pushing " << w->m_vertexId - << ", parent vertexId: " << v->m_vertexId); + NS_DEBUG ("SPFNext: Pushing " << + w->GetVertexId () << ", parent vertexId: " << + v->GetVertexId ()); } } } else if (w_lsa->GetStatus () == @@ -390,22 +513,22 @@ StaticRouteManager::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->m_distanceFromRoot < distance) + if (w->GetDistanceFromRoot () < distance) { // // This is not a shorter path, so don't do anything. // continue; } - else if (w->m_distanceFromRoot == distance) - { + 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 @@ -414,15 +537,15 @@ StaticRouteManager::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 (); - } - } + candidate.Reorder (); + } + } } // point-to-point } // for loop } @@ -479,7 +602,7 @@ StaticRouteManager::SPFNexthopCalculation ( // node if this root node is a router. We then need to see if this node // is a router. // - if (w->m_vertexType == SPFVertex::VertexRouter) + if (w->GetVertexType () == SPFVertex::VertexRouter) { // // In the case of point-to-point links, the link data field (m_linkData) of a @@ -507,18 +630,19 @@ StaticRouteManager::SPFNexthopCalculation ( // from the root node to the host represented by vertex , you have to send // the packet to the next hop address specified in w->m_nextHop. // - w->m_nextHop = linkRemote->GetLinkData (); + w->SetNextHop(linkRemote->GetLinkData ()); // // Now find the outgoing interface corresponding to the point to point link // from the perspective of -- remember that is the link "from" // "to" . // - w->m_rootOif = FindOutgoingInterfaceId (l->GetLinkData ()); + w->SetOutgoingInterfaceId ( + FindOutgoingInterfaceId (l->GetLinkData ())); NS_DEBUG ("SPFNexthopCalculation: Next hop from " << - v->m_vertexId << " to " << w->m_vertexId << - " goes through next hop " << w->m_nextHop << - " via outgoing interface " << w->m_rootOif); + v->GetVertexId () << " to " << w->GetVertexId () << + " goes through next hop " << w->GetNextHop () << + " via outgoing interface " << w->GetOutgoingInterfaceId ()); } } else @@ -536,14 +660,14 @@ StaticRouteManager::SPFNexthopCalculation ( // (shortest) paths. So the next hop and outoing interface remain the same // (are inherited). // - w->m_nextHop = v->m_nextHop; - w->m_rootOif = v->m_rootOif; + w->SetNextHop (v->GetNextHop ()); + w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ()); } // // In all cases, we need valid values for the distance metric and a parent. // - w->m_distanceFromRoot = distance; - w->m_parent = v; + w->SetDistanceFromRoot (distance); + w->SetParent (v); return 1; } @@ -587,9 +711,9 @@ StaticRouteManager::SPFGetNextLink ( // looking for records representing the point-to-point links off of this // vertex. // - for (uint32_t i = 0; i < v->m_lsa->GetNLinkRecords (); ++i) + for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) { - l = v->m_lsa->GetLinkRecord (i); + l = v->GetLSA ()->GetLinkRecord (i); if (l->GetLinkType () != StaticRouterLinkRecord::PointToPoint) { continue; @@ -602,7 +726,7 @@ StaticRouteManager::SPFGetNextLink ( // We're just checking to see if the link is actually the link from to // . // - if (l->GetLinkId () == w->m_vertexId) { + if (l->GetLinkId () == w->GetVertexId ()) { NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " << l->GetLinkId () << " linkData = " << l->GetLinkData ()); // @@ -672,8 +796,8 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // We also mark this vertex as being in the SPF tree. // m_spfroot= v; - v->m_distanceFromRoot = 0; - v->m_lsa->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); + v->SetDistanceFromRoot (0); + v->GetLSA ()->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); for (;;) { @@ -713,12 +837,12 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // the candidate list. // v = candidate.Pop (); - NS_DEBUG ("SPFCalculate: Popped vertex " << v->m_vertexId); + NS_DEBUG ("SPFCalculate: Popped vertex " << v->GetVertexId ()); // // Update the status field of the vertex to indicate that it is in the SPF // tree. // - v->m_lsa->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); + v->GetLSA ()->SetStatus (StaticRouterLSA::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 @@ -792,7 +916,7 @@ StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) // node in order to iterate the interfaces and find the one corresponding to // the address in question. // - Ipv4Address routerId = m_spfroot->m_vertexId; + 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 @@ -878,7 +1002,7 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) // going to use this ID to discover which node it is that we're actually going // to update. // - Ipv4Address routerId = m_spfroot->m_vertexId; + Ipv4Address routerId = m_spfroot->GetVertexId (); NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter ():" "Vertex ID = " << routerId); @@ -927,7 +1051,7 @@ StaticRouteManager::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. // - StaticRouterLSA *lsa = v->m_lsa; + StaticRouterLSA *lsa = v->GetLSA (); NS_ASSERT_MSG (lsa, "StaticRouteManager::SPFIntraAddRouter (): " "Expected valid LSA in SPFVertex* v"); @@ -955,8 +1079,8 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " " Node " << node->GetId () << " add route to " << lr->GetLinkData () << - " using next hop " << v->m_nextHop << - " via interface " << v->m_rootOif); + " using next hop " << v->GetNextHop () << + " via interface " << v->GetOutgoingInterfaceId ()); // // Here's why we did all of that work. We're going to add a host route to the // host address found in the m_linkData field of the point-to-point link @@ -970,8 +1094,8 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) // Similarly, the vertex has an m_rootOif (outbound interface index) to // which the packets should be send for forwarding. // - ipv4->AddHostRouteTo (lr->GetLinkData (), v->m_nextHop, - v->m_rootOif); + ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (), + v->GetOutgoingInterfaceId ()); } } // @@ -994,8 +1118,10 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) void StaticRouteManager::SPFVertexAddParent (SPFVertex* v) { - // For now, only one parent (not doing equal-cost multipath) - v->m_parent->m_children.push_back (v); +// +// For now, only one parent (not doing equal-cost multipath) +// + v->GetParent ()->AddChild (v); } } // namespace ns3 @@ -1052,7 +1178,7 @@ StaticRouteManagerTest::RunTests (void) for (int i = 0; i < 100; ++i) { SPFVertex *v = new SPFVertex; - v->m_distanceFromRoot = rand () % 100; + v->SetDistanceFromRoot (rand () % 100); candidate.Push (v); } @@ -1061,11 +1187,11 @@ StaticRouteManagerTest::RunTests (void) for (int i = 0; i < 100; ++i) { SPFVertex *v = candidate.Pop (); - if (v->m_distanceFromRoot < lastDistance) + if (v->GetDistanceFromRoot () < lastDistance) { ok = false; } - lastDistance = v->m_distanceFromRoot; + lastDistance = v->GetDistanceFromRoot (); delete v; v = 0; } diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 2f47d0b40..a54cf2fdd 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -47,23 +47,58 @@ public: VertexUnknown = 0, VertexRouter, VertexNetwork - } m_vertexType; + }; + void SetVertexType (VertexType type); + VertexType GetVertexType (void) const; + + void SetVertexId (Ipv4Address idV); + Ipv4Address GetVertexId (void) const; + + void SetLSA (StaticRouterLSA* lsa); + StaticRouterLSA* GetLSA (void) const; + + void SetDistanceFromRoot (uint32_t distance); + uint32_t GetDistanceFromRoot (void) const; + + void SetOutgoingInterfaceId (uint32_t id); + uint32_t GetOutgoingInterfaceId (void) const; + + void SetNextHop (Ipv4Address nextHop); + Ipv4Address GetNextHop (void) const; + + void SetParent (SPFVertex* parent); + SPFVertex* GetParent (void) const; + + uint32_t GetNChildren (void) const; + SPFVertex* GetChild (uint32_t n) const; + + uint32_t AddChild (SPFVertex* child); + +private: + VertexType m_vertexType; Ipv4Address m_vertexId; // router id - StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes - - // need to keep track of current parent vertex - SPFVertex* m_parent; - // m_children lists the leaves from your SPF tree - typedef std::list t_listOfSPFVertex; - t_listOfSPFVertex m_children; - t_listOfSPFVertex::iterator m_SPFVertexIter; - uint32_t m_distanceFromRoot; uint32_t m_rootOif; Ipv4Address m_nextHop; + // need to keep track of current parent vertex + SPFVertex* m_parent; + + // m_children lists the leaves from your SPF tree + typedef std::list ListOfSPFVertex_t; + ListOfSPFVertex_t m_children; +/** + * The SPFVertex copy construction is disallowed. There's no need for + * it and a compiler provided shallow copy would be wrong. + */ + SPFVertex (SPFVertex& v); +/** + * The SPFVertex copy assignment operator is disallowed. There's no need for + * it and a compiler provided shallow copy would be wrong. + */ + SPFVertex& operator= (SPFVertex& v); }; /** @@ -72,6 +107,7 @@ public: class StaticRouteManagerLSDB { public: + StaticRouteManagerLSDB (); ~StaticRouteManagerLSDB (); void Insert(Ipv4Address addr, StaticRouterLSA* lsa); StaticRouterLSA* GetLSA (Ipv4Address addr); @@ -83,6 +119,17 @@ public: typedef std::map LSDBMap_t; typedef std::pair LSDBPair_t; LSDBMap_t m_database; +private: +/** + * StaticRouteManagerLSDB copy construction is disallowed. There's no + * need for it and a compiler provided shallow copy would be hopelessly wrong. + */ + StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); +/** + * The SPFVertex copy assignment operator is disallowed. There's no need for + * it and a compiler provided shallow copy would be wrong. + */ + StaticRouteManagerLSDB& operator= (StaticRouteManagerLSDB& lsdb); }; /** @@ -126,6 +173,18 @@ public: protected: private: +/** + * Static Route Manager copy construction is disallowed. There's no need for + * it and a compiler provided shallow copy would be hopelessly wrong. + * + */ + StaticRouteManager (StaticRouteManager& srm); +/** + * Static Router copy assignment operator is disallowed. There's no need for + * it and a compiler provided shallow copy would be hopelessly wrong. + */ + StaticRouteManager& operator= (StaticRouteManager& srm); + SPFVertex* m_spfroot; StaticRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); diff --git a/src/routing/static-router.h b/src/routing/static-router.h index f1e5252b0..6f3f66cc6 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -39,11 +39,11 @@ namespace ns3 { class StaticRouterLinkRecord { public: - /** - * Enumeration of the possible types of Static Router Link Records. These - * are defined in the OSPF spec. We currently only use PointToPoint and - * StubNetwork types. - */ +/** + * Enumeration of the possible types of Static Router Link Records. These + * are defined in the OSPF spec. We currently only use PointToPoint and + * StubNetwork types. + */ enum LinkType { Unknown = 0, /**< Uninitialized Link Record */ PointToPoint, /**< Record representing a point to point channel */ @@ -51,148 +51,151 @@ public: StubNetwork, /**< Record represents a leaf node network */ VirtualLink /**< Unused -- for future OSPF compatibility */ }; - /** - * Construct an empty ("uninitialized") Static Router 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. - */ +/** + * Construct an empty ("uninitialized") Static Router 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. + */ StaticRouterLinkRecord (); - /** - * Construct a fully uninitialized Static Router Link Record. - * - * @param linkType The type of link record to construct. - * @param linkId The link ID for the record. - * @param linkData The link data field for the record. - * @param metric The metric field for the record. - * @see LinkType - * @see SetLinkId - * @see SetLinkData - */ +/** + * Construct a fully uninitialized Static Router Link Record. + * + * @param linkType The type of link record to construct. + * @param linkId The link ID for the record. + * @param linkData The link data field for the record. + * @param metric The metric field for the record. + * @see LinkType + * @see SetLinkId + * @see SetLinkData + */ StaticRouterLinkRecord ( LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, uint32_t metric); - /** - * Destroy a Static Router Link Record. - * - * Currently does nothing. Here as a placeholder only. - */ +/** + * Destroy a Static Router Link Record. + * + * Currently does nothing. Here as a placeholder only. + */ ~StaticRouterLinkRecord (); - /** - * Get the Link ID field of the Static Router Link Record. - * - * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID - * of the neighboring router. - * - * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent - * neighbor's IP address - */ +/** + * Get the Link ID field of the Static Router Link Record. + * + * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID + * of the neighboring router. + * + * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent + * neighbor's IP address + */ Ipv4Address GetLinkId(void) const; - /** - * Set the Link ID field of the Static Router Link Record. - * - * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID - * of the neighboring router. - * - * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent - * neighbor's IP address - */ +/** + * Set the Link ID field of the Static Router Link Record. + * + * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID + * of the neighboring router. + * + * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent + * neighbor's IP address + */ void SetLinkId(Ipv4Address addr); - /** - * Get the Link Data field of the Static Router 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. - * - * For an OSPF type 3 link (StubNetwork), the Link Data will be the - * network mask - */ +/** + * Get the Link Data field of the Static Router 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. + * + * For an OSPF type 3 link (StubNetwork), the Link Data will be the + * network mask + */ Ipv4Address GetLinkData(void) const; - /** - * Set the Link Data field of the Static Router 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. - * - * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the - * network mask - */ +/** + * Set the Link Data field of the Static Router 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. + * + * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the + * network mask + */ void SetLinkData(Ipv4Address addr); - /** - * Get the Link Type field of the Static Router Link Record. - * - * The Link Type describes the kind of link a given record represents. The - * values are defined by OSPF. - * - * @see LinkType - */ +/** + * Get the Link Type field of the Static Router Link Record. + * + * The Link Type describes the kind of link a given record represents. The + * values are defined by OSPF. + * + * @see LinkType + */ LinkType GetLinkType(void) const; - /** - * Set the Link Type field of the Static Router Link Record. - * - * The Link Type describes the kind of link a given record represents. The - * values are defined by OSPF. - * - * @see LinkType - */ +/** + * Set the Link Type field of the Static Router Link Record. + * + * The Link Type describes the kind of link a given record represents. The + * values are defined by OSPF. + * + * @see LinkType + */ void SetLinkType(LinkType linkType); - /** - * Get the Metric Data field of the Static Router 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 - * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of - * two hops relate to the cost of sending a packet); rather you should use - * something like delay. - */ +/** + * Get the Metric Data field of the Static Router 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 + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of + * two hops relate to the cost of sending a packet); rather you should use + * something like delay. + */ uint32_t GetMetric(void) const; - /** - * Set the Metric Data field of the Static Router 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 - * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of - * two hops relate to the cost of sending a packet); rather you should use - * something like delay. - */ +/** + * Set the Metric Data field of the Static Router 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 + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of + * two hops relate to the cost of sending a packet); rather you should use + * something like delay. + */ void SetMetric(uint32_t metric); private: - /** - * m_linkId and m_linkData are defined by OSPF to have different meanings - * depending on the type of link a given link records represents. They work - * together. - * - * For Type 1 link (PointToPoint), set m_linkId to Router ID of - * neighboring router. - * - * For Type 3 link (Stub), set m_linkId to neighbor's IP address - */ +/** + * m_linkId and m_linkData are defined by OSPF to have different meanings + * depending on the type of link a given link records represents. They work + * together. + * + * For Type 1 link (PointToPoint), set m_linkId to Router ID of + * neighboring router. + * + * For Type 3 link (Stub), set m_linkId to neighbor's IP address + */ Ipv4Address m_linkId; - /** - * m_linkId and m_linkData are defined by OSPF to have different meanings - * depending on the type of link a given link records represents. They work - * together. - * - * For Type 1 link (PointToPoint), set m_linkData to local IP address - * - * For Type 3 link (Stub), set m_linkData to mask - */ +/** + * m_linkId and m_linkData are defined by OSPF to have different meanings + * depending on the type of link a given link records represents. They work + * together. + * + * For Type 1 link (PointToPoint), set m_linkData to local IP address + * + * For Type 3 link (Stub), set m_linkData to mask + */ Ipv4Address m_linkData; // for links to RouterLSA, - +/** + * The type of the Static Router Link Record. Defined in the OSPF spec. + * We currently only use PointToPoint and StubNetwork types. + */ LinkType m_linkType; - /** - * The metric for a given link. - * - * A metric is abstract cost associated with forwarding a packet across a - * link. A sum of metrics must have a well-defined meaning. That is, you - * shouldn't use bandwidth as a metric (how does the sum of the bandwidth - * of two hops relate to the cost of sending a packet); rather you should - * use something like delay. - */ +/** + * The metric for a given link. + * + * A metric is abstract cost associated with forwarding a packet across a + * link. A sum of metrics must have a well-defined meaning. That is, you + * shouldn't use bandwidth as a metric (how does the sum of the bandwidth + * of two hops relate to the cost of sending a packet); rather you should + * use something like delay. + */ uint32_t m_metric; }; @@ -405,79 +408,79 @@ std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); class StaticRouter : public Object { public: - /** - * The Interface ID of the Static Router interface. - * - * @see Object::QueryInterface () - */ +/** + * The Interface ID of the Static Router interface. + * + * @see Object::QueryInterface () + */ static const InterfaceId iid; - /** - * Create a Static Router class and aggregate its interface onto the Node - * provided. - * - * @param node The existing Node onto which this router will be aggregated. - */ +/** + * Create a Static Router class and aggregate its interface onto the Node + * provided. + * + * @param node The existing Node onto which this router will be aggregated. + */ StaticRouter (Ptr node); - /** - * Get the Router ID associated with this Static Router. The Router IDs - * are allocated in the RoutingEnvironment -- one per Router, starting at - * 0.0.0.1 and incrementing with each instantiation of a router. - * - * @see RoutingEnvironment::AllocateRouterId () - * @returns The Router ID associated with the Static Router. - */ +/** + * Get the Router ID associated with this Static Router. The Router IDs + * are allocated in the RoutingEnvironment -- one per Router, starting at + * 0.0.0.1 and incrementing with each instantiation of a router. + * + * @see RoutingEnvironment::AllocateRouterId () + * @returns The Router ID associated with the Static Router. + */ Ipv4Address GetRouterId (void) const; - /** - * Walk the connected channels, discover the adjacent routers and build - * the associated number of Static Router Link State Advertisements that - * this router can export. - * - * This is a fairly expensive operation in that every time it is called - * the current list of LSAs is built by walking connected point-to-point - * channels and peeking into adjacent IPV4 stacks to get address information. - * This is done to allow for limited dymanics of the Static Routing - * environment. By that we mean that you can discover new link state - * advertisements after a network topology change by calling DiscoverLSAs - * and then by reading those advertisements. - * - * @see StaticRouterLSA - * @see StaticRouter::GetLSA () - * @returns The number of Static Router Link State Advertisements. - */ +/** + * Walk the connected channels, discover the adjacent routers and build + * the associated number of Static Router Link State Advertisements that + * this router can export. + * + * This is a fairly expensive operation in that every time it is called + * the current list of LSAs is built by walking connected point-to-point + * channels and peeking into adjacent IPV4 stacks to get address information. + * This is done to allow for limited dymanics of the Static Routing + * environment. By that we mean that you can discover new link state + * advertisements after a network topology change by calling DiscoverLSAs + * and then by reading those advertisements. + * + * @see StaticRouterLSA + * @see StaticRouter::GetLSA () + * @returns The number of Static Router Link State Advertisements. + */ uint32_t DiscoverLSAs (void); - /** - * Get the Number of Static Router Link State Advertisements that this - * router can export. To get meaningful information you must have - * previously called DiscoverLSAs. After you know how many LSAs are - * present in the router, you may call GetLSA () to retrieve the actual - * advertisement. - * - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () - * @see StaticRouter::GetLSA () - * @returns The number of Static Router Link State Advertisements. - */ +/** + * Get the Number of Static Router Link State Advertisements that this + * router can export. To get meaningful information you must have + * previously called DiscoverLSAs. After you know how many LSAs are + * present in the router, you may call GetLSA () to retrieve the actual + * advertisement. + * + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @see StaticRouter::GetLSA () + * @returns The number of Static Router Link State Advertisements. + */ uint32_t GetNumLSAs (void) const; - /** - * Get a Static Router 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 Static Router Link - * State Advertisement into the requested StaticRouterLSA object. - * - * You must call StaticRouter::GetNumLSAs before calling this method in - * order to discover the adjacent routers and build the advertisements. - * GetNumLSAs will return the number of LSAs this router advertises. - * The parameter n (requested LSA number) must be in the range 0 to - * GetNumLSAs() - 1. - * - * @see StaticRouterLSA - * @see StaticRouter::GetNumLSAs () - * @param n The index number of the LSA you want to read. - * @param lsa The StaticRouterLSA class to receive the LSA information. - * @returns The number of Static Router Link State Advertisements. - */ +/** + * Get a Static Router 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 Static Router Link + * State Advertisement into the requested StaticRouterLSA object. + * + * You must call StaticRouter::GetNumLSAs before calling this method in + * order to discover the adjacent routers and build the advertisements. + * GetNumLSAs will return the number of LSAs this router advertises. + * The parameter n (requested LSA number) must be in the range 0 to + * GetNumLSAs() - 1. + * + * @see StaticRouterLSA + * @see StaticRouter::GetNumLSAs () + * @param n The index number of the LSA you want to read. + * @param lsa The StaticRouterLSA class to receive the LSA information. + * @returns The number of Static Router Link State Advertisements. + */ bool GetLSA (uint32_t n, StaticRouterLSA &lsa) const; protected: @@ -495,13 +498,13 @@ protected: Ipv4Address m_routerId; private: - /** - * Static Router copy construction is disallowed. - */ +/** + * Static Router copy construction is disallowed. + */ StaticRouter (StaticRouter& sr); - /** - * Static Router copy assignment operator is disallowed. - */ +/** + * Static Router copy assignment operator is disallowed. + */ StaticRouter& operator= (StaticRouter& sr); }; From f3523e838195ad30bf1587cde4c446bae97e1e5b Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 19 Jul 2007 22:48:50 -0700 Subject: [PATCH 72/92] last parts of general cleaup and commenting --- src/routing/candidate-queue.h | 18 +- src/routing/static-route-manager.cc | 86 ++-- src/routing/static-route-manager.h | 613 +++++++++++++++++++++++++--- src/routing/static-router.cc | 18 + src/routing/static-router.h | 16 +- 5 files changed, 643 insertions(+), 108 deletions(-) diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index e9c985287..5d8993f2e 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -24,7 +24,7 @@ namespace ns3 { /** - * \brief a Candidate Queue used in static routing. + * \brief A Candidate Queue used in static routing. * * The CandidateQueue is used in the OSPF shortest path computations. It * is a priority queue used to store candidates for the shortest path to a @@ -62,7 +62,7 @@ public: * * @see SPFVertex */ - void Clear (void); + void Clear (void); /** * Push a Shortest Path First Vertex pointer onto the queue according to the * priority scheme. @@ -75,7 +75,7 @@ public: * @see SPFVertex * @param vNew The Shortest Path First Vertex to add to the queue. */ - void Push (SPFVertex *vNew); + void Push (SPFVertex *vNew); /** * Pop the Shortest Path First Vertex pointer at the top of the queue. * The caller is given the responsiblity for releasing the resources @@ -85,7 +85,7 @@ public: * @see Top () * @returns The Shortest Path First Vertex pointer at the top of the queue. */ - SPFVertex* Pop (void); + SPFVertex* Pop (void); /** * Return the Shortest Path First Vertex pointer at the top of the queue. * This method does not pop the SPFVertex* off of the queue, it simply @@ -95,13 +95,13 @@ public: * @see Pop () * @returns The Shortest Path First Vertex pointer at the top of the queue. */ - SPFVertex* Top (void) const; + SPFVertex* Top (void) const; /** * Test the Candidate Queue to determine if it is empty. * * @returns True if the queue is empty, false otherwise. */ - bool Empty (void) const; + bool Empty (void) const; /** * Return the number of Shortest Path First Vertex pointers presently * stored in the Candidate Queue. @@ -109,7 +109,7 @@ public: * @see SPFVertex * @returns The number of SPFVertex* pointers in the Candidate Queue. */ - uint32_t Size (void) const; + uint32_t Size (void) const; /** * Searches the Candidate Queue for a Shortest Path First Vertex pointer * that points to a vertex having the given IP address. @@ -118,7 +118,7 @@ public: * @param addr The IP address to search for. * @returns The SPFVertex* pointer corresponding to the given IP address. */ - SPFVertex* Find (const Ipv4Address addr) const; + SPFVertex* Find (const Ipv4Address addr) const; /** * Reorders the Candidate Queue according to the priority scheme. On * completion, the top of the queue will hold the Shortest Path First @@ -131,7 +131,7 @@ public: * * @see SPFVertex */ - void Reorder (void); + void Reorder (void); protected: typedef std::list CandidateList_t; diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 408f2a91d..02948ac9c 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -30,6 +30,12 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); namespace ns3 { +// --------------------------------------------------------------------------- +// +// SPFVertex Implementation +// +// --------------------------------------------------------------------------- + SPFVertex::SPFVertex () : m_vertexType (VertexUnknown), m_vertexId ("255.255.255.255"), @@ -183,6 +189,12 @@ SPFVertex::AddChild (SPFVertex* child) return m_children.size (); } +// --------------------------------------------------------------------------- +// +// StaticRouteManagerLSDB Implementation +// +// --------------------------------------------------------------------------- + StaticRouteManagerLSDB::StaticRouteManagerLSDB () : m_database () @@ -205,7 +217,7 @@ StaticRouteManagerLSDB::~StaticRouteManagerLSDB () m_database.clear (); } -void + void StaticRouteManagerLSDB::Initialize () { NS_DEBUG ("StaticRouteManagerLSDB::Initialize ()"); @@ -218,19 +230,21 @@ StaticRouteManagerLSDB::Initialize () } } -void + void StaticRouteManagerLSDB::Insert (Ipv4Address addr, StaticRouterLSA* lsa) { NS_DEBUG ("StaticRouteManagerLSDB::Insert ()"); m_database.insert (LSDBPair_t (addr, lsa)); } -StaticRouterLSA* -StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) + StaticRouterLSA* +StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) const { NS_DEBUG ("StaticRouteManagerLSDB::GetLSA ()"); - // Look up an LSA by its address - LSDBMap_t::iterator i; +// +// Look up an LSA by its address. +// + LSDBMap_t::const_iterator i; for (i= m_database.begin (); i!= m_database.end (); i++) { if (i->first == addr) @@ -241,7 +255,15 @@ StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) return 0; } -StaticRouteManager::StaticRouteManager () : m_spfroot (0) +// --------------------------------------------------------------------------- +// +// StaticRouteManager Implementation +// +// --------------------------------------------------------------------------- + +StaticRouteManager::StaticRouteManager () +: + m_spfroot (0) { m_lsdb = new StaticRouteManagerLSDB (); } @@ -256,7 +278,7 @@ StaticRouteManager::~StaticRouteManager () } } -void + void StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) { if (m_lsdb) @@ -273,7 +295,7 @@ StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) // add them to the Link State DataBase (LSDB) from which the routes will // ultimately be computed. // -void + void StaticRouteManager::BuildStaticRoutingDatabase () { NS_DEBUG ("StaticRouteManager::BuildStaticRoutingDatabase()"); @@ -356,7 +378,7 @@ StaticRouteManager::BuildStaticRoutingDatabase () // algorithm then iterates again. It terminates when the candidate // list becomes empty. // -void + void StaticRouteManager::InitializeRoutes () { NS_DEBUG ("StaticRouteManager::InitializeRoutes ()"); @@ -397,7 +419,7 @@ StaticRouteManager::InitializeRoutes () // vertices not already on the list. If a lower-cost path is found to a // vertex already on the candidate list, store the new (lower) cost. // -void + void StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) { SPFVertex* w = 0; @@ -561,7 +583,7 @@ StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) // // For now, this is greatly simplified from the quagga code // -int + int StaticRouteManager::SPFNexthopCalculation ( SPFVertex* v, SPFVertex* w, @@ -684,15 +706,14 @@ StaticRouteManager::SPFNexthopCalculation ( // to . If prev_link is not NULL, we return a Static Router Link Record // representing a possible *second* link from to . // -// BUGBUG This seems to be a bug? Shouldn't this function look for any link -// records after pre_link and not just after the first? +// 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? // -StaticRouterLinkRecord* + StaticRouterLinkRecord* StaticRouteManager::SPFGetNextLink ( SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* prev_link - ) + StaticRouterLinkRecord* prev_link) { NS_DEBUG ("StaticRouteManager::SPFGetNextLink ()"); @@ -760,14 +781,14 @@ StaticRouteManager::SPFGetNextLink ( // // Used for unit tests. // -void + void StaticRouteManager::DebugSPFCalculate (Ipv4Address root) { SPFCalculate (root); } // quagga ospf_spf_calculate -void + void StaticRouteManager::SPFCalculate (Ipv4Address root) { NS_DEBUG ("StaticRouteManager::SPFCalculate (): " @@ -870,11 +891,11 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) // root in order of distance from the root. For each of the vertices, we call // SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the // point-to-point Static Router Link Records (the links to nodes adjacent to -// the node represented by the vertex). We add a link to the IP address +// the node represented by the vertex). We add a route to the IP address // specified by the m_linkData field of each of those link records. This will // be the *local* IP address associated with the interface attached to the // link. We use the outbound interface and next hop information present in -// the vertex . +// the vertex which have possibly been inherited from the root. // // To summarize, we're going to look at the node represented by and loop // through its point-to-point links, adding a *host* route to the local IP @@ -901,11 +922,11 @@ StaticRouteManager::SPFCalculate (Ipv4Address root) } // -// XXX this should probably be a method on Ipv4 +// BUGBUG FIXME: This should probably be a method on Ipv4 // // Return the interface index corresponding to a given IP address // -uint32_t + uint32_t StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) { // @@ -988,7 +1009,7 @@ StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) // a destination IP address, reachable from the root, to which we add a host // route. // -void + void StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) { NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter ()"); @@ -1115,12 +1136,11 @@ StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) // Given a pointer to a vertex, it links back to the vertex's parent that it // already has set and adds itself to that vertex's list of children. // -void -StaticRouteManager::SPFVertexAddParent (SPFVertex* v) -{ -// // For now, only one parent (not doing equal-cost multipath) // + void +StaticRouteManager::SPFVertexAddParent (SPFVertex* v) +{ v->GetParent ()->AddChild (v); } @@ -1128,6 +1148,12 @@ StaticRouteManager::SPFVertexAddParent (SPFVertex* v) #ifdef RUN_SELF_TESTS +// --------------------------------------------------------------------------- +// +// Unit Tests +// +// --------------------------------------------------------------------------- + #include "ns3/test.h" namespace ns3 { @@ -1147,7 +1173,7 @@ StaticRouterTestNode::StaticRouterTestNode () // Ptr ipv4 = Create (this); } -TraceResolver* + TraceResolver* StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) { return 0; @@ -1168,7 +1194,7 @@ StaticRouteManagerTest::StaticRouteManagerTest () StaticRouteManagerTest::~StaticRouteManagerTest () {} -bool + bool StaticRouteManagerTest::RunTests (void) { bool ok = true; diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index a54cf2fdd..67e120da4 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -32,140 +32,618 @@ const uint32_t SPF_INFINITY = 0xffffffff; class CandidateQueue; /** - * \brief Vertex used in shortest path first (SPF) computations + * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328, + * Section 16. * - * See RFC 2328, Section 16. + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is the SPFVertex representing the router that is having + * its routing tables set. The SPFVertex objects representing other routers + * or networks in the simulation are arranged in the SPF tree. It is this + * tree that represents the Shortest Paths to the other networks. + * + * Each SPFVertex has a pointer to the Static Router Link State Advertisement + * (LSA) that its underlying router has exported. Within these LSAs are + * Static Router Link Records that describe the point to point links from the + * underlying router to other nodes (represented by other SPFVertex objects) + * in the simulation topology. The combination of the arrangement of the + * SPFVertex objects in the SPF tree, along with the details of the link + * records that connect them provide the information required to construct the + * required routes. */ class SPFVertex { public: - SPFVertex(); - SPFVertex(StaticRouterLSA*); - ~SPFVertex(); - +/** + * @enum Enumeration of the possible types of SPFVertex objects. Currently + * we use VertexRouter to identify objects that represent a router in the + * simulation topology, and VertexNetwork to identify objects that represent + * a network. + */ enum VertexType { - VertexUnknown = 0, - VertexRouter, - VertexNetwork + VertexUnknown = 0, /**< Uninitialized Link Record */ + VertexRouter, /**< Vertex representing a router in the topology */ + VertexNetwork /**< Vertex representing a network in the topology */ }; - - void SetVertexType (VertexType type); +/** + * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First + * Vertex). + * + * The Vertex Type is set to VertexUnknown, the Vertex ID is set to + * 255.255.255.255, and the distance from root is set to infinity + * (UINT32_MAX). The referenced Link State Advertisement (LSA) is set to + * null as is the parent SPFVertex. The outgoing interface index is set to + * infinity, the next hop address is set to 0.0.0.0 and the list of children + * of the SPFVertex is initialized to empty. + * + * @see VertexType + */ + SPFVertex(); +/** + * @brief Construct an initialized SPFVertex (Shortest Path First Vertex). + * + * The Vertex Type is initialized to VertexRouter and the Vertex ID is found + * from the Link State ID of the Link State Advertisement (LSA) passed as a + * parameter. The Link State ID is set to the Router ID of the advertising + * router. The referenced LSA (m_lsa) is set to the given LSA. Other than + * these members, initialization is as in the default constructor. + * of the SPFVertex is initialized to empty. + * + * @see SPFVertex::SPFVertex () + * @see VertexType + * @see StaticRouterLSA + * @param lsa The Link State Advertisement used for finding initial values. + */ + SPFVertex(StaticRouterLSA* lsa); +/** + * @brief Destroy an SPFVertex (Shortest Path First Vertex). + * + * The children vertices of the SPFVertex are recursively deleted. + * + * @see SPFVertex::SPFVertex () + */ + ~SPFVertex(); +/** + * @brief Get the Vertex Type field of a SPFVertex object. + * + * The Vertex Type describes the kind of simulation object a given SPFVertex + * represents. + * + * @see VertexType + * @returns The VertexType of the current SPFVertex object. + */ VertexType GetVertexType (void) const; - - void SetVertexId (Ipv4Address idV); +/** + * @brief Set the Vertex Type field of a SPFVertex object. + * + * The Vertex Type describes the kind of simulation object a given SPFVertex + * represents. + * + * @see VertexType + * @param The new VertexType for the current SPFVertex object. + */ + void SetVertexType (VertexType type); +/** + * @brief Get the Vertex ID field of a SPFVertex object. + * + * The Vertex ID uniquely identifies the simulation object a given SPFVertex + * represents. Typically, this is the Router ID for SPFVertex objects + * representing routers, and comes from the Link State Advertisement of a + * router aggregated to a node in the simulation. These IDs are allocated + * automatically by the routing environment and look like IP addresses + * beginning at 0.0.0.0 and monotonically increasing as new routers are + * instantiated. + * + * @returns The Ipv4Address Vertex ID of the current SPFVertex object. + */ Ipv4Address GetVertexId (void) const; - - void SetLSA (StaticRouterLSA* lsa); +/** + * @brief Set the Vertex ID field of a SPFVertex object. + * + * The Vertex ID uniquely identifies the simulation object a given SPFVertex + * represents. Typically, this is the Router ID for SPFVertex objects + * representing routers, and comes from the Link State Advertisement of a + * router aggregated to a node in the simulation. These IDs are allocated + * automatically by the routing environment and look like IP addresses + * beginning at 0.0.0.0 and monotonically increasing as new routers are + * instantiated. + * + * @param id The new Ipv4Address Vertex ID for the current SPFVertex object. + */ + void SetVertexId (Ipv4Address id); +/** + * @brief Get the Static Router Link State Advertisement returned by the + * Static Router represented by this SPFVertex during the route discovery + * process. + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @returns A pointer to the StaticRouterLSA found by the router represented + * by this SPFVertex object. + */ StaticRouterLSA* GetLSA (void) const; - - void SetDistanceFromRoot (uint32_t distance); +/** + * @brief Set the Static Router Link State Advertisement returned by the + * Static Router represented by this SPFVertex during the route discovery + * process. + * + * @see SPFVertex::GetLSA () + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You + * must not delete the LSA after calling this method. + * @param A pointer to the StaticRouterLSA. + */ + void SetLSA (StaticRouterLSA* lsa); +/** + * @brief Get the distance from the root vertex to "this" SPFVertex object. + * + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex to which + * a route is being calculated from the root. The distance from the root that + * we're asking for is the number of hops from the root vertex to the vertex + * in question. + * + * The distance is calculated during route discovery and is stored in a + * member variable. This method simply fetches that value. + * + * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex. + */ uint32_t GetDistanceFromRoot (void) const; - - void SetOutgoingInterfaceId (uint32_t id); +/** + * @brief Set the distance from the root vertex to "this" SPFVertex object. + * + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex to which + * a route is being calculated from the root. The distance from the root that + * we're asking for is the number of hops from the root vertex to the vertex + * in question. + * + * @param distance The distance, in hops, from the root SPFVertex to "this" + * SPFVertex. + */ + void SetDistanceFromRoot (uint32_t distance); +/** + * @brief Get the interface ID that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The outgoing interface that we're asking for is the interface + * index on the root node that should be used to start packets along the + * path to "this" vertex. + * + * When initializing the root SPFVertex, the interface ID is determined by + * examining the Static Router Link Records of the Link State Advertisement + * generated by the root node's StaticRouter. These interfaces are used to + * forward packets off of the root's network down those links. As other + * vertices are discovered which are further away from the root, they will + * be accessible down one of the paths begun by a Static Router Link Record. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to the interface of that + * first hop. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, the root node is asking, "which of my local interfaces + * should I use to get a packet to the network or host represented by 'this' + * SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @returns The interface index to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ uint32_t GetOutgoingInterfaceId (void) const; - - void SetNextHop (Ipv4Address nextHop); +/** + * @brief Set the interface ID that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The outgoing interface that we're asking for is the interface + * index on the root node that should be used to start packets along the + * path to "this" vertex. + * + * When initializing the root SPFVertex, the interface ID is determined by + * examining the Static Router Link Records of the Link State Advertisement + * generated by the root node's StaticRouter. These interfaces are used to + * forward packets off of the root's network down those links. As other + * vertices are discovered which are further away from the root, they will + * be accessible down one of the paths begun by a Static Router Link Record. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to the interface of that + * first hop. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, we are letting the root node know which of its local + * interfaces it should use to get a packet to the network or host represented + * by "this" SPFVertex. + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @param id The interface index to use when forwarding packets to the host or + * network represented by "this" SPFVertex. + */ + void SetOutgoingInterfaceId (uint32_t id); +/** + * @brief Get the IP address that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The IP address that we're asking for is the address on the + * remote side of a link off of the root node that should be used as the + * destination for packets along the path to "this" vertex. + * + * When initializing the root SPFVertex, the IP address used when forwarding + * packets is determined by examining the Static Router Link Records of the + * Link State Advertisement generated by the root node's StaticRouter. This + * address is used to forward packets off of the root's network down those + * links. As other vertices / nodes are discovered which are further away + * from the root, they will be accessible down one of the paths via a link + * described by one of these Static Router Link Records. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to a first hop router down + * an interface. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, the root node is asking, "which router should I send a + * packet to in order to get that packet to the network or host represented + * by 'this' SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @returns The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ Ipv4Address GetNextHop (void) const; - - void SetParent (SPFVertex* parent); +/** + * @brief Set the IP address that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The IP address that we're asking for is the address on the + * remote side of a link off of the root node that should be used as the + * destination for packets along the path to "this" vertex. + * + * When initializing the root SPFVertex, the IP address used when forwarding + * packets is determined by examining the Static Router Link Records of the + * Link State Advertisement generated by the root node's StaticRouter. This + * address is used to forward packets off of the root's network down those + * links. As other vertices / nodes are discovered which are further away + * from the root, they will be accessible down one of the paths via a link + * described by one of these Static Router Link Records. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to a first hop router down + * an interface. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method we are telling the root node which router it should send + * should I send a packet to in order to get that packet to the network or + * host represented by 'this' SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @param nextHop The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ + void SetNextHop (Ipv4Address nextHop); +/** + * @brief Get a pointer to the SPFVector that is the parent of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. + * + * This method returns a pointer to the parent node of "this" SPFVertex + * (both of which reside in that SPF tree). + * + * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex + * in the SPF tree. + */ SPFVertex* GetParent (void) const; - +/** + * @brief Set the pointer to the SPFVector that is the parent of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. + * + * This method sets the parent pointer of "this" SPFVertex (both of which + * reside in that SPF tree). + * + * @param parent A pointer to the SPFVertex that is the parent of "this" + * SPFVertex* in the SPF tree. + */ + void SetParent (SPFVertex* parent); +/** + * @brief Get the number of children of "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method returns the number of children of "this" SPFVertex (which + * reside in the SPF tree). + * + * @returns The number of children of "this" SPFVertex (which reside in the + * SPF tree). + */ uint32_t GetNChildren (void) const; +/** + * @brief Get a borrowed SPFVertex pointer to the specified child of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method the number of children of "this" SPFVertex (which reside in + * the SPF tree. + * + * @see SPFVertex::GetNChildren + * @param n The index (from 0 to the number of children minus 1) of the + * child SPFVertex to return. + * @warning The pointer returned by GetChild () is a borrowed pointer. You + * do not have any ownership of the underlying object and must not delete + * that object. + * @returns A pointer to the specified child SPFVertex (which resides in the + * SPF tree). + */ SPFVertex* GetChild (uint32_t n) const; - +/** + * @brief Get a borrowed SPFVertex pointer to the specified child of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method the number of children of "this" SPFVertex (which reside in + * the SPF tree. + * + * @see SPFVertex::GetNChildren + * @param n The index (from 0 to the number of children minus 1) of the + * child SPFVertex to return. + * @warning Ownership of the pointer added to the children of "this" + * SPFVertex is transferred to the "this" SPFVertex. You must not delete the + * (now) child SPFVertex after calling this method. + * @param child A pointer to the SPFVertex (which resides in the SPF tree) to + * be added to the list of children of "this" SPFVertex. + * @returns The number of children of "this" SPFVertex after the addition of + * the new child. + */ uint32_t AddChild (SPFVertex* child); private: VertexType m_vertexType; - Ipv4Address m_vertexId; // router id - StaticRouterLSA* m_lsa; // This pointer owns LSA for mem. mgmt purposes + Ipv4Address m_vertexId; + StaticRouterLSA* m_lsa; uint32_t m_distanceFromRoot; uint32_t m_rootOif; Ipv4Address m_nextHop; - - // need to keep track of current parent vertex SPFVertex* m_parent; - - // m_children lists the leaves from your SPF tree typedef std::list ListOfSPFVertex_t; ListOfSPFVertex_t m_children; /** - * The SPFVertex copy construction is disallowed. There's no need for + * @brief The SPFVertex copy construction is disallowed. There's no need for * it and a compiler provided shallow copy would be wrong. */ SPFVertex (SPFVertex& v); /** - * The SPFVertex copy assignment operator is disallowed. There's no need for - * it and a compiler provided shallow copy would be wrong. + * @brief The SPFVertex copy assignment operator is disallowed. There's no + * need for it and a compiler provided shallow copy would be wrong. */ SPFVertex& operator= (SPFVertex& v); }; /** - * \brief The Link State DataBase (LSDB) of a static router + * @brief The Link State DataBase (LSDB) of the Static Route Manager. + * + * Each node in the simulation participating in static routing has a + * StaticRouter interface. The primary job of this interface is to export + * Static Router Link State Advertisements (LSAs). These advertisements in + * turn contain a number of Static Router Link Records that describe the + * point to point links from the underlying node to other nodes (that will + * also export their own LSAs. + * + * This class implements a searchable database of LSAs gathered from every + * router in the simulation. */ class StaticRouteManagerLSDB { public: +/** + * @brief Construct an empty Static Router Manager Link State Database. + * + * The database map composing the Link State Database is initialized in + * this constructor. + */ StaticRouteManagerLSDB (); +/** + * @brief Destroy an empty Static Router Manager Link State Database. + * + * The database map is walked and all of the Link State Advertisements stored + * in the database are freed; then the database map itself is clear ()ed to + * release any remaining resources. + */ ~StaticRouteManagerLSDB (); +/** + * @brief Insert an IP address / Link State Advertisement pair into the Link + * State Database. + * + * The IPV4 address and the StaticRouterLSA given as parameters are converted + * to an STL pair and are inserted into the database map. + * + * @see StaticRouterLSA + * @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, StaticRouterLSA* lsa); - StaticRouterLSA* GetLSA (Ipv4Address addr); - /** - * \brief Set all LSA flags to an initialized state, for SPF computation - */ +/** + * @brief Look up the Link State Advertisement associated with the given + * IP Address. + * + * The database map is searched for the given IPV4 address and corresponding + * StaticRouterLSA is returned. + * + * @see StaticRouterLSA + * @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. + */ + StaticRouterLSA* GetLSA (Ipv4Address addr) const; +/** + * @brief Set all LSA flags to an initialized state, for SPF computation + * + * This function walks the database and resets the status flags of all of the + * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done + * prior to each SPF calculation to reset the state of the SPFVertex structures + * that will reference the LSAs during the calculation. + * + * @see StaticRouterLSA + * @see SPFVertex + */ void Initialize (); +private: typedef std::map LSDBMap_t; typedef std::pair LSDBPair_t; + LSDBMap_t m_database; -private: /** - * StaticRouteManagerLSDB copy construction is disallowed. There's no + * @brief StaticRouteManagerLSDB copy construction is disallowed. There's no * need for it and a compiler provided shallow copy would be hopelessly wrong. */ StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); /** - * The SPFVertex copy assignment operator is disallowed. There's no need for - * it and a compiler provided shallow copy would be wrong. + * @brief The SPFVertex copy assignment operator is disallowed. There's no + * need for it and a compiler provided shallow copy would be wrong. */ StaticRouteManagerLSDB& operator= (StaticRouteManagerLSDB& lsdb); }; /** - * \brief A global static router + * @brief A global static router * * This singleton object can query interface each node in the system * for a StaticRouter interface. For those nodes, it fetches one or - * more LSAs and stores them in a local database. Then, it - * can compute shortest paths on a per-node basis to all routers, and - * finally configure each of the node's forwarding tables. + * more Link State Advertisements and stores them in a local database. + * Then, it can compute shortest paths on a per-node basis to all routers, + * and finally configure each of the node's forwarding tables. * - * The design is guided by OSPFv2 RFC 2328 section 16.1.1 - * and quagga ospfd + * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd. */ class StaticRouteManager : public Object { public: static const InterfaceId iid; StaticRouteManager (); - /** - * \brief Build routing database by gathering LSA from each routing node - */ +/** + * @brief Build the routing database by gathering Link State Advertisements + * from each node exporting a StaticRouter interface. + * + */ virtual void BuildStaticRoutingDatabase(); - /** - * \brief Compute routes using Dijkstra SPF computation, and populate - * per-node forwarding tables - */ +/** + * @brief Compute routes using a Dijkstra SPF computation and populate + * per-node forwarding tables + */ virtual void InitializeRoutes(); - - /** - * \brief Debugging routine; allow client code to supply a pre-built LSDB - */ +/** + * @brief Debugging routine; allow client code to supply a pre-built LSDB + */ void DebugUseLsdb (StaticRouteManagerLSDB*); - /** - * \brief Debugging routine; call the core SPF from the unit tests - */ +/** + * @brief Debugging routine; call the core SPF from the unit tests + */ void DebugSPFCalculate (Ipv4Address root); virtual ~StaticRouteManager (); @@ -174,14 +652,14 @@ protected: private: /** - * Static Route Manager copy construction is disallowed. There's no need for - * it and a compiler provided shallow copy would be hopelessly wrong. + * @brief Static Route Manager copy construction is disallowed. There's no + * need for it and a compiler provided shallow copy would be hopelessly wrong. * */ StaticRouteManager (StaticRouteManager& srm); /** - * Static Router copy assignment operator is disallowed. There's no need for - * it and a compiler provided shallow copy would be hopelessly wrong. + * @brief Static Router copy assignment operator is disallowed. There's no + * need for it and a compiler provided shallow copy would be hopelessly wrong. */ StaticRouteManager& operator= (StaticRouteManager& srm); @@ -196,7 +674,6 @@ private: StaticRouterLinkRecord* prev_link); void SPFIntraAddRouter(SPFVertex* v); uint32_t FindOutgoingInterfaceId(Ipv4Address a); - }; } // namespace ns3 diff --git a/src/routing/static-router.cc b/src/routing/static-router.cc index b70d865e1..82aa2c2e4 100644 --- a/src/routing/static-router.cc +++ b/src/routing/static-router.cc @@ -26,6 +26,12 @@ NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); namespace ns3 { +// --------------------------------------------------------------------------- +// +// StaticRouterLinkRecord Implementation +// +// --------------------------------------------------------------------------- + StaticRouterLinkRecord::StaticRouterLinkRecord () : m_linkId ("0.0.0.0"), @@ -113,6 +119,12 @@ StaticRouterLinkRecord::SetMetric (uint32_t metric) m_metric = metric; } +// --------------------------------------------------------------------------- +// +// StaticRouterLSA Implementation +// +// --------------------------------------------------------------------------- + StaticRouterLSA::StaticRouterLSA() : m_linkStateId("0.0.0.0"), @@ -297,6 +309,12 @@ std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa) return os; } +// --------------------------------------------------------------------------- +// +// StaticRouter Implementation +// +// --------------------------------------------------------------------------- + const InterfaceId StaticRouter::iid = MakeInterfaceId ("StaticRouter", Object::iid); diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 6f3f66cc6..24bceca70 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -60,7 +60,7 @@ public: */ StaticRouterLinkRecord (); /** - * Construct a fully uninitialized Static Router Link Record. + * Construct an initialized Static Router Link Record. * * @param linkType The type of link record to construct. * @param linkId The link ID for the record. @@ -89,6 +89,8 @@ public: * * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent * neighbor's IP address + * + * @returns The Ipv4Address corresponding to the Link ID field of the record. */ Ipv4Address GetLinkId(void) const; /** @@ -99,6 +101,8 @@ public: * * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent * neighbor's IP address + * + * @param An Ipv4Address to store in the Link ID field of the record. */ void SetLinkId(Ipv4Address addr); /** @@ -109,6 +113,8 @@ public: * * For an OSPF type 3 link (StubNetwork), the Link Data will be the * network mask + * + * @returns The Ipv4Address corresponding to the Link Data field of the record. */ Ipv4Address GetLinkData(void) const; /** @@ -119,6 +125,8 @@ public: * * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the * network mask + * + * @param An Ipv4Address to store in the Link Data field of the record. */ void SetLinkData(Ipv4Address addr); /** @@ -128,6 +136,7 @@ public: * values are defined by OSPF. * * @see LinkType + * @returns The LinkType of the current Static Router Link Record. */ LinkType GetLinkType(void) const; /** @@ -137,6 +146,7 @@ public: * values are defined by OSPF. * * @see LinkType + * @param linkType The new LinkType for the current Static Router Link Record. */ void SetLinkType(LinkType linkType); /** @@ -147,6 +157,8 @@ public: * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of * two hops relate to the cost of sending a packet); rather you should use * something like delay. + * + * @returns The metric field of the Static Router Link Record. */ uint32_t GetMetric(void) const; /** @@ -157,6 +169,8 @@ public: * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of * 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 Static Router Link Record. */ void SetMetric(uint32_t metric); From ab93e1f56d3b9e4df08ccd1d23c591bfea49af47 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 19 Jul 2007 23:04:09 -0700 Subject: [PATCH 73/92] overlooked one --- src/routing/static-router.h | 130 +++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 60 deletions(-) diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 24bceca70..85ec59fad 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -30,7 +30,7 @@ namespace ns3 { /** - * \brief A single link record for a link state advertisement. + * @brief A single link record for a link state advertisement. * * The StaticRouterLinkRecord is modeled after the OSPF link record field of * a Link State Advertisement. Right now we will only see two types of link @@ -40,8 +40,8 @@ class StaticRouterLinkRecord { public: /** - * Enumeration of the possible types of Static Router Link Records. These - * are defined in the OSPF spec. We currently only use PointToPoint and + * @enum Enumeration of the possible types of Static Router Link Records. + * These are defined in the OSPF spec. We currently only use PointToPoint and * StubNetwork types. */ enum LinkType { @@ -52,7 +52,7 @@ public: VirtualLink /**< Unused -- for future OSPF compatibility */ }; /** - * Construct an empty ("uninitialized") Static Router Link Record. + * @brief Construct an empty ("uninitialized") Static Router Link Record. * * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0"; * The Link Type is set to Unknown; @@ -76,7 +76,7 @@ public: Ipv4Address linkData, uint32_t metric); /** - * Destroy a Static Router Link Record. + * @brief Destroy a Static Router Link Record. * * Currently does nothing. Here as a placeholder only. */ @@ -94,7 +94,7 @@ public: */ Ipv4Address GetLinkId(void) const; /** - * Set the Link ID field of the Static Router Link Record. + * @brief Set the Link ID field of the Static Router Link Record. * * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID * of the neighboring router. @@ -106,7 +106,7 @@ public: */ void SetLinkId(Ipv4Address addr); /** - * Get the Link Data field of the Static Router Link Record. + * @brief Get the Link Data field of the Static Router 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. @@ -118,7 +118,7 @@ public: */ Ipv4Address GetLinkData(void) const; /** - * Set the Link Data field of the Static Router Link Record. + * @brief Set the Link Data field of the Static Router 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. @@ -130,7 +130,7 @@ public: */ void SetLinkData(Ipv4Address addr); /** - * Get the Link Type field of the Static Router Link Record. + * @brief Get the Link Type field of the Static Router Link Record. * * The Link Type describes the kind of link a given record represents. The * values are defined by OSPF. @@ -140,7 +140,7 @@ public: */ LinkType GetLinkType(void) const; /** - * Set the Link Type field of the Static Router Link Record. + * @brief Set the Link Type field of the Static Router Link Record. * * The Link Type describes the kind of link a given record represents. The * values are defined by OSPF. @@ -150,7 +150,7 @@ public: */ void SetLinkType(LinkType linkType); /** - * Get the Metric Data field of the Static Router Link Record. + * @brief Get the Metric Data field of the Static Router 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 @@ -162,7 +162,7 @@ public: */ uint32_t GetMetric(void) const; /** - * Set the Metric Data field of the Static Router Link Record. + * @brief Set the Metric Data field of the Static Router 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 @@ -214,7 +214,8 @@ private: }; /** - * \brief a Link State Advertisement (LSA) for a router, used in static routing + * @brief a Link State Advertisement (LSA) for a router, used in static + * routing. * * Roughly equivalent to a static incarnation of the OSPF link state header * combined with a list of Link Records. Since it's static, there's @@ -224,8 +225,8 @@ class StaticRouterLSA { public: /** - * Enumeration of the possible values of the status flag in the Router Link - * State Advertisements. + * @enum Enumeration of the possible values of the status flag in the Router + * Link State Advertisements. */ enum SPFStatus { LSA_SPF_NOT_EXPLORED = 0, /**< New vertex not yet considered */ @@ -233,14 +234,16 @@ public: LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */ }; /** - * Create a blank Static Router Link State Advertisement. On completion, - * any Ipv4Address variables initialized to 0.0.0.0 and the list of Link - * State Records is empty. + * @brief Create a blank Static Router Link State Advertisement. + * + * On completion Ipv4Address variables initialized to 0.0.0.0 and the + * list of Link State Records is empty. */ StaticRouterLSA(); /** - * Create an initialized Static Router Link State Advertisement. On - * completion the list of Link State Records is empty. + * @brief Create an initialized Static Router Link State Advertisement. + * + * On completion the list of Link State Records is empty. * * @param status The status to of the new LSA. * @param linkStateId The Ipv4Address for the link state ID field. @@ -249,7 +252,8 @@ public: StaticRouterLSA(SPFStatus status, Ipv4Address linkStateId, Ipv4Address advertisingRtr); /** - * Copy constructor for a Static Router Link State Advertisement. + * @brief Copy constructor for a Static Router Link State Advertisement. + * * Takes a piece of memory and constructs a semantically identical copy of * the given LSA. * @@ -257,12 +261,14 @@ public: */ StaticRouterLSA (StaticRouterLSA& lsa); /** - * Destroy an existing Static Router Link State Advertisement. Any Static - * router Link Records present in the list are freed. + * @brief Destroy an existing Static Router Link State Advertisement. + * + * Any Static Router Link Records present in the list are freed. */ ~StaticRouterLSA(); /** - * Assignment operator for a Static Router Link State Advertisement. + * @brief Assignment operator for a Static Router Link State Advertisement. + * * Takes an existing Static Router Link State Advertisement and overwrites * it to make a semantically identical copy of a given prototype LSA. * @@ -274,54 +280,56 @@ public: */ StaticRouterLSA& operator= (const StaticRouterLSA& lsa); /** - * Copy any Static Router Link Records in a given Static Router Link - * State Advertisement to the current LSA. Existing Link Records are not - * deleted -- this is a concatenation of Link Records. + * @brief Copy any Static Router Link Records in a given Static Router Link + * State Advertisement to the current LSA. + * + * Existing Link Records are not deleted -- this is a concatenation of Link + * Records. * * @see ClearLinkRecords () * @param lsa The LSA to copy the Link Records from. */ void CopyLinkRecords (const StaticRouterLSA& lsa); /** - * Add a given Static Router Link Record to the LSA. + * @brief Add a given Static Router Link Record to the LSA. * * @param lr The Static Router Link Record to be added. * @returns The number of link records in the list. */ uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); /** - * Return the number of Static Router Link Records in the LSA. + * @brief Return the number of Static Router Link Records in the LSA. * * @returns The number of link records in the list. */ uint32_t GetNLinkRecords (void) const; /** - * Return a pointer to the specified Static Router Link Record. + * @brief Return a pointer to the specified Static Router Link Record. * * @param n The LSA number desired. * @returns The number of link records in the list. */ StaticRouterLinkRecord* GetLinkRecord (uint32_t n) const; /** - * Release all of the Static Router Link Records present in the Static + * @brief Release all of the Static Router Link Records present in the Static * Router Link State Advertisement and make the list of link records empty. */ void ClearLinkRecords(void); /** - * Check to see of the list of Static Router Link Records present in the + * @brief Check to see if the list of Static Router Link Records present in the * Static Router Link State Advertisement is empty. * * @returns True if the list is empty, false otherwise. */ bool IsEmpty(void) const; /** - * Print the contents of the Static Router Link State Advertisement and + * @brief Print the contents of the Static Router Link State Advertisement and * any Static Router Link Records present in the list. Quite verbose. */ void Print (std::ostream &os) const; /** - * 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. + * @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 StaticRouter::GetRouterId () @@ -329,16 +337,16 @@ public: */ Ipv4Address GetLinkStateId (void) const; /** - * Set the Link State ID is defined by the OSPF spec. We always set it to - * the router ID of the router making the advertisement. + * @brief Set 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 StaticRouter::GetRouterId () */ void SetLinkStateId (Ipv4Address addr); /** - * Get the Advertising Router as defined by the OSPF spec. We always set - * it to the router ID of the router making the advertisement. + * @brief Get the Advertising Router as defined by the OSPF spec. We always + * set it to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () * @see StaticRouter::GetRouterId () @@ -346,22 +354,22 @@ public: */ Ipv4Address GetAdvertisingRouter (void) const; /** - * Set the Advertising Router as defined by the OSPF spec. We always set - * it to the router ID of the router making the advertisement. + * @brief Set the Advertising Router as defined by the OSPF spec. We always + * set it to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () * @see StaticRouter::GetRouterId () */ void SetAdvertisingRouter (Ipv4Address rtr); /** - * Get the SPF status of the advertisement. + * @brief Get the SPF status of the advertisement. * * @see SPFStatus * @returns The SPFStatus of the LSA. */ SPFStatus GetStatus (void) const; /** - * Set the SPF status of the advertisement + * @brief Set the SPF status of the advertisement * * @see SPFStatus */ @@ -411,7 +419,7 @@ private: std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); /** - * \brief An interface aggregated to a node to provide static routing info + * @brief An interface aggregated to a node to provide static routing info * * An interface aggregated to a node that provides static routing information * to a global route manager. The presence of the interface indicates that @@ -423,29 +431,30 @@ class StaticRouter : public Object { public: /** - * The Interface ID of the Static Router interface. + * @brief The Interface ID of the Static Router interface. * * @see Object::QueryInterface () */ static const InterfaceId iid; /** - * Create a Static Router class and aggregate its interface onto the Node - * provided. + * @brief Create a Static Router class and aggregate its interface onto the + * Node provided. * * @param node The existing Node onto which this router will be aggregated. */ StaticRouter (Ptr node); /** - * Get the Router ID associated with this Static Router. The Router IDs - * are allocated in the RoutingEnvironment -- one per Router, starting at - * 0.0.0.1 and incrementing with each instantiation of a router. + * @brief Get the Router ID associated with this Static Router. + * + * The Router IDs are allocated in the RoutingEnvironment -- one per Router, + * starting at 0.0.0.1 and incrementing with each instantiation of a router. * * @see RoutingEnvironment::AllocateRouterId () * @returns The Router ID associated with the Static Router. */ Ipv4Address GetRouterId (void) const; /** - * Walk the connected channels, discover the adjacent routers and build + * @brief Walk the connected channels, discover the adjacent routers and build * the associated number of Static Router Link State Advertisements that * this router can export. * @@ -463,11 +472,12 @@ public: */ uint32_t DiscoverLSAs (void); /** - * Get the Number of Static Router Link State Advertisements that this - * router can export. To get meaningful information you must have - * previously called DiscoverLSAs. After you know how many LSAs are - * present in the router, you may call GetLSA () to retrieve the actual - * advertisement. + * @brief Get the Number of Static Router Link State Advertisements that this + * router can export. + * + * To get meaningful information you must have previously called DiscoverLSAs. + * After you know how many LSAs are present in the router, you may call + * GetLSA () to retrieve the actual advertisement. * * @see StaticRouterLSA * @see StaticRouter::DiscoverLSAs () @@ -476,8 +486,8 @@ public: */ uint32_t GetNumLSAs (void) const; /** - * Get a Static Router Link State Advertisements that this router has said - * that it can export. + * @brief Get a Static Router 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 Static Router Link @@ -513,11 +523,11 @@ protected: private: /** - * Static Router copy construction is disallowed. + * @brief Static Router copy construction is disallowed. */ StaticRouter (StaticRouter& sr); /** - * Static Router copy assignment operator is disallowed. + * @brief Static Router assignment operator is disallowed. */ StaticRouter& operator= (StaticRouter& sr); }; From 4d3d250d5ee6dfcfbd354628521411e662b2d9f0 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 20 Jul 2007 14:21:21 -0700 Subject: [PATCH 74/92] make static router a singleton, make implementation details private --- SConstruct | 4 +- examples/simple-static-routing.cc | 7 +- src/routing/candidate-queue.h | 2 +- src/routing/static-route-manager-impl.cc | 1382 ++++++++++++++++++++++ src/routing/static-route-manager-impl.h | 677 +++++++++++ src/routing/static-route-manager.cc | 1338 +-------------------- src/routing/static-route-manager.h | 626 +--------- 7 files changed, 2077 insertions(+), 1959 deletions(-) create mode 100644 src/routing/static-route-manager-impl.cc create mode 100644 src/routing/static-route-manager-impl.h diff --git a/SConstruct b/SConstruct index 8d8468c27..9c9a2567c 100644 --- a/SConstruct +++ b/SConstruct @@ -374,15 +374,17 @@ routing.add_sources([ 'routing-environment.cc', 'static-router.cc', 'static-route-manager.cc', + 'static-route-manager-impl.cc', 'candidate-queue.cc', ]) routing.add_headers ([ + 'candidate-queue.h', + 'static-route-manager-impl.h', ]) routing.add_inst_headers([ 'routing-environment.h', 'static-router.h', 'static-route-manager.h', - 'candidate-queue.h', ]) # utils diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 55200e7af..01848c92c 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -65,6 +65,7 @@ #include "ns3/ipv4-route.h" #include "ns3/p2p-topology.h" #include "ns3/onoff-application.h" +#include "ns3/routing-environment.h" #include "ns3/static-route-manager.h" using namespace ns3; @@ -84,6 +85,7 @@ int main (int argc, char *argv[]) DebugComponentEnable("StaticRouter"); DebugComponentEnable("StaticRouteManager"); #endif + DebugComponentEnable("StaticRouteManager"); // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, @@ -142,9 +144,8 @@ int main (int argc, char *argv[]) if (RoutingEnvironment::StaticRoutingEnabled()) { - Ptr routeManager = Create (); - routeManager->BuildStaticRoutingDatabase (); - routeManager->InitializeRoutes (); + StaticRouteManager::BuildStaticRoutingDatabase (); + StaticRouteManager::InitializeRoutes (); } // Create the OnOff application to send UDP datagrams of size diff --git a/src/routing/candidate-queue.h b/src/routing/candidate-queue.h index 5d8993f2e..27fcd01b4 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/candidate-queue.h @@ -19,7 +19,7 @@ #include #include -#include "static-route-manager.h" +#include "static-route-manager-impl.h" namespace ns3 { diff --git a/src/routing/static-route-manager-impl.cc b/src/routing/static-route-manager-impl.cc new file mode 100644 index 000000000..52f8d4b32 --- /dev/null +++ b/src/routing/static-route-manager-impl.cc @@ -0,0 +1,1382 @@ +/* -*- 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 + */ + +#include +#include +#include +#include "ns3/assert.h" +#include "ns3/fatal-error.h" +#include "ns3/debug.h" +#include "ns3/node-list.h" +#include "ns3/ipv4.h" +#include "static-router.h" +#include "static-route-manager-impl.h" +#include "candidate-queue.h" + +NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); + +namespace ns3 { + +// --------------------------------------------------------------------------- +// +// SPFVertex Implementation +// +// --------------------------------------------------------------------------- + +SPFVertex::SPFVertex () : + m_vertexType (VertexUnknown), + m_vertexId ("255.255.255.255"), + m_lsa (0), + m_distanceFromRoot (SPF_INFINITY), + m_rootOif (SPF_INFINITY), + m_nextHop ("0.0.0.0"), + m_parent (0), + m_children () +{ +} + +SPFVertex::SPFVertex (StaticRouterLSA* lsa) : + m_vertexType (VertexRouter), + m_vertexId (lsa->GetLinkStateId ()), + m_lsa (lsa), + m_distanceFromRoot (SPF_INFINITY), + m_rootOif (SPF_INFINITY), + m_nextHop ("0.0.0.0"), + m_parent (0), + m_children () +{ +} + +SPFVertex::~SPFVertex () +{ + for ( ListOfSPFVertex_t::iterator i = m_children.begin (); + i != m_children.end (); + i++) + { + SPFVertex *p = *i; + delete p; + p = 0; + *i = 0; + } + m_children.clear (); +} + + void +SPFVertex::SetVertexType (SPFVertex::VertexType type) +{ + m_vertexType = type; +} + + SPFVertex::VertexType +SPFVertex::GetVertexType (void) const +{ + return m_vertexType; +} + + void +SPFVertex::SetVertexId (Ipv4Address id) +{ + m_vertexId = id; +} + + Ipv4Address +SPFVertex::GetVertexId (void) const +{ + return m_vertexId; +} + + void +SPFVertex::SetLSA (StaticRouterLSA* lsa) +{ + m_lsa = lsa; +} + + StaticRouterLSA* +SPFVertex::GetLSA (void) const +{ + return m_lsa; +} + + void +SPFVertex::SetDistanceFromRoot (uint32_t distance) +{ + m_distanceFromRoot = distance; +} + + uint32_t +SPFVertex::GetDistanceFromRoot (void) const +{ + return m_distanceFromRoot; +} + + void +SPFVertex::SetOutgoingInterfaceId (uint32_t id) +{ + m_rootOif = id; +} + + uint32_t +SPFVertex::GetOutgoingInterfaceId (void) const +{ + return m_rootOif; +} + + void +SPFVertex::SetNextHop (Ipv4Address nextHop) +{ + m_nextHop = nextHop; +} + + Ipv4Address +SPFVertex::GetNextHop (void) const +{ + return m_nextHop; +} + + void +SPFVertex::SetParent (SPFVertex* parent) +{ + m_parent = parent; +} + + SPFVertex* +SPFVertex::GetParent (void) const +{ + return m_parent; +} + + uint32_t +SPFVertex::GetNChildren (void) const +{ + return m_children.size (); +} + + SPFVertex* +SPFVertex::GetChild (uint32_t n) const +{ + uint32_t j = 0; + + for ( ListOfSPFVertex_t::const_iterator i = m_children.begin (); + i != m_children.end (); + i++, j++) + { + if (j == n) + { + return *i; + } + } + NS_ASSERT_MSG(false, "Index out of range."); + return 0; +} + + uint32_t +SPFVertex::AddChild (SPFVertex* child) +{ + m_children.push_back (child); + return m_children.size (); +} + +// --------------------------------------------------------------------------- +// +// StaticRouteManagerLSDB Implementation +// +// --------------------------------------------------------------------------- + +StaticRouteManagerLSDB::StaticRouteManagerLSDB () +: + m_database () +{ + NS_DEBUG ("StaticRouteManagerLSDB::StaticRouteManagerLSDB ()"); +} + +StaticRouteManagerLSDB::~StaticRouteManagerLSDB () +{ + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); + + LSDBMap_t::iterator i; + for (i= m_database.begin (); i!= m_database.end (); i++) + { + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ():free LSA"); + StaticRouterLSA* temp = i->second; + delete temp; + } + NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); + m_database.clear (); +} + + void +StaticRouteManagerLSDB::Initialize () +{ + NS_DEBUG ("StaticRouteManagerLSDB::Initialize ()"); + + LSDBMap_t::iterator i; + for (i= m_database.begin (); i!= m_database.end (); i++) + { + StaticRouterLSA* temp = i->second; + temp->SetStatus (StaticRouterLSA::LSA_SPF_NOT_EXPLORED); + } +} + + void +StaticRouteManagerLSDB::Insert (Ipv4Address addr, StaticRouterLSA* lsa) +{ + NS_DEBUG ("StaticRouteManagerLSDB::Insert ()"); + m_database.insert (LSDBPair_t (addr, lsa)); +} + + StaticRouterLSA* +StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) const +{ + NS_DEBUG ("StaticRouteManagerLSDB::GetLSA ()"); +// +// Look up an LSA by its address. +// + LSDBMap_t::const_iterator i; + for (i= m_database.begin (); i!= m_database.end (); i++) + { + if (i->first == addr) + { + return i->second; + } + } + return 0; +} + +// --------------------------------------------------------------------------- +// +// StaticRouteManagerImpl Implementation +// +// --------------------------------------------------------------------------- + +StaticRouteManagerImpl::StaticRouteManagerImpl () +: + m_spfroot (0) +{ + NS_DEBUG ("StaticRouteManagerImpl::StaticRoutemanagerImpl ()"); + m_lsdb = new StaticRouteManagerLSDB (); +} + +StaticRouteManagerImpl::~StaticRouteManagerImpl () +{ + NS_DEBUG ("StaticRouteManagerImpl::~StaticRouteManagerImpl ()"); + + if (m_lsdb) + { + delete m_lsdb; + } +} + + void +StaticRouteManagerImpl::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) +{ + NS_DEBUG ("StaticRouteManagerImpl::DebugUseLsdb ()"); + + if (m_lsdb) + { + delete m_lsdb; + } + m_lsdb = lsdb; +} + +// +// In order to build the routing database, we need to walk the list of nodes +// in the system and look for those that support the StaticRouter interface. +// These routers will export a number of Link State Advertisements (LSAs) +// that describe the links and networks that are "adjacent" (i.e., that are +// on the other side of a point-to-point link). We take these LSAs and put +// add them to the Link State DataBase (LSDB) from which the routes will +// ultimately be computed. +// + void +StaticRouteManagerImpl::BuildStaticRoutingDatabase () +{ + NS_DEBUG ("StaticRouteManagerImpl::BuildStaticRoutingDatabase()"); +// +// Walk the list of nodes looking for the StaticRouter Interface. +// + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; + + Ptr rtr = + node->QueryInterface (StaticRouter::iid); +// +// Ignore nodes that aren't participating in routing. +// + if (!rtr) + { + continue; + } +// +// You must call DiscoverLSAs () before trying to use any routing info or to +// update LSAs. DiscoverLSAs () drives the process of discovering routes in +// the StaticRouter. Afterward, you may use GetNumLSAs (), which is a very +// computationally inexpensive call. If you call GetNumLSAs () before calling +// DiscoverLSAs () will get zero as the number since no routes have been +// found. +// + uint32_t numLSAs = rtr->DiscoverLSAs (); + NS_DEBUG ("Discover LSAs: Found " << numLSAs << " LSAs"); + + for (uint32_t j = 0; j < numLSAs; ++j) + { + StaticRouterLSA* lsa = new StaticRouterLSA (); +// +// 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. +// + m_lsdb->Insert (lsa->GetLinkStateId (), lsa); + } + } +} + +// +// For each node that is a static router (which is determined by the presence +// of an aggregated StaticRouter interface), run the Dijkstra SPF calculation +// on the database rooted at that router, and populate the node forwarding +// tables. +// +// This function parallels RFC2328, Section 16.1.1, and quagga ospfd +// +// This calculation yields the set of intra-area routes associated +// with an area (called hereafter Area A). A router calculates the +// shortest-path tree using itself as the root. The formation +// of the shortest path tree is done here in two stages. In the +// first stage, only links between routers and transit networks are +// considered. Using the Dijkstra algorithm, a tree is formed from +// this subset of the link state database. In the second stage, +// leaves are added to the tree by considering the links to stub +// networks. +// +// The area's link state database is represented as a directed graph. +// The graph's vertices are routers, transit networks and stub networks. +// +// The first stage of the procedure (i.e., the Dijkstra algorithm) +// can now be summarized as follows. At each iteration of the +// algorithm, there is a list of candidate vertices. Paths from +// the root to these vertices have been found, but not necessarily +// the shortest ones. However, the paths to the candidate vertex +// that is closest to the root are guaranteed to be shortest; this +// vertex is added to the shortest-path tree, removed from the +// candidate list, and its adjacent vertices are examined for +// possible addition to/modification of the candidate list. The +// algorithm then iterates again. It terminates when the candidate +// list becomes empty. +// + void +StaticRouteManagerImpl::InitializeRoutes () +{ + NS_DEBUG ("StaticRouteManagerImpl::InitializeRoutes ()"); +// +// Walk the list of nodes in the system. +// + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; +// +// Look for the StaticRouter interface that indicates that the node is +// participating in routing. +// + Ptr rtr = + node->QueryInterface (StaticRouter::iid); +// +// if the node has a static router interface, then run the static routing +// algorithms. +// + if (rtr && rtr->GetNumLSAs () ) + { + SPFCalculate (rtr->GetRouterId ()); + } + } +} + +// +// This method is derived from quagga ospf_spf_next (). See RFC2328 Section +// 16.1 (2) for further details. +// +// We're passed a parameter that is a vertex which is already in the SPF +// tree. A vertex represents a router node. We also get a reference to the +// SPF candidate queue, which is a priority queue containing the shortest paths +// to the networks we know about. +// +// We examine the links in v's LSA and update the list of candidates with any +// vertices not already on the list. If a lower-cost path is found to a +// vertex already on the candidate list, store the new (lower) cost. +// + void +StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) +{ + SPFVertex* w = 0; + StaticRouterLSA* w_lsa = 0; + uint32_t distance = 0; + + NS_DEBUG ("StaticRouteManagerImpl::SPFNext ()"); +// +// Always true for now, since all our LSAs are RouterLSAs. +// + if (v->GetVertexType () == SPFVertex::VertexRouter) + { + if (true) + { + 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. +// + StaticRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); + if (l->GetLinkType () == StaticRouterLinkRecord::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 () == StaticRouterLinkRecord::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 ()); +// +// (c) If vertex W is already on the shortest-path tree, examine the next +// link in the LSA. +// +// 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 () == + StaticRouterLSA::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. +// +// (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 (w_lsa->GetStatus () == + StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + { +// +// If we havent yet considered the link represented by we have to create +// a new SPFVertex to represent it. +// + w = new SPFVertex (w_lsa); +// +// 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 ( + StaticRouterLSA::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 () == + StaticRouterLSA::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 +// distance metric. +// +// 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) + { +// +// This is not a shorter path, so don't do anything. +// + 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 + { +// +// 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 +// (vertex ) +// +// 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 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 + } + } +} + +// +// 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. +// +// For now, this is greatly simplified from the quagga code +// + int +StaticRouteManagerImpl::SPFNexthopCalculation ( + SPFVertex* v, + SPFVertex* w, + StaticRouterLinkRecord* l, + uint32_t distance) +{ + NS_DEBUG ("StaticRouteManagerImpl::SPFNexthopCalculation ()"); +// +// 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 +// calculating the routes. +// +// There are two distinct cases for calculating the next hop information. +// First, if we're considering a hop from the root to an "adjacent" network +// (one that is on the other side of a point-to-point link connected to the +// root), then we need to store the information needed to forward down that +// link. The second case is if the network is not directly adjacent. In that +// case we need to use the forwarding information from the vertex on the path +// to the destination that is directly adjacent [node 1] in both cases of the +// diagram below. +// +// (1) [root] -> [point-to-point] -> [node 1] +// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2] +// +// We call the propagation of next hop information down vertices of a path +// "inheriting" the next hop information. +// +// The point-to-point link information is only useful in this calculation when +// we are examining the root node. +// + if (v == m_spfroot) + { +// +// In this case is the root node, which means it is the starting point +// for the packets forwarded by that node. This also means that the next hop +// address of packets headed for some arbitrary off-network destination must +// be the destination at the other end of one of the links off of the root +// node if this root node is a router. We then need to see if this node +// is a router. +// + if (w->GetVertexType () == SPFVertex::VertexRouter) + { +// +// In the case of point-to-point links, the link data field (m_linkData) of a +// Static Router Link Record contains the local IP address. If we look at the +// link record describing the link from the perspecive of (the remote +// node from the viewpoint of ) back to the root node, we can discover the +// IP address of the router to which is adjacent. This is a distinguished +// address -- the next hop address to get from to and all networks +// accessed through that path. +// +// SPFGetNextLink () is a little odd. used in this way it is just going to +// return the link record describing the link from to . Think of it as +// SPFGetLink. +// + StaticRouterLinkRecord *linkRemote = 0; + linkRemote = SPFGetNextLink (w, v, linkRemote); +// +// At this point, is the Static Router Link Record describing the point- +// to point link from to from the perspective of ; and +// is the Static Router Link Record describing that same link from the +// perspective of (back to ). Now we can just copy the next hop +// address from the m_linkData member variable. +// +// The next hop member variable we put in has the sense "in order to get +// from the root node to the host represented by vertex , you have to send +// the packet to the next hop address specified in w->m_nextHop. +// + w->SetNextHop(linkRemote->GetLinkData ()); +// +// Now find the outgoing interface corresponding to the point to point link +// from the perspective of -- remember that is the link "from" +// "to" . +// + w->SetOutgoingInterfaceId ( + FindOutgoingInterfaceId (l->GetLinkData ())); + + NS_DEBUG ("SPFNexthopCalculation: Next hop from " << + v->GetVertexId () << " to " << w->GetVertexId () << + " goes through next hop " << w->GetNextHop () << + " via outgoing interface " << w->GetOutgoingInterfaceId ()); + } + } + else + { +// +// If we're calculating the next hop information from a node (v) that is +// *not* the root, then we need to "inherit" the information needed to +// forward the packet from the vertex closer to the root. That is, we'll +// still send packets to the next hop address of the router adjacent to the +// root on the path toward . +// +// Above, when we were considering the root node, we calculated the next hop +// address and outgoing interface required to get off of the root network. +// At this point, we are further away from the root network along one of the +// (shortest) paths. So the next hop and outoing interface remain the same +// (are inherited). +// + w->SetNextHop (v->GetNextHop ()); + w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ()); + } +// +// In all cases, we need valid values for the distance metric and a parent. +// + w->SetDistanceFromRoot (distance); + w->SetParent (v); + + return 1; +} + +// +// This method is derived from quagga ospf_get_next_link () +// +// First search the Static Router Link Records of vertex for one +// representing a point-to point link to vertex . +// +// What is done depends on prev_link. Contrary to appearances, prev_link just +// acts as a flag here. If prev_link is NULL, we return the first Static +// Router Link Record we find that describes a point-to-point link from +// to . If prev_link is not NULL, we return a Static 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? +// + StaticRouterLinkRecord* +StaticRouteManagerImpl::SPFGetNextLink ( + SPFVertex* v, + SPFVertex* w, + StaticRouterLinkRecord* prev_link) +{ + NS_DEBUG ("StaticRouteManagerImpl::SPFGetNextLink ()"); + + bool skip = true; + StaticRouterLinkRecord* l; +// +// If prev_link is 0, we are really looking for the first link, not the next +// link. +// + if (prev_link == 0) + { + skip = false; + } +// +// Iterate through the Static Router Link Records advertised by the vertex +// looking for records representing the point-to-point links off of this +// vertex. +// + for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) + { + l = v->GetLSA ()->GetLinkRecord (i); + if (l->GetLinkType () != StaticRouterLinkRecord::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 +// connects from the perspective of in this case. The vertex ID is also +// set to the router ID (using the link state advertisement of a router node). +// 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 = " << + l->GetLinkId () << " linkData = " << l->GetLinkData ()); +// +// If skip is false, don't (not too surprisingly) skip the link found -- it's +// the one we're interested in. That's either because we didn't pass in a +// previous link, and we're interested in the first one, or because we've +// skipped a previous link and moved forward to the next (which is then the +// one we want). +// + if (skip == false) + { + NS_DEBUG ("SPFGetNextLink: Returning the found link"); + return l; + } + else + { +// +// Skip is true and we've found a link from to . We want the next one. +// Setting skip to false gets us the next point-to-point static router link +// record in the LSA from . +// + NS_DEBUG ("SPFGetNextLink: Skipping the found link"); + skip = false; + continue; + } + } + } + return 0; +} + +// +// Used for unit tests. +// + void +StaticRouteManagerImpl::DebugSPFCalculate (Ipv4Address root) +{ + NS_DEBUG ("StaticRouteManagerImpl::DebugSPFCalculate ()"); + SPFCalculate (root); +} + +// quagga ospf_spf_calculate + void +StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) +{ + NS_DEBUG ("StaticRouteManagerImpl::SPFCalculate (): " + "root = " << root); + + SPFVertex *v; +// +// Initialize the Link State Database. +// + m_lsdb->Initialize (); +// +// The candidate queue is a priority queue of SPFVertex objects, with the top +// of the queue being the closest vertex in terms of distance from the root +// of the tree. Initially, this queue is empty. +// + CandidateQueue candidate; + NS_ASSERT(candidate.Size () == 0); +// +// Initialize the shortest-path tree to only contain the router doing the +// calculation. Each router (and corresponding network) is a vertex in the +// shortest path first (SPF) tree. +// + v = new SPFVertex (m_lsdb->GetLSA (root)); +// +// This vertex is the root of the SPF tree and it is distance 0 from the root. +// We also mark this vertex as being in the SPF tree. +// + m_spfroot= v; + v->SetDistanceFromRoot (0); + v->GetLSA ()->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); + + for (;;) + { +// +// The operations we need to do are given in the OSPF RFC which we reference +// as we go along. +// +// RFC2328 16.1. (2). +// +// We examine the Static Router Link Records in the Link State +// Advertisements of the current vertex. If there are any point-to-point +// links to unexplored adjacent vertices we add them to the tree and update +// the distance and next hop information on how to get there. We also add +// the new vertices to the candidate queue (the priority queue ordered by +// shortest path). If the new vertices represent shorter paths, we use them +// and update the path cost. +// + SPFNext (v, candidate); +// +// RFC2328 16.1. (3). +// +// If at this step the candidate list is empty, the shortest-path tree (of +// transit vertices) has been completely built and this stage of the +// procedure terminates. +// + if (candidate.Size () == 0) + { + break; + } +// +// Choose the vertex belonging to the candidate list that is closest to the +// root, and add it to the shortest-path tree (removing it from the candidate +// list in the process). +// +// Recall that in the previous step, we created SPFVertex structures for each +// of the routers found in the Static Router Link Records and added tehm to +// the candidate list. +// + v = candidate.Pop (); + NS_DEBUG ("SPFCalculate: Popped vertex " << v->GetVertexId ()); +// +// Update the status field of the vertex to indicate that it is in the SPF +// tree. +// + v->GetLSA ()->SetStatus (StaticRouterLSA::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 +// children of that parent vertex. In the next hop calculation called during +// SPFNext, the parent pointer was set but the vertex has been orphaned up +// to now. +// + SPFVertexAddParent (v); +// +// Note that when there is a choice of vertices closest to the root, network +// vertices must be chosen before router vertices in order to necessarily +// find all equal-cost paths. We don't do this at this moment, we should add +// the treatment above codes. -- kunihiro. +// +// RFC2328 16.1. (4). +// +// This is the method that actually adds the routes. It'll walk the list +// of nodes in the system, looking for the node corresponding to the router +// ID of the root of the tree -- that is the router we're building the routes +// for. It looks for the Ipv4 interface of that node and remembers it. So +// we are only actually adding routes to that one node at the root of the SPF +// tree. +// +// We're going to pop of a pointer to every vertex in the tree except the +// root in order of distance from the root. For each of the vertices, we call +// SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the +// point-to-point Static Router Link Records (the links to nodes adjacent to +// the node represented by the vertex). We add a route to the IP address +// specified by the m_linkData field of each of those link records. This will +// be the *local* IP address associated with the interface attached to the +// link. We use the outbound interface and next hop information present in +// the vertex which have possibly been inherited from the root. +// +// To summarize, we're going to look at the node represented by and loop +// 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); +// +// RFC2328 16.1. (5). +// +// Iterate the algorithm by returning to Step 2 until there are no more +// candidate vertices. +// + } +// +// Second stage of SPF calculation procedure's +// NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); +// +// We're all done setting the routing information for the node at the root of +// the SPF tree. Delete all of the vertices and corresponding resources. Go +// possibly do it again for the next router. +// + delete m_spfroot; + m_spfroot = 0; +} + +// +// BUGBUG FIXME: This should probably be a method on Ipv4 +// +// Return the interface index corresponding to a given IP address +// + uint32_t +StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) +{ +// +// 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 (StaticRouter::iid); +// +// If the node doesn't have a StaticRouter 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, + "StaticRouteManagerImpl::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) == a) + { + NS_DEBUG ( + "StaticRouteManagerImpl::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 +// tables of the individual nodes. +// +// The vertex passed as a parameter has just been added to the SPF tree. +// This vertex must have a valid m_root_oid, corresponding to the outgoing +// interface on the root router of the tree that is the first hop on the path +// to the vertex. The vertex must also have a next hop address, corresponding +// to the next hop on the path to the vertex. The vertex has an m_lsa field +// that has some number of link records. For each point to point link record, +// the m_linkData is the local IP address of the link. This corresponds to +// a destination IP address, reachable from the root, to which we add a host +// route. +// + void +StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) +{ + NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter ()"); + + NS_ASSERT_MSG (m_spfroot, + "StaticRouteManagerImpl::SPFIntraAddRouter (): 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 ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + "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 StaticRouter interface, so we need +// to QI for that interface. If there's no StaticRouter interface, the node +// in question cannot be the router we want, so we continue. +// + Ptr rtr = + node->QueryInterface (StaticRouter::iid); + + if (rtr == 0) + { + NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + "No StaticRouter 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 ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + "Considering router " << rtr->GetRouterId ()); + + if (rtr->GetRouterId () == routerId) + { + NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + "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, + "StaticRouteManagerImpl::SPFIntraAddRouter (): " + "QI for interface failed"); +// +// Get the Static Router Link State Advertisement from the vertex we're +// adding the routes to. The LSA will have a number of attached Static 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. +// + StaticRouterLSA *lsa = v->GetLSA (); + NS_ASSERT_MSG (lsa, + "StaticRouteManagerImpl::SPFIntraAddRouter (): " + "Expected valid LSA in SPFVertex* v"); + + uint32_t nLinkRecords = lsa->GetNLinkRecords (); +// +// Iterate through the link records on the vertex to which we're going to add +// routes. To make sure we're being clear, we're going to add routing table +// entries to the tables on the node corresping to the root of the SPF tree. +// These entries will have routes to the IP addresses we find from looking at +// the local side of the point-to-point links found on the node described by +// the vertex . +// + for (uint32_t j = 0; j < nLinkRecords; j += 2) + { +// +// We are only concerned about point-to-point links +// + StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); + if (lr->GetLinkType () != StaticRouterLinkRecord::PointToPoint) + { + continue; + } + + NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + " Node " << node->GetId () << + " add route to " << lr->GetLinkData () << + " using next hop " << v->GetNextHop () << + " via interface " << v->GetOutgoingInterfaceId ()); +// +// Here's why we did all of that work. We're going to add a host route to the +// host address found in the m_linkData field of the point-to-point link +// record. In the case of a point-to-point link, this is the local IP address +// of the node connected to the link. Each of these point-to-point links +// will correspond to a local interface that has an IP address to which +// the node at the root of the SPF tree can send packets. The vertex +// (corresponding to the node that has these links and interfaces) has +// an m_nextHop address precalculated for us that is the address to which the +// root node should send packets to be forwarded to these IP addresses. +// Similarly, the vertex has an m_rootOif (outbound interface index) to +// which the packets should be send for forwarding. +// + ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (), + v->GetOutgoingInterfaceId ()); + } +// +// Done adding the routes for the selected node. +// + return; + } + } +} + +// Derived from quagga ospf_vertex_add_parents () +// +// This is a somewhat oddly named method (blame quagga). Although you might +// expect it to add a parent *to* something, it actually adds a vertex +// to the list of children *in* each of its parents. +// +// Given a pointer to a vertex, it links back to the vertex's parent that it +// already has set and adds itself to that vertex's list of children. +// +// For now, only one parent (not doing equal-cost multipath) +// + void +StaticRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) +{ + v->GetParent ()->AddChild (v); +} + +} // namespace ns3 + +#ifdef RUN_SELF_TESTS + +// --------------------------------------------------------------------------- +// +// Unit Tests +// +// --------------------------------------------------------------------------- + +#include "ns3/test.h" + +namespace ns3 { + +class StaticRouterTestNode : public Node +{ +public: + StaticRouterTestNode (); + +private: + virtual void DoAddDevice (Ptr device) const {}; + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); +}; + +StaticRouterTestNode::StaticRouterTestNode () +{ +// Ptr ipv4 = Create (this); +} + + TraceResolver* +StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) +{ + return 0; +} + +class StaticRouteManagerImplTest : public Test { +public: + StaticRouteManagerImplTest (); + virtual ~StaticRouteManagerImplTest (); + virtual bool RunTests (void); +}; + +StaticRouteManagerImplTest::StaticRouteManagerImplTest () + : Test ("StaticRouteManagerImpl") +{ +} + +StaticRouteManagerImplTest::~StaticRouteManagerImplTest () +{} + + bool +StaticRouteManagerImplTest::RunTests (void) +{ + bool ok = true; + + CandidateQueue candidate; + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = new SPFVertex; + v->SetDistanceFromRoot (rand () % 100); + candidate.Push (v); + } + + uint32_t lastDistance = 0; + + for (int i = 0; i < 100; ++i) + { + SPFVertex *v = candidate.Pop (); + if (v->GetDistanceFromRoot () < lastDistance) + { + ok = false; + } + lastDistance = v->GetDistanceFromRoot (); + delete v; + v = 0; + } + + // Build fake link state database; four routers (0-3), 3 point-to-point + // links + // + // n0 + // \ link 0 + // \ link 2 + // n2 -------------------------n3 + // / + // / link 1 + // n1 + // + // link0: 10.1.1.1/30, 10.1.1.2/30 + // link1: 10.1.2.1/30, 10.1.2.2/30 + // link2: 10.1.3.1/30, 10.1.3.2/30 + // + // Router 0 + StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", // router ID 0.0.0.2 + "10.1.1.1", // local ID + 1); // metric + + StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.1.1", + "255.255.255.252", + 1); + + StaticRouterLSA* lsa0 = new StaticRouterLSA (); + lsa0->SetLinkStateId ("0.0.0.0"); + lsa0->SetAdvertisingRouter ("0.0.0.0"); + lsa0->AddLinkRecord (lr0); + lsa0->AddLinkRecord (lr1); + + // Router 1 + StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + + StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + + StaticRouterLSA* lsa1 = new StaticRouterLSA (); + lsa1->SetLinkStateId ("0.0.0.1"); + lsa1->SetAdvertisingRouter ("0.0.0.1"); + lsa1->AddLinkRecord (lr2); + lsa1->AddLinkRecord (lr3); + + // Router 2 + StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.0", + "10.1.1.2", + 1); + + StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.1.2", + "255.255.255.252", + 1); + + StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.1", + "10.1.2.2", + 1); + + StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.2", + "255.255.255.252", + 1); + + StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.3", + "10.1.3.2", + 1); + + StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.3.2", + "255.255.255.252", + 1); + + StaticRouterLSA* lsa2 = new StaticRouterLSA (); + lsa2->SetLinkStateId ("0.0.0.2"); + lsa2->SetAdvertisingRouter ("0.0.0.2"); + lsa2->AddLinkRecord (lr4); + lsa2->AddLinkRecord (lr5); + lsa2->AddLinkRecord (lr6); + lsa2->AddLinkRecord (lr7); + lsa2->AddLinkRecord (lr8); + lsa2->AddLinkRecord (lr9); + + // Router 3 + StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::PointToPoint, + "0.0.0.2", + "10.1.2.1", + 1); + + StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord ( + StaticRouterLinkRecord::StubNetwork, + "10.1.2.1", + "255.255.255.252", + 1); + + StaticRouterLSA* lsa3 = new StaticRouterLSA (); + lsa3->SetLinkStateId ("0.0.0.3"); + lsa3->SetAdvertisingRouter ("0.0.0.3"); + lsa3->AddLinkRecord (lr10); + lsa3->AddLinkRecord (lr11); + + // Test the database + StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB (); + srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0); + srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1); + srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2); + srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3); + NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ())); + + // XXX next, calculate routes based on the manually created LSDB + StaticRouteManagerImpl* srm = new StaticRouteManagerImpl (); + srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB + // Note-- this will succeed without any nodes in the topology + // because the NodeList is empty + srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 + + // This delete clears the srm, which deletes the LSDB, which clears + // all of the LSAs, which each destroys the attached LinkRecords. + delete srm; + + return ok; +} + +// Instantiate this class for the unit tests +static StaticRouteManagerImplTest g_staticRouteManagerTest; + +} // namespace ns3 + +#endif diff --git a/src/routing/static-route-manager-impl.h b/src/routing/static-route-manager-impl.h new file mode 100644 index 000000000..a4d97db77 --- /dev/null +++ b/src/routing/static-route-manager-impl.h @@ -0,0 +1,677 @@ +/* -*- 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 + */ +#ifndef STATIC_ROUTE_MANAGER_IMPL_H +#define STATIC_ROUTE_MANAGER_IMPL_H + +#include +#include +#include +#include +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" +#include "static-router.h" + +namespace ns3 { + +const uint32_t SPF_INFINITY = 0xffffffff; + +class CandidateQueue; + +/** + * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328, + * Section 16. + * + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is the SPFVertex representing the router that is having + * its routing tables set. The SPFVertex objects representing other routers + * or networks in the simulation are arranged in the SPF tree. It is this + * tree that represents the Shortest Paths to the other networks. + * + * Each SPFVertex has a pointer to the Static Router Link State Advertisement + * (LSA) that its underlying router has exported. Within these LSAs are + * Static Router Link Records that describe the point to point links from the + * underlying router to other nodes (represented by other SPFVertex objects) + * in the simulation topology. The combination of the arrangement of the + * SPFVertex objects in the SPF tree, along with the details of the link + * records that connect them provide the information required to construct the + * required routes. + */ +class SPFVertex +{ +public: +/** + * @enum Enumeration of the possible types of SPFVertex objects. Currently + * we use VertexRouter to identify objects that represent a router in the + * simulation topology, and VertexNetwork to identify objects that represent + * a network. + */ + enum VertexType { + VertexUnknown = 0, /**< Uninitialized Link Record */ + VertexRouter, /**< Vertex representing a router in the topology */ + VertexNetwork /**< Vertex representing a network in the topology */ + }; +/** + * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First + * Vertex). + * + * The Vertex Type is set to VertexUnknown, the Vertex ID is set to + * 255.255.255.255, and the distance from root is set to infinity + * (UINT32_MAX). The referenced Link State Advertisement (LSA) is set to + * null as is the parent SPFVertex. The outgoing interface index is set to + * infinity, the next hop address is set to 0.0.0.0 and the list of children + * of the SPFVertex is initialized to empty. + * + * @see VertexType + */ + SPFVertex(); +/** + * @brief Construct an initialized SPFVertex (Shortest Path First Vertex). + * + * The Vertex Type is initialized to VertexRouter and the Vertex ID is found + * from the Link State ID of the Link State Advertisement (LSA) passed as a + * parameter. The Link State ID is set to the Router ID of the advertising + * router. The referenced LSA (m_lsa) is set to the given LSA. Other than + * these members, initialization is as in the default constructor. + * of the SPFVertex is initialized to empty. + * + * @see SPFVertex::SPFVertex () + * @see VertexType + * @see StaticRouterLSA + * @param lsa The Link State Advertisement used for finding initial values. + */ + SPFVertex(StaticRouterLSA* lsa); +/** + * @brief Destroy an SPFVertex (Shortest Path First Vertex). + * + * The children vertices of the SPFVertex are recursively deleted. + * + * @see SPFVertex::SPFVertex () + */ + ~SPFVertex(); +/** + * @brief Get the Vertex Type field of a SPFVertex object. + * + * The Vertex Type describes the kind of simulation object a given SPFVertex + * represents. + * + * @see VertexType + * @returns The VertexType of the current SPFVertex object. + */ + VertexType GetVertexType (void) const; +/** + * @brief Set the Vertex Type field of a SPFVertex object. + * + * The Vertex Type describes the kind of simulation object a given SPFVertex + * represents. + * + * @see VertexType + * @param The new VertexType for the current SPFVertex object. + */ + void SetVertexType (VertexType type); +/** + * @brief Get the Vertex ID field of a SPFVertex object. + * + * The Vertex ID uniquely identifies the simulation object a given SPFVertex + * represents. Typically, this is the Router ID for SPFVertex objects + * representing routers, and comes from the Link State Advertisement of a + * router aggregated to a node in the simulation. These IDs are allocated + * automatically by the routing environment and look like IP addresses + * beginning at 0.0.0.0 and monotonically increasing as new routers are + * instantiated. + * + * @returns The Ipv4Address Vertex ID of the current SPFVertex object. + */ + Ipv4Address GetVertexId (void) const; +/** + * @brief Set the Vertex ID field of a SPFVertex object. + * + * The Vertex ID uniquely identifies the simulation object a given SPFVertex + * represents. Typically, this is the Router ID for SPFVertex objects + * representing routers, and comes from the Link State Advertisement of a + * router aggregated to a node in the simulation. These IDs are allocated + * automatically by the routing environment and look like IP addresses + * beginning at 0.0.0.0 and monotonically increasing as new routers are + * instantiated. + * + * @param id The new Ipv4Address Vertex ID for the current SPFVertex object. + */ + void SetVertexId (Ipv4Address id); +/** + * @brief Get the Static Router Link State Advertisement returned by the + * Static Router represented by this SPFVertex during the route discovery + * process. + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @returns A pointer to the StaticRouterLSA found by the router represented + * by this SPFVertex object. + */ + StaticRouterLSA* GetLSA (void) const; +/** + * @brief Set the Static Router Link State Advertisement returned by the + * Static Router represented by this SPFVertex during the route discovery + * process. + * + * @see SPFVertex::GetLSA () + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouter::DiscoverLSAs () + * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You + * must not delete the LSA after calling this method. + * @param A pointer to the StaticRouterLSA. + */ + void SetLSA (StaticRouterLSA* lsa); +/** + * @brief Get the distance from the root vertex to "this" SPFVertex object. + * + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex to which + * a route is being calculated from the root. The distance from the root that + * we're asking for is the number of hops from the root vertex to the vertex + * in question. + * + * The distance is calculated during route discovery and is stored in a + * member variable. This method simply fetches that value. + * + * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex. + */ + uint32_t GetDistanceFromRoot (void) const; +/** + * @brief Set the distance from the root vertex to "this" SPFVertex object. + * + * Each router in the simulation is associated with an SPFVertex object. When + * calculating routes, each of these routers is, in turn, chosen as the "root" + * of the calculation and routes to all of the other routers are eventually + * saved in the routing tables of each of the chosen nodes. Each of these + * routers in the calculation has an associated SPFVertex. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex to which + * a route is being calculated from the root. The distance from the root that + * we're asking for is the number of hops from the root vertex to the vertex + * in question. + * + * @param distance The distance, in hops, from the root SPFVertex to "this" + * SPFVertex. + */ + void SetDistanceFromRoot (uint32_t distance); +/** + * @brief Get the interface ID that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The outgoing interface that we're asking for is the interface + * index on the root node that should be used to start packets along the + * path to "this" vertex. + * + * When initializing the root SPFVertex, the interface ID is determined by + * examining the Static Router Link Records of the Link State Advertisement + * generated by the root node's StaticRouter. These interfaces are used to + * forward packets off of the root's network down those links. As other + * vertices are discovered which are further away from the root, they will + * be accessible down one of the paths begun by a Static Router Link Record. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to the interface of that + * first hop. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, the root node is asking, "which of my local interfaces + * should I use to get a packet to the network or host represented by 'this' + * SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @returns The interface index to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ + uint32_t GetOutgoingInterfaceId (void) const; +/** + * @brief Set the interface ID that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The outgoing interface that we're asking for is the interface + * index on the root node that should be used to start packets along the + * path to "this" vertex. + * + * When initializing the root SPFVertex, the interface ID is determined by + * examining the Static Router Link Records of the Link State Advertisement + * generated by the root node's StaticRouter. These interfaces are used to + * forward packets off of the root's network down those links. As other + * vertices are discovered which are further away from the root, they will + * be accessible down one of the paths begun by a Static Router Link Record. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to the interface of that + * first hop. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, we are letting the root node know which of its local + * interfaces it should use to get a packet to the network or host represented + * by "this" SPFVertex. + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @param id The interface index to use when forwarding packets to the host or + * network represented by "this" SPFVertex. + */ + void SetOutgoingInterfaceId (uint32_t id); +/** + * @brief Get the IP address that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The IP address that we're asking for is the address on the + * remote side of a link off of the root node that should be used as the + * destination for packets along the path to "this" vertex. + * + * When initializing the root SPFVertex, the IP address used when forwarding + * packets is determined by examining the Static Router Link Records of the + * Link State Advertisement generated by the root node's StaticRouter. This + * address is used to forward packets off of the root's network down those + * links. As other vertices / nodes are discovered which are further away + * from the root, they will be accessible down one of the paths via a link + * described by one of these Static Router Link Records. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to a first hop router down + * an interface. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method, the root node is asking, "which router should I send a + * packet to in order to get that packet to the network or host represented + * by 'this' SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @returns The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ + Ipv4Address GetNextHop (void) const; +/** + * @brief Set the IP address that should be used to begin forwarding packets + * from the root SPFVertex to "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set. The "this" SPFVertex is the vertex that + * represents the host or network to which a route is being calculated from + * the root. The IP address that we're asking for is the address on the + * remote side of a link off of the root node that should be used as the + * destination for packets along the path to "this" vertex. + * + * When initializing the root SPFVertex, the IP address used when forwarding + * packets is determined by examining the Static Router Link Records of the + * Link State Advertisement generated by the root node's StaticRouter. This + * address is used to forward packets off of the root's network down those + * links. As other vertices / nodes are discovered which are further away + * from the root, they will be accessible down one of the paths via a link + * described by one of these Static Router Link Records. + * + * To forward packets to these hosts or networks, the root node must begin + * the forwarding process by sending the packets to a first hop router down + * an interface. This means that the first hop address and interface ID must + * be the same for all downstream SPFVertices. We call this "inheriting" + * the interface and next hop. + * + * In this method we are telling the root node which router it should send + * should I send a packet to in order to get that packet to the network or + * host represented by 'this' SPFVertex." + * + * @see StaticRouter + * @see StaticRouterLSA + * @see StaticRouterLinkRecord + * @param nextHop The IP address to use when forwarding packets to the host + * or network represented by "this" SPFVertex. + */ + void SetNextHop (Ipv4Address nextHop); +/** + * @brief Get a pointer to the SPFVector that is the parent of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. + * + * This method returns a pointer to the parent node of "this" SPFVertex + * (both of which reside in that SPF tree). + * + * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex + * in the SPF tree. + */ + SPFVertex* GetParent (void) const; +/** + * @brief Set the pointer to the SPFVector that is the parent of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. + * + * This method sets the parent pointer of "this" SPFVertex (both of which + * reside in that SPF tree). + * + * @param parent A pointer to the SPFVertex that is the parent of "this" + * SPFVertex* in the SPF tree. + */ + void SetParent (SPFVertex* parent); +/** + * @brief Get the number of children of "this" SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method returns the number of children of "this" SPFVertex (which + * reside in the SPF tree). + * + * @returns The number of children of "this" SPFVertex (which reside in the + * SPF tree). + */ + uint32_t GetNChildren (void) const; +/** + * @brief Get a borrowed SPFVertex pointer to the specified child of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method the number of children of "this" SPFVertex (which reside in + * the SPF tree. + * + * @see SPFVertex::GetNChildren + * @param n The index (from 0 to the number of children minus 1) of the + * child SPFVertex to return. + * @warning The pointer returned by GetChild () is a borrowed pointer. You + * do not have any ownership of the underlying object and must not delete + * that object. + * @returns A pointer to the specified child SPFVertex (which resides in the + * SPF tree). + */ + SPFVertex* GetChild (uint32_t n) const; +/** + * @brief Get a borrowed SPFVertex pointer to the specified child of "this" + * SPFVertex. + * + * Each router node in the simulation is associated with an SPFVertex object. + * When calculating routes, each of these routers is, in turn, chosen as the + * "root" of the calculation and routes to all of the other routers are + * eventually saved in the routing tables of each of the chosen nodes. + * + * The "Root" vertex is then the SPFVertex representing the router that is + * having its routing tables set and is the root of the SPF tree. Each vertex + * in the SPF tree can have a number of children that represent host or + * network routes available via that vertex. + * + * This method the number of children of "this" SPFVertex (which reside in + * the SPF tree. + * + * @see SPFVertex::GetNChildren + * @param n The index (from 0 to the number of children minus 1) of the + * child SPFVertex to return. + * @warning Ownership of the pointer added to the children of "this" + * SPFVertex is transferred to the "this" SPFVertex. You must not delete the + * (now) child SPFVertex after calling this method. + * @param child A pointer to the SPFVertex (which resides in the SPF tree) to + * be added to the list of children of "this" SPFVertex. + * @returns The number of children of "this" SPFVertex after the addition of + * the new child. + */ + uint32_t AddChild (SPFVertex* child); + +private: + VertexType m_vertexType; + Ipv4Address m_vertexId; + StaticRouterLSA* m_lsa; + uint32_t m_distanceFromRoot; + uint32_t m_rootOif; + Ipv4Address m_nextHop; + SPFVertex* m_parent; + typedef std::list ListOfSPFVertex_t; + ListOfSPFVertex_t m_children; +/** + * @brief The SPFVertex copy construction is disallowed. There's no need for + * it and a compiler provided shallow copy would be wrong. + */ + SPFVertex (SPFVertex& v); +/** + * @brief The SPFVertex copy assignment operator is disallowed. There's no + * need for it and a compiler provided shallow copy would be wrong. + */ + SPFVertex& operator= (SPFVertex& v); +}; + +/** + * @brief The Link State DataBase (LSDB) of the Static Route Manager. + * + * Each node in the simulation participating in static routing has a + * StaticRouter interface. The primary job of this interface is to export + * Static Router Link State Advertisements (LSAs). These advertisements in + * turn contain a number of Static Router Link Records that describe the + * point to point links from the underlying node to other nodes (that will + * also export their own LSAs. + * + * This class implements a searchable database of LSAs gathered from every + * router in the simulation. + */ +class StaticRouteManagerLSDB +{ +public: +/** + * @brief Construct an empty Static Router Manager Link State Database. + * + * The database map composing the Link State Database is initialized in + * this constructor. + */ + StaticRouteManagerLSDB (); +/** + * @brief Destroy an empty Static Router Manager Link State Database. + * + * The database map is walked and all of the Link State Advertisements stored + * in the database are freed; then the database map itself is clear ()ed to + * release any remaining resources. + */ + ~StaticRouteManagerLSDB (); +/** + * @brief Insert an IP address / Link State Advertisement pair into the Link + * State Database. + * + * The IPV4 address and the StaticRouterLSA given as parameters are converted + * to an STL pair and are inserted into the database map. + * + * @see StaticRouterLSA + * @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, StaticRouterLSA* lsa); +/** + * @brief Look up the Link State Advertisement associated with the given + * IP Address. + * + * The database map is searched for the given IPV4 address and corresponding + * StaticRouterLSA is returned. + * + * @see StaticRouterLSA + * @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. + */ + StaticRouterLSA* GetLSA (Ipv4Address addr) const; +/** + * @brief Set all LSA flags to an initialized state, for SPF computation + * + * This function walks the database and resets the status flags of all of the + * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done + * prior to each SPF calculation to reset the state of the SPFVertex structures + * that will reference the LSAs during the calculation. + * + * @see StaticRouterLSA + * @see SPFVertex + */ + void Initialize (); + +private: + typedef std::map LSDBMap_t; + typedef std::pair LSDBPair_t; + + LSDBMap_t m_database; +/** + * @brief StaticRouteManagerLSDB copy construction is disallowed. There's no + * need for it and a compiler provided shallow copy would be hopelessly wrong. + */ + StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); +/** + * @brief The SPFVertex copy assignment operator is disallowed. There's no + * need for it and a compiler provided shallow copy would be wrong. + */ + StaticRouteManagerLSDB& operator= (StaticRouteManagerLSDB& lsdb); +}; + +/** + * @brief A global static router + * + * This singleton object can query interface each node in the system + * for a StaticRouter interface. For those nodes, it fetches one or + * more Link State Advertisements and stores them in a local database. + * Then, it can compute shortest paths on a per-node basis to all routers, + * and finally configure each of the node's forwarding tables. + * + * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd. + */ +class StaticRouteManagerImpl +{ +public: + StaticRouteManagerImpl (); + virtual ~StaticRouteManagerImpl (); +/** + * @brief Build the routing database by gathering Link State Advertisements + * from each node exporting a StaticRouter interface. + * + */ + virtual void BuildStaticRoutingDatabase(); +/** + * @brief Compute routes using a Dijkstra SPF computation and populate + * per-node forwarding tables + */ + virtual void InitializeRoutes(); +/** + * @brief Debugging routine; allow client code to supply a pre-built LSDB + */ + void DebugUseLsdb (StaticRouteManagerLSDB*); +/** + * @brief Debugging routine; call the core SPF from the unit tests + */ + void DebugSPFCalculate (Ipv4Address root); +private: +/** + * @brief Static Route Manager Implementation copy construction is disallowed. + * There's no need for it and a compiler provided shallow copy would be + * hopelessly wrong. + */ + StaticRouteManagerImpl (StaticRouteManagerImpl& srmi); +/** + * @brief Static Route Manager Implementation assignment operator is + * disallowed. There's no need for it and a compiler provided shallow copy + * would be hopelessly wrong. + */ + StaticRouteManagerImpl& operator= (StaticRouteManagerImpl& srmi); + + SPFVertex* m_spfroot; + StaticRouteManagerLSDB* m_lsdb; + void SPFCalculate (Ipv4Address root); + void SPFNext (SPFVertex*, CandidateQueue&); + int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, + StaticRouterLinkRecord* l, uint32_t distance); + void SPFVertexAddParent(SPFVertex* v); + StaticRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, + StaticRouterLinkRecord* prev_link); + void SPFIntraAddRouter(SPFVertex* v); + uint32_t FindOutgoingInterfaceId(Ipv4Address a); +}; + +} // namespace ns3 + +#endif /* STATIC_ROUTE_MANAGER_IMPL_H */ diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 02948ac9c..09ced494f 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -14,1358 +14,32 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include #include "ns3/assert.h" -#include "ns3/fatal-error.h" #include "ns3/debug.h" -#include "ns3/node-list.h" -#include "ns3/ipv4.h" -#include "static-router.h" +#include "ns3/simulation-singleton.h" #include "static-route-manager.h" -#include "candidate-queue.h" - -NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); +#include "static-route-manager-impl.h" namespace ns3 { -// --------------------------------------------------------------------------- -// -// SPFVertex Implementation -// -// --------------------------------------------------------------------------- - -SPFVertex::SPFVertex () : - m_vertexType (VertexUnknown), - m_vertexId ("255.255.255.255"), - m_lsa (0), - m_distanceFromRoot (SPF_INFINITY), - m_rootOif (SPF_INFINITY), - m_nextHop ("0.0.0.0"), - m_parent (0), - m_children () -{ -} - -SPFVertex::SPFVertex (StaticRouterLSA* lsa) : - m_vertexType (VertexRouter), - m_vertexId (lsa->GetLinkStateId ()), - m_lsa (lsa), - m_distanceFromRoot (SPF_INFINITY), - m_rootOif (SPF_INFINITY), - m_nextHop ("0.0.0.0"), - m_parent (0), - m_children () -{ -} - -SPFVertex::~SPFVertex () -{ - for ( ListOfSPFVertex_t::iterator i = m_children.begin (); - i != m_children.end (); - i++) - { - SPFVertex *p = *i; - delete p; - p = 0; - *i = 0; - } - m_children.clear (); -} - - void -SPFVertex::SetVertexType (SPFVertex::VertexType type) -{ - m_vertexType = type; -} - - SPFVertex::VertexType -SPFVertex::GetVertexType (void) const -{ - return m_vertexType; -} - - void -SPFVertex::SetVertexId (Ipv4Address id) -{ - m_vertexId = id; -} - - Ipv4Address -SPFVertex::GetVertexId (void) const -{ - return m_vertexId; -} - - void -SPFVertex::SetLSA (StaticRouterLSA* lsa) -{ - m_lsa = lsa; -} - - StaticRouterLSA* -SPFVertex::GetLSA (void) const -{ - return m_lsa; -} - - void -SPFVertex::SetDistanceFromRoot (uint32_t distance) -{ - m_distanceFromRoot = distance; -} - - uint32_t -SPFVertex::GetDistanceFromRoot (void) const -{ - return m_distanceFromRoot; -} - - void -SPFVertex::SetOutgoingInterfaceId (uint32_t id) -{ - m_rootOif = id; -} - - uint32_t -SPFVertex::GetOutgoingInterfaceId (void) const -{ - return m_rootOif; -} - - void -SPFVertex::SetNextHop (Ipv4Address nextHop) -{ - m_nextHop = nextHop; -} - - Ipv4Address -SPFVertex::GetNextHop (void) const -{ - return m_nextHop; -} - - void -SPFVertex::SetParent (SPFVertex* parent) -{ - m_parent = parent; -} - - SPFVertex* -SPFVertex::GetParent (void) const -{ - return m_parent; -} - - uint32_t -SPFVertex::GetNChildren (void) const -{ - return m_children.size (); -} - - SPFVertex* -SPFVertex::GetChild (uint32_t n) const -{ - uint32_t j = 0; - - for ( ListOfSPFVertex_t::const_iterator i = m_children.begin (); - i != m_children.end (); - i++, j++) - { - if (j == n) - { - return *i; - } - } - NS_ASSERT_MSG(false, "Index out of range."); - return 0; -} - - uint32_t -SPFVertex::AddChild (SPFVertex* child) -{ - m_children.push_back (child); - return m_children.size (); -} - -// --------------------------------------------------------------------------- -// -// StaticRouteManagerLSDB Implementation -// -// --------------------------------------------------------------------------- - -StaticRouteManagerLSDB::StaticRouteManagerLSDB () -: - m_database () -{ - NS_DEBUG ("StaticRouteManagerLSDB::StaticRouteManagerLSDB ()"); -} - -StaticRouteManagerLSDB::~StaticRouteManagerLSDB () -{ - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); - - LSDBMap_t::iterator i; - for (i= m_database.begin (); i!= m_database.end (); i++) - { - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ():free LSA"); - StaticRouterLSA* temp = i->second; - delete temp; - } - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); - m_database.clear (); -} - - void -StaticRouteManagerLSDB::Initialize () -{ - NS_DEBUG ("StaticRouteManagerLSDB::Initialize ()"); - - LSDBMap_t::iterator i; - for (i= m_database.begin (); i!= m_database.end (); i++) - { - StaticRouterLSA* temp = i->second; - temp->SetStatus (StaticRouterLSA::LSA_SPF_NOT_EXPLORED); - } -} - - void -StaticRouteManagerLSDB::Insert (Ipv4Address addr, StaticRouterLSA* lsa) -{ - NS_DEBUG ("StaticRouteManagerLSDB::Insert ()"); - m_database.insert (LSDBPair_t (addr, lsa)); -} - - StaticRouterLSA* -StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) const -{ - NS_DEBUG ("StaticRouteManagerLSDB::GetLSA ()"); -// -// Look up an LSA by its address. -// - LSDBMap_t::const_iterator i; - for (i= m_database.begin (); i!= m_database.end (); i++) - { - if (i->first == addr) - { - return i->second; - } - } - return 0; -} - // --------------------------------------------------------------------------- // // StaticRouteManager Implementation // // --------------------------------------------------------------------------- -StaticRouteManager::StaticRouteManager () -: - m_spfroot (0) -{ - m_lsdb = new StaticRouteManagerLSDB (); -} - -StaticRouteManager::~StaticRouteManager () -{ - NS_DEBUG ("StaticRouteManager::~StaticRouteManager ()"); - - if (m_lsdb) - { - delete m_lsdb; - } -} - - void -StaticRouteManager::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) -{ - if (m_lsdb) - delete m_lsdb; - m_lsdb = lsdb; -} - -// -// In order to build the routing database, we need to walk the list of nodes -// in the system and look for those that support the StaticRouter interface. -// These routers will export a number of Link State Advertisements (LSAs) -// that describe the links and networks that are "adjacent" (i.e., that are -// on the other side of a point-to-point link). We take these LSAs and put -// add them to the Link State DataBase (LSDB) from which the routes will -// ultimately be computed. -// void StaticRouteManager::BuildStaticRoutingDatabase () { - NS_DEBUG ("StaticRouteManager::BuildStaticRoutingDatabase()"); -// -// Walk the list of nodes looking for the StaticRouter Interface. -// - typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) - { - Ptr node = *i; - - Ptr rtr = - node->QueryInterface (StaticRouter::iid); -// -// Ignore nodes that aren't participating in routing. -// - if (!rtr) - { - continue; - } -// -// You must call DiscoverLSAs () before trying to use any routing info or to -// update LSAs. DiscoverLSAs () drives the process of discovering routes in -// the StaticRouter. Afterward, you may use GetNumLSAs (), which is a very -// computationally inexpensive call. If you call GetNumLSAs () before calling -// DiscoverLSAs () will get zero as the number since no routes have been -// found. -// - uint32_t numLSAs = rtr->DiscoverLSAs (); - NS_DEBUG ("Discover LSAs: Found " << numLSAs << " LSAs"); - - for (uint32_t j = 0; j < numLSAs; ++j) - { - StaticRouterLSA* lsa = new StaticRouterLSA (); -// -// 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. -// - m_lsdb->Insert (lsa->GetLinkStateId (), lsa); - } - } + return SimulationSingleton::Get ()-> + BuildStaticRoutingDatabase (); } -// -// For each node that is a static router (which is determined by the presence -// of an aggregated StaticRouter interface), run the Dijkstra SPF calculation -// on the database rooted at that router, and populate the node forwarding -// tables. -// -// This function parallels RFC2328, Section 16.1.1, and quagga ospfd -// -// This calculation yields the set of intra-area routes associated -// with an area (called hereafter Area A). A router calculates the -// shortest-path tree using itself as the root. The formation -// of the shortest path tree is done here in two stages. In the -// first stage, only links between routers and transit networks are -// considered. Using the Dijkstra algorithm, a tree is formed from -// this subset of the link state database. In the second stage, -// leaves are added to the tree by considering the links to stub -// networks. -// -// The area's link state database is represented as a directed graph. -// The graph's vertices are routers, transit networks and stub networks. -// -// The first stage of the procedure (i.e., the Dijkstra algorithm) -// can now be summarized as follows. At each iteration of the -// algorithm, there is a list of candidate vertices. Paths from -// the root to these vertices have been found, but not necessarily -// the shortest ones. However, the paths to the candidate vertex -// that is closest to the root are guaranteed to be shortest; this -// vertex is added to the shortest-path tree, removed from the -// candidate list, and its adjacent vertices are examined for -// possible addition to/modification of the candidate list. The -// algorithm then iterates again. It terminates when the candidate -// list becomes empty. -// void StaticRouteManager::InitializeRoutes () { - NS_DEBUG ("StaticRouteManager::InitializeRoutes ()"); -// -// Walk the list of nodes in the system. -// - typedef std::vector < Ptr >::iterator Iterator; - for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) - { - Ptr node = *i; -// -// Look for the StaticRouter interface that indicates that the node is -// participating in routing. -// - Ptr rtr = - node->QueryInterface (StaticRouter::iid); -// -// if the node has a static router interface, then run the static routing -// algorithms. -// - if (rtr && rtr->GetNumLSAs () ) - { - SPFCalculate (rtr->GetRouterId ()); - } - } -} - -// -// This method is derived from quagga ospf_spf_next (). See RFC2328 Section -// 16.1 (2) for further details. -// -// We're passed a parameter that is a vertex which is already in the SPF -// tree. A vertex represents a router node. We also get a reference to the -// SPF candidate queue, which is a priority queue containing the shortest paths -// to the networks we know about. -// -// We examine the links in v's LSA and update the list of candidates with any -// vertices not already on the list. If a lower-cost path is found to a -// vertex already on the candidate list, store the new (lower) cost. -// - void -StaticRouteManager::SPFNext (SPFVertex* v, CandidateQueue& candidate) -{ - SPFVertex* w = 0; - StaticRouterLSA* w_lsa = 0; - uint32_t distance = 0; - - NS_DEBUG ("StaticRouteManager::SPFNext ()"); -// -// Always true for now, since all our LSAs are RouterLSAs. -// - if (v->GetVertexType () == SPFVertex::VertexRouter) - { - if (true) - { - 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. -// - StaticRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); - if (l->GetLinkType () == StaticRouterLinkRecord::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 () == StaticRouterLinkRecord::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 ()); -// -// (c) If vertex W is already on the shortest-path tree, examine the next -// link in the LSA. -// -// 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 () == - StaticRouterLSA::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. -// -// (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 (w_lsa->GetStatus () == - StaticRouterLSA::LSA_SPF_NOT_EXPLORED) - { -// -// If we havent yet considered the link represented by we have to create -// a new SPFVertex to represent it. -// - w = new SPFVertex (w_lsa); -// -// 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 ( - StaticRouterLSA::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 () == - StaticRouterLSA::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 -// distance metric. -// -// 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) - { -// -// This is not a shorter path, so don't do anything. -// - 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 - { -// -// 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 -// (vertex ) -// -// 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 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 - } - } -} - -// -// 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. -// -// For now, this is greatly simplified from the quagga code -// - int -StaticRouteManager::SPFNexthopCalculation ( - SPFVertex* v, - SPFVertex* w, - StaticRouterLinkRecord* l, - uint32_t distance) -{ - NS_DEBUG ("StaticRouteManager::SPFNexthopCalculation ()"); -// -// 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 -// calculating the routes. -// -// There are two distinct cases for calculating the next hop information. -// First, if we're considering a hop from the root to an "adjacent" network -// (one that is on the other side of a point-to-point link connected to the -// root), then we need to store the information needed to forward down that -// link. The second case is if the network is not directly adjacent. In that -// case we need to use the forwarding information from the vertex on the path -// to the destination that is directly adjacent [node 1] in both cases of the -// diagram below. -// -// (1) [root] -> [point-to-point] -> [node 1] -// (2) [root] -> [point-to-point] -> [node 1] -> [point-to-point] -> [node 2] -// -// We call the propagation of next hop information down vertices of a path -// "inheriting" the next hop information. -// -// The point-to-point link information is only useful in this calculation when -// we are examining the root node. -// - if (v == m_spfroot) - { -// -// In this case is the root node, which means it is the starting point -// for the packets forwarded by that node. This also means that the next hop -// address of packets headed for some arbitrary off-network destination must -// be the destination at the other end of one of the links off of the root -// node if this root node is a router. We then need to see if this node -// is a router. -// - if (w->GetVertexType () == SPFVertex::VertexRouter) - { -// -// In the case of point-to-point links, the link data field (m_linkData) of a -// Static Router Link Record contains the local IP address. If we look at the -// link record describing the link from the perspecive of (the remote -// node from the viewpoint of ) back to the root node, we can discover the -// IP address of the router to which is adjacent. This is a distinguished -// address -- the next hop address to get from to and all networks -// accessed through that path. -// -// SPFGetNextLink () is a little odd. used in this way it is just going to -// return the link record describing the link from to . Think of it as -// SPFGetLink. -// - StaticRouterLinkRecord *linkRemote = 0; - linkRemote = SPFGetNextLink (w, v, linkRemote); -// -// At this point, is the Static Router Link Record describing the point- -// to point link from to from the perspective of ; and -// is the Static Router Link Record describing that same link from the -// perspective of (back to ). Now we can just copy the next hop -// address from the m_linkData member variable. -// -// The next hop member variable we put in has the sense "in order to get -// from the root node to the host represented by vertex , you have to send -// the packet to the next hop address specified in w->m_nextHop. -// - w->SetNextHop(linkRemote->GetLinkData ()); -// -// Now find the outgoing interface corresponding to the point to point link -// from the perspective of -- remember that is the link "from" -// "to" . -// - w->SetOutgoingInterfaceId ( - FindOutgoingInterfaceId (l->GetLinkData ())); - - NS_DEBUG ("SPFNexthopCalculation: Next hop from " << - v->GetVertexId () << " to " << w->GetVertexId () << - " goes through next hop " << w->GetNextHop () << - " via outgoing interface " << w->GetOutgoingInterfaceId ()); - } - } - else - { -// -// If we're calculating the next hop information from a node (v) that is -// *not* the root, then we need to "inherit" the information needed to -// forward the packet from the vertex closer to the root. That is, we'll -// still send packets to the next hop address of the router adjacent to the -// root on the path toward . -// -// Above, when we were considering the root node, we calculated the next hop -// address and outgoing interface required to get off of the root network. -// At this point, we are further away from the root network along one of the -// (shortest) paths. So the next hop and outoing interface remain the same -// (are inherited). -// - w->SetNextHop (v->GetNextHop ()); - w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ()); - } -// -// In all cases, we need valid values for the distance metric and a parent. -// - w->SetDistanceFromRoot (distance); - w->SetParent (v); - - return 1; -} - -// -// This method is derived from quagga ospf_get_next_link () -// -// First search the Static Router Link Records of vertex for one -// representing a point-to point link to vertex . -// -// What is done depends on prev_link. Contrary to appearances, prev_link just -// acts as a flag here. If prev_link is NULL, we return the first Static -// Router Link Record we find that describes a point-to-point link from -// to . If prev_link is not NULL, we return a Static 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? -// - StaticRouterLinkRecord* -StaticRouteManager::SPFGetNextLink ( - SPFVertex* v, - SPFVertex* w, - StaticRouterLinkRecord* prev_link) -{ - NS_DEBUG ("StaticRouteManager::SPFGetNextLink ()"); - - bool skip = true; - StaticRouterLinkRecord* l; -// -// If prev_link is 0, we are really looking for the first link, not the next -// link. -// - if (prev_link == 0) - { - skip = false; - } -// -// Iterate through the Static Router Link Records advertised by the vertex -// looking for records representing the point-to-point links off of this -// vertex. -// - for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) - { - l = v->GetLSA ()->GetLinkRecord (i); - if (l->GetLinkType () != StaticRouterLinkRecord::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 -// connects from the perspective of in this case. The vertex ID is also -// set to the router ID (using the link state advertisement of a router node). -// 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 = " << - l->GetLinkId () << " linkData = " << l->GetLinkData ()); -// -// If skip is false, don't (not too surprisingly) skip the link found -- it's -// the one we're interested in. That's either because we didn't pass in a -// previous link, and we're interested in the first one, or because we've -// skipped a previous link and moved forward to the next (which is then the -// one we want). -// - if (skip == false) - { - NS_DEBUG ("SPFGetNextLink: Returning the found link"); - return l; - } - else - { -// -// Skip is true and we've found a link from to . We want the next one. -// Setting skip to false gets us the next point-to-point static router link -// record in the LSA from . -// - NS_DEBUG ("SPFGetNextLink: Skipping the found link"); - skip = false; - continue; - } - } - } - return 0; -} - -// -// Used for unit tests. -// - void -StaticRouteManager::DebugSPFCalculate (Ipv4Address root) -{ - SPFCalculate (root); -} - -// quagga ospf_spf_calculate - void -StaticRouteManager::SPFCalculate (Ipv4Address root) -{ - NS_DEBUG ("StaticRouteManager::SPFCalculate (): " - "root = " << root); - - SPFVertex *v; -// -// Initialize the Link State Database. -// - m_lsdb->Initialize (); -// -// The candidate queue is a priority queue of SPFVertex objects, with the top -// of the queue being the closest vertex in terms of distance from the root -// of the tree. Initially, this queue is empty. -// - CandidateQueue candidate; - NS_ASSERT(candidate.Size () == 0); -// -// Initialize the shortest-path tree to only contain the router doing the -// calculation. Each router (and corresponding network) is a vertex in the -// shortest path first (SPF) tree. -// - v = new SPFVertex (m_lsdb->GetLSA (root)); -// -// This vertex is the root of the SPF tree and it is distance 0 from the root. -// We also mark this vertex as being in the SPF tree. -// - m_spfroot= v; - v->SetDistanceFromRoot (0); - v->GetLSA ()->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); - - for (;;) - { -// -// The operations we need to do are given in the OSPF RFC which we reference -// as we go along. -// -// RFC2328 16.1. (2). -// -// We examine the Static Router Link Records in the Link State -// Advertisements of the current vertex. If there are any point-to-point -// links to unexplored adjacent vertices we add them to the tree and update -// the distance and next hop information on how to get there. We also add -// the new vertices to the candidate queue (the priority queue ordered by -// shortest path). If the new vertices represent shorter paths, we use them -// and update the path cost. -// - SPFNext (v, candidate); -// -// RFC2328 16.1. (3). -// -// If at this step the candidate list is empty, the shortest-path tree (of -// transit vertices) has been completely built and this stage of the -// procedure terminates. -// - if (candidate.Size () == 0) - { - break; - } -// -// Choose the vertex belonging to the candidate list that is closest to the -// root, and add it to the shortest-path tree (removing it from the candidate -// list in the process). -// -// Recall that in the previous step, we created SPFVertex structures for each -// of the routers found in the Static Router Link Records and added tehm to -// the candidate list. -// - v = candidate.Pop (); - NS_DEBUG ("SPFCalculate: Popped vertex " << v->GetVertexId ()); -// -// Update the status field of the vertex to indicate that it is in the SPF -// tree. -// - v->GetLSA ()->SetStatus (StaticRouterLSA::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 -// children of that parent vertex. In the next hop calculation called during -// SPFNext, the parent pointer was set but the vertex has been orphaned up -// to now. -// - SPFVertexAddParent (v); -// -// Note that when there is a choice of vertices closest to the root, network -// vertices must be chosen before router vertices in order to necessarily -// find all equal-cost paths. We don't do this at this moment, we should add -// the treatment above codes. -- kunihiro. -// -// RFC2328 16.1. (4). -// -// This is the method that actually adds the routes. It'll walk the list -// of nodes in the system, looking for the node corresponding to the router -// ID of the root of the tree -- that is the router we're building the routes -// for. It looks for the Ipv4 interface of that node and remembers it. So -// we are only actually adding routes to that one node at the root of the SPF -// tree. -// -// We're going to pop of a pointer to every vertex in the tree except the -// root in order of distance from the root. For each of the vertices, we call -// SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the -// point-to-point Static Router Link Records (the links to nodes adjacent to -// the node represented by the vertex). We add a route to the IP address -// specified by the m_linkData field of each of those link records. This will -// be the *local* IP address associated with the interface attached to the -// link. We use the outbound interface and next hop information present in -// the vertex which have possibly been inherited from the root. -// -// To summarize, we're going to look at the node represented by and loop -// 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); -// -// RFC2328 16.1. (5). -// -// Iterate the algorithm by returning to Step 2 until there are no more -// candidate vertices. -// - } -// -// Second stage of SPF calculation procedure's -// NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); -// -// We're all done setting the routing information for the node at the root of -// the SPF tree. Delete all of the vertices and corresponding resources. Go -// possibly do it again for the next router. -// - delete m_spfroot; - m_spfroot = 0; -} - -// -// BUGBUG FIXME: This should probably be a method on Ipv4 -// -// Return the interface index corresponding to a given IP address -// - uint32_t -StaticRouteManager::FindOutgoingInterfaceId (Ipv4Address a) -{ -// -// 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 (StaticRouter::iid); -// -// If the node doesn't have a StaticRouter 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, - "StaticRouteManager::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) == a) - { - NS_DEBUG ("StaticRouteManager::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 -// tables of the individual nodes. -// -// The vertex passed as a parameter has just been added to the SPF tree. -// This vertex must have a valid m_root_oid, corresponding to the outgoing -// interface on the root router of the tree that is the first hop on the path -// to the vertex. The vertex must also have a next hop address, corresponding -// to the next hop on the path to the vertex. The vertex has an m_lsa field -// that has some number of link records. For each point to point link record, -// the m_linkData is the local IP address of the link. This corresponds to -// a destination IP address, reachable from the root, to which we add a host -// route. -// - void -StaticRouteManager::SPFIntraAddRouter (SPFVertex* v) -{ - NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter ()"); - - NS_ASSERT_MSG (m_spfroot, - "StaticRouteManager::SPFIntraAddRouter (): 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 ("StaticRouteManager::SPFIntraAddRouter ():" - "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 StaticRouter interface, so we need -// to QI for that interface. If there's no StaticRouter interface, the node -// in question cannot be the router we want, so we continue. -// - Ptr rtr = - node->QueryInterface (StaticRouter::iid); - - if (rtr == 0) - { - 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. -// - if (rtr->GetRouterId () == routerId) - { - NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " - "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, - "StaticRouteManager::SPFIntraAddRouter (): " - "QI for interface failed"); -// -// Get the Static Router Link State Advertisement from the vertex we're -// adding the routes to. The LSA will have a number of attached Static 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. -// - StaticRouterLSA *lsa = v->GetLSA (); - NS_ASSERT_MSG (lsa, - "StaticRouteManager::SPFIntraAddRouter (): " - "Expected valid LSA in SPFVertex* v"); - - uint32_t nLinkRecords = lsa->GetNLinkRecords (); -// -// Iterate through the link records on the vertex to which we're going to add -// routes. To make sure we're being clear, we're going to add routing table -// entries to the tables on the node corresping to the root of the SPF tree. -// These entries will have routes to the IP addresses we find from looking at -// the local side of the point-to-point links found on the node described by -// the vertex . -// - for (uint32_t j = 0; j < nLinkRecords; j += 2) - { -// -// We are only concerned about point-to-point links -// - StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); - if (lr->GetLinkType () != StaticRouterLinkRecord::PointToPoint) - { - continue; - } - - NS_DEBUG ("StaticRouteManager::SPFIntraAddRouter (): " - " Node " << node->GetId () << - " add route to " << lr->GetLinkData () << - " using next hop " << v->GetNextHop () << - " via interface " << v->GetOutgoingInterfaceId ()); -// -// Here's why we did all of that work. We're going to add a host route to the -// host address found in the m_linkData field of the point-to-point link -// record. In the case of a point-to-point link, this is the local IP address -// of the node connected to the link. Each of these point-to-point links -// will correspond to a local interface that has an IP address to which -// the node at the root of the SPF tree can send packets. The vertex -// (corresponding to the node that has these links and interfaces) has -// an m_nextHop address precalculated for us that is the address to which the -// root node should send packets to be forwarded to these IP addresses. -// Similarly, the vertex has an m_rootOif (outbound interface index) to -// which the packets should be send for forwarding. -// - ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (), - v->GetOutgoingInterfaceId ()); - } - } -// -// We've found the node and added the routes. Don't need to search forward -// for another node we'll never find. -// - return; - } -} - -// Derived from quagga ospf_vertex_add_parents () -// -// This is a somewhat oddly named method (blame quagga). Although you might -// expect it to add a parent *to* something, it actually adds a vertex -// to the list of children *in* each of its parents. -// -// Given a pointer to a vertex, it links back to the vertex's parent that it -// already has set and adds itself to that vertex's list of children. -// -// For now, only one parent (not doing equal-cost multipath) -// - void -StaticRouteManager::SPFVertexAddParent (SPFVertex* v) -{ - v->GetParent ()->AddChild (v); + return SimulationSingleton::Get ()-> + InitializeRoutes (); } } // namespace ns3 - -#ifdef RUN_SELF_TESTS - -// --------------------------------------------------------------------------- -// -// Unit Tests -// -// --------------------------------------------------------------------------- - -#include "ns3/test.h" - -namespace ns3 { - -class StaticRouterTestNode : public Node -{ -public: - StaticRouterTestNode (); - -private: - virtual void DoAddDevice (Ptr device) const {}; - virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); -}; - -StaticRouterTestNode::StaticRouterTestNode () -{ -// Ptr ipv4 = Create (this); -} - - TraceResolver* -StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) -{ - return 0; -} - -class StaticRouteManagerTest : public Test { -public: - StaticRouteManagerTest (); - virtual ~StaticRouteManagerTest (); - virtual bool RunTests (void); -}; - -StaticRouteManagerTest::StaticRouteManagerTest () - : Test ("StaticRouteManager") -{ -} - -StaticRouteManagerTest::~StaticRouteManagerTest () -{} - - bool -StaticRouteManagerTest::RunTests (void) -{ - bool ok = true; - - CandidateQueue candidate; - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = new SPFVertex; - v->SetDistanceFromRoot (rand () % 100); - candidate.Push (v); - } - - uint32_t lastDistance = 0; - - for (int i = 0; i < 100; ++i) - { - SPFVertex *v = candidate.Pop (); - if (v->GetDistanceFromRoot () < lastDistance) - { - ok = false; - } - lastDistance = v->GetDistanceFromRoot (); - delete v; - v = 0; - } - - // Build fake link state database; four routers (0-3), 3 point-to-point - // links - // - // n0 - // \ link 0 - // \ link 2 - // n2 -------------------------n3 - // / - // / link 1 - // n1 - // - // link0: 10.1.1.1/30, 10.1.1.2/30 - // link1: 10.1.2.1/30, 10.1.2.2/30 - // link2: 10.1.3.1/30, 10.1.3.2/30 - // - // Router 0 - StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.2", // router ID 0.0.0.2 - "10.1.1.1", // local ID - 1); // metric - - StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.1.1", - "255.255.255.252", - 1); - - StaticRouterLSA* lsa0 = new StaticRouterLSA (); - lsa0->SetLinkStateId ("0.0.0.0"); - lsa0->SetAdvertisingRouter ("0.0.0.0"); - lsa0->AddLinkRecord (lr0); - lsa0->AddLinkRecord (lr1); - - // Router 1 - StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.2", - "10.1.2.1", - 1); - - StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.2.1", - "255.255.255.252", - 1); - - StaticRouterLSA* lsa1 = new StaticRouterLSA (); - lsa1->SetLinkStateId ("0.0.0.1"); - lsa1->SetAdvertisingRouter ("0.0.0.1"); - lsa1->AddLinkRecord (lr2); - lsa1->AddLinkRecord (lr3); - - // Router 2 - StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.0", - "10.1.1.2", - 1); - - StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.1.2", - "255.255.255.252", - 1); - - StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.1", - "10.1.2.2", - 1); - - StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.2.2", - "255.255.255.252", - 1); - - StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.3", - "10.1.3.2", - 1); - - StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.3.2", - "255.255.255.252", - 1); - - StaticRouterLSA* lsa2 = new StaticRouterLSA (); - lsa2->SetLinkStateId ("0.0.0.2"); - lsa2->SetAdvertisingRouter ("0.0.0.2"); - lsa2->AddLinkRecord (lr4); - lsa2->AddLinkRecord (lr5); - lsa2->AddLinkRecord (lr6); - lsa2->AddLinkRecord (lr7); - lsa2->AddLinkRecord (lr8); - lsa2->AddLinkRecord (lr9); - - // Router 3 - StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, - "0.0.0.2", - "10.1.2.1", - 1); - - StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, - "10.1.2.1", - "255.255.255.252", - 1); - - StaticRouterLSA* lsa3 = new StaticRouterLSA (); - lsa3->SetLinkStateId ("0.0.0.3"); - lsa3->SetAdvertisingRouter ("0.0.0.3"); - lsa3->AddLinkRecord (lr10); - lsa3->AddLinkRecord (lr11); - - // Test the database - StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB (); - srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0); - srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1); - srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2); - srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3); - NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ())); - - // XXX next, calculate routes based on the manually created LSDB - StaticRouteManager* srm = new StaticRouteManager (); - srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB - // Note-- this will succeed without any nodes in the topology - // because the NodeList is empty - srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 - - // This delete clears the srm, which deletes the LSDB, which clears - // all of the LSAs, which each destroys the attached LinkRecords. - delete srm; - - return ok; -} - -// Instantiate this class for the unit tests -static StaticRouteManagerTest g_staticRouteManagerTest; - -} // namespace ns3 - -#endif diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 67e120da4..e8616d573 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -13,603 +13,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef STATIC_ROUTE_MANAGER_H #define STATIC_ROUTE_MANAGER_H -#include -#include -#include -#include -#include "ns3/object.h" -#include "ns3/ptr.h" -#include "ns3/ipv4-address.h" -#include "static-router.h" - namespace ns3 { -const uint32_t SPF_INFINITY = 0xffffffff; - -class CandidateQueue; - -/** - * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328, - * Section 16. - * - * Each router in the simulation is associated with an SPFVertex object. When - * calculating routes, each of these routers is, in turn, chosen as the "root" - * of the calculation and routes to all of the other routers are eventually - * saved in the routing tables of each of the chosen nodes. Each of these - * routers in the calculation has an associated SPFVertex. - * - * The "Root" vertex is the SPFVertex representing the router that is having - * its routing tables set. The SPFVertex objects representing other routers - * or networks in the simulation are arranged in the SPF tree. It is this - * tree that represents the Shortest Paths to the other networks. - * - * Each SPFVertex has a pointer to the Static Router Link State Advertisement - * (LSA) that its underlying router has exported. Within these LSAs are - * Static Router Link Records that describe the point to point links from the - * underlying router to other nodes (represented by other SPFVertex objects) - * in the simulation topology. The combination of the arrangement of the - * SPFVertex objects in the SPF tree, along with the details of the link - * records that connect them provide the information required to construct the - * required routes. - */ -class SPFVertex -{ -public: -/** - * @enum Enumeration of the possible types of SPFVertex objects. Currently - * we use VertexRouter to identify objects that represent a router in the - * simulation topology, and VertexNetwork to identify objects that represent - * a network. - */ - enum VertexType { - VertexUnknown = 0, /**< Uninitialized Link Record */ - VertexRouter, /**< Vertex representing a router in the topology */ - VertexNetwork /**< Vertex representing a network in the topology */ - }; -/** - * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First - * Vertex). - * - * The Vertex Type is set to VertexUnknown, the Vertex ID is set to - * 255.255.255.255, and the distance from root is set to infinity - * (UINT32_MAX). The referenced Link State Advertisement (LSA) is set to - * null as is the parent SPFVertex. The outgoing interface index is set to - * infinity, the next hop address is set to 0.0.0.0 and the list of children - * of the SPFVertex is initialized to empty. - * - * @see VertexType - */ - SPFVertex(); -/** - * @brief Construct an initialized SPFVertex (Shortest Path First Vertex). - * - * The Vertex Type is initialized to VertexRouter and the Vertex ID is found - * from the Link State ID of the Link State Advertisement (LSA) passed as a - * parameter. The Link State ID is set to the Router ID of the advertising - * router. The referenced LSA (m_lsa) is set to the given LSA. Other than - * these members, initialization is as in the default constructor. - * of the SPFVertex is initialized to empty. - * - * @see SPFVertex::SPFVertex () - * @see VertexType - * @see StaticRouterLSA - * @param lsa The Link State Advertisement used for finding initial values. - */ - SPFVertex(StaticRouterLSA* lsa); -/** - * @brief Destroy an SPFVertex (Shortest Path First Vertex). - * - * The children vertices of the SPFVertex are recursively deleted. - * - * @see SPFVertex::SPFVertex () - */ - ~SPFVertex(); -/** - * @brief Get the Vertex Type field of a SPFVertex object. - * - * The Vertex Type describes the kind of simulation object a given SPFVertex - * represents. - * - * @see VertexType - * @returns The VertexType of the current SPFVertex object. - */ - VertexType GetVertexType (void) const; -/** - * @brief Set the Vertex Type field of a SPFVertex object. - * - * The Vertex Type describes the kind of simulation object a given SPFVertex - * represents. - * - * @see VertexType - * @param The new VertexType for the current SPFVertex object. - */ - void SetVertexType (VertexType type); -/** - * @brief Get the Vertex ID field of a SPFVertex object. - * - * The Vertex ID uniquely identifies the simulation object a given SPFVertex - * represents. Typically, this is the Router ID for SPFVertex objects - * representing routers, and comes from the Link State Advertisement of a - * router aggregated to a node in the simulation. These IDs are allocated - * automatically by the routing environment and look like IP addresses - * beginning at 0.0.0.0 and monotonically increasing as new routers are - * instantiated. - * - * @returns The Ipv4Address Vertex ID of the current SPFVertex object. - */ - Ipv4Address GetVertexId (void) const; -/** - * @brief Set the Vertex ID field of a SPFVertex object. - * - * The Vertex ID uniquely identifies the simulation object a given SPFVertex - * represents. Typically, this is the Router ID for SPFVertex objects - * representing routers, and comes from the Link State Advertisement of a - * router aggregated to a node in the simulation. These IDs are allocated - * automatically by the routing environment and look like IP addresses - * beginning at 0.0.0.0 and monotonically increasing as new routers are - * instantiated. - * - * @param id The new Ipv4Address Vertex ID for the current SPFVertex object. - */ - void SetVertexId (Ipv4Address id); -/** - * @brief Get the Static Router Link State Advertisement returned by the - * Static Router represented by this SPFVertex during the route discovery - * process. - * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () - * @returns A pointer to the StaticRouterLSA found by the router represented - * by this SPFVertex object. - */ - StaticRouterLSA* GetLSA (void) const; -/** - * @brief Set the Static Router Link State Advertisement returned by the - * Static Router represented by this SPFVertex during the route discovery - * process. - * - * @see SPFVertex::GetLSA () - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () - * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You - * must not delete the LSA after calling this method. - * @param A pointer to the StaticRouterLSA. - */ - void SetLSA (StaticRouterLSA* lsa); -/** - * @brief Get the distance from the root vertex to "this" SPFVertex object. - * - * Each router in the simulation is associated with an SPFVertex object. When - * calculating routes, each of these routers is, in turn, chosen as the "root" - * of the calculation and routes to all of the other routers are eventually - * saved in the routing tables of each of the chosen nodes. Each of these - * routers in the calculation has an associated SPFVertex. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex to which - * a route is being calculated from the root. The distance from the root that - * we're asking for is the number of hops from the root vertex to the vertex - * in question. - * - * The distance is calculated during route discovery and is stored in a - * member variable. This method simply fetches that value. - * - * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex. - */ - uint32_t GetDistanceFromRoot (void) const; -/** - * @brief Set the distance from the root vertex to "this" SPFVertex object. - * - * Each router in the simulation is associated with an SPFVertex object. When - * calculating routes, each of these routers is, in turn, chosen as the "root" - * of the calculation and routes to all of the other routers are eventually - * saved in the routing tables of each of the chosen nodes. Each of these - * routers in the calculation has an associated SPFVertex. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex to which - * a route is being calculated from the root. The distance from the root that - * we're asking for is the number of hops from the root vertex to the vertex - * in question. - * - * @param distance The distance, in hops, from the root SPFVertex to "this" - * SPFVertex. - */ - void SetDistanceFromRoot (uint32_t distance); -/** - * @brief Get the interface ID that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The outgoing interface that we're asking for is the interface - * index on the root node that should be used to start packets along the - * path to "this" vertex. - * - * When initializing the root SPFVertex, the interface ID is determined by - * examining the Static Router Link Records of the Link State Advertisement - * generated by the root node's StaticRouter. These interfaces are used to - * forward packets off of the root's network down those links. As other - * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Static Router Link Record. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to the interface of that - * first hop. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, the root node is asking, "which of my local interfaces - * should I use to get a packet to the network or host represented by 'this' - * SPFVertex." - * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord - * @returns The interface index to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - uint32_t GetOutgoingInterfaceId (void) const; -/** - * @brief Set the interface ID that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The outgoing interface that we're asking for is the interface - * index on the root node that should be used to start packets along the - * path to "this" vertex. - * - * When initializing the root SPFVertex, the interface ID is determined by - * examining the Static Router Link Records of the Link State Advertisement - * generated by the root node's StaticRouter. These interfaces are used to - * forward packets off of the root's network down those links. As other - * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Static Router Link Record. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to the interface of that - * first hop. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, we are letting the root node know which of its local - * interfaces it should use to get a packet to the network or host represented - * by "this" SPFVertex. - * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord - * @param id The interface index to use when forwarding packets to the host or - * network represented by "this" SPFVertex. - */ - void SetOutgoingInterfaceId (uint32_t id); -/** - * @brief Get the IP address that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The IP address that we're asking for is the address on the - * remote side of a link off of the root node that should be used as the - * destination for packets along the path to "this" vertex. - * - * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Static Router Link Records of the - * Link State Advertisement generated by the root node's StaticRouter. This - * address is used to forward packets off of the root's network down those - * links. As other vertices / nodes are discovered which are further away - * from the root, they will be accessible down one of the paths via a link - * described by one of these Static Router Link Records. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to a first hop router down - * an interface. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, the root node is asking, "which router should I send a - * packet to in order to get that packet to the network or host represented - * by 'this' SPFVertex." - * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord - * @returns The IP address to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - Ipv4Address GetNextHop (void) const; -/** - * @brief Set the IP address that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The IP address that we're asking for is the address on the - * remote side of a link off of the root node that should be used as the - * destination for packets along the path to "this" vertex. - * - * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Static Router Link Records of the - * Link State Advertisement generated by the root node's StaticRouter. This - * address is used to forward packets off of the root's network down those - * links. As other vertices / nodes are discovered which are further away - * from the root, they will be accessible down one of the paths via a link - * described by one of these Static Router Link Records. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to a first hop router down - * an interface. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method we are telling the root node which router it should send - * should I send a packet to in order to get that packet to the network or - * host represented by 'this' SPFVertex." - * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord - * @param nextHop The IP address to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - void SetNextHop (Ipv4Address nextHop); -/** - * @brief Get a pointer to the SPFVector that is the parent of "this" - * SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set and is the root of the SPF tree. - * - * This method returns a pointer to the parent node of "this" SPFVertex - * (both of which reside in that SPF tree). - * - * @returns A pointer to the SPFVertex that is the parent of "this" SPFVertex - * in the SPF tree. - */ - SPFVertex* GetParent (void) const; -/** - * @brief Set the pointer to the SPFVector that is the parent of "this" - * SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set and is the root of the SPF tree. - * - * This method sets the parent pointer of "this" SPFVertex (both of which - * reside in that SPF tree). - * - * @param parent A pointer to the SPFVertex that is the parent of "this" - * SPFVertex* in the SPF tree. - */ - void SetParent (SPFVertex* parent); -/** - * @brief Get the number of children of "this" SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set and is the root of the SPF tree. Each vertex - * in the SPF tree can have a number of children that represent host or - * network routes available via that vertex. - * - * This method returns the number of children of "this" SPFVertex (which - * reside in the SPF tree). - * - * @returns The number of children of "this" SPFVertex (which reside in the - * SPF tree). - */ - uint32_t GetNChildren (void) const; -/** - * @brief Get a borrowed SPFVertex pointer to the specified child of "this" - * SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set and is the root of the SPF tree. Each vertex - * in the SPF tree can have a number of children that represent host or - * network routes available via that vertex. - * - * This method the number of children of "this" SPFVertex (which reside in - * the SPF tree. - * - * @see SPFVertex::GetNChildren - * @param n The index (from 0 to the number of children minus 1) of the - * child SPFVertex to return. - * @warning The pointer returned by GetChild () is a borrowed pointer. You - * do not have any ownership of the underlying object and must not delete - * that object. - * @returns A pointer to the specified child SPFVertex (which resides in the - * SPF tree). - */ - SPFVertex* GetChild (uint32_t n) const; -/** - * @brief Get a borrowed SPFVertex pointer to the specified child of "this" - * SPFVertex. - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set and is the root of the SPF tree. Each vertex - * in the SPF tree can have a number of children that represent host or - * network routes available via that vertex. - * - * This method the number of children of "this" SPFVertex (which reside in - * the SPF tree. - * - * @see SPFVertex::GetNChildren - * @param n The index (from 0 to the number of children minus 1) of the - * child SPFVertex to return. - * @warning Ownership of the pointer added to the children of "this" - * SPFVertex is transferred to the "this" SPFVertex. You must not delete the - * (now) child SPFVertex after calling this method. - * @param child A pointer to the SPFVertex (which resides in the SPF tree) to - * be added to the list of children of "this" SPFVertex. - * @returns The number of children of "this" SPFVertex after the addition of - * the new child. - */ - uint32_t AddChild (SPFVertex* child); - -private: - VertexType m_vertexType; - Ipv4Address m_vertexId; - StaticRouterLSA* m_lsa; - uint32_t m_distanceFromRoot; - uint32_t m_rootOif; - Ipv4Address m_nextHop; - SPFVertex* m_parent; - typedef std::list ListOfSPFVertex_t; - ListOfSPFVertex_t m_children; -/** - * @brief The SPFVertex copy construction is disallowed. There's no need for - * it and a compiler provided shallow copy would be wrong. - */ - SPFVertex (SPFVertex& v); -/** - * @brief The SPFVertex copy assignment operator is disallowed. There's no - * need for it and a compiler provided shallow copy would be wrong. - */ - SPFVertex& operator= (SPFVertex& v); -}; - -/** - * @brief The Link State DataBase (LSDB) of the Static Route Manager. - * - * Each node in the simulation participating in static routing has a - * StaticRouter interface. The primary job of this interface is to export - * Static Router Link State Advertisements (LSAs). These advertisements in - * turn contain a number of Static Router Link Records that describe the - * point to point links from the underlying node to other nodes (that will - * also export their own LSAs. - * - * This class implements a searchable database of LSAs gathered from every - * router in the simulation. - */ -class StaticRouteManagerLSDB -{ -public: -/** - * @brief Construct an empty Static Router Manager Link State Database. - * - * The database map composing the Link State Database is initialized in - * this constructor. - */ - StaticRouteManagerLSDB (); -/** - * @brief Destroy an empty Static Router Manager Link State Database. - * - * The database map is walked and all of the Link State Advertisements stored - * in the database are freed; then the database map itself is clear ()ed to - * release any remaining resources. - */ - ~StaticRouteManagerLSDB (); -/** - * @brief Insert an IP address / Link State Advertisement pair into the Link - * State Database. - * - * The IPV4 address and the StaticRouterLSA given as parameters are converted - * to an STL pair and are inserted into the database map. - * - * @see StaticRouterLSA - * @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, StaticRouterLSA* lsa); -/** - * @brief Look up the Link State Advertisement associated with the given - * IP Address. - * - * The database map is searched for the given IPV4 address and corresponding - * StaticRouterLSA is returned. - * - * @see StaticRouterLSA - * @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. - */ - StaticRouterLSA* GetLSA (Ipv4Address addr) const; -/** - * @brief Set all LSA flags to an initialized state, for SPF computation - * - * This function walks the database and resets the status flags of all of the - * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done - * prior to each SPF calculation to reset the state of the SPFVertex structures - * that will reference the LSAs during the calculation. - * - * @see StaticRouterLSA - * @see SPFVertex - */ - void Initialize (); - -private: - typedef std::map LSDBMap_t; - typedef std::pair LSDBPair_t; - - LSDBMap_t m_database; -/** - * @brief StaticRouteManagerLSDB copy construction is disallowed. There's no - * need for it and a compiler provided shallow copy would be hopelessly wrong. - */ - StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); -/** - * @brief The SPFVertex copy assignment operator is disallowed. There's no - * need for it and a compiler provided shallow copy would be wrong. - */ - StaticRouteManagerLSDB& operator= (StaticRouteManagerLSDB& lsdb); -}; - /** * @brief A global static router * @@ -621,35 +30,20 @@ private: * * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd. */ -class StaticRouteManager : public Object +class StaticRouteManager { public: - static const InterfaceId iid; - StaticRouteManager (); /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a StaticRouter interface. * */ - virtual void BuildStaticRoutingDatabase(); + static void BuildStaticRoutingDatabase(); /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables */ - virtual void InitializeRoutes(); -/** - * @brief Debugging routine; allow client code to supply a pre-built LSDB - */ - void DebugUseLsdb (StaticRouteManagerLSDB*); -/** - * @brief Debugging routine; call the core SPF from the unit tests - */ - void DebugSPFCalculate (Ipv4Address root); - - virtual ~StaticRouteManager (); - -protected: - + static void InitializeRoutes(); private: /** * @brief Static Route Manager copy construction is disallowed. There's no @@ -662,18 +56,6 @@ private: * need for it and a compiler provided shallow copy would be hopelessly wrong. */ StaticRouteManager& operator= (StaticRouteManager& srm); - - SPFVertex* m_spfroot; - StaticRouteManagerLSDB* m_lsdb; - void SPFCalculate (Ipv4Address root); - void SPFNext (SPFVertex*, CandidateQueue&); - int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* l, uint32_t distance); - void SPFVertexAddParent(SPFVertex* v); - StaticRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* prev_link); - void SPFIntraAddRouter(SPFVertex* v); - uint32_t FindOutgoingInterfaceId(Ipv4Address a); }; } // namespace ns3 From c9b7590dd95575b768a7975256d76ad020d2f4a3 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 20 Jul 2007 14:22:46 -0700 Subject: [PATCH 75/92] turn off debug flag --- examples/simple-static-routing.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 01848c92c..fb6568f96 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -85,7 +85,6 @@ int main (int argc, char *argv[]) DebugComponentEnable("StaticRouter"); DebugComponentEnable("StaticRouteManager"); #endif - DebugComponentEnable("StaticRouteManager"); // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, From 897a5187506161568000a96e786372f870a0d418 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 20 Jul 2007 14:28:18 -0700 Subject: [PATCH 76/92] parenthesis police were here --- examples/simple-static-routing.cc | 60 +++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index fb6568f96..544e68721 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -76,17 +76,17 @@ 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("StaticRouter"); - DebugComponentEnable("StaticRouteManager"); + DebugComponentEnable ("Object"); + DebugComponentEnable ("Queue"); + DebugComponentEnable ("DropTailQueue"); + DebugComponentEnable ("Channel"); + DebugComponentEnable ("PointToPointChannel"); + DebugComponentEnable ("PointToPointNetDevice"); + DebugComponentEnable ("StaticRouter"); + DebugComponentEnable ("StaticRouteManager"); #endif - // Set up some default values for the simulation. Use the Bind() + // 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 @@ -105,7 +105,7 @@ int main (int argc, char *argv[]) //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 + // Bind ()s at run-time, via command-line arguments CommandLine::Parse (argc, argv); // Here, we will explicitly create four nodes. In more sophisticated @@ -118,30 +118,30 @@ int main (int argc, char *argv[]) // We create the channels first without any IP addressing information Ptr channel0 = PointToPointTopology::AddPointToPointLink ( - n0, n2, DataRate(5000000), MilliSeconds(2)); + n0, n2, DataRate (5000000), MilliSeconds (2)); Ptr channel1 = PointToPointTopology::AddPointToPointLink ( - n1, n2, DataRate(5000000), MilliSeconds(2)); + n1, n2, DataRate (5000000), MilliSeconds (2)); Ptr channel2 = PointToPointTopology::AddPointToPointLink ( - n2, n3, DataRate(1500000), MilliSeconds(10)); + n2, n3, DataRate (1500000), MilliSeconds (10)); // Later, we add IP addresses. PointToPointTopology::AddIpv4Addresses ( - channel0, n0, Ipv4Address("10.1.1.1"), - n2, Ipv4Address("10.1.1.2")); + 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")); + channel1, n1, Ipv4Address ("10.1.2.1"), + n2, Ipv4Address ("10.1.2.2")); PointToPointTopology::AddIpv4Addresses ( - channel2, n2, Ipv4Address("10.1.3.1"), - n3, Ipv4Address("10.1.3.2")); + channel2, n2, Ipv4Address ("10.1.3.1"), + n3, Ipv4Address ("10.1.3.2")); - if (RoutingEnvironment::StaticRoutingEnabled()) + if (RoutingEnvironment::StaticRoutingEnabled ()) { StaticRouteManager::BuildStaticRoutingDatabase (); StaticRouteManager::InitializeRoutes (); @@ -151,26 +151,26 @@ int main (int argc, char *argv[]) // 210 bytes at a rate of 448 Kb/s Ptr ooff = Create ( n0, - Ipv4Address("10.1.3.2"), + Ipv4Address ("10.1.3.2"), 80, "Udp", - ConstantVariable(1), - ConstantVariable(0)); + ConstantVariable (1), + ConstantVariable (0)); // Start the application - ooff->Start(Seconds(1.0)); - ooff->Stop (Seconds(10.0)); + ooff->Start (Seconds (1.0)); + ooff->Stop (Seconds (10.0)); // Create a similar flow from n3 to n1, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.2.1"), + Ipv4Address ("10.1.2.1"), 80, "Udp", - ConstantVariable(1), - ConstantVariable(0)); + ConstantVariable (1), + ConstantVariable (0)); // Start the application - ooff->Start(Seconds(1.1)); - ooff->Stop (Seconds(10.0)); + ooff->Start (Seconds (1.1)); + ooff->Stop (Seconds (10.0)); // Here, finish off packet routing configuration // This will likely set by some global StaticRouting object in the future From bb8c8e5fa82cfda7abfd62615cf679655e0653aa Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 23 Jul 2007 14:31:24 -0700 Subject: [PATCH 77/92] remove doxygen warnings, make waf work --- src/routing/static-route-manager-impl.h | 15 +++++++-------- src/routing/static-router.h | 17 ++++++++++------- src/routing/wscript | 1 + 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/routing/static-route-manager-impl.h b/src/routing/static-route-manager-impl.h index a4d97db77..ec886fccb 100644 --- a/src/routing/static-route-manager-impl.h +++ b/src/routing/static-route-manager-impl.h @@ -59,10 +59,11 @@ class SPFVertex { public: /** - * @enum Enumeration of the possible types of SPFVertex objects. Currently - * we use VertexRouter to identify objects that represent a router in the - * simulation topology, and VertexNetwork to identify objects that represent - * a network. + * @brief Enumeration of the possible types of SPFVertex objects. + * + * Currently we use VertexRouter to identify objects that represent a router + * in the simulation topology, and VertexNetwork to identify objects that + * represent a network. */ enum VertexType { VertexUnknown = 0, /**< Uninitialized Link Record */ @@ -124,7 +125,7 @@ public: * represents. * * @see VertexType - * @param The new VertexType for the current SPFVertex object. + * @param type The new VertexType for the current SPFVertex object. */ void SetVertexType (VertexType type); /** @@ -178,7 +179,7 @@ public: * @see StaticRouter::DiscoverLSAs () * @warning Ownership of the LSA is transferred to the "this" SPFVertex. You * must not delete the LSA after calling this method. - * @param A pointer to the StaticRouterLSA. + * @param lsa A pointer to the StaticRouterLSA. */ void SetLSA (StaticRouterLSA* lsa); /** @@ -486,8 +487,6 @@ public: * the SPF tree. * * @see SPFVertex::GetNChildren - * @param n The index (from 0 to the number of children minus 1) of the - * child SPFVertex to return. * @warning Ownership of the pointer added to the children of "this" * SPFVertex is transferred to the "this" SPFVertex. You must not delete the * (now) child SPFVertex after calling this method. diff --git a/src/routing/static-router.h b/src/routing/static-router.h index 85ec59fad..9465c1319 100644 --- a/src/routing/static-router.h +++ b/src/routing/static-router.h @@ -40,9 +40,11 @@ class StaticRouterLinkRecord { public: /** - * @enum Enumeration of the possible types of Static Router Link Records. - * These are defined in the OSPF spec. We currently only use PointToPoint and - * StubNetwork types. + * @enum LinkType + * @brief Enumeration of the possible types of Static Router Link Records. + * + * These values are defined in the OSPF spec. We currently only use + * PointToPoint and StubNetwork types. */ enum LinkType { Unknown = 0, /**< Uninitialized Link Record */ @@ -102,7 +104,7 @@ public: * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent * neighbor's IP address * - * @param An Ipv4Address to store in the Link ID field of the record. + * @param addr An Ipv4Address to store in the Link ID field of the record. */ void SetLinkId(Ipv4Address addr); /** @@ -126,7 +128,7 @@ public: * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the * network mask * - * @param An Ipv4Address to store in the Link Data field of the record. + * @param addr An Ipv4Address to store in the Link Data field of the record. */ void SetLinkData(Ipv4Address addr); /** @@ -225,7 +227,8 @@ class StaticRouterLSA { public: /** - * @enum Enumeration of the possible values of the status flag in the Router + * @enum SPFStatus + * @brief Enumeration of the possible values of the status flag in the Router * Link State Advertisements. */ enum SPFStatus { @@ -247,7 +250,7 @@ public: * * @param status The status to of the new LSA. * @param linkStateId The Ipv4Address for the link state ID field. - * @param advertisingRouter The Ipv4Address for the advertising router field. + * @param advertisingRtr The Ipv4Address for the advertising router field. */ StaticRouterLSA(SPFStatus status, Ipv4Address linkStateId, Ipv4Address advertisingRtr); diff --git a/src/routing/wscript b/src/routing/wscript index 79f8c2b21..8cdee7644 100644 --- a/src/routing/wscript +++ b/src/routing/wscript @@ -13,6 +13,7 @@ def build(bld): 'routing-environment.cc', 'static-router.cc', 'static-route-manager.cc', + 'static-route-manager-impl.cc', 'candidate-queue.cc', ] From 2f682ca9f8d424dfb70c9ad1ef77693c74b7b16a Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 23 Jul 2007 15:53:37 -0700 Subject: [PATCH 78/92] single populate call --- examples/simple-static-routing.cc | 3 +-- src/routing/static-route-manager.cc | 7 +++++++ src/routing/static-route-manager.h | 19 ++++++++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 544e68721..02efaa407 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -143,8 +143,7 @@ int main (int argc, char *argv[]) if (RoutingEnvironment::StaticRoutingEnabled ()) { - StaticRouteManager::BuildStaticRoutingDatabase (); - StaticRouteManager::InitializeRoutes (); + StaticRouteManager::PopulateRoutingTables (); } // Create the OnOff application to send UDP datagrams of size diff --git a/src/routing/static-route-manager.cc b/src/routing/static-route-manager.cc index 09ced494f..b3a0cb6ff 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/static-route-manager.cc @@ -28,6 +28,13 @@ namespace ns3 { // // --------------------------------------------------------------------------- + void +StaticRouteManager::PopulateRoutingTables () +{ + BuildStaticRoutingDatabase (); + InitializeRoutes (); +} + void StaticRouteManager::BuildStaticRoutingDatabase () { diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index e8616d573..4f1cdc8ae 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -33,18 +33,31 @@ namespace ns3 { class StaticRouteManager { public: +/** + * @brief Build a routing database and initialize the routing tables of + * the nodes in the simulation. + * + * All this function does is call BuildStaticRoutingDatabase () and + * InitializeRoutes (). There's no reason to export the two-step process + * since a high-level caller has no need to know how we're implementing the + * process. + * + * @see BuildStaticRoutingDatabase (); + * @see InitializeRoutes (); + */ + static void PopulateRoutingTables (); +private: /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a StaticRouter interface. * */ - static void BuildStaticRoutingDatabase(); + static void BuildStaticRoutingDatabase (); /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables */ - static void InitializeRoutes(); -private: + static void InitializeRoutes (); /** * @brief Static Route Manager copy construction is disallowed. There's no * need for it and a compiler provided shallow copy would be hopelessly wrong. From bc634975d4bb48987d78fa504ad5e6a8c9f9524e Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 23 Jul 2007 19:02:55 -0700 Subject: [PATCH 79/92] remove old routing code --- examples/simple-static-routing.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc index 02efaa407..9a7d66dcf 100644 --- a/examples/simple-static-routing.cc +++ b/examples/simple-static-routing.cc @@ -171,14 +171,6 @@ int main (int argc, char *argv[]) ooff->Start (Seconds (1.1)); ooff->Stop (Seconds (10.0)); - // Here, finish off packet routing configuration - // This will likely set by some global StaticRouting object in the future - Ptr ipv4; - ipv4 = n0->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); - ipv4 = n3->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); - // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-static-routing.tr file AsciiTrace asciitrace ("simple-static-routing.tr"); From bdf28a79fc9e376b723ff5bcd04623f363db8a7e Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 23 Jul 2007 19:27:01 -0700 Subject: [PATCH 80/92] revise README --- README.routing | 125 +++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 46 deletions(-) diff --git a/README.routing b/README.routing index 7b5166f5c..2d8e0f88a 100644 --- a/README.routing +++ b/README.routing @@ -1,31 +1,52 @@ -Routing overview, mid-July - -This is a proposal to add global static routing to ns-3 - -The previously announced roadmap: -* July 15: Support IPv4 static routing with PointToPoint numbered links -* August 15: Extend IPv4 static routing to Ethernet (shared links), add static multicast forwarding over Ethernet and PointToPoint -* Sept 15: Add static multicast forwarding over wireless interface - -This would provide the first bullet above. - -Note: This is orthogonal to Gustavo's OLSR code, but could also exist -as a static routing protocol in the framework that he proposes; right now, -this just writes directly into the existing Ipv4 routing API - -1. Code: - -- source code is in a routing module src/routing/ -- an example script is in examples/simple-static-routing.cc -- StaticRouteManager is added in the run-tests unit tests - -2. Approach +Static routing overview +--------------- +This is brief documentation of a proposal to add global static routing to ns-3 Static routing is used to automatically populate the forwarding tables in a topology without running a dynamic routing protocol or asking the user to manually enter routes themselves. -A single object (StaticRouteManager) is responsible for populating +The previously announced roadmap: +* July 15: Support IPv4 static routing with PointToPoint numbered links +* August 15: Extend IPv4 static routing to Ethernet (shared links), +add static multicast forwarding over Ethernet and PointToPoint +* Sept 15: Add static multicast forwarding over wireless interface + +This code would provide the first bullet above. + +Note: This is orthogonal to Gustavo's OLSR code, but could also exist +as a static routing protocol in the framework that he proposes; right now, +this code just writes directly into the existing Ipv4 routing API + +1. Code: + +- source code is in a routing module src/routing/ +- an example script is in examples/simple-static-routing.cc. It produces the +same output as simple-p2p.cc +- StaticRouteManager is added in the run-tests unit tests + +2. API: + +The public API is very minimal. + +- user scripts include the following: +#include "ns3/routing-environment.h" +#include "ns3/static-route-manager.h" + +- A single default value (default false) enables static routing + Bind ("DoStaticRouting", "true"); + +- The call to build the static routes themselves is a single method, +called after the topology has been addressed: + + if (RoutingEnvironment::StaticRoutingEnabled ()) + { + StaticRouteManager::PopulateRoutingTables (); + } + +3. Approach: + +A singleton object (StaticRouteManager) is responsible for populating the static routes on each node, using the public Ipv4 API of that node. It queries each node in the topology for a "staticRouter" interface. If found, it uses the API of that interface to obtain a "link state @@ -38,13 +59,6 @@ the StaticRouteManager executes the OSPF shortest path first (SPF) computation on the database, and populates the routing tables on each node. -This computation is initiated during the pre-simulation phase (after -topology and IP addressing has been done) with the following lines of code, -presently: - Ptr routeManager = Create (); - routeManager->BuildStaticRoutingDatabase (); - routeManager->InitializeRoutes (); - The quagga (http://www.quagga.net) OSPF implementation was used as the basis for the routing computation logic. One benefit of following an existing OSPF SPF implementation is that @@ -60,34 +74,53 @@ straightforward now that the underlying OSPF SPF framework is in place. Presently, we can handle IPv4 point-to-point, numbered links, and we do not do equal-cost multipath. -3. Bootstrapping - -Static routing can be enabled using a DoStaticRouting flag in the -default value system: - Bind ("DoStaticRouting", "true"); -This bind tells the system to use global static routing. It results in -a StaticRouter interface being aggregated to the internet nodes and the -creation of a Route Manager component to oversee the route generation. - -If this flag is true, when an InternetNode is created, it will aggregate -a routing interface to it. +The support for this relies on the node object supporting a StaticRouter +interface. This can be manually added to each node, or alternatively, +we have modified InternetNode::Construct() as follows: if (RoutingEnvironment::StaticRoutingEnabled()) { Ptr staticRouter = Create (this); Object::AddInterface (staticRouter); } -this flag is also tested before creating a StaticRouteManager object. 4. Some open issues +- trying to enable this with the default value framework raised some +questions. Access to an underlying default variable is required +across compilation units. The routing environment was designed +to put everything in one compilation unit. Whether this is good +practice or just overly paranoid is for further discussion. An +alternative may be to define some kind of test with the same default +value system such as +if (IsBound("DoStaticRouting", "true")) ... + +- along the same lines, Bind() is kind of an oddball in the present +system. We do NodeList::Begin (), Simulator::Run (), +CommandLine::Parse (); but simply Bind (). This isn't very consistent. + +(note: the choice of "bind()" was due to ns-2's methods of the same name) + +Perhaps it would be better to do something like, + +Configurator::Set ("DoStaticRouting", "true"); + +if (Configurator::IsEqual ("DoStaticRouting", "true")) + { + } + - how transparent vs. explicit the enabling of static routing should be (e.g., if we have a higher layer Inversion-of-Control framework, do these static routing functions exist in some kind of Init() or Presimulate() -method?) +method?). Presently, it is explicitly enabled. + - whether to add some kind of flag in an InternetNode that is equivalent to /proc/sys/net/ipv4/ip_forward , so that every InternetNode is not necessarily a router. + - whether to continue to write to the existing IPv4 API or load a static -router component into the node like Gustavo's OLSR -- whether to make a single global forwarding table instead of distributing -it among all the routers +router component into the node such as Gustavo's OLSR code does + +- what to name this. Gustavo had suggestions to pick another name for +the StaticRouteManager. One possibility I would be fine with is to call +it GlobalRouteManager (although I would still argue it adds static routes +into the nodes in any case). From b16efc8c0b574ef40605f8828474048002eda5e7 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 23 Jul 2007 20:06:00 -0700 Subject: [PATCH 81/92] a few edits on the doxygen --- README.routing | 9 ++++++++- src/routing/routing-environment.h | 11 ++++++++++- src/routing/static-route-manager-impl.cc | 11 +++++------ src/routing/static-route-manager-impl.h | 23 ++++++++++++----------- src/routing/static-route-manager.h | 8 +++----- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/README.routing b/README.routing index 2d8e0f88a..f787371be 100644 --- a/README.routing +++ b/README.routing @@ -72,7 +72,8 @@ Therefore, we think that enabling these other link types will be more straightforward now that the underlying OSPF SPF framework is in place. Presently, we can handle IPv4 point-to-point, numbered links, and we do -not do equal-cost multipath. +not do equal-cost multipath. We also do not allow for non-unit-cost +links, although it should be trivially extensible to do so. The support for this relies on the node object supporting a StaticRouter interface. This can be manually added to each node, or alternatively, @@ -124,3 +125,9 @@ router component into the node such as Gustavo's OLSR code does the StaticRouteManager. One possibility I would be fine with is to call it GlobalRouteManager (although I would still argue it adds static routes into the nodes in any case). + +- this method probably belongs in the Ipv4 (find InterfaceId corresponding +to the provided address) + uint32_t +StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) + diff --git a/src/routing/routing-environment.h b/src/routing/routing-environment.h index 51ee61f2b..b233c821a 100644 --- a/src/routing/routing-environment.h +++ b/src/routing/routing-environment.h @@ -23,8 +23,17 @@ namespace ns3 { namespace RoutingEnvironment { - + +/** + * @brief This function tests the value of the global default value + * "DoStaticRouting". This approach puts everything in one compilation + * unit, as opposed to explicitly testing the value of the underlying + * static variable. + */ bool StaticRoutingEnabled(void); +/** + * @brief Allocate a 32-bit router ID from monotonically increasing counter. + */ uint32_t AllocateRouterId(void); } // namespace RoutingEnvironment diff --git a/src/routing/static-route-manager-impl.cc b/src/routing/static-route-manager-impl.cc index 52f8d4b32..0b2a61ddb 100644 --- a/src/routing/static-route-manager-impl.cc +++ b/src/routing/static-route-manager-impl.cc @@ -505,7 +505,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) StaticRouterLSA::LSA_SPF_NOT_EXPLORED) { // -// If we havent yet considered the link represented by we have to create +// 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); @@ -710,9 +710,6 @@ StaticRouteManagerImpl::SPFNexthopCalculation ( // Router Link Record we find that describes a point-to-point link from // to . If prev_link is not NULL, we return a Static 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? // StaticRouterLinkRecord* StaticRouteManagerImpl::SPFGetNextLink ( @@ -928,7 +925,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) } // -// BUGBUG FIXME: This should probably be a method on Ipv4 +// XXX This should probably be a method on Ipv4 // // Return the interface index corresponding to a given IP address // @@ -1360,12 +1357,14 @@ StaticRouteManagerImplTest::RunTests (void) srmlsdb->Insert (lsa3->GetLinkStateId (), lsa3); NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ())); - // XXX next, calculate routes based on the manually created LSDB + // next, calculate routes based on the manually created LSDB StaticRouteManagerImpl* srm = new StaticRouteManagerImpl (); srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB // Note-- this will succeed without any nodes in the topology // because the NodeList is empty srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 + + // XXX here we should do some verification of the routes built // This delete clears the srm, which deletes the LSDB, which clears // all of the LSAs, which each destroys the attached LinkRecords. diff --git a/src/routing/static-route-manager-impl.h b/src/routing/static-route-manager-impl.h index ec886fccb..776904818 100644 --- a/src/routing/static-route-manager-impl.h +++ b/src/routing/static-route-manager-impl.h @@ -136,7 +136,7 @@ public: * representing routers, and comes from the Link State Advertisement of a * router aggregated to a node in the simulation. These IDs are allocated * automatically by the routing environment and look like IP addresses - * beginning at 0.0.0.0 and monotonically increasing as new routers are + * beginning at 0.0.0.0 and monotonically increase as new routers are * instantiated. * * @returns The Ipv4Address Vertex ID of the current SPFVertex object. @@ -150,8 +150,9 @@ public: * representing routers, and comes from the Link State Advertisement of a * router aggregated to a node in the simulation. These IDs are allocated * automatically by the routing environment and look like IP addresses - * beginning at 0.0.0.0 and monotonically increasing as new routers are - * instantiated. + * beginning at 0.0.0.0 and monotonically increase as new routers are + * instantiated. This method is an explicit override of the automatically + * generated value. * * @param id The new Ipv4Address Vertex ID for the current SPFVertex object. */ @@ -520,7 +521,7 @@ private: }; /** - * @brief The Link State DataBase (LSDB) of the Static Route Manager. + * @brief The Link State DataBase (LSDB) of the StaticRouteManager. * * Each node in the simulation participating in static routing has a * StaticRouter interface. The primary job of this interface is to export @@ -536,14 +537,14 @@ class StaticRouteManagerLSDB { public: /** - * @brief Construct an empty Static Router Manager Link State Database. + * @brief Construct an empty StaticRoutingManager Link State Database. * * The database map composing the Link State Database is initialized in * this constructor. */ StaticRouteManagerLSDB (); /** - * @brief Destroy an empty Static Router Manager Link State Database. + * @brief Destroy an empty StaticRoutingManager Link State Database. * * The database map is walked and all of the Link State Advertisements stored * in the database are freed; then the database map itself is clear ()ed to @@ -599,7 +600,7 @@ private: LSDBMap_t m_database; /** * @brief StaticRouteManagerLSDB copy construction is disallowed. There's no - * need for it and a compiler provided shallow copy would be hopelessly wrong. + * need for it and a compiler provided shallow copy would be wrong. */ StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); /** @@ -646,15 +647,15 @@ public: void DebugSPFCalculate (Ipv4Address root); private: /** - * @brief Static Route Manager Implementation copy construction is disallowed. + * @brief StaticRouteManager Implementation copy construction is disallowed. * There's no need for it and a compiler provided shallow copy would be - * hopelessly wrong. + * wrong. */ StaticRouteManagerImpl (StaticRouteManagerImpl& srmi); /** - * @brief Static Route Manager Implementation assignment operator is + * @brief StaticRouteManager Implementation assignment operator is * disallowed. There's no need for it and a compiler provided shallow copy - * would be hopelessly wrong. + * would be wrong. */ StaticRouteManagerImpl& operator= (StaticRouteManagerImpl& srmi); diff --git a/src/routing/static-route-manager.h b/src/routing/static-route-manager.h index 4f1cdc8ae..11c6ec718 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/static-route-manager.h @@ -38,9 +38,7 @@ public: * the nodes in the simulation. * * All this function does is call BuildStaticRoutingDatabase () and - * InitializeRoutes (). There's no reason to export the two-step process - * since a high-level caller has no need to know how we're implementing the - * process. + * InitializeRoutes (). * * @see BuildStaticRoutingDatabase (); * @see InitializeRoutes (); @@ -60,13 +58,13 @@ private: static void InitializeRoutes (); /** * @brief Static Route Manager copy construction is disallowed. There's no - * need for it and a compiler provided shallow copy would be hopelessly wrong. + * need for it and a compiler provided shallow copy would be wrong. * */ StaticRouteManager (StaticRouteManager& srm); /** * @brief Static Router copy assignment operator is disallowed. There's no - * need for it and a compiler provided shallow copy would be hopelessly wrong. + * need for it and a compiler provided shallow copy would be wrong. */ StaticRouteManager& operator= (StaticRouteManager& srm); }; From d38da7ae3d0a6085650ef206eb1df11967cf6abe Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jul 2007 14:04:54 -0700 Subject: [PATCH 82/92] rename party --- examples/wscript | 7 +- src/internet-node/internet-node.cc | 8 +- src/routing/{ => global}/candidate-queue.cc | 0 src/routing/{ => global}/candidate-queue.h | 2 +- .../global-route-manager-impl.cc} | 312 +++++++++--------- .../global-route-manager-impl.h} | 174 +++++----- .../global-route-manager.cc} | 20 +- .../global-route-manager.h} | 32 +- .../global-router-interface.cc} | 206 ++++++------ .../global-router-interface.h} | 194 +++++------ .../{ => global}/routing-environment.cc | 8 +- .../{ => global}/routing-environment.h | 5 +- src/routing/wscript | 26 -- src/wscript | 2 +- 14 files changed, 490 insertions(+), 506 deletions(-) rename src/routing/{ => global}/candidate-queue.cc (100%) rename src/routing/{ => global}/candidate-queue.h (99%) rename src/routing/{static-route-manager-impl.cc => global/global-route-manager-impl.cc} (81%) rename src/routing/{static-route-manager-impl.h => global/global-route-manager-impl.h} (85%) rename src/routing/{static-route-manager.cc => global/global-route-manager.cc} (71%) rename src/routing/{static-route-manager.h => global/global-route-manager.h} (73%) rename src/routing/{static-router.cc => global/global-router-interface.cc} (68%) rename src/routing/{static-router.h => global/global-router-interface.h} (72%) rename src/routing/{ => global}/routing-environment.cc (85%) rename src/routing/{ => global}/routing-environment.h (97%) delete mode 100644 src/routing/wscript diff --git a/examples/wscript b/examples/wscript index 6e8fea84d..f16c98c84 100644 --- a/examples/wscript +++ b/examples/wscript @@ -9,6 +9,9 @@ def build(bld): obj.source = source return obj - obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node']) - obj = create_ns_prog('simple-static-routing', 'simple-static-routing.cc', deps=['p2p', 'internet-node', 'routing']) + obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', + deps=['p2p', 'internet-node']) + + obj = create_ns_prog('simple-global-routing', 'simple-global-routing.cc', + deps=['p2p', 'internet-node', 'routing']) diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index 611b6c9a5..c6eb92f43 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -24,7 +24,7 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/net-device.h" #include "ns3/routing-environment.h" -#include "ns3/static-router.h" +#include "ns3/global-router-interface.h" #include "l3-demux.h" #include "ipv4-l4-demux.h" @@ -83,10 +83,10 @@ InternetNode::Construct (void) // of the StaticRouter interface tells the route manager that it needs to // ask a given node about any link state records that it may want to advertise. // - if (RoutingEnvironment::StaticRoutingEnabled()) + if (RoutingEnvironment::GlobalRoutingEnabled()) { - Ptr staticRouter = Create (this); - Object::AddInterface (staticRouter); + Ptr globalRouter = Create (this); + Object::AddInterface (globalRouter); } } diff --git a/src/routing/candidate-queue.cc b/src/routing/global/candidate-queue.cc similarity index 100% rename from src/routing/candidate-queue.cc rename to src/routing/global/candidate-queue.cc diff --git a/src/routing/candidate-queue.h b/src/routing/global/candidate-queue.h similarity index 99% rename from src/routing/candidate-queue.h rename to src/routing/global/candidate-queue.h index 27fcd01b4..1c01cb2ec 100644 --- a/src/routing/candidate-queue.h +++ b/src/routing/global/candidate-queue.h @@ -19,7 +19,7 @@ #include #include -#include "static-route-manager-impl.h" +#include "global-route-manager-impl.h" namespace ns3 { diff --git a/src/routing/static-route-manager-impl.cc b/src/routing/global/global-route-manager-impl.cc similarity index 81% rename from src/routing/static-route-manager-impl.cc rename to src/routing/global/global-route-manager-impl.cc index 0b2a61ddb..df6ad3ad5 100644 --- a/src/routing/static-route-manager-impl.cc +++ b/src/routing/global/global-route-manager-impl.cc @@ -22,11 +22,11 @@ #include "ns3/debug.h" #include "ns3/node-list.h" #include "ns3/ipv4.h" -#include "static-router.h" -#include "static-route-manager-impl.h" +#include "global-router-interface.h" +#include "global-route-manager-impl.h" #include "candidate-queue.h" -NS_DEBUG_COMPONENT_DEFINE ("StaticRouteManager"); +NS_DEBUG_COMPONENT_DEFINE ("GlobalRouteManager"); namespace ns3 { @@ -48,7 +48,7 @@ SPFVertex::SPFVertex () : { } -SPFVertex::SPFVertex (StaticRouterLSA* lsa) : +SPFVertex::SPFVertex (GlobalRouterLSA* lsa) : m_vertexType (VertexRouter), m_vertexId (lsa->GetLinkStateId ()), m_lsa (lsa), @@ -99,12 +99,12 @@ SPFVertex::GetVertexId (void) const } void -SPFVertex::SetLSA (StaticRouterLSA* lsa) +SPFVertex::SetLSA (GlobalRouterLSA* lsa) { m_lsa = lsa; } - StaticRouterLSA* + GlobalRouterLSA* SPFVertex::GetLSA (void) const { return m_lsa; @@ -191,56 +191,56 @@ SPFVertex::AddChild (SPFVertex* child) // --------------------------------------------------------------------------- // -// StaticRouteManagerLSDB Implementation +// GlobalRouteManagerLSDB Implementation // // --------------------------------------------------------------------------- -StaticRouteManagerLSDB::StaticRouteManagerLSDB () +GlobalRouteManagerLSDB::GlobalRouteManagerLSDB () : m_database () { - NS_DEBUG ("StaticRouteManagerLSDB::StaticRouteManagerLSDB ()"); + NS_DEBUG ("GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()"); } -StaticRouteManagerLSDB::~StaticRouteManagerLSDB () +GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB () { - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ()"); + NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()"); LSDBMap_t::iterator i; for (i= m_database.begin (); i!= m_database.end (); i++) { - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB ():free LSA"); - StaticRouterLSA* temp = i->second; + NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA"); + GlobalRouterLSA* temp = i->second; delete temp; } - NS_DEBUG ("StaticRouteManagerLSDB::~StaticRouteManagerLSDB (): clear map"); + NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB (): clear map"); m_database.clear (); } void -StaticRouteManagerLSDB::Initialize () +GlobalRouteManagerLSDB::Initialize () { - NS_DEBUG ("StaticRouteManagerLSDB::Initialize ()"); + NS_DEBUG ("GlobalRouteManagerLSDB::Initialize ()"); LSDBMap_t::iterator i; for (i= m_database.begin (); i!= m_database.end (); i++) { - StaticRouterLSA* temp = i->second; - temp->SetStatus (StaticRouterLSA::LSA_SPF_NOT_EXPLORED); + GlobalRouterLSA* temp = i->second; + temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED); } } void -StaticRouteManagerLSDB::Insert (Ipv4Address addr, StaticRouterLSA* lsa) +GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa) { - NS_DEBUG ("StaticRouteManagerLSDB::Insert ()"); + NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()"); m_database.insert (LSDBPair_t (addr, lsa)); } - StaticRouterLSA* -StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) const + GlobalRouterLSA* +GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const { - NS_DEBUG ("StaticRouteManagerLSDB::GetLSA ()"); + NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()"); // // Look up an LSA by its address. // @@ -257,21 +257,21 @@ StaticRouteManagerLSDB::GetLSA (Ipv4Address addr) const // --------------------------------------------------------------------------- // -// StaticRouteManagerImpl Implementation +// GlobalRouteManagerImpl Implementation // // --------------------------------------------------------------------------- -StaticRouteManagerImpl::StaticRouteManagerImpl () +GlobalRouteManagerImpl::GlobalRouteManagerImpl () : m_spfroot (0) { - NS_DEBUG ("StaticRouteManagerImpl::StaticRoutemanagerImpl ()"); - m_lsdb = new StaticRouteManagerLSDB (); + NS_DEBUG ("GlobalRouteManagerImpl::GlobalRoutemanagerImpl ()"); + m_lsdb = new GlobalRouteManagerLSDB (); } -StaticRouteManagerImpl::~StaticRouteManagerImpl () +GlobalRouteManagerImpl::~GlobalRouteManagerImpl () { - NS_DEBUG ("StaticRouteManagerImpl::~StaticRouteManagerImpl ()"); + NS_DEBUG ("GlobalRouteManagerImpl::~GlobalRouteManagerImpl ()"); if (m_lsdb) { @@ -280,9 +280,9 @@ StaticRouteManagerImpl::~StaticRouteManagerImpl () } void -StaticRouteManagerImpl::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) +GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb) { - NS_DEBUG ("StaticRouteManagerImpl::DebugUseLsdb ()"); + NS_DEBUG ("GlobalRouteManagerImpl::DebugUseLsdb ()"); if (m_lsdb) { @@ -293,7 +293,7 @@ StaticRouteManagerImpl::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) // // In order to build the routing database, we need to walk the list of nodes -// in the system and look for those that support the StaticRouter interface. +// in the system and look for those that support the GlobalRouter interface. // These routers will export a number of Link State Advertisements (LSAs) // that describe the links and networks that are "adjacent" (i.e., that are // on the other side of a point-to-point link). We take these LSAs and put @@ -301,19 +301,19 @@ StaticRouteManagerImpl::DebugUseLsdb (StaticRouteManagerLSDB* lsdb) // ultimately be computed. // void -StaticRouteManagerImpl::BuildStaticRoutingDatabase () +GlobalRouteManagerImpl::BuildGlobalRoutingDatabase () { - NS_DEBUG ("StaticRouteManagerImpl::BuildStaticRoutingDatabase()"); + NS_DEBUG ("GlobalRouteManagerImpl::BuildGlobalRoutingDatabase()"); // -// Walk the list of nodes looking for the StaticRouter Interface. +// Walk the list of nodes looking for the GlobalRouter Interface. // typedef std::vector < Ptr >::iterator Iterator; for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) { Ptr node = *i; - Ptr rtr = - node->QueryInterface (StaticRouter::iid); + Ptr rtr = + node->QueryInterface (GlobalRouter::iid); // // Ignore nodes that aren't participating in routing. // @@ -324,7 +324,7 @@ StaticRouteManagerImpl::BuildStaticRoutingDatabase () // // You must call DiscoverLSAs () before trying to use any routing info or to // update LSAs. DiscoverLSAs () drives the process of discovering routes in -// the StaticRouter. Afterward, you may use GetNumLSAs (), which is a very +// the GlobalRouter. Afterward, you may use GetNumLSAs (), which is a very // computationally inexpensive call. If you call GetNumLSAs () before calling // DiscoverLSAs () will get zero as the number since no routes have been // found. @@ -334,7 +334,7 @@ StaticRouteManagerImpl::BuildStaticRoutingDatabase () for (uint32_t j = 0; j < numLSAs; ++j) { - StaticRouterLSA* lsa = new StaticRouterLSA (); + GlobalRouterLSA* lsa = new GlobalRouterLSA (); // // This is the call to actually fetch a Link State Advertisement from the // router. @@ -351,8 +351,8 @@ StaticRouteManagerImpl::BuildStaticRoutingDatabase () } // -// For each node that is a static router (which is determined by the presence -// of an aggregated StaticRouter interface), run the Dijkstra SPF calculation +// For each node that is a global router (which is determined by the presence +// of an aggregated GlobalRouter interface), run the Dijkstra SPF calculation // on the database rooted at that router, and populate the node forwarding // tables. // @@ -384,9 +384,9 @@ StaticRouteManagerImpl::BuildStaticRoutingDatabase () // list becomes empty. // void -StaticRouteManagerImpl::InitializeRoutes () +GlobalRouteManagerImpl::InitializeRoutes () { - NS_DEBUG ("StaticRouteManagerImpl::InitializeRoutes ()"); + NS_DEBUG ("GlobalRouteManagerImpl::InitializeRoutes ()"); // // Walk the list of nodes in the system. // @@ -395,13 +395,13 @@ StaticRouteManagerImpl::InitializeRoutes () { Ptr node = *i; // -// Look for the StaticRouter interface that indicates that the node is +// Look for the GlobalRouter interface that indicates that the node is // participating in routing. // - Ptr rtr = - node->QueryInterface (StaticRouter::iid); + Ptr rtr = + node->QueryInterface (GlobalRouter::iid); // -// if the node has a static router interface, then run the static routing +// if the node has a global router interface, then run the global routing // algorithms. // if (rtr && rtr->GetNumLSAs () ) @@ -425,13 +425,13 @@ StaticRouteManagerImpl::InitializeRoutes () // vertex already on the candidate list, store the new (lower) cost. // void -StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) +GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) { SPFVertex* w = 0; - StaticRouterLSA* w_lsa = 0; + GlobalRouterLSA* w_lsa = 0; uint32_t distance = 0; - NS_DEBUG ("StaticRouteManagerImpl::SPFNext ()"); + NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()"); // // Always true for now, since all our LSAs are RouterLSAs. // @@ -452,8 +452,8 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // Links to stub networks will be considered in the second stage of the // shortest path calculation. // - StaticRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); - if (l->GetLinkType () == StaticRouterLinkRecord::StubNetwork) + GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); + if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork) { NS_DEBUG ("SPFNext: Found a Stub record to " << l->GetLinkId ()); @@ -464,7 +464,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // the vertex W's LSA (router-LSA or network-LSA) in Area A's link state // database. // - if (l->GetLinkType () == StaticRouterLinkRecord::PointToPoint) + if (l->GetLinkType () == GlobalRouterLinkRecord::PointToPoint) { // // Lookup the link state advertisement of the new link -- we call it in @@ -482,7 +482,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // then we have it covered -- ignore it. // if (w_lsa->GetStatus () == - StaticRouterLSA::LSA_SPF_IN_SPFTREE) + GlobalRouterLSA::LSA_SPF_IN_SPFTREE) { NS_DEBUG ("SPFNext: Skipping-> LSA "<< w_lsa->GetLinkStateId () << " already in SPF tree"); @@ -502,7 +502,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) w_lsa->GetLinkStateId ()); if (w_lsa->GetStatus () == - StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + GlobalRouterLSA::LSA_SPF_NOT_EXPLORED) { // // If we haven't yet considered the link represented by we have to create @@ -518,7 +518,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) if (SPFNexthopCalculation (v, w, l, distance)) { w_lsa->SetStatus ( - StaticRouterLSA::LSA_SPF_CANDIDATE); + GlobalRouterLSA::LSA_SPF_CANDIDATE); // // Push this new vertex onto the priority queue (ordered by distance from the // root node). @@ -530,7 +530,7 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) } } } else if (w_lsa->GetStatus () == - StaticRouterLSA::LSA_SPF_CANDIDATE) + GlobalRouterLSA::LSA_SPF_CANDIDATE) { // // We have already considered the link represented by . What wse have to @@ -589,13 +589,13 @@ StaticRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // For now, this is greatly simplified from the quagga code // int -StaticRouteManagerImpl::SPFNexthopCalculation ( +GlobalRouteManagerImpl::SPFNexthopCalculation ( SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* l, + GlobalRouterLinkRecord* l, uint32_t distance) { - NS_DEBUG ("StaticRouteManagerImpl::SPFNexthopCalculation ()"); + NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()"); // // 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 @@ -633,7 +633,7 @@ StaticRouteManagerImpl::SPFNexthopCalculation ( { // // In the case of point-to-point links, the link data field (m_linkData) of a -// Static Router Link Record contains the local IP address. If we look at the +// Global Router Link Record contains the local IP address. If we look at the // link record describing the link from the perspecive of (the remote // node from the viewpoint of ) back to the root node, we can discover the // IP address of the router to which is adjacent. This is a distinguished @@ -644,12 +644,12 @@ StaticRouteManagerImpl::SPFNexthopCalculation ( // return the link record describing the link from to . Think of it as // SPFGetLink. // - StaticRouterLinkRecord *linkRemote = 0; + GlobalRouterLinkRecord *linkRemote = 0; linkRemote = SPFGetNextLink (w, v, linkRemote); // -// At this point, is the Static Router Link Record describing the point- +// At this point, is the Global Router Link Record describing the point- // to point link from to from the perspective of ; and -// is the Static Router Link Record describing that same link from the +// is the Global Router Link Record describing that same link from the // perspective of (back to ). Now we can just copy the next hop // address from the m_linkData member variable. // @@ -702,25 +702,28 @@ StaticRouteManagerImpl::SPFNexthopCalculation ( // // This method is derived from quagga ospf_get_next_link () // -// First search the Static Router Link Records of vertex for one +// First search the Global Router Link Records of vertex for one // representing a point-to point link to vertex . // // What is done depends on prev_link. Contrary to appearances, prev_link just -// acts as a flag here. If prev_link is NULL, we return the first Static +// acts as a flag here. If prev_link is NULL, we return the first Global // Router Link Record we find that describes a point-to-point link from -// to . If prev_link is not NULL, we return a Static Router Link Record +// to . If prev_link is not NULL, we return a Global Router Link Record // representing a possible *second* link from to . // - StaticRouterLinkRecord* -StaticRouteManagerImpl::SPFGetNextLink ( +// 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* +GlobalRouteManagerImpl::SPFGetNextLink ( SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* prev_link) + GlobalRouterLinkRecord* prev_link) { - NS_DEBUG ("StaticRouteManagerImpl::SPFGetNextLink ()"); + NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()"); bool skip = true; - StaticRouterLinkRecord* l; + GlobalRouterLinkRecord* l; // // If prev_link is 0, we are really looking for the first link, not the next // link. @@ -730,14 +733,14 @@ StaticRouteManagerImpl::SPFGetNextLink ( skip = false; } // -// Iterate through the Static Router Link Records advertised by the vertex +// Iterate through the Global Router Link Records advertised by the vertex // looking for records representing the point-to-point links off of this // vertex. // for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i) { l = v->GetLSA ()->GetLinkRecord (i); - if (l->GetLinkType () != StaticRouterLinkRecord::PointToPoint) + if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint) { continue; } @@ -768,7 +771,7 @@ StaticRouteManagerImpl::SPFGetNextLink ( { // // Skip is true and we've found a link from to . We want the next one. -// Setting skip to false gets us the next point-to-point static router link +// Setting skip to false gets us the next point-to-point global router link // record in the LSA from . // NS_DEBUG ("SPFGetNextLink: Skipping the found link"); @@ -784,17 +787,17 @@ StaticRouteManagerImpl::SPFGetNextLink ( // Used for unit tests. // void -StaticRouteManagerImpl::DebugSPFCalculate (Ipv4Address root) +GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root) { - NS_DEBUG ("StaticRouteManagerImpl::DebugSPFCalculate ()"); + NS_DEBUG ("GlobalRouteManagerImpl::DebugSPFCalculate ()"); SPFCalculate (root); } // quagga ospf_spf_calculate void -StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) +GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) { - NS_DEBUG ("StaticRouteManagerImpl::SPFCalculate (): " + NS_DEBUG ("GlobalRouteManagerImpl::SPFCalculate (): " "root = " << root); SPFVertex *v; @@ -821,7 +824,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // m_spfroot= v; v->SetDistanceFromRoot (0); - v->GetLSA ()->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); + v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE); for (;;) { @@ -831,7 +834,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // // RFC2328 16.1. (2). // -// We examine the Static Router Link Records in the Link State +// We examine the Global Router Link Records in the Link State // Advertisements of the current vertex. If there are any point-to-point // links to unexplored adjacent vertices we add them to the tree and update // the distance and next hop information on how to get there. We also add @@ -857,7 +860,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // list in the process). // // Recall that in the previous step, we created SPFVertex structures for each -// of the routers found in the Static Router Link Records and added tehm to +// of the routers found in the Global Router Link Records and added tehm to // the candidate list. // v = candidate.Pop (); @@ -866,7 +869,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // Update the status field of the vertex to indicate that it is in the SPF // tree. // - v->GetLSA ()->SetStatus (StaticRouterLSA::LSA_SPF_IN_SPFTREE); + v->GetLSA ()->SetStatus (GlobalRouterLSA::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 @@ -893,7 +896,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // We're going to pop of a pointer to every vertex in the tree except the // root in order of distance from the root. For each of the vertices, we call // SPFIntraAddRouter (). Down in SPFIntraAddRouter, we look at all of the -// point-to-point Static Router Link Records (the links to nodes adjacent to +// point-to-point Global Router Link Records (the links to nodes adjacent to // the node represented by the vertex). We add a route to the IP address // specified by the m_linkData field of each of those link records. This will // be the *local* IP address associated with the interface attached to the @@ -930,7 +933,7 @@ StaticRouteManagerImpl::SPFCalculate (Ipv4Address root) // Return the interface index corresponding to a given IP address // uint32_t -StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) +GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) { // // We have an IP address and a vertex ID of the root of the SPF tree. @@ -951,10 +954,10 @@ StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) { Ptr node = *i; - Ptr rtr = - node->QueryInterface (StaticRouter::iid); + Ptr rtr = + node->QueryInterface (GlobalRouter::iid); // -// If the node doesn't have a StaticRouter interface it can't be the one +// If the node doesn't have a GlobalRouter interface it can't be the one // we're interested in. // if (rtr == 0) @@ -972,7 +975,7 @@ StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) // Ptr ipv4 = node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG (ipv4, - "StaticRouteManagerImpl::FindOutgoingInterfaceId (): " + "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " "QI for interface failed"); // // Look through the interfaces on this node for one that has the IP address @@ -984,7 +987,7 @@ StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) if (ipv4->GetAddress (i) == a) { NS_DEBUG ( - "StaticRouteManagerImpl::FindOutgoingInterfaceId (): " + "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " "Interface match for " << a); return i; } @@ -1014,12 +1017,12 @@ StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) // route. // void -StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) +GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) { - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter ()"); + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter ()"); NS_ASSERT_MSG (m_spfroot, - "StaticRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set"); + "GlobalRouteManagerImpl::SPFIntraAddRouter (): 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 @@ -1029,7 +1032,7 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // Ipv4Address routerId = m_spfroot->GetVertexId (); - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter (): " "Vertex ID = " << routerId); // // We need to walk the list of nodes looking for the one that has the router @@ -1041,17 +1044,17 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) { Ptr node = *i; // -// The router ID is accessible through the StaticRouter interface, so we need -// to QI for that interface. If there's no StaticRouter interface, the node +// 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 (StaticRouter::iid); + Ptr rtr = + node->QueryInterface (GlobalRouter::iid); if (rtr == 0) { - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " - "No StaticRouter interface on node " << node->GetId ()); + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "No GlobalRouter interface on node " << node->GetId ()); continue; } // @@ -1059,12 +1062,12 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // root of the SPF tree, then this node is the one for which we need to // write the routing tables. // - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter (): " "Considering router " << rtr->GetRouterId ()); if (rtr->GetRouterId () == routerId) { - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter (): " "setting routes for node " << node->GetId ()); // // Routing information is updated using the Ipv4 interface. We need to QI @@ -1073,17 +1076,17 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // Ptr ipv4 = node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG (ipv4, - "StaticRouteManagerImpl::SPFIntraAddRouter (): " + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " "QI for interface failed"); // -// Get the Static Router Link State Advertisement from the vertex we're -// adding the routes to. The LSA will have a number of attached Static Router +// 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. // - StaticRouterLSA *lsa = v->GetLSA (); + GlobalRouterLSA *lsa = v->GetLSA (); NS_ASSERT_MSG (lsa, - "StaticRouteManagerImpl::SPFIntraAddRouter (): " + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " "Expected valid LSA in SPFVertex* v"); uint32_t nLinkRecords = lsa->GetNLinkRecords (); @@ -1100,13 +1103,13 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // // We are only concerned about point-to-point links // - StaticRouterLinkRecord *lr = lsa->GetLinkRecord (j); - if (lr->GetLinkType () != StaticRouterLinkRecord::PointToPoint) + GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j); + if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint) { continue; } - NS_DEBUG ("StaticRouteManagerImpl::SPFIntraAddRouter (): " + NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddRouter (): " " Node " << node->GetId () << " add route to " << lr->GetLinkData () << " using next hop " << v->GetNextHop () << @@ -1147,7 +1150,7 @@ StaticRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // For now, only one parent (not doing equal-cost multipath) // void -StaticRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) +GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) { v->GetParent ()->AddChild (v); } @@ -1166,44 +1169,44 @@ StaticRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) namespace ns3 { -class StaticRouterTestNode : public Node +class GlobalRouterTestNode : public Node { public: - StaticRouterTestNode (); + GlobalRouterTestNode (); private: virtual void DoAddDevice (Ptr device) const {}; virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); }; -StaticRouterTestNode::StaticRouterTestNode () +GlobalRouterTestNode::GlobalRouterTestNode () { // Ptr ipv4 = Create (this); } TraceResolver* -StaticRouterTestNode::DoCreateTraceResolver (TraceContext const &context) +GlobalRouterTestNode::DoCreateTraceResolver (TraceContext const &context) { return 0; } -class StaticRouteManagerImplTest : public Test { +class GlobalRouteManagerImplTest : public Test { public: - StaticRouteManagerImplTest (); - virtual ~StaticRouteManagerImplTest (); + GlobalRouteManagerImplTest (); + virtual ~GlobalRouteManagerImplTest (); virtual bool RunTests (void); }; -StaticRouteManagerImplTest::StaticRouteManagerImplTest () - : Test ("StaticRouteManagerImpl") +GlobalRouteManagerImplTest::GlobalRouteManagerImplTest () + : Test ("GlobalRouteManagerImpl") { } -StaticRouteManagerImplTest::~StaticRouteManagerImplTest () +GlobalRouteManagerImplTest::~GlobalRouteManagerImplTest () {} bool -StaticRouteManagerImplTest::RunTests (void) +GlobalRouteManagerImplTest::RunTests (void) { bool ok = true; @@ -1246,81 +1249,81 @@ StaticRouteManagerImplTest::RunTests (void) // link2: 10.1.3.1/30, 10.1.3.2/30 // // Router 0 - StaticRouterLinkRecord* lr0 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.2", // router ID 0.0.0.2 "10.1.1.1", // local ID 1); // metric - StaticRouterLinkRecord* lr1 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.1.1", "255.255.255.252", 1); - StaticRouterLSA* lsa0 = new StaticRouterLSA (); + GlobalRouterLSA* lsa0 = new GlobalRouterLSA (); lsa0->SetLinkStateId ("0.0.0.0"); lsa0->SetAdvertisingRouter ("0.0.0.0"); lsa0->AddLinkRecord (lr0); lsa0->AddLinkRecord (lr1); // Router 1 - StaticRouterLinkRecord* lr2 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.2", "10.1.2.1", 1); - StaticRouterLinkRecord* lr3 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.2.1", "255.255.255.252", 1); - StaticRouterLSA* lsa1 = new StaticRouterLSA (); + GlobalRouterLSA* lsa1 = new GlobalRouterLSA (); lsa1->SetLinkStateId ("0.0.0.1"); lsa1->SetAdvertisingRouter ("0.0.0.1"); lsa1->AddLinkRecord (lr2); lsa1->AddLinkRecord (lr3); // Router 2 - StaticRouterLinkRecord* lr4 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.0", "10.1.1.2", 1); - StaticRouterLinkRecord* lr5 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.1.2", "255.255.255.252", 1); - StaticRouterLinkRecord* lr6 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.1", "10.1.2.2", 1); - StaticRouterLinkRecord* lr7 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.2.2", "255.255.255.252", 1); - StaticRouterLinkRecord* lr8 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.3", "10.1.3.2", 1); - StaticRouterLinkRecord* lr9 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.3.2", "255.255.255.252", 1); - StaticRouterLSA* lsa2 = new StaticRouterLSA (); + GlobalRouterLSA* lsa2 = new GlobalRouterLSA (); lsa2->SetLinkStateId ("0.0.0.2"); lsa2->SetAdvertisingRouter ("0.0.0.2"); lsa2->AddLinkRecord (lr4); @@ -1331,26 +1334,26 @@ StaticRouteManagerImplTest::RunTests (void) lsa2->AddLinkRecord (lr9); // Router 3 - StaticRouterLinkRecord* lr10 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::PointToPoint, + GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::PointToPoint, "0.0.0.2", "10.1.2.1", 1); - StaticRouterLinkRecord* lr11 = new StaticRouterLinkRecord ( - StaticRouterLinkRecord::StubNetwork, + GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord ( + GlobalRouterLinkRecord::StubNetwork, "10.1.2.1", "255.255.255.252", 1); - StaticRouterLSA* lsa3 = new StaticRouterLSA (); + GlobalRouterLSA* lsa3 = new GlobalRouterLSA (); lsa3->SetLinkStateId ("0.0.0.3"); lsa3->SetAdvertisingRouter ("0.0.0.3"); lsa3->AddLinkRecord (lr10); lsa3->AddLinkRecord (lr11); // Test the database - StaticRouteManagerLSDB* srmlsdb = new StaticRouteManagerLSDB (); + GlobalRouteManagerLSDB* srmlsdb = new GlobalRouteManagerLSDB (); srmlsdb->Insert (lsa0->GetLinkStateId (), lsa0); srmlsdb->Insert (lsa1->GetLinkStateId (), lsa1); srmlsdb->Insert (lsa2->GetLinkStateId (), lsa2); @@ -1358,13 +1361,11 @@ StaticRouteManagerImplTest::RunTests (void) NS_ASSERT (lsa2 == srmlsdb->GetLSA (lsa2->GetLinkStateId ())); // next, calculate routes based on the manually created LSDB - StaticRouteManagerImpl* srm = new StaticRouteManagerImpl (); + GlobalRouteManagerImpl* srm = new GlobalRouteManagerImpl (); srm->DebugUseLsdb (srmlsdb); // manually add in an LSDB // Note-- this will succeed without any nodes in the topology // because the NodeList is empty srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0 - - // XXX here we should do some verification of the routes built // This delete clears the srm, which deletes the LSDB, which clears // all of the LSAs, which each destroys the attached LinkRecords. @@ -1374,7 +1375,8 @@ StaticRouteManagerImplTest::RunTests (void) } // Instantiate this class for the unit tests -static StaticRouteManagerImplTest g_staticRouteManagerTest; +// XXX here we should do some verification of the routes built +static GlobalRouteManagerImplTest g_globalRouteManagerTest; } // namespace ns3 diff --git a/src/routing/static-route-manager-impl.h b/src/routing/global/global-route-manager-impl.h similarity index 85% rename from src/routing/static-route-manager-impl.h rename to src/routing/global/global-route-manager-impl.h index 776904818..a355cdfb0 100644 --- a/src/routing/static-route-manager-impl.h +++ b/src/routing/global/global-route-manager-impl.h @@ -13,8 +13,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef STATIC_ROUTE_MANAGER_IMPL_H -#define STATIC_ROUTE_MANAGER_IMPL_H +#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H +#define GLOBAL_ROUTE_MANAGER_IMPL_H #include #include @@ -23,7 +23,7 @@ #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/ipv4-address.h" -#include "static-router.h" +#include "global-router-interface.h" namespace ns3 { @@ -46,9 +46,9 @@ class CandidateQueue; * or networks in the simulation are arranged in the SPF tree. It is this * tree that represents the Shortest Paths to the other networks. * - * Each SPFVertex has a pointer to the Static Router Link State Advertisement + * Each SPFVertex has a pointer to the Global Router Link State Advertisement * (LSA) that its underlying router has exported. Within these LSAs are - * Static Router Link Records that describe the point to point links from the + * Global Router Link Records that describe the point to point links from the * underlying router to other nodes (represented by other SPFVertex objects) * in the simulation topology. The combination of the arrangement of the * SPFVertex objects in the SPF tree, along with the details of the link @@ -96,10 +96,10 @@ public: * * @see SPFVertex::SPFVertex () * @see VertexType - * @see StaticRouterLSA + * @see GlobalRouterLSA * @param lsa The Link State Advertisement used for finding initial values. */ - SPFVertex(StaticRouterLSA* lsa); + SPFVertex(GlobalRouterLSA* lsa); /** * @brief Destroy an SPFVertex (Shortest Path First Vertex). * @@ -136,7 +136,7 @@ public: * representing routers, and comes from the Link State Advertisement of a * router aggregated to a node in the simulation. These IDs are allocated * automatically by the routing environment and look like IP addresses - * beginning at 0.0.0.0 and monotonically increase as new routers are + * beginning at 0.0.0.0 and monotonically increasing as new routers are * instantiated. * * @returns The Ipv4Address Vertex ID of the current SPFVertex object. @@ -158,31 +158,31 @@ public: */ void SetVertexId (Ipv4Address id); /** - * @brief Get the Static Router Link State Advertisement returned by the - * Static Router represented by this SPFVertex during the route discovery + * @brief Get the Global Router Link State Advertisement returned by the + * Global Router represented by this SPFVertex during the route discovery * process. * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () - * @returns A pointer to the StaticRouterLSA found by the router represented + * @see GlobalRouter + * @see GlobalRouterLSA + * @see GlobalRouter::DiscoverLSAs () + * @returns A pointer to the GlobalRouterLSA found by the router represented * by this SPFVertex object. */ - StaticRouterLSA* GetLSA (void) const; + GlobalRouterLSA* GetLSA (void) const; /** - * @brief Set the Static Router Link State Advertisement returned by the - * Static Router represented by this SPFVertex during the route discovery + * @brief Set the Global Router Link State Advertisement returned by the + * Global Router represented by this SPFVertex during the route discovery * process. * * @see SPFVertex::GetLSA () - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () + * @see GlobalRouter + * @see GlobalRouterLSA + * @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 StaticRouterLSA. + * @param lsa A pointer to the GlobalRouterLSA. */ - void SetLSA (StaticRouterLSA* lsa); + void SetLSA (GlobalRouterLSA* lsa); /** * @brief Get the distance from the root vertex to "this" SPFVertex object. * @@ -240,11 +240,11 @@ public: * path to "this" vertex. * * When initializing the root SPFVertex, the interface ID is determined by - * examining the Static Router Link Records of the Link State Advertisement - * generated by the root node's StaticRouter. These interfaces are used to + * examining the Global Router Link Records of the Link State Advertisement + * generated by the root node's GlobalRouter. These interfaces are used to * forward packets off of the root's network down those links. As other * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Static Router Link Record. + * be accessible down one of the paths begun by a Global Router Link Record. * * To forward packets to these hosts or networks, the root node must begin * the forwarding process by sending the packets to the interface of that @@ -256,9 +256,9 @@ public: * should I use to get a packet to the network or host represented by 'this' * SPFVertex." * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord + * @see GlobalRouter + * @see GlobalRouterLSA + * @see GlobalRouterLinkRecord * @returns The interface index to use when forwarding packets to the host * or network represented by "this" SPFVertex. */ @@ -280,11 +280,11 @@ public: * path to "this" vertex. * * When initializing the root SPFVertex, the interface ID is determined by - * examining the Static Router Link Records of the Link State Advertisement - * generated by the root node's StaticRouter. These interfaces are used to + * examining the Global Router Link Records of the Link State Advertisement + * generated by the root node's GlobalRouter. These interfaces are used to * forward packets off of the root's network down those links. As other * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Static Router Link Record. + * be accessible down one of the paths begun by a Global Router Link Record. * * To forward packets to these hosts or networks, the root node must begin * the forwarding process by sending the packets to the interface of that @@ -296,9 +296,9 @@ public: * interfaces it should use to get a packet to the network or host represented * by "this" SPFVertex. * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord + * @see GlobalRouter + * @see GlobalRouterLSA + * @see GlobalRouterLinkRecord * @param id The interface index to use when forwarding packets to the host or * network represented by "this" SPFVertex. */ @@ -320,12 +320,12 @@ public: * destination for packets along the path to "this" vertex. * * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Static Router Link Records of the - * Link State Advertisement generated by the root node's StaticRouter. This + * packets is determined by examining the Global Router Link Records of the + * Link State Advertisement generated by the root node's GlobalRouter. This * address is used to forward packets off of the root's network down those * links. As other vertices / nodes are discovered which are further away * from the root, they will be accessible down one of the paths via a link - * described by one of these Static Router Link Records. + * described by one of these Global Router Link Records. * * To forward packets to these hosts or networks, the root node must begin * the forwarding process by sending the packets to a first hop router down @@ -337,9 +337,9 @@ public: * packet to in order to get that packet to the network or host represented * by 'this' SPFVertex." * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord + * @see GlobalRouter + * @see GlobalRouterLSA + * @see GlobalRouterLinkRecord * @returns The IP address to use when forwarding packets to the host * or network represented by "this" SPFVertex. */ @@ -361,12 +361,12 @@ public: * destination for packets along the path to "this" vertex. * * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Static Router Link Records of the - * Link State Advertisement generated by the root node's StaticRouter. This + * packets is determined by examining the Global Router Link Records of the + * Link State Advertisement generated by the root node's GlobalRouter. This * address is used to forward packets off of the root's network down those * links. As other vertices / nodes are discovered which are further away * from the root, they will be accessible down one of the paths via a link - * described by one of these Static Router Link Records. + * described by one of these Global Router Link Records. * * To forward packets to these hosts or networks, the root node must begin * the forwarding process by sending the packets to a first hop router down @@ -378,9 +378,9 @@ public: * should I send a packet to in order to get that packet to the network or * host represented by 'this' SPFVertex." * - * @see StaticRouter - * @see StaticRouterLSA - * @see StaticRouterLinkRecord + * @see GlobalRouter + * @see GlobalRouterLSA + * @see GlobalRouterLinkRecord * @param nextHop The IP address to use when forwarding packets to the host * or network represented by "this" SPFVertex. */ @@ -501,7 +501,7 @@ public: private: VertexType m_vertexType; Ipv4Address m_vertexId; - StaticRouterLSA* m_lsa; + GlobalRouterLSA* m_lsa; uint32_t m_distanceFromRoot; uint32_t m_rootOif; Ipv4Address m_nextHop; @@ -521,65 +521,65 @@ private: }; /** - * @brief The Link State DataBase (LSDB) of the StaticRouteManager. + * @brief The Link State DataBase (LSDB) of the Global Route Manager. * - * Each node in the simulation participating in static routing has a - * StaticRouter interface. The primary job of this interface is to export - * Static Router Link State Advertisements (LSAs). These advertisements in - * turn contain a number of Static Router Link Records that describe the + * Each node in the simulation participating in global routing has a + * GlobalRouter interface. The primary job of this interface is to export + * Global Router Link State Advertisements (LSAs). These advertisements in + * turn contain a number of Global Router Link Records that describe the * point to point links from the underlying node to other nodes (that will * also export their own LSAs. * * This class implements a searchable database of LSAs gathered from every * router in the simulation. */ -class StaticRouteManagerLSDB +class GlobalRouteManagerLSDB { public: /** - * @brief Construct an empty StaticRoutingManager Link State Database. + * @brief Construct an empty Global Router Manager Link State Database. * * The database map composing the Link State Database is initialized in * this constructor. */ - StaticRouteManagerLSDB (); + GlobalRouteManagerLSDB (); /** - * @brief Destroy an empty StaticRoutingManager Link State Database. + * @brief Destroy an empty Global Router Manager Link State Database. * * The database map is walked and all of the Link State Advertisements stored * in the database are freed; then the database map itself is clear ()ed to * release any remaining resources. */ - ~StaticRouteManagerLSDB (); + ~GlobalRouteManagerLSDB (); /** * @brief Insert an IP address / Link State Advertisement pair into the Link * State Database. * - * The IPV4 address and the StaticRouterLSA given as parameters are converted + * The IPV4 address and the GlobalRouterLSA given as parameters are converted * to an STL pair and are inserted into the database map. * - * @see StaticRouterLSA + * @see GlobalRouterLSA * @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, StaticRouterLSA* lsa); + void Insert(Ipv4Address addr, GlobalRouterLSA* lsa); /** * @brief Look up the Link State Advertisement associated with the given * IP Address. * * The database map is searched for the given IPV4 address and corresponding - * StaticRouterLSA is returned. + * GlobalRouterLSA is returned. * - * @see StaticRouterLSA + * @see GlobalRouterLSA * @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. */ - StaticRouterLSA* GetLSA (Ipv4Address addr) const; + GlobalRouterLSA* GetLSA (Ipv4Address addr) const; /** * @brief Set all LSA flags to an initialized state, for SPF computation * @@ -588,50 +588,50 @@ public: * prior to each SPF calculation to reset the state of the SPFVertex structures * that will reference the LSAs during the calculation. * - * @see StaticRouterLSA + * @see GlobalRouterLSA * @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; /** - * @brief StaticRouteManagerLSDB copy construction is disallowed. There's no + * @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. */ - StaticRouteManagerLSDB (StaticRouteManagerLSDB& lsdb); + GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb); /** * @brief The SPFVertex copy assignment operator is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. */ - StaticRouteManagerLSDB& operator= (StaticRouteManagerLSDB& lsdb); + GlobalRouteManagerLSDB& operator= (GlobalRouteManagerLSDB& lsdb); }; /** - * @brief A global static router + * @brief A global router implementation. * * This singleton object can query interface each node in the system - * for a StaticRouter interface. For those nodes, it fetches one or + * for a GlobalRouter interface. For those nodes, it fetches one or * more Link State Advertisements and stores them in a local database. * Then, it can compute shortest paths on a per-node basis to all routers, * and finally configure each of the node's forwarding tables. * * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd. */ -class StaticRouteManagerImpl +class GlobalRouteManagerImpl { public: - StaticRouteManagerImpl (); - virtual ~StaticRouteManagerImpl (); + GlobalRouteManagerImpl (); + virtual ~GlobalRouteManagerImpl (); /** * @brief Build the routing database by gathering Link State Advertisements - * from each node exporting a StaticRouter interface. + * from each node exporting a GlobalRouter interface. * */ - virtual void BuildStaticRoutingDatabase(); + virtual void BuildGlobalRoutingDatabase(); /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables @@ -640,38 +640,38 @@ public: /** * @brief Debugging routine; allow client code to supply a pre-built LSDB */ - void DebugUseLsdb (StaticRouteManagerLSDB*); + void DebugUseLsdb (GlobalRouteManagerLSDB*); /** * @brief Debugging routine; call the core SPF from the unit tests */ void DebugSPFCalculate (Ipv4Address root); private: /** - * @brief StaticRouteManager Implementation copy construction is disallowed. + * @brief GlobalRouteManagerImpl copy construction is disallowed. * There's no need for it and a compiler provided shallow copy would be * wrong. */ - StaticRouteManagerImpl (StaticRouteManagerImpl& srmi); + GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi); /** - * @brief StaticRouteManager Implementation assignment operator is + * @brief Global Route Manager Implementation assignment operator is * disallowed. There's no need for it and a compiler provided shallow copy - * would be wrong. + * would be hopelessly wrong. */ - StaticRouteManagerImpl& operator= (StaticRouteManagerImpl& srmi); + GlobalRouteManagerImpl& operator= (GlobalRouteManagerImpl& srmi); SPFVertex* m_spfroot; - StaticRouteManagerLSDB* m_lsdb; + GlobalRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); void SPFNext (SPFVertex*, CandidateQueue&); int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* l, uint32_t distance); + GlobalRouterLinkRecord* l, uint32_t distance); void SPFVertexAddParent(SPFVertex* v); - StaticRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, - StaticRouterLinkRecord* prev_link); + GlobalRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, + GlobalRouterLinkRecord* prev_link); void SPFIntraAddRouter(SPFVertex* v); uint32_t FindOutgoingInterfaceId(Ipv4Address a); }; } // namespace ns3 -#endif /* STATIC_ROUTE_MANAGER_IMPL_H */ +#endif /* GLOBAL_ROUTE_MANAGER_IMPL_H */ diff --git a/src/routing/static-route-manager.cc b/src/routing/global/global-route-manager.cc similarity index 71% rename from src/routing/static-route-manager.cc rename to src/routing/global/global-route-manager.cc index b3a0cb6ff..ce9e891c0 100644 --- a/src/routing/static-route-manager.cc +++ b/src/routing/global/global-route-manager.cc @@ -17,35 +17,35 @@ #include "ns3/assert.h" #include "ns3/debug.h" #include "ns3/simulation-singleton.h" -#include "static-route-manager.h" -#include "static-route-manager-impl.h" +#include "global-route-manager.h" +#include "global-route-manager-impl.h" namespace ns3 { // --------------------------------------------------------------------------- // -// StaticRouteManager Implementation +// GlobalRouteManager Implementation // // --------------------------------------------------------------------------- void -StaticRouteManager::PopulateRoutingTables () +GlobalRouteManager::PopulateRoutingTables () { - BuildStaticRoutingDatabase (); + BuildGlobalRoutingDatabase (); InitializeRoutes (); } void -StaticRouteManager::BuildStaticRoutingDatabase () +GlobalRouteManager::BuildGlobalRoutingDatabase () { - return SimulationSingleton::Get ()-> - BuildStaticRoutingDatabase (); + return SimulationSingleton::Get ()-> + BuildGlobalRoutingDatabase (); } void -StaticRouteManager::InitializeRoutes () +GlobalRouteManager::InitializeRoutes () { - return SimulationSingleton::Get ()-> + return SimulationSingleton::Get ()-> InitializeRoutes (); } diff --git a/src/routing/static-route-manager.h b/src/routing/global/global-route-manager.h similarity index 73% rename from src/routing/static-route-manager.h rename to src/routing/global/global-route-manager.h index 11c6ec718..3a695dcdf 100644 --- a/src/routing/static-route-manager.h +++ b/src/routing/global/global-route-manager.h @@ -15,60 +15,64 @@ */ #ifndef STATIC_ROUTE_MANAGER_H -#define STATIC_ROUTE_MANAGER_H +#define GLOBAL_ROUTE_MANAGER_H namespace ns3 { /** - * @brief A global static router + * @brief A global global router * * This singleton object can query interface each node in the system - * for a StaticRouter interface. For those nodes, it fetches one or + * for a GlobalRouter interface. For those nodes, it fetches one or * more Link State Advertisements and stores them in a local database. * Then, it can compute shortest paths on a per-node basis to all routers, * and finally configure each of the node's forwarding tables. * * The design is guided by OSPFv2 RFC 2328 section 16.1.1 and quagga ospfd. */ -class StaticRouteManager +class GlobalRouteManager { public: /** * @brief Build a routing database and initialize the routing tables of * the nodes in the simulation. * - * All this function does is call BuildStaticRoutingDatabase () and - * InitializeRoutes (). + * All this function does is call BuildGlobalRoutingDatabase () and + * InitializeRoutes (). * - * @see BuildStaticRoutingDatabase (); + * @see BuildGlobalRoutingDatabase (); * @see InitializeRoutes (); */ static void PopulateRoutingTables (); + private: /** * @brief Build the routing database by gathering Link State Advertisements - * from each node exporting a StaticRouter interface. + * from each node exporting a GlobalRouter interface. * */ - static void BuildStaticRoutingDatabase (); + static void BuildGlobalRoutingDatabase (); + /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables */ static void InitializeRoutes (); + /** - * @brief Static Route Manager copy construction is disallowed. There's no + * @brief Global Route Manager copy construction is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. * */ - StaticRouteManager (StaticRouteManager& srm); + GlobalRouteManager (GlobalRouteManager& srm); + /** - * @brief Static Router copy assignment operator is disallowed. There's no + * @brief Global Router copy assignment operator is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. */ - StaticRouteManager& operator= (StaticRouteManager& srm); + GlobalRouteManager& operator= (GlobalRouteManager& srm); }; } // namespace ns3 -#endif /* STATIC_ROUTE_MANAGER_H */ +#endif /* GLOBAL_ROUTE_MANAGER_H */ diff --git a/src/routing/static-router.cc b/src/routing/global/global-router-interface.cc similarity index 68% rename from src/routing/static-router.cc rename to src/routing/global/global-router-interface.cc index 82aa2c2e4..ff1f06318 100644 --- a/src/routing/static-router.cc +++ b/src/routing/global/global-router-interface.cc @@ -20,29 +20,29 @@ #include "ns3/net-device.h" #include "ns3/internet-node.h" #include "ns3/ipv4.h" -#include "static-router.h" +#include "global-router-interface.h" -NS_DEBUG_COMPONENT_DEFINE ("StaticRouter"); +NS_DEBUG_COMPONENT_DEFINE ("GlobalRouter"); namespace ns3 { // --------------------------------------------------------------------------- // -// StaticRouterLinkRecord Implementation +// GlobalRouterLinkRecord Implementation // // --------------------------------------------------------------------------- -StaticRouterLinkRecord::StaticRouterLinkRecord () +GlobalRouterLinkRecord::GlobalRouterLinkRecord () : m_linkId ("0.0.0.0"), m_linkData ("0.0.0.0"), m_linkType (Unknown), m_metric (0) { - NS_DEBUG("StaticRouterLinkRecord::StaticRouterLinkRecord ()"); + NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord ()"); } -StaticRouterLinkRecord::StaticRouterLinkRecord ( +GlobalRouterLinkRecord::GlobalRouterLinkRecord ( LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, @@ -53,90 +53,90 @@ StaticRouterLinkRecord::StaticRouterLinkRecord ( m_linkType (linkType), m_metric (metric) { - NS_DEBUG("StaticRouterLinkRecord::StaticRouterLinkRecord (" << + NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord (" << linkType << ", " << linkId << ", " << linkData << ", " << metric << ")"); } -StaticRouterLinkRecord::~StaticRouterLinkRecord () +GlobalRouterLinkRecord::~GlobalRouterLinkRecord () { - NS_DEBUG("StaticRouterLinkRecord::~StaticRouterLinkRecord ()"); + NS_DEBUG("GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()"); } Ipv4Address -StaticRouterLinkRecord::GetLinkId (void) const +GlobalRouterLinkRecord::GetLinkId (void) const { - NS_DEBUG("StaticRouterLinkRecord::GetLinkId ()"); + NS_DEBUG("GlobalRouterLinkRecord::GetLinkId ()"); return m_linkId; } void -StaticRouterLinkRecord::SetLinkId (Ipv4Address addr) +GlobalRouterLinkRecord::SetLinkId (Ipv4Address addr) { - NS_DEBUG("StaticRouterLinkRecord::SetLinkId ()"); + NS_DEBUG("GlobalRouterLinkRecord::SetLinkId ()"); m_linkId = addr; } Ipv4Address -StaticRouterLinkRecord::GetLinkData (void) const +GlobalRouterLinkRecord::GetLinkData (void) const { - NS_DEBUG("StaticRouterLinkRecord::GetLinkData ()"); + NS_DEBUG("GlobalRouterLinkRecord::GetLinkData ()"); return m_linkData; } void -StaticRouterLinkRecord::SetLinkData (Ipv4Address addr) +GlobalRouterLinkRecord::SetLinkData (Ipv4Address addr) { - NS_DEBUG("StaticRouterLinkRecord::SetLinkData ()"); + NS_DEBUG("GlobalRouterLinkRecord::SetLinkData ()"); m_linkData = addr; } - StaticRouterLinkRecord::LinkType -StaticRouterLinkRecord::GetLinkType (void) const + GlobalRouterLinkRecord::LinkType +GlobalRouterLinkRecord::GetLinkType (void) const { - NS_DEBUG("StaticRouterLinkRecord::GetLinkType ()"); + NS_DEBUG("GlobalRouterLinkRecord::GetLinkType ()"); return m_linkType; } void -StaticRouterLinkRecord::SetLinkType ( - StaticRouterLinkRecord::LinkType linkType) +GlobalRouterLinkRecord::SetLinkType ( + GlobalRouterLinkRecord::LinkType linkType) { - NS_DEBUG("StaticRouterLinkRecord::SetLinkType ()"); + NS_DEBUG("GlobalRouterLinkRecord::SetLinkType ()"); m_linkType = linkType; } uint32_t -StaticRouterLinkRecord::GetMetric (void) const +GlobalRouterLinkRecord::GetMetric (void) const { - NS_DEBUG("StaticRouterLinkRecord::GetMetric ()"); + NS_DEBUG("GlobalRouterLinkRecord::GetMetric ()"); return m_metric; } void -StaticRouterLinkRecord::SetMetric (uint32_t metric) +GlobalRouterLinkRecord::SetMetric (uint32_t metric) { - NS_DEBUG("StaticRouterLinkRecord::SetMetric ()"); + NS_DEBUG("GlobalRouterLinkRecord::SetMetric ()"); m_metric = metric; } // --------------------------------------------------------------------------- // -// StaticRouterLSA Implementation +// GlobalRouterLSA Implementation // // --------------------------------------------------------------------------- -StaticRouterLSA::StaticRouterLSA() +GlobalRouterLSA::GlobalRouterLSA() : m_linkStateId("0.0.0.0"), m_advertisingRtr("0.0.0.0"), m_linkRecords(), - m_status(StaticRouterLSA::LSA_SPF_NOT_EXPLORED) + m_status(GlobalRouterLSA::LSA_SPF_NOT_EXPLORED) { - NS_DEBUG("StaticRouterLSA::StaticRouterLSA ()"); + NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA ()"); } -StaticRouterLSA::StaticRouterLSA ( - StaticRouterLSA::SPFStatus status, +GlobalRouterLSA::GlobalRouterLSA ( + GlobalRouterLSA::SPFStatus status, Ipv4Address linkStateId, Ipv4Address advertisingRtr) : @@ -145,21 +145,21 @@ StaticRouterLSA::StaticRouterLSA ( m_linkRecords(), m_status(status) { - NS_DEBUG("StaticRouterLSA::StaticRouterLSA (" << status << ", " << + NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA (" << status << ", " << linkStateId << ", " << advertisingRtr << ")"); } -StaticRouterLSA::StaticRouterLSA (StaticRouterLSA& lsa) +GlobalRouterLSA::GlobalRouterLSA (GlobalRouterLSA& lsa) : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr), m_status(lsa.m_status) { NS_ASSERT_MSG(IsEmpty(), - "StaticRouterLSA::StaticRouterLSA (): Non-empty LSA in constructor"); + "GlobalRouterLSA::GlobalRouterLSA (): Non-empty LSA in constructor"); CopyLinkRecords (lsa); } - StaticRouterLSA& -StaticRouterLSA::operator= (const StaticRouterLSA& lsa) + GlobalRouterLSA& +GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa) { m_linkStateId = lsa.m_linkStateId; m_advertisingRtr = lsa.m_advertisingRtr; @@ -171,14 +171,14 @@ StaticRouterLSA::operator= (const StaticRouterLSA& lsa) } void -StaticRouterLSA::CopyLinkRecords (const StaticRouterLSA& lsa) +GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa) { for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin (); i != lsa.m_linkRecords.end (); i++) { - StaticRouterLinkRecord *pSrc = *i; - StaticRouterLinkRecord *pDst = new StaticRouterLinkRecord; + GlobalRouterLinkRecord *pSrc = *i; + GlobalRouterLinkRecord *pDst = new GlobalRouterLinkRecord; pDst->SetLinkType (pSrc->GetLinkType ()); pDst->SetLinkId (pSrc->GetLinkId ()); @@ -189,46 +189,46 @@ StaticRouterLSA::CopyLinkRecords (const StaticRouterLSA& lsa) } } -StaticRouterLSA::~StaticRouterLSA() +GlobalRouterLSA::~GlobalRouterLSA() { - NS_DEBUG("StaticRouterLSA::~StaticRouterLSA ()"); + NS_DEBUG("GlobalRouterLSA::~GlobalRouterLSA ()"); ClearLinkRecords (); } void -StaticRouterLSA::ClearLinkRecords(void) +GlobalRouterLSA::ClearLinkRecords(void) { for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin (); i != m_linkRecords.end (); i++) { - NS_DEBUG("StaticRouterLSA::ClearLinkRecords (): free link record"); + NS_DEBUG("GlobalRouterLSA::ClearLinkRecords (): free link record"); - StaticRouterLinkRecord *p = *i; + GlobalRouterLinkRecord *p = *i; delete p; p = 0; *i = 0; } - NS_DEBUG("StaticRouterLSA::ClearLinkRecords(): clear list"); + NS_DEBUG("GlobalRouterLSA::ClearLinkRecords(): clear list"); m_linkRecords.clear(); } uint32_t -StaticRouterLSA::AddLinkRecord (StaticRouterLinkRecord* lr) +GlobalRouterLSA::AddLinkRecord (GlobalRouterLinkRecord* lr) { m_linkRecords.push_back (lr); return m_linkRecords.size (); } uint32_t -StaticRouterLSA::GetNLinkRecords (void) const +GlobalRouterLSA::GetNLinkRecords (void) const { return m_linkRecords.size (); } - StaticRouterLinkRecord * -StaticRouterLSA::GetLinkRecord (uint32_t n) const + GlobalRouterLinkRecord * +GlobalRouterLSA::GetLinkRecord (uint32_t n) const { uint32_t j = 0; for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin (); @@ -240,54 +240,54 @@ StaticRouterLSA::GetLinkRecord (uint32_t n) const return *i; } } - NS_ASSERT_MSG(false, "StaticRouterLSA::GetLinkRecord (): invalid index"); + NS_ASSERT_MSG(false, "GlobalRouterLSA::GetLinkRecord (): invalid index"); return 0; } bool -StaticRouterLSA::IsEmpty (void) const +GlobalRouterLSA::IsEmpty (void) const { return m_linkRecords.size () == 0; } Ipv4Address -StaticRouterLSA::GetLinkStateId (void) const +GlobalRouterLSA::GetLinkStateId (void) const { return m_linkStateId; } void -StaticRouterLSA::SetLinkStateId (Ipv4Address addr) +GlobalRouterLSA::SetLinkStateId (Ipv4Address addr) { m_linkStateId = addr; } Ipv4Address -StaticRouterLSA::GetAdvertisingRouter (void) const +GlobalRouterLSA::GetAdvertisingRouter (void) const { return m_advertisingRtr; } void -StaticRouterLSA::SetAdvertisingRouter (Ipv4Address addr) +GlobalRouterLSA::SetAdvertisingRouter (Ipv4Address addr) { m_advertisingRtr = addr; } - StaticRouterLSA::SPFStatus -StaticRouterLSA::GetStatus (void) const + GlobalRouterLSA::SPFStatus +GlobalRouterLSA::GetStatus (void) const { return m_status; } void -StaticRouterLSA::SetStatus (StaticRouterLSA::SPFStatus status) +GlobalRouterLSA::SetStatus (GlobalRouterLSA::SPFStatus status) { m_status = status; } void -StaticRouterLSA::Print (std::ostream &os) const +GlobalRouterLSA::Print (std::ostream &os) const { os << "m_linkStateId = " << m_linkStateId << std::endl << "m_advertisingRtr = " << m_advertisingRtr << std::endl; @@ -296,14 +296,14 @@ StaticRouterLSA::Print (std::ostream &os) const i != m_linkRecords.end (); i++) { - StaticRouterLinkRecord *p = *i; + GlobalRouterLinkRecord *p = *i; os << "----------" << std::endl; os << "m_linkId = " << p->GetLinkId () << std::endl; os << "m_linkData = " << p->GetLinkData () << std::endl; } } -std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa) +std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa) { lsa.Print (os); return os; @@ -311,50 +311,50 @@ std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa) // --------------------------------------------------------------------------- // -// StaticRouter Implementation +// GlobalRouter Implementation // // --------------------------------------------------------------------------- -const InterfaceId StaticRouter::iid = - MakeInterfaceId ("StaticRouter", Object::iid); +const InterfaceId GlobalRouter::iid = + MakeInterfaceId ("GlobalRouter", Object::iid); -StaticRouter::StaticRouter (Ptr node) +GlobalRouter::GlobalRouter (Ptr node) : m_node(node), m_LSAs() { - NS_DEBUG("StaticRouter::StaticRouter ()"); - SetInterfaceId (StaticRouter::iid); + NS_DEBUG("GlobalRouter::GlobalRouter ()"); + SetInterfaceId (GlobalRouter::iid); m_routerId.Set(RoutingEnvironment::AllocateRouterId()); } -StaticRouter::~StaticRouter () +GlobalRouter::~GlobalRouter () { - NS_DEBUG("StaticRouter::~StaticRouter ()"); + NS_DEBUG("GlobalRouter::~GlobalRouter ()"); ClearLSAs(); } void -StaticRouter::ClearLSAs () +GlobalRouter::ClearLSAs () { - NS_DEBUG("StaticRouter::ClearLSAs ()"); + NS_DEBUG("GlobalRouter::ClearLSAs ()"); for ( ListOfLSAs_t::iterator i = m_LSAs.begin (); i != m_LSAs.end (); i++) { - NS_DEBUG("StaticRouter::ClearLSAs (): free LSA"); + NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA"); - StaticRouterLSA *p = *i; + GlobalRouterLSA *p = *i; delete p; p = 0; *i = 0; } - NS_DEBUG("StaticRouter::ClearLSAs (): clear list"); + NS_DEBUG("GlobalRouter::ClearLSAs (): clear list"); m_LSAs.clear(); } Ipv4Address -StaticRouter::GetRouterId (void) const +GlobalRouter::GetRouterId (void) const { return m_routerId; } @@ -364,11 +364,11 @@ StaticRouter::GetRouterId (void) const // Advertisements that reflect them and their associated networks. // uint32_t -StaticRouter::DiscoverLSAs (void) +GlobalRouter::DiscoverLSAs (void) { - NS_DEBUG("StaticRouter::DiscoverLSAs ()"); + NS_DEBUG("GlobalRouter::DiscoverLSAs ()"); NS_ASSERT_MSG(m_node, - "StaticRouter::DiscoverLSAs (): interface not set"); + "GlobalRouter::DiscoverLSAs (): interface not set"); ClearLSAs (); // @@ -378,17 +378,17 @@ StaticRouter::DiscoverLSAs (void) // Ptr ipv4Local = m_node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4Local, - "StaticRouter::DiscoverLSAs (): QI for interface failed"); + "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. // - StaticRouterLSA *pLSA = new StaticRouterLSA; + GlobalRouterLSA *pLSA = new GlobalRouterLSA; pLSA->SetLinkStateId (m_routerId); pLSA->SetAdvertisingRouter (m_routerId); - pLSA->SetStatus (StaticRouterLSA::LSA_SPF_NOT_EXPLORED); + pLSA->SetStatus (GlobalRouterLSA::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) @@ -398,7 +398,7 @@ StaticRouter::DiscoverLSAs (void) // a point-to-point channel. // uint32_t numDevices = m_node->GetNDevices(); - NS_DEBUG("StaticRouter::DiscoverLSAs (): numDevices = " << numDevices); + NS_DEBUG("GlobalRouter::DiscoverLSAs (): numDevices = " << numDevices); // // Loop through the devices looking for those connected to a point-to-point // channel. @@ -409,11 +409,11 @@ StaticRouter::DiscoverLSAs (void) if (!ndLocal->IsPointToPoint ()) { - NS_DEBUG("StaticRouter::DiscoverLSAs (): non-point-to-point device"); + NS_DEBUG("GlobalRouter::DiscoverLSAs (): non-point-to-point device"); continue; } - NS_DEBUG("StaticRouter::DiscoverLSAs (): Point-to-point device"); + NS_DEBUG("GlobalRouter::DiscoverLSAs (): 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 @@ -442,15 +442,15 @@ StaticRouter::DiscoverLSAs (void) Ptr nodeRemote = ndRemote->GetNode(); Ptr ipv4Remote = nodeRemote->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4Remote, - "StaticRouter::DiscoverLSAs (): QI for remote failed"); + "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 (StaticRouter::iid); + Ptr srRemote = + nodeRemote->QueryInterface (GlobalRouter::iid); NS_ASSERT_MSG(srRemote, - "StaticRouter::DiscoverLSAs (): QI for remote failed"); + "GlobalRouter::DiscoverLSAs (): QI for remote failed"); Ipv4Address rtrIdRemote = srRemote->GetRouterId(); NS_DEBUG("Working with remote router " << rtrIdRemote); // @@ -470,15 +470,15 @@ StaticRouter::DiscoverLSAs (void) // 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. // - StaticRouterLinkRecord *plr = new StaticRouterLinkRecord; - plr->SetLinkType (StaticRouterLinkRecord::PointToPoint); + GlobalRouterLinkRecord *plr = new GlobalRouterLinkRecord; + plr->SetLinkType (GlobalRouterLinkRecord::PointToPoint); plr->SetLinkId (rtrIdRemote); plr->SetLinkData (addrLocal); pLSA->AddLinkRecord(plr); plr = 0; - plr = new StaticRouterLinkRecord; - plr->SetLinkType (StaticRouterLinkRecord::StubNetwork); + plr = new GlobalRouterLinkRecord; + plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork); plr->SetLinkId (addrRemote); plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown pLSA->AddLinkRecord(plr); @@ -493,9 +493,9 @@ StaticRouter::DiscoverLSAs (void) } uint32_t -StaticRouter::GetNumLSAs (void) const +GlobalRouter::GetNumLSAs (void) const { - NS_DEBUG("StaticRouter::GetNumLSAs ()"); + NS_DEBUG("GlobalRouter::GetNumLSAs ()"); return m_LSAs.size (); } @@ -503,9 +503,9 @@ StaticRouter::GetNumLSAs (void) const // Get the nth link state advertisement from this router. // bool -StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) const +GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const { - NS_ASSERT_MSG(lsa.IsEmpty(), "StaticRouter::GetLSA (): Must pass empty LSA"); + NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA"); // // All of the work was done in GetNumLSAs. All we have to do here is to // walk the list of link state advertisements created there and return the @@ -518,7 +518,7 @@ StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) const { if (j == n) { - StaticRouterLSA *p = *i; + GlobalRouterLSA *p = *i; lsa = *p; return true; } @@ -532,7 +532,7 @@ StaticRouter::GetLSA (uint32_t n, StaticRouterLSA &lsa) const // other end. This only makes sense with a point-to-point channel. // Ptr -StaticRouter::GetAdjacent(Ptr nd, Ptr ch) const +GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const { // // Double-check that channel agrees with device that it's a point-to-point @@ -541,7 +541,7 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) const uint32_t nDevices = ch->GetNDevices(); NS_ASSERT_MSG(nDevices == 2, - "StaticRouter::GetAdjacent (): Channel with other than two devices"); + "GlobalRouter::GetAdjacent (): Channel with other than two devices"); // // This is a point to point channel with two endpoints. Get both of them. // @@ -563,7 +563,7 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) const else { NS_ASSERT_MSG(false, - "StaticRouter::GetAdjacent (): Wrong or confused channel?"); + "GlobalRouter::GetAdjacent (): Wrong or confused channel?"); return 0; } } @@ -573,7 +573,7 @@ StaticRouter::GetAdjacent(Ptr nd, Ptr ch) const // corresponds to that net device. // uint32_t -StaticRouter::FindIfIndexForDevice(Ptr node, Ptr nd) const +GlobalRouter::FindIfIndexForDevice(Ptr node, Ptr nd) const { Ptr ipv4 = node->QueryInterface (Ipv4::iid); NS_ASSERT_MSG(ipv4, "QI for interface failed"); diff --git a/src/routing/static-router.h b/src/routing/global/global-router-interface.h similarity index 72% rename from src/routing/static-router.h rename to src/routing/global/global-router-interface.h index 9465c1319..fed346b49 100644 --- a/src/routing/static-router.h +++ b/src/routing/global/global-router-interface.h @@ -15,8 +15,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef STATIC_ROUTER_H -#define STATIC_ROUTER_H +#ifndef GLOBAL_ROUTER_H +#define GLOBAL_ROUTER_H #include #include @@ -32,16 +32,16 @@ namespace ns3 { /** * @brief A single link record for a link state advertisement. * - * The StaticRouterLinkRecord is modeled after the OSPF link record field of + * The GlobalRouterLinkRecord 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 StaticRouterLinkRecord +class GlobalRouterLinkRecord { public: /** * @enum LinkType - * @brief Enumeration of the possible types of Static Router Link Records. + * @brief Enumeration of the possible types of Global Router Link Records. * * These values are defined in the OSPF spec. We currently only use * PointToPoint and StubNetwork types. @@ -54,15 +54,15 @@ public: VirtualLink /**< Unused -- for future OSPF compatibility */ }; /** - * @brief Construct an empty ("uninitialized") Static Router Link Record. + * @brief Construct an empty ("uninitialized") Global Router 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. */ - StaticRouterLinkRecord (); + GlobalRouterLinkRecord (); /** - * Construct an initialized Static Router Link Record. + * Construct an initialized Global Router Link Record. * * @param linkType The type of link record to construct. * @param linkId The link ID for the record. @@ -72,19 +72,19 @@ public: * @see SetLinkId * @see SetLinkData */ - StaticRouterLinkRecord ( + GlobalRouterLinkRecord ( LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, uint32_t metric); /** - * @brief Destroy a Static Router Link Record. + * @brief Destroy a Global Router Link Record. * * Currently does nothing. Here as a placeholder only. */ - ~StaticRouterLinkRecord (); + ~GlobalRouterLinkRecord (); /** - * Get the Link ID field of the Static Router Link Record. + * Get the Link ID field of the Global Router Link Record. * * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID * of the neighboring router. @@ -96,7 +96,7 @@ public: */ Ipv4Address GetLinkId(void) const; /** - * @brief Set the Link ID field of the Static Router Link Record. + * @brief Set the Link ID field of the Global Router Link Record. * * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID * of the neighboring router. @@ -108,7 +108,7 @@ public: */ void SetLinkId(Ipv4Address addr); /** - * @brief Get the Link Data field of the Static Router Link Record. + * @brief Get the Link Data field of the Global Router 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. @@ -120,7 +120,7 @@ public: */ Ipv4Address GetLinkData(void) const; /** - * @brief Set the Link Data field of the Static Router Link Record. + * @brief Set the Link Data field of the Global Router 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. @@ -132,27 +132,27 @@ public: */ void SetLinkData(Ipv4Address addr); /** - * @brief Get the Link Type field of the Static Router Link Record. + * @brief Get the Link Type field of the Global Router 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 Static Router Link Record. + * @returns The LinkType of the current Global Router Link Record. */ LinkType GetLinkType(void) const; /** - * @brief Set the Link Type field of the Static Router Link Record. + * @brief Set the Link Type field of the Global Router 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 Static Router Link Record. + * @param linkType The new LinkType for the current Global Router Link Record. */ void SetLinkType(LinkType linkType); /** - * @brief Get the Metric Data field of the Static Router Link Record. + * @brief Get the Metric Data field of the Global Router 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 @@ -160,11 +160,11 @@ public: * two hops relate to the cost of sending a packet); rather you should use * something like delay. * - * @returns The metric field of the Static Router Link Record. + * @returns The metric field of the Global Router Link Record. */ uint32_t GetMetric(void) const; /** - * @brief Set the Metric Data field of the Static Router Link Record. + * @brief Set the Metric Data field of the Global Router 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 @@ -172,7 +172,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 Static Router Link Record. + * @param metric The new metric for the current Global Router Link Record. */ void SetMetric(uint32_t metric); @@ -199,7 +199,7 @@ private: */ Ipv4Address m_linkData; // for links to RouterLSA, /** - * The type of the Static Router Link Record. Defined in the OSPF spec. + * The type of the Global Router Link Record. Defined in the OSPF spec. * We currently only use PointToPoint and StubNetwork types. */ LinkType m_linkType; @@ -216,14 +216,14 @@ private: }; /** - * @brief a Link State Advertisement (LSA) for a router, used in static + * @brief a Link State Advertisement (LSA) for a router, used in global * routing. * - * Roughly equivalent to a static incarnation of the OSPF link state header - * combined with a list of Link Records. Since it's static, there's + * Roughly equivalent to a global incarnation of the OSPF link state header + * 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 StaticRouterLSA +class GlobalRouterLSA { public: /** @@ -237,14 +237,14 @@ public: LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */ }; /** - * @brief Create a blank Static Router Link State Advertisement. + * @brief Create a blank Global Router Link State Advertisement. * * On completion Ipv4Address variables initialized to 0.0.0.0 and the * list of Link State Records is empty. */ - StaticRouterLSA(); + GlobalRouterLSA(); /** - * @brief Create an initialized Static Router Link State Advertisement. + * @brief Create an initialized Global Router Link State Advertisement. * * On completion the list of Link State Records is empty. * @@ -252,38 +252,38 @@ public: * @param linkStateId The Ipv4Address for the link state ID field. * @param advertisingRtr The Ipv4Address for the advertising router field. */ - StaticRouterLSA(SPFStatus status, Ipv4Address linkStateId, + GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId, Ipv4Address advertisingRtr); /** - * @brief Copy constructor for a Static Router Link State Advertisement. + * @brief Copy constructor for a Global Router 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. */ - StaticRouterLSA (StaticRouterLSA& lsa); + GlobalRouterLSA (GlobalRouterLSA& lsa); /** - * @brief Destroy an existing Static Router Link State Advertisement. + * @brief Destroy an existing Global Router Link State Advertisement. * - * Any Static Router Link Records present in the list are freed. + * Any Global Router Link Records present in the list are freed. */ - ~StaticRouterLSA(); + ~GlobalRouterLSA(); /** - * @brief Assignment operator for a Static Router Link State Advertisement. + * @brief Assignment operator for a Global Router Link State Advertisement. * - * Takes an existing Static Router Link State Advertisement and overwrites + * Takes an existing Global Router Link State Advertisement and overwrites * it to make a semantically identical copy of a given prototype LSA. * - * If there are any Static Router Link Records present in the existing + * If there are any Global Router 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. */ - StaticRouterLSA& operator= (const StaticRouterLSA& lsa); + GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa); /** - * @brief Copy any Static Router Link Records in a given Static Router Link + * @brief Copy any Global Router Link Records in a given Global Router Link * State Advertisement to the current LSA. * * Existing Link Records are not deleted -- this is a concatenation of Link @@ -292,42 +292,42 @@ public: * @see ClearLinkRecords () * @param lsa The LSA to copy the Link Records from. */ - void CopyLinkRecords (const StaticRouterLSA& lsa); + void CopyLinkRecords (const GlobalRouterLSA& lsa); /** - * @brief Add a given Static Router Link Record to the LSA. + * @brief Add a given Global Router Link Record to the LSA. * - * @param lr The Static Router Link Record to be added. + * @param lr The Global Router Link Record to be added. * @returns The number of link records in the list. */ - uint32_t AddLinkRecord (StaticRouterLinkRecord* lr); + uint32_t AddLinkRecord (GlobalRouterLinkRecord* lr); /** - * @brief Return the number of Static Router Link Records in the LSA. + * @brief Return the number of Global Router 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 Static Router Link Record. + * @brief Return a pointer to the specified Global Router Link Record. * * @param n The LSA number desired. * @returns The number of link records in the list. */ - StaticRouterLinkRecord* GetLinkRecord (uint32_t n) const; + GlobalRouterLinkRecord* GetLinkRecord (uint32_t n) const; /** - * @brief Release all of the Static Router Link Records present in the Static + * @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. */ void ClearLinkRecords(void); /** - * @brief Check to see if the list of Static Router Link Records present in the - * Static Router Link State Advertisement is empty. + * @brief Check to see if the list of Global Router Link Records present in the + * Global Router Link State Advertisement is empty. * * @returns True if the list is empty, false otherwise. */ bool IsEmpty(void) const; /** - * @brief Print the contents of the Static Router Link State Advertisement and - * any Static Router Link Records present in the list. Quite verbose. + * @brief Print the contents of the Global Router Link State Advertisement and + * any Global Router Link Records present in the list. Quite verbose. */ void Print (std::ostream &os) const; /** @@ -335,7 +335,7 @@ public: * to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::GetRouterId () * @returns The Ipv4Address stored as the link state ID. */ Ipv4Address GetLinkStateId (void) const; @@ -344,7 +344,7 @@ public: * to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::GetRouterId () */ void SetLinkStateId (Ipv4Address addr); /** @@ -352,7 +352,7 @@ public: * set it to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::GetRouterId () * @returns The Ipv4Address stored as the advetising router. */ Ipv4Address GetAdvertisingRouter (void) const; @@ -361,7 +361,7 @@ public: * set it to the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::GetRouterId () */ void SetAdvertisingRouter (Ipv4Address rtr); /** @@ -384,7 +384,7 @@ private: * router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::GetRouterId () */ Ipv4Address m_linkStateId; /** @@ -392,13 +392,13 @@ private: * the router ID of the router making the advertisement. * * @see RoutingEnvironment::AllocateRouterId () - * @see StaticRouter::GetRouterId () + * @see GlobalRouter::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 * describe the kinds of links that are attached to a given node. We @@ -407,7 +407,7 @@ private: * m_linkRecords is an STL list container to hold the Link Records that have * been discovered and prepared for the advertisement. * - * @see StaticRouter::DiscoverLSAs () + * @see GlobalRouter::DiscoverLSAs () */ ListOfLinkRecords_t m_linkRecords; /** @@ -419,99 +419,99 @@ private: SPFStatus m_status; }; -std::ostream& operator<< (std::ostream& os, StaticRouterLSA& lsa); +std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa); /** - * @brief An interface aggregated to a node to provide static routing info + * @brief An interface aggregated to a node to provide global routing info * - * An interface aggregated to a node that provides static routing information + * An interface aggregated to a node that provides global routing information * to a global route manager. The presence of the interface indicates that * the node is a router. The interface is the mechanism by which the router * advertises its connections to neighboring routers. We're basically * allowing the route manager to query for link state advertisements. */ -class StaticRouter : public Object +class GlobalRouter : public Object { public: /** - * @brief The Interface ID of the Static Router interface. + * @brief The Interface ID of the Global Router interface. * * @see Object::QueryInterface () */ static const InterfaceId iid; /** - * @brief Create a Static Router class and aggregate its interface onto the + * @brief Create a Global Router class and aggregate its interface onto the * Node provided. * * @param node The existing Node onto which this router will be aggregated. */ - StaticRouter (Ptr node); + GlobalRouter (Ptr node); /** - * @brief Get the Router ID associated with this Static Router. + * @brief Get the Router ID associated with this Global Router. * * The Router IDs are allocated in the RoutingEnvironment -- one per Router, * starting at 0.0.0.1 and incrementing with each instantiation of a router. * * @see RoutingEnvironment::AllocateRouterId () - * @returns The Router ID associated with the Static Router. + * @returns The Router ID associated with the Global Router. */ Ipv4Address GetRouterId (void) const; /** * @brief Walk the connected channels, discover the adjacent routers and build - * the associated number of Static Router Link State Advertisements that + * the associated number of Global Router Link State Advertisements that * this router can export. * * This is a fairly expensive operation in that every time it is called * the current list of LSAs is built by walking connected point-to-point * channels and peeking into adjacent IPV4 stacks to get address information. - * This is done to allow for limited dymanics of the Static Routing + * This is done to allow for limited dymanics of the Global Routing * environment. By that we mean that you can discover new link state * advertisements after a network topology change by calling DiscoverLSAs * and then by reading those advertisements. * - * @see StaticRouterLSA - * @see StaticRouter::GetLSA () - * @returns The number of Static Router Link State Advertisements. + * @see GlobalRouterLSA + * @see GlobalRouter::GetLSA () + * @returns The number of Global Router Link State Advertisements. */ uint32_t DiscoverLSAs (void); /** - * @brief Get the Number of Static Router Link State Advertisements that this + * @brief Get the Number of Global Router Link State Advertisements that this * router can export. * * To get meaningful information you must have previously called DiscoverLSAs. * After you know how many LSAs are present in the router, you may call * GetLSA () to retrieve the actual advertisement. * - * @see StaticRouterLSA - * @see StaticRouter::DiscoverLSAs () - * @see StaticRouter::GetLSA () - * @returns The number of Static Router Link State Advertisements. + * @see GlobalRouterLSA + * @see GlobalRouter::DiscoverLSAs () + * @see GlobalRouter::GetLSA () + * @returns The number of Global Router Link State Advertisements. */ uint32_t GetNumLSAs (void) const; /** - * @brief Get a Static Router Link State Advertisements that this router has + * @brief Get a Global Router 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 Static Router Link - * State Advertisement into the requested StaticRouterLSA object. + * was done in GetNumLSAs. We just copy the indicated Global Router Link + * State Advertisement into the requested GlobalRouterLSA object. * - * You must call StaticRouter::GetNumLSAs before calling this method in + * You must call GlobalRouter::GetNumLSAs before calling this method in * order to discover the adjacent routers and build the advertisements. * GetNumLSAs will return the number of LSAs this router advertises. * The parameter n (requested LSA number) must be in the range 0 to * GetNumLSAs() - 1. * - * @see StaticRouterLSA - * @see StaticRouter::GetNumLSAs () + * @see GlobalRouterLSA + * @see GlobalRouter::GetNumLSAs () * @param n The index number of the LSA you want to read. - * @param lsa The StaticRouterLSA class to receive the LSA information. - * @returns The number of Static Router Link State Advertisements. + * @param lsa The GlobalRouterLSA class to receive the LSA information. + * @returns The number of Global Router Link State Advertisements. */ - bool GetLSA (uint32_t n, StaticRouterLSA &lsa) const; + bool GetLSA (uint32_t n, GlobalRouterLSA &lsa) const; protected: - virtual ~StaticRouter (); + virtual ~GlobalRouter (); void ClearLSAs (void); Ptr GetAdjacent(Ptr nd, Ptr ch) const; @@ -519,22 +519,22 @@ protected: Ptr m_node; - typedef std::list ListOfLSAs_t; + typedef std::list ListOfLSAs_t; ListOfLSAs_t m_LSAs; Ipv4Address m_routerId; private: /** - * @brief Static Router copy construction is disallowed. + * @brief Global Router copy construction is disallowed. */ - StaticRouter (StaticRouter& sr); + GlobalRouter (GlobalRouter& sr); /** - * @brief Static Router assignment operator is disallowed. + * @brief Global Router assignment operator is disallowed. */ - StaticRouter& operator= (StaticRouter& sr); + GlobalRouter& operator= (GlobalRouter& sr); }; } // namespace ns3 -#endif /* STATIC_ROUTER_H */ +#endif /* GLOBAL_ROUTER_H */ diff --git a/src/routing/routing-environment.cc b/src/routing/global/routing-environment.cc similarity index 85% rename from src/routing/routing-environment.cc rename to src/routing/global/routing-environment.cc index 33eeafbe5..ca075512c 100644 --- a/src/routing/routing-environment.cc +++ b/src/routing/global/routing-environment.cc @@ -26,13 +26,13 @@ NS_DEBUG_COMPONENT_DEFINE ("RoutingEnvironment"); namespace ns3 { namespace RoutingEnvironment { -BooleanDefaultValue g_doStaticRoutingDefaultValue ("DoStaticRouting", - "Enable global static routing", false); +BooleanDefaultValue g_doGlobalRoutingDefaultValue ("DoGlobalRouting", + "Enable global global routing", false); bool -StaticRoutingEnabled(void) +GlobalRoutingEnabled(void) { - return g_doStaticRoutingDefaultValue.GetValue(); + return g_doGlobalRoutingDefaultValue.GetValue(); } uint32_t diff --git a/src/routing/routing-environment.h b/src/routing/global/routing-environment.h similarity index 97% rename from src/routing/routing-environment.h rename to src/routing/global/routing-environment.h index b233c821a..5b305a0e3 100644 --- a/src/routing/routing-environment.h +++ b/src/routing/global/routing-environment.h @@ -23,14 +23,15 @@ namespace ns3 { namespace RoutingEnvironment { - + /** * @brief This function tests the value of the global default value * "DoStaticRouting". This approach puts everything in one compilation * unit, as opposed to explicitly testing the value of the underlying * static variable. */ -bool StaticRoutingEnabled(void); +bool GlobalRoutingEnabled(void); + /** * @brief Allocate a 32-bit router ID from monotonically increasing counter. */ diff --git a/src/routing/wscript b/src/routing/wscript deleted file mode 100644 index 8cdee7644..000000000 --- a/src/routing/wscript +++ /dev/null @@ -1,26 +0,0 @@ -## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- - -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-routing') - - -def build(bld): - module = bld.create_obj('cpp', 'shlib') - module.name = 'ns3-routing' - module.target = module.name - module.uselib_local = ['ns3-node'] - module.source = [ - 'routing-environment.cc', - 'static-router.cc', - 'static-route-manager.cc', - 'static-route-manager-impl.cc', - 'candidate-queue.cc', - ] - - headers = bld.create_obj('ns3header') - headers.source = [ - 'routing-environment.h', - 'static-router.h', - 'static-route-manager.h', - 'candidate-queue.h', - ] diff --git a/src/wscript b/src/wscript index 33032283b..9f6a7a2be 100644 --- a/src/wscript +++ b/src/wscript @@ -17,7 +17,7 @@ all_modules = [ 'internet-node', 'devices/p2p', 'applications', - 'routing', + 'routing/global', ] From ef462dbb5e4e03862b0b6ed64c853d74c5517e98 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jul 2007 14:09:02 -0700 Subject: [PATCH 83/92] copywrongs --- examples/simple-static-routing.cc | 190 ------------------ .../global/global-route-manager-impl.h | 1 + src/routing/global/global-router-interface.h | 1 - src/routing/global/routing-environment.cc | 2 - src/routing/global/routing-environment.h | 1 + 5 files changed, 2 insertions(+), 193 deletions(-) delete mode 100644 examples/simple-static-routing.cc diff --git a/examples/simple-static-routing.cc b/examples/simple-static-routing.cc deleted file mode 100644 index 9a7d66dcf..000000000 --- a/examples/simple-static-routing.cc +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- 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 - * - * ns-2 simple.tcl script (ported from ns-2) - * Originally authored by Steve McCanne, 12/19/1996 - */ - -// Port of ns-2/tcl/ex/simple.tcl to ns-3 -// -// Network topology -// -// n0 -// \ 5 Mb/s, 2ms -// \ 1.5Mb/s, 10ms -// n2 -------------------------n3 -// / -// / 5 Mb/s, 2ms -// n1 -// -// - all links are point-to-point links with indicated one-way BW/delay -// - CBR/UDP flows from n0 to n3, and from n3 to n1 -// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. -// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. -// (i.e., DataRate of 448,000 bps) -// - DropTail queues -// - Tracing of queues and packet receptions to file "simple-static-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/p2p-channel.h" -#include "ns3/p2p-net-device.h" -#include "ns3/mac-address.h" -#include "ns3/ipv4-address.h" -#include "ns3/ipv4.h" -#include "ns3/socket.h" -#include "ns3/ipv4-route.h" -#include "ns3/p2p-topology.h" -#include "ns3/onoff-application.h" -#include "ns3/routing-environment.h" -#include "ns3/static-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 ("StaticRouter"); - DebugComponentEnable ("StaticRouteManager"); -#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 Bind command tells the queue factory which class to - // instantiate, when the queue factory is invoked in the topology code - Bind ("Queue", "DropTailQueue"); - - // This bind tells the system to use global static routing. It results in - // a StaticRouter interface being aggregated to the internet nodes and the - // creation of a Route Manager component to oversee the route generation. - Bind ("DoStaticRouting", "true"); - - Bind ("OnOffApplicationPacketSize", "210"); - Bind ("OnOffApplicationDataRate", "448kb/s"); - - //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); - - // Here, we will explicitly create four nodes. In more sophisticated - // topologies, we could configure a node factory. - Ptr n0 = Create (); - Ptr n1 = Create (); - Ptr n2 = Create (); - Ptr n3 = 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 ( - n2, n3, DataRate (1500000), MilliSeconds (10)); - - // 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, n2, Ipv4Address ("10.1.3.1"), - n3, Ipv4Address ("10.1.3.2")); - - if (RoutingEnvironment::StaticRoutingEnabled ()) - { - StaticRouteManager::PopulateRoutingTables (); - } - - // Create the OnOff application to send UDP datagrams of size - // 210 bytes at a rate of 448 Kb/s - Ptr ooff = Create ( - n0, - Ipv4Address ("10.1.3.2"), - 80, - "Udp", - ConstantVariable (1), - ConstantVariable (0)); - // Start the application - ooff->Start (Seconds (1.0)); - ooff->Stop (Seconds (10.0)); - - // Create a similar flow from n3 to n1, starting at time 1.1 seconds - ooff = Create ( - n3, - Ipv4Address ("10.1.2.1"), - 80, - "Udp", - ConstantVariable (1), - ConstantVariable (0)); - // Start the application - ooff->Start (Seconds (1.1)); - ooff->Stop (Seconds (10.0)); - - // Configure tracing of all enqueue, dequeue, and NetDevice receive events - // Trace output will be sent to the simple-static-routing.tr file - AsciiTrace asciitrace ("simple-static-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 ("simple-static-routing.pcap"); - pcaptrace.TraceAllIp (); - - Simulator::Run (); - - Simulator::Destroy (); -} diff --git a/src/routing/global/global-route-manager-impl.h b/src/routing/global/global-route-manager-impl.h index a355cdfb0..ee9ad5b3b 100644 --- a/src/routing/global/global-route-manager-impl.h +++ b/src/routing/global/global-route-manager-impl.h @@ -13,6 +13,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef GLOBAL_ROUTE_MANAGER_IMPL_H #define GLOBAL_ROUTE_MANAGER_IMPL_H diff --git a/src/routing/global/global-router-interface.h b/src/routing/global/global-router-interface.h index fed346b49..c1d2f5bad 100644 --- a/src/routing/global/global-router-interface.h +++ b/src/routing/global/global-router-interface.h @@ -1,4 +1,3 @@ - /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * This program is free software; you can redistribute it and/or modify diff --git a/src/routing/global/routing-environment.cc b/src/routing/global/routing-environment.cc index ca075512c..cea926fc1 100644 --- a/src/routing/global/routing-environment.cc +++ b/src/routing/global/routing-environment.cc @@ -1,7 +1,5 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * All rights reserved. - * * 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; diff --git a/src/routing/global/routing-environment.h b/src/routing/global/routing-environment.h index 5b305a0e3..24c4450df 100644 --- a/src/routing/global/routing-environment.h +++ b/src/routing/global/routing-environment.h @@ -13,6 +13,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef ROUTING_ENVIRONMENT_H #define ROUTING_ENVIRONMENT_H From 510083f0ea4c8f7c527d7f04d58819785e33e57f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jul 2007 20:34:25 -0700 Subject: [PATCH 84/92] remove routing environment, move router interface creation to global-route-manager --- src/internet-node/internet-node.cc | 13 ----- .../global/global-route-manager-impl.cc | 25 +++++++++ .../global/global-route-manager-impl.h | 51 ++++++++++++++++--- src/routing/global/global-route-manager.cc | 20 +++++++- src/routing/global/global-route-manager.h | 14 ++++- src/routing/global/global-router-interface.cc | 2 +- src/routing/global/global-router-interface.h | 2 +- src/routing/global/routing-environment.cc | 44 ---------------- src/routing/global/routing-environment.h | 44 ---------------- src/routing/global/wscript | 24 +++++++++ 10 files changed, 127 insertions(+), 112 deletions(-) delete mode 100644 src/routing/global/routing-environment.cc delete mode 100644 src/routing/global/routing-environment.h create mode 100644 src/routing/global/wscript diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index c6eb92f43..f7519a6a2 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -23,8 +23,6 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/net-device.h" -#include "ns3/routing-environment.h" -#include "ns3/global-router-interface.h" #include "l3-demux.h" #include "ipv4-l4-demux.h" @@ -77,17 +75,6 @@ InternetNode::Construct (void) Object::AddInterface (udpImpl); Object::AddInterface (l3Demux); Object::AddInterface (ipv4L4Demux); -// -// If static routing has been enabled via bind(), all nodes will have the -// capacity to participate in the global static routing scheme. The presence -// of the StaticRouter interface tells the route manager that it needs to -// ask a given node about any link state records that it may want to advertise. -// - if (RoutingEnvironment::GlobalRoutingEnabled()) - { - Ptr globalRouter = Create (this); - Object::AddInterface (globalRouter); - } } TraceResolver * diff --git a/src/routing/global/global-route-manager-impl.cc b/src/routing/global/global-route-manager-impl.cc index df6ad3ad5..03578cb96 100644 --- a/src/routing/global/global-route-manager-impl.cc +++ b/src/routing/global/global-route-manager-impl.cc @@ -291,6 +291,31 @@ GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb) m_lsdb = lsdb; } +// +// In order to build the routing database, we need at least one of the nodes +// to participate as a router. Eventually we expect to provide a mechanism +// for selecting a subset of the nodes to participate; for now, we just make +// all nodes routers. We do this by walking the list of nodes in the system +// and aggregating a Global Router Interface to each of the nodes. +// + void +GlobalRouteManagerImpl::SelectRouterNodes () +{ + NS_DEBUG ("GlobalRouteManagerImpl::SelectRouterNodes ()"); + + typedef std::vector < Ptr >::iterator Iterator; + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; + NS_DEBUG ("GlobalRouteManagerImpl::SelectRouterNodes (): " + "Adding GlobalRouter interface to node " << + node->GetId ()); + + Ptr globalRouter = Create (node); + node->AddInterface (globalRouter); + } +} + // // In order to build the routing database, we need to walk the list of nodes // in the system and look for those that support the GlobalRouter interface. diff --git a/src/routing/global/global-route-manager-impl.h b/src/routing/global/global-route-manager-impl.h index ee9ad5b3b..87e64919b 100644 --- a/src/routing/global/global-route-manager-impl.h +++ b/src/routing/global/global-route-manager-impl.h @@ -71,6 +71,7 @@ public: VertexRouter, /**< Vertex representing a router in the topology */ VertexNetwork /**< Vertex representing a network in the topology */ }; + /** * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First * Vertex). @@ -85,6 +86,7 @@ public: * @see VertexType */ SPFVertex(); + /** * @brief Construct an initialized SPFVertex (Shortest Path First Vertex). * @@ -101,6 +103,7 @@ public: * @param lsa The Link State Advertisement used for finding initial values. */ SPFVertex(GlobalRouterLSA* lsa); + /** * @brief Destroy an SPFVertex (Shortest Path First Vertex). * @@ -109,6 +112,7 @@ public: * @see SPFVertex::SPFVertex () */ ~SPFVertex(); + /** * @brief Get the Vertex Type field of a SPFVertex object. * @@ -119,6 +123,7 @@ public: * @returns The VertexType of the current SPFVertex object. */ VertexType GetVertexType (void) const; + /** * @brief Set the Vertex Type field of a SPFVertex object. * @@ -129,6 +134,7 @@ public: * @param type The new VertexType for the current SPFVertex object. */ void SetVertexType (VertexType type); + /** * @brief Get the Vertex ID field of a SPFVertex object. * @@ -143,6 +149,7 @@ public: * @returns The Ipv4Address Vertex ID of the current SPFVertex object. */ Ipv4Address GetVertexId (void) const; + /** * @brief Set the Vertex ID field of a SPFVertex object. * @@ -158,6 +165,7 @@ public: * @param id The new Ipv4Address Vertex ID for the current SPFVertex object. */ void SetVertexId (Ipv4Address id); + /** * @brief Get the Global Router Link State Advertisement returned by the * Global Router represented by this SPFVertex during the route discovery @@ -170,6 +178,7 @@ public: * by this SPFVertex object. */ GlobalRouterLSA* GetLSA (void) const; + /** * @brief Set the Global Router Link State Advertisement returned by the * Global Router represented by this SPFVertex during the route discovery @@ -184,6 +193,7 @@ public: * @param lsa A pointer to the GlobalRouterLSA. */ void SetLSA (GlobalRouterLSA* lsa); + /** * @brief Get the distance from the root vertex to "this" SPFVertex object. * @@ -205,6 +215,7 @@ public: * @returns The distance, in hops, from the root SPFVertex to "this" SPFVertex. */ uint32_t GetDistanceFromRoot (void) const; + /** * @brief Set the distance from the root vertex to "this" SPFVertex object. * @@ -224,6 +235,7 @@ public: * SPFVertex. */ void SetDistanceFromRoot (uint32_t distance); + /** * @brief Get the interface ID that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. @@ -264,6 +276,7 @@ public: * or network represented by "this" SPFVertex. */ uint32_t GetOutgoingInterfaceId (void) const; + /** * @brief Set the interface ID that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. @@ -304,6 +317,7 @@ public: * network represented by "this" SPFVertex. */ void SetOutgoingInterfaceId (uint32_t id); + /** * @brief Get the IP address that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. @@ -345,6 +359,7 @@ public: * or network represented by "this" SPFVertex. */ Ipv4Address GetNextHop (void) const; + /** * @brief Set the IP address that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. @@ -386,6 +401,7 @@ public: * or network represented by "this" SPFVertex. */ void SetNextHop (Ipv4Address nextHop); + /** * @brief Get a pointer to the SPFVector that is the parent of "this" * SPFVertex. @@ -405,6 +421,7 @@ public: * in the SPF tree. */ SPFVertex* GetParent (void) const; + /** * @brief Set the pointer to the SPFVector that is the parent of "this" * SPFVertex. @@ -424,6 +441,7 @@ public: * SPFVertex* in the SPF tree. */ void SetParent (SPFVertex* parent); + /** * @brief Get the number of children of "this" SPFVertex. * @@ -444,6 +462,7 @@ public: * SPF tree). */ uint32_t GetNChildren (void) const; + /** * @brief Get a borrowed SPFVertex pointer to the specified child of "this" * SPFVertex. @@ -471,6 +490,7 @@ public: * SPF tree). */ SPFVertex* GetChild (uint32_t n) const; + /** * @brief Get a borrowed SPFVertex pointer to the specified child of "this" * SPFVertex. @@ -509,11 +529,13 @@ private: SPFVertex* m_parent; typedef std::list ListOfSPFVertex_t; ListOfSPFVertex_t m_children; + /** * @brief The SPFVertex copy construction is disallowed. There's no need for * it and a compiler provided shallow copy would be wrong. */ SPFVertex (SPFVertex& v); + /** * @brief The SPFVertex copy assignment operator is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. @@ -544,6 +566,7 @@ public: * this constructor. */ GlobalRouteManagerLSDB (); + /** * @brief Destroy an empty Global Router Manager Link State Database. * @@ -552,6 +575,7 @@ public: * release any remaining resources. */ ~GlobalRouteManagerLSDB (); + /** * @brief Insert an IP address / Link State Advertisement pair into the Link * State Database. @@ -566,6 +590,7 @@ public: * @param lsa A pointer to the Link State Advertisement for the router. */ void Insert(Ipv4Address addr, GlobalRouterLSA* lsa); + /** * @brief Look up the Link State Advertisement associated with the given * IP Address. @@ -581,6 +606,7 @@ public: * by the IP address addr. */ GlobalRouterLSA* GetLSA (Ipv4Address addr) const; + /** * @brief Set all LSA flags to an initialized state, for SPF computation * @@ -604,6 +630,7 @@ private: * need for it and a compiler provided shallow copy would be wrong. */ GlobalRouteManagerLSDB (GlobalRouteManagerLSDB& lsdb); + /** * @brief The SPFVertex copy assignment operator is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. @@ -627,25 +654,36 @@ class GlobalRouteManagerImpl public: GlobalRouteManagerImpl (); virtual ~GlobalRouteManagerImpl (); +/** + * @brief Select which nodes in the system are to be router nodes and + * aggregate the appropriate interfaces onto those nodes. + * + */ + virtual void SelectRouterNodes (); + /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. * */ - virtual void BuildGlobalRoutingDatabase(); + virtual void BuildGlobalRoutingDatabase (); + /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables */ - virtual void InitializeRoutes(); + virtual void InitializeRoutes (); + /** * @brief Debugging routine; allow client code to supply a pre-built LSDB */ void DebugUseLsdb (GlobalRouteManagerLSDB*); + /** * @brief Debugging routine; call the core SPF from the unit tests */ void DebugSPFCalculate (Ipv4Address root); + private: /** * @brief GlobalRouteManagerImpl copy construction is disallowed. @@ -653,6 +691,7 @@ private: * wrong. */ GlobalRouteManagerImpl (GlobalRouteManagerImpl& srmi); + /** * @brief Global Route Manager Implementation assignment operator is * disallowed. There's no need for it and a compiler provided shallow copy @@ -666,11 +705,11 @@ private: void SPFNext (SPFVertex*, CandidateQueue&); int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, GlobalRouterLinkRecord* l, uint32_t distance); - void SPFVertexAddParent(SPFVertex* v); - GlobalRouterLinkRecord* SPFGetNextLink(SPFVertex* v, SPFVertex* w, + void SPFVertexAddParent (SPFVertex* v); + GlobalRouterLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w, GlobalRouterLinkRecord* prev_link); - void SPFIntraAddRouter(SPFVertex* v); - uint32_t FindOutgoingInterfaceId(Ipv4Address a); + void SPFIntraAddRouter (SPFVertex* v); + uint32_t FindOutgoingInterfaceId (Ipv4Address a); }; } // namespace ns3 diff --git a/src/routing/global/global-route-manager.cc b/src/routing/global/global-route-manager.cc index ce9e891c0..c166da015 100644 --- a/src/routing/global/global-route-manager.cc +++ b/src/routing/global/global-route-manager.cc @@ -31,22 +31,38 @@ namespace ns3 { void GlobalRouteManager::PopulateRoutingTables () { + SelectRouterNodes (); BuildGlobalRoutingDatabase (); InitializeRoutes (); } + void +GlobalRouteManager::SelectRouterNodes () +{ + SimulationSingleton::Get ()-> + SelectRouterNodes (); +} + void GlobalRouteManager::BuildGlobalRoutingDatabase () { - return SimulationSingleton::Get ()-> + SimulationSingleton::Get ()-> BuildGlobalRoutingDatabase (); } void GlobalRouteManager::InitializeRoutes () { - return SimulationSingleton::Get ()-> + SimulationSingleton::Get ()-> InitializeRoutes (); } + uint32_t +GlobalRouteManager::AllocateRouterId () +{ + static uint32_t routerId = 0; + return routerId++; +} + + } // namespace ns3 diff --git a/src/routing/global/global-route-manager.h b/src/routing/global/global-route-manager.h index 3a695dcdf..b4f8d53b8 100644 --- a/src/routing/global/global-route-manager.h +++ b/src/routing/global/global-route-manager.h @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef STATIC_ROUTE_MANAGER_H +#ifndef GLOBAL_ROUTE_MANAGER_H #define GLOBAL_ROUTE_MANAGER_H namespace ns3 { @@ -45,7 +45,19 @@ public: */ static void PopulateRoutingTables (); +/** + * @brief Allocate a 32-bit router ID from monotonically increasing counter. + */ + static uint32_t AllocateRouterId (); + private: +/** + * @brief Select which nodes in the system are to be router nodes and + * aggregate the appropriate interfaces onto those nodes. + * + */ + static void SelectRouterNodes (); + /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. diff --git a/src/routing/global/global-router-interface.cc b/src/routing/global/global-router-interface.cc index ff1f06318..7df422ec3 100644 --- a/src/routing/global/global-router-interface.cc +++ b/src/routing/global/global-router-interface.cc @@ -323,7 +323,7 @@ GlobalRouter::GlobalRouter (Ptr node) { NS_DEBUG("GlobalRouter::GlobalRouter ()"); SetInterfaceId (GlobalRouter::iid); - m_routerId.Set(RoutingEnvironment::AllocateRouterId()); + m_routerId.Set(GlobalRouteManager::AllocateRouterId ()); } GlobalRouter::~GlobalRouter () diff --git a/src/routing/global/global-router-interface.h b/src/routing/global/global-router-interface.h index c1d2f5bad..d5ddbb3e2 100644 --- a/src/routing/global/global-router-interface.h +++ b/src/routing/global/global-router-interface.h @@ -24,7 +24,7 @@ #include "ns3/node.h" #include "ns3/channel.h" #include "ns3/ipv4-address.h" -#include "ns3/routing-environment.h" +#include "ns3/global-route-manager.h" namespace ns3 { diff --git a/src/routing/global/routing-environment.cc b/src/routing/global/routing-environment.cc deleted file mode 100644 index cea926fc1..000000000 --- a/src/routing/global/routing-environment.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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 - */ - -#include "ns3/debug.h" -#include "ns3/default-value.h" - -#include "routing-environment.h" - -NS_DEBUG_COMPONENT_DEFINE ("RoutingEnvironment"); - -namespace ns3 { -namespace RoutingEnvironment { - -BooleanDefaultValue g_doGlobalRoutingDefaultValue ("DoGlobalRouting", - "Enable global global routing", false); - - bool -GlobalRoutingEnabled(void) -{ - return g_doGlobalRoutingDefaultValue.GetValue(); -} - - uint32_t -AllocateRouterId(void) -{ - static uint32_t routerId = 0; - return routerId++; -} - -} // namespace RoutingEnvironment -} // namespace ns3 diff --git a/src/routing/global/routing-environment.h b/src/routing/global/routing-environment.h deleted file mode 100644 index 24c4450df..000000000 --- a/src/routing/global/routing-environment.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- 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 - */ - -#ifndef ROUTING_ENVIRONMENT_H -#define ROUTING_ENVIRONMENT_H - -#include -#include "ns3/object.h" -#include "ns3/ptr.h" -#include "ns3/ipv4-address.h" - -namespace ns3 { -namespace RoutingEnvironment { - -/** - * @brief This function tests the value of the global default value - * "DoStaticRouting". This approach puts everything in one compilation - * unit, as opposed to explicitly testing the value of the underlying - * static variable. - */ -bool GlobalRoutingEnabled(void); - -/** - * @brief Allocate a 32-bit router ID from monotonically increasing counter. - */ -uint32_t AllocateRouterId(void); - -} // namespace RoutingEnvironment -} // namespace ns3 - -#endif /* ROUTING_ENVIRONMENT_H */ diff --git a/src/routing/global/wscript b/src/routing/global/wscript new file mode 100644 index 000000000..130b633f2 --- /dev/null +++ b/src/routing/global/wscript @@ -0,0 +1,24 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def configure(conf): + conf.env.append_value('NS3_MODULES', 'ns3-routing') + + +def build(bld): + module = bld.create_obj('cpp', 'shlib') + module.name = 'ns3-routing' + module.target = module.name + module.uselib_local = ['ns3-node'] + module.source = [ + 'global-router-interface.cc', + 'global-route-manager.cc', + 'global-route-manager-impl.cc', + 'candidate-queue.cc', + ] + + headers = bld.create_obj('ns3header') + headers.source = [ + 'global-router-interface.h', + 'global-route-manager.h', + 'candidate-queue.h', + ] From b4698b7ccaff722497491241a009a9698b77dd45 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jul 2007 20:48:21 -0700 Subject: [PATCH 85/92] doxygen update (@internal) --- src/routing/global/candidate-queue.h | 202 ++++++++++-------- .../global/global-route-manager-impl.h | 32 ++- src/routing/global/global-route-manager.h | 3 + 3 files changed, 147 insertions(+), 90 deletions(-) diff --git a/src/routing/global/candidate-queue.h b/src/routing/global/candidate-queue.h index 1c01cb2ec..09b3a5c22 100644 --- a/src/routing/global/candidate-queue.h +++ b/src/routing/global/candidate-queue.h @@ -43,94 +43,117 @@ namespace ns3 { class CandidateQueue { public: - /** - * Create an empty SPF Candidate Queue. - * - * @see SPFVertex - */ +/** + * @brief Create an empty SPF Candidate Queue. + * @internal + * + * @see SPFVertex + */ CandidateQueue (); - /** - * Destroy an SPF Candidate Queue and release any resources held by the - * contents. - * - * @see SPFVertex - */ + +/** + * @internal Destroy an SPF Candidate Queue and release any resources held + * by the contents. + * @internal + * + * @see SPFVertex + */ virtual ~CandidateQueue (); - /** - * Empty the Candidate Queue and release all of the resources associated - * with the Shortest Path First Vertex pointers in the queue. - * - * @see SPFVertex - */ + +/** + * @brief Empty the Candidate Queue and release all of the resources + * associated with the Shortest Path First Vertex pointers in the queue. + * @internal + * + * @see SPFVertex + */ void Clear (void); - /** - * Push a Shortest Path First Vertex pointer onto the queue according to the - * priority scheme. - * - * On completion, the top of the queue will hold the Shortest Path First - * Vertex pointer that points to a vertex having lowest value of the field - * m_distanceFromRoot. Remaining vertices are ordered according to - * increasing distance. - * - * @see SPFVertex - * @param vNew The Shortest Path First Vertex to add to the queue. - */ + +/** + * @brief Push a Shortest Path First Vertex pointer onto the queue according + * to the priority scheme. + * @internal + * + * On completion, the top of the queue will hold the Shortest Path First + * Vertex pointer that points to a vertex having lowest value of the field + * m_distanceFromRoot. Remaining vertices are ordered according to + * increasing distance. + * + * @see SPFVertex + * @param vNew The Shortest Path First Vertex to add to the queue. + */ void Push (SPFVertex *vNew); - /** - * Pop the Shortest Path First Vertex pointer at the top of the queue. - * The caller is given the responsiblity for releasing the resources - * associated with the vertex. - * - * @see SPFVertex - * @see Top () - * @returns The Shortest Path First Vertex pointer at the top of the queue. - */ + +/** + * @brief Pop the Shortest Path First Vertex pointer at the top of the queue. + * @internal + * + * The caller is given the responsiblity for releasing the resources + * associated with the vertex. + * + * @see SPFVertex + * @see Top () + * @returns The Shortest Path First Vertex pointer at the top of the queue. + */ SPFVertex* Pop (void); - /** - * Return the Shortest Path First Vertex pointer at the top of the queue. - * This method does not pop the SPFVertex* off of the queue, it simply - * returns the pointer. - * - * @see SPFVertex - * @see Pop () - * @returns The Shortest Path First Vertex pointer at the top of the queue. - */ + +/** + * @brief Return the Shortest Path First Vertex pointer at the top of the + * queue. + * @internal + * + * This method does not pop the SPFVertex* off of the queue, it simply + * returns the pointer. + * + * @see SPFVertex + * @see Pop () + * @returns The Shortest Path First Vertex pointer at the top of the queue. + */ SPFVertex* Top (void) const; - /** - * Test the Candidate Queue to determine if it is empty. - * - * @returns True if the queue is empty, false otherwise. - */ + +/** + * @brief Test the Candidate Queue to determine if it is empty. + * @internal + * + * @returns True if the queue is empty, false otherwise. + */ bool Empty (void) const; - /** - * Return the number of Shortest Path First Vertex pointers presently - * stored in the Candidate Queue. - * - * @see SPFVertex - * @returns The number of SPFVertex* pointers in the Candidate Queue. - */ + +/** + * @brief Return the number of Shortest Path First Vertex pointers presently + * stored in the Candidate Queue. + * @internal + * + * @see SPFVertex + * @returns The number of SPFVertex* pointers in the Candidate Queue. + */ uint32_t Size (void) const; - /** - * Searches the Candidate Queue for a Shortest Path First Vertex pointer - * that points to a vertex having the given IP address. - * - * @see SPFVertex - * @param addr The IP address to search for. - * @returns The SPFVertex* pointer corresponding to the given IP address. - */ + +/** + * @brief Searches the Candidate Queue for a Shortest Path First Vertex + * pointer that points to a vertex having the given IP address. + * @internal + * + * @see SPFVertex + * @param addr The IP address to search for. + * @returns The SPFVertex* pointer corresponding to the given IP address. + */ SPFVertex* Find (const Ipv4Address addr) const; - /** - * Reorders the Candidate Queue according to the priority scheme. On - * completion, the top of the queue will hold the Shortest Path First - * Vertex pointer that points to a vertex having lowest value of the field - * m_distanceFromRoot. Remaining vertices are ordered according to - * increasing distance. - * - * This method is provided in case the values of m_distanceFromRoot change - * during the routing calculations. - * - * @see SPFVertex - */ + +/** + * @brief Reorders the Candidate Queue according to the priority scheme. + * @internal + * + * On completion, the top of the queue will hold the Shortest Path First + * Vertex pointer that points to a vertex having lowest value of the field + * m_distanceFromRoot. Remaining vertices are ordered according to + * increasing distance. + * + * This method is provided in case the values of m_distanceFromRoot change + * during the routing calculations. + * + * @see SPFVertex + */ void Reorder (void); protected: @@ -138,17 +161,18 @@ protected: CandidateList_t m_candidates; private: - /** - * Candidate Queue copy construction is disallowed (not implemented) to - * prevent the compiler from slipping in incorrect versions that don't - * properly deal with deep copies. - */ +/** + * Candidate Queue copy construction is disallowed (not implemented) to + * prevent the compiler from slipping in incorrect versions that don't + * properly deal with deep copies. + */ CandidateQueue (CandidateQueue& sr); - /** - * Candidate Queue assignment operator is disallowed (not implemented) to - * prevent the compiler from slipping in incorrect versions that don't - * properly deal with deep copies. - */ + +/** + * Candidate Queue assignment operator is disallowed (not implemented) to + * prevent the compiler from slipping in incorrect versions that don't + * properly deal with deep copies. + */ CandidateQueue& operator= (CandidateQueue& sr); }; diff --git a/src/routing/global/global-route-manager-impl.h b/src/routing/global/global-route-manager-impl.h index 87e64919b..7979cb4a2 100644 --- a/src/routing/global/global-route-manager-impl.h +++ b/src/routing/global/global-route-manager-impl.h @@ -61,6 +61,7 @@ class SPFVertex public: /** * @brief Enumeration of the possible types of SPFVertex objects. + * @internal * * Currently we use VertexRouter to identify objects that represent a router * in the simulation topology, and VertexNetwork to identify objects that @@ -75,6 +76,7 @@ public: /** * @brief Construct an empty ("uninitialized") SPFVertex (Shortest Path First * Vertex). + * @internal * * The Vertex Type is set to VertexUnknown, the Vertex ID is set to * 255.255.255.255, and the distance from root is set to infinity @@ -89,6 +91,7 @@ public: /** * @brief Construct an initialized SPFVertex (Shortest Path First Vertex). + * @internal * * The Vertex Type is initialized to VertexRouter and the Vertex ID is found * from the Link State ID of the Link State Advertisement (LSA) passed as a @@ -106,6 +109,7 @@ public: /** * @brief Destroy an SPFVertex (Shortest Path First Vertex). + * @internal * * The children vertices of the SPFVertex are recursively deleted. * @@ -115,6 +119,7 @@ public: /** * @brief Get the Vertex Type field of a SPFVertex object. + * @internal * * The Vertex Type describes the kind of simulation object a given SPFVertex * represents. @@ -126,6 +131,7 @@ public: /** * @brief Set the Vertex Type field of a SPFVertex object. + * @internal * * The Vertex Type describes the kind of simulation object a given SPFVertex * represents. @@ -137,6 +143,7 @@ public: /** * @brief Get the Vertex ID field of a SPFVertex object. + * @internal * * The Vertex ID uniquely identifies the simulation object a given SPFVertex * represents. Typically, this is the Router ID for SPFVertex objects @@ -152,6 +159,7 @@ public: /** * @brief Set the Vertex ID field of a SPFVertex object. + * @internal * * The Vertex ID uniquely identifies the simulation object a given SPFVertex * represents. Typically, this is the Router ID for SPFVertex objects @@ -170,6 +178,7 @@ public: * @brief Get the Global Router Link State Advertisement returned by the * Global Router represented by this SPFVertex during the route discovery * process. + * @internal * * @see GlobalRouter * @see GlobalRouterLSA @@ -183,6 +192,7 @@ public: * @brief Set the Global Router Link State Advertisement returned by the * Global Router represented by this SPFVertex during the route discovery * process. + * @internal * * @see SPFVertex::GetLSA () * @see GlobalRouter @@ -196,6 +206,7 @@ public: /** * @brief Get the distance from the root vertex to "this" SPFVertex object. + * @internal * * Each router in the simulation is associated with an SPFVertex object. When * calculating routes, each of these routers is, in turn, chosen as the "root" @@ -218,6 +229,7 @@ public: /** * @brief Set the distance from the root vertex to "this" SPFVertex object. + * @internal * * Each router in the simulation is associated with an SPFVertex object. When * calculating routes, each of these routers is, in turn, chosen as the "root" @@ -239,6 +251,7 @@ public: /** * @brief Get the interface ID that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -280,6 +293,7 @@ public: /** * @brief Set the interface ID that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -321,6 +335,7 @@ public: /** * @brief Get the IP address that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -363,6 +378,7 @@ public: /** * @brief Set the IP address that should be used to begin forwarding packets * from the root SPFVertex to "this" SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -405,6 +421,7 @@ public: /** * @brief Get a pointer to the SPFVector that is the parent of "this" * SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -425,6 +442,7 @@ public: /** * @brief Set the pointer to the SPFVector that is the parent of "this" * SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -444,6 +462,7 @@ public: /** * @brief Get the number of children of "this" SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -466,6 +485,7 @@ public: /** * @brief Get a borrowed SPFVertex pointer to the specified child of "this" * SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -494,6 +514,7 @@ public: /** * @brief Get a borrowed SPFVertex pointer to the specified child of "this" * SPFVertex. + * @internal * * Each router node in the simulation is associated with an SPFVertex object. * When calculating routes, each of these routers is, in turn, chosen as the @@ -561,6 +582,7 @@ class GlobalRouteManagerLSDB public: /** * @brief Construct an empty Global Router Manager Link State Database. + * @internal * * The database map composing the Link State Database is initialized in * this constructor. @@ -569,6 +591,7 @@ public: /** * @brief Destroy an empty Global Router Manager Link State Database. + * @internal * * The database map is walked and all of the Link State Advertisements stored * in the database are freed; then the database map itself is clear ()ed to @@ -579,6 +602,7 @@ public: /** * @brief Insert an IP address / Link State Advertisement pair into the Link * State Database. + * @internal * * The IPV4 address and the GlobalRouterLSA given as parameters are converted * to an STL pair and are inserted into the database map. @@ -594,6 +618,7 @@ public: /** * @brief Look up the Link State Advertisement associated with the given * IP Address. + * @internal * * The database map is searched for the given IPV4 address and corresponding * GlobalRouterLSA is returned. @@ -609,6 +634,7 @@ public: /** * @brief Set all LSA flags to an initialized state, for SPF computation + * @internal * * This function walks the database and resets the status flags of all of the * contained Link State Advertisements to LSA_SPF_NOT_EXPLORED. This is done @@ -657,6 +683,7 @@ public: /** * @brief Select which nodes in the system are to be router nodes and * aggregate the appropriate interfaces onto those nodes. + * @internal * */ virtual void SelectRouterNodes (); @@ -664,23 +691,26 @@ public: /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. - * + * @internal */ virtual void BuildGlobalRoutingDatabase (); /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables + * @internal */ virtual void InitializeRoutes (); /** * @brief Debugging routine; allow client code to supply a pre-built LSDB + * @internal */ void DebugUseLsdb (GlobalRouteManagerLSDB*); /** * @brief Debugging routine; call the core SPF from the unit tests + * @internal */ void DebugSPFCalculate (Ipv4Address root); diff --git a/src/routing/global/global-route-manager.h b/src/routing/global/global-route-manager.h index b4f8d53b8..7562da67d 100644 --- a/src/routing/global/global-route-manager.h +++ b/src/routing/global/global-route-manager.h @@ -54,6 +54,7 @@ private: /** * @brief Select which nodes in the system are to be router nodes and * aggregate the appropriate interfaces onto those nodes. + * @internal * */ static void SelectRouterNodes (); @@ -61,6 +62,7 @@ private: /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. + * @internal * */ static void BuildGlobalRoutingDatabase (); @@ -68,6 +70,7 @@ private: /** * @brief Compute routes using a Dijkstra SPF computation and populate * per-node forwarding tables + * @internal */ static void InitializeRoutes (); From d5086e07a099fd2acd4187813c0a08278eb9a6a2 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Fri, 27 Jul 2007 21:58:19 -0700 Subject: [PATCH 86/92] small readability change --- src/routing/global/global-router-interface.h | 47 ++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/routing/global/global-router-interface.h b/src/routing/global/global-router-interface.h index d5ddbb3e2..b2927d631 100644 --- a/src/routing/global/global-router-interface.h +++ b/src/routing/global/global-router-interface.h @@ -14,8 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef GLOBAL_ROUTER_H -#define GLOBAL_ROUTER_H +#ifndef GLOBAL_ROUTER_INTERFACE_H +#define GLOBAL_ROUTER_INTERFACE_H #include #include @@ -52,6 +52,7 @@ public: StubNetwork, /**< Record represents a leaf node network */ VirtualLink /**< Unused -- for future OSPF compatibility */ }; + /** * @brief Construct an empty ("uninitialized") Global Router Link Record. * @@ -60,6 +61,7 @@ public: * The metric is set to 0. */ GlobalRouterLinkRecord (); + /** * Construct an initialized Global Router Link Record. * @@ -76,12 +78,14 @@ public: Ipv4Address linkId, Ipv4Address linkData, uint32_t metric); + /** * @brief Destroy a Global Router Link Record. * * Currently does nothing. Here as a placeholder only. */ ~GlobalRouterLinkRecord (); + /** * Get the Link ID field of the Global Router Link Record. * @@ -94,6 +98,7 @@ public: * @returns The Ipv4Address corresponding to the Link ID field of the record. */ Ipv4Address GetLinkId(void) const; + /** * @brief Set the Link ID field of the Global Router Link Record. * @@ -106,6 +111,7 @@ public: * @param addr An Ipv4Address to store in the Link ID field of the record. */ void SetLinkId(Ipv4Address addr); + /** * @brief Get the Link Data field of the Global Router Link Record. * @@ -118,6 +124,7 @@ public: * @returns The Ipv4Address corresponding to the Link Data field of the record. */ Ipv4Address GetLinkData(void) const; + /** * @brief Set the Link Data field of the Global Router Link Record. * @@ -130,6 +137,7 @@ public: * @param addr An Ipv4Address to store in the Link Data field of the record. */ void SetLinkData(Ipv4Address addr); + /** * @brief Get the Link Type field of the Global Router Link Record. * @@ -140,6 +148,7 @@ public: * @returns The LinkType of the current Global Router Link Record. */ LinkType GetLinkType(void) const; + /** * @brief Set the Link Type field of the Global Router Link Record. * @@ -150,6 +159,7 @@ public: * @param linkType The new LinkType for the current Global Router Link Record. */ void SetLinkType(LinkType linkType); + /** * @brief Get the Metric Data field of the Global Router Link Record. * @@ -162,6 +172,7 @@ public: * @returns The metric field of the Global Router Link Record. */ uint32_t GetMetric(void) const; + /** * @brief Set the Metric Data field of the Global Router Link Record. * @@ -187,6 +198,7 @@ private: * For Type 3 link (Stub), set m_linkId to neighbor's IP address */ Ipv4Address m_linkId; + /** * m_linkId and m_linkData are defined by OSPF to have different meanings * depending on the type of link a given link records represents. They work @@ -197,11 +209,13 @@ private: * For Type 3 link (Stub), set m_linkData to mask */ Ipv4Address m_linkData; // for links to RouterLSA, + /** * The type of the Global Router Link Record. Defined in the OSPF spec. * We currently only use PointToPoint and StubNetwork types. */ LinkType m_linkType; + /** * The metric for a given link. * @@ -235,6 +249,7 @@ 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. * @@ -242,6 +257,7 @@ public: * list of Link State Records is empty. */ GlobalRouterLSA(); + /** * @brief Create an initialized Global Router Link State Advertisement. * @@ -253,6 +269,7 @@ public: */ GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId, Ipv4Address advertisingRtr); + /** * @brief Copy constructor for a Global Router Link State Advertisement. * @@ -262,12 +279,14 @@ public: * @param lsa The existing LSA to be used as the source. */ GlobalRouterLSA (GlobalRouterLSA& lsa); + /** * @brief Destroy an existing Global Router Link State Advertisement. * * Any Global Router Link Records present in the list are freed. */ ~GlobalRouterLSA(); + /** * @brief Assignment operator for a Global Router Link State Advertisement. * @@ -281,6 +300,7 @@ public: * @returns Reference to the overwritten LSA. */ GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa); + /** * @brief Copy any Global Router Link Records in a given Global Router Link * State Advertisement to the current LSA. @@ -292,6 +312,7 @@ public: * @param lsa The LSA to copy the Link Records from. */ void CopyLinkRecords (const GlobalRouterLSA& lsa); + /** * @brief Add a given Global Router Link Record to the LSA. * @@ -299,12 +320,14 @@ public: * @returns The number of link records in the list. */ uint32_t AddLinkRecord (GlobalRouterLinkRecord* lr); + /** * @brief Return the number of Global Router 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. * @@ -312,11 +335,13 @@ public: * @returns The number of link records in the list. */ GlobalRouterLinkRecord* 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. */ 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. @@ -324,11 +349,13 @@ public: * @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. */ void Print (std::ostream &os) const; + /** * @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. @@ -338,6 +365,7 @@ public: * @returns The Ipv4Address stored as the link state ID. */ Ipv4Address GetLinkStateId (void) const; + /** * @brief Set the Link State ID is defined by the OSPF spec. We always set it * to the router ID of the router making the advertisement. @@ -346,6 +374,7 @@ public: * @see GlobalRouter::GetRouterId () */ void SetLinkStateId (Ipv4Address addr); + /** * @brief Get the Advertising Router as defined by the OSPF spec. We always * set it to the router ID of the router making the advertisement. @@ -355,6 +384,7 @@ public: * @returns The Ipv4Address stored as the advetising router. */ Ipv4Address GetAdvertisingRouter (void) const; + /** * @brief Set the Advertising Router as defined by the OSPF spec. We always * set it to the router ID of the router making the advertisement. @@ -363,6 +393,7 @@ public: * @see GlobalRouter::GetRouterId () */ void SetAdvertisingRouter (Ipv4Address rtr); + /** * @brief Get the SPF status of the advertisement. * @@ -370,6 +401,7 @@ public: * @returns The SPFStatus of the LSA. */ SPFStatus GetStatus (void) const; + /** * @brief Set the SPF status of the advertisement * @@ -386,6 +418,7 @@ private: * @see GlobalRouter::GetRouterId () */ Ipv4Address m_linkStateId; + /** * The Advertising Router is defined by the OSPF spec. We always set it to * the router ID of the router making the advertisement. @@ -394,10 +427,12 @@ private: * @see GlobalRouter::GetRouterId () */ Ipv4Address m_advertisingRtr; + /** * A convenience typedef to avoid too much writers cramp. */ typedef std::list ListOfLinkRecords_t; + /** * Each Link State Advertisement contains a number of Link Records that * describe the kinds of links that are attached to a given node. We @@ -409,6 +444,7 @@ private: * @see GlobalRouter::DiscoverLSAs () */ ListOfLinkRecords_t m_linkRecords; + /** * 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 @@ -438,6 +474,7 @@ public: * @see Object::QueryInterface () */ static const InterfaceId iid; + /** * @brief Create a Global Router class and aggregate its interface onto the * Node provided. @@ -445,6 +482,7 @@ public: * @param node The existing Node onto which this router will be aggregated. */ GlobalRouter (Ptr node); + /** * @brief Get the Router ID associated with this Global Router. * @@ -455,6 +493,7 @@ public: * @returns The Router ID associated with the Global Router. */ Ipv4Address GetRouterId (void) const; + /** * @brief Walk the connected channels, discover the adjacent routers and build * the associated number of Global Router Link State Advertisements that @@ -473,6 +512,7 @@ public: * @returns The number of Global Router Link State Advertisements. */ uint32_t DiscoverLSAs (void); + /** * @brief Get the Number of Global Router Link State Advertisements that this * router can export. @@ -487,6 +527,7 @@ public: * @returns The number of Global Router Link State Advertisements. */ uint32_t GetNumLSAs (void) const; + /** * @brief Get a Global Router Link State Advertisements that this router has * said that it can export. @@ -536,4 +577,4 @@ private: } // namespace ns3 -#endif /* GLOBAL_ROUTER_H */ +#endif /* GLOBAL_ROUTER_INTERFACE_H */ From 833462a84e4c1b9725f4b0582e9ce8403dc7cbe0 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 30 Jul 2007 15:50:20 -0700 Subject: [PATCH 87/92] add simple-global-routing.cc --- examples/simple-global-routing.cc | 191 ++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 examples/simple-global-routing.cc diff --git a/examples/simple-global-routing.cc b/examples/simple-global-routing.cc new file mode 100644 index 000000000..54db2cd10 --- /dev/null +++ b/examples/simple-global-routing.cc @@ -0,0 +1,191 @@ +/* -*- 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 + * + * ns-2 simple.tcl script (ported from ns-2) + * Originally authored by Steve McCanne, 12/19/1996 + */ + +// Port of ns-2/tcl/ex/simple.tcl to ns-3 +// +// Network topology +// +// n0 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 -------------------------n3 +// / +// / 5 Mb/s, 2ms +// n1 +// +// - all links are point-to-point links with indicated one-way BW/delay +// - CBR/UDP flows from n0 to n3, and from n3 to n1 +// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "simple-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/p2p-channel.h" +#include "ns3/p2p-net-device.h" +#include "ns3/mac-address.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/ipv4-route.h" +#include "ns3/p2p-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 Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + Bind ("Queue", "DropTailQueue"); + + Bind ("OnOffApplicationPacketSize", "210"); + Bind ("OnOffApplicationDataRate", "448kb/s"); + + //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); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = 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 ( + n2, n3, DataRate (1500000), MilliSeconds (10)); + + // 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, n2, Ipv4Address ("10.1.3.1"), + n3, Ipv4Address ("10.1.3.2")); + + // 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, + Ipv4Address ("10.1.3.2"), + 80, + "Udp", + ConstantVariable (1), + ConstantVariable (0)); + // Start the application + ooff->Start (Seconds (1.0)); + ooff->Stop (Seconds (10.0)); + + // Create a similar flow from n3 to n1, starting at time 1.1 seconds + ooff = Create ( + n3, + Ipv4Address ("10.1.2.1"), + 80, + "Udp", + ConstantVariable (1), + ConstantVariable (0)); + // Start the application + ooff->Start (Seconds (1.1)); + ooff->Stop (Seconds (10.0)); + + // Here, finish off packet routing configuration + // This will likely set by some GlobalRouting object in the future + Ptr ipv4; + ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); + ipv4 = n3->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-global-routing.tr file + AsciiTrace asciitrace ("simple-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 ("simple-global-routing.pcap"); + pcaptrace.TraceAllIp (); + + Simulator::Run (); + + Simulator::Destroy (); +} From d3f1f2a3416a777a69c3a959f7267275143468c8 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 31 Jul 2007 09:45:13 -0700 Subject: [PATCH 88/92] remove manual routing commands from example script --- examples/simple-global-routing.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/examples/simple-global-routing.cc b/examples/simple-global-routing.cc index 54db2cd10..d5038f389 100644 --- a/examples/simple-global-routing.cc +++ b/examples/simple-global-routing.cc @@ -164,14 +164,6 @@ int main (int argc, char *argv[]) ooff->Start (Seconds (1.1)); ooff->Stop (Seconds (10.0)); - // Here, finish off packet routing configuration - // This will likely set by some GlobalRouting object in the future - Ptr ipv4; - ipv4 = n0->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); - ipv4 = n3->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); - // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-global-routing.tr file AsciiTrace asciitrace ("simple-global-routing.tr"); From 3378f0de1982b7a40899f67fdc06a45a0c81e6af Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 3 Aug 2007 08:23:23 -0700 Subject: [PATCH 89/92] remove Channel::GetType --- src/devices/p2p/p2p-channel.cc | 6 ------ src/devices/p2p/p2p-channel.h | 2 -- src/node/channel.h | 15 --------------- src/routing/global/global-router-interface.cc | 4 ---- 4 files changed, 27 deletions(-) diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/p2p/p2p-channel.cc index c91fe368c..cbc3eb805 100644 --- a/src/devices/p2p/p2p-channel.cc +++ b/src/devices/p2p/p2p-channel.cc @@ -171,12 +171,6 @@ PointToPointChannel::GetDevice (uint32_t i) const return m_link[i].m_src; } - Channel::ChannelType -PointToPointChannel::GetType (void) const -{ - return Channel::PointToPoint; -} - DataRate PointToPointChannel::GetDataRate (void) { diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/p2p/p2p-channel.h index 6bd849741..b534df915 100644 --- a/src/devices/p2p/p2p-channel.h +++ b/src/devices/p2p/p2p-channel.h @@ -94,8 +94,6 @@ public: virtual uint32_t GetNDevices (void) const; virtual Ptr GetDevice (uint32_t i) const; - virtual ChannelType GetType (void) const; - virtual DataRate GetDataRate (void); virtual Time GetDelay (void); diff --git a/src/node/channel.h b/src/node/channel.h index 0fa8d9656..5e72e1ae5 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -36,12 +36,6 @@ class Channel : public Object { public: static const InterfaceId iid; - enum ChannelType - { - Unknown = 0, - PointToPoint, - Multipoint - }; Channel (); Channel (std::string name); @@ -63,18 +57,9 @@ public: */ virtual Ptr GetDevice (uint32_t i) const = 0; - /** - * \returns the abstract type of this channel. Right now this is only - * PointToPoint (p2p) or Multipoint (Ethernet). - * - * This method must be implemented by subclasses. - */ - virtual ChannelType GetType (void) const = 0; - protected: virtual ~Channel (); std::string m_name; - ChannelType m_channelType; private: }; diff --git a/src/routing/global/global-router-interface.cc b/src/routing/global/global-router-interface.cc index 7df422ec3..24a84be06 100644 --- a/src/routing/global/global-router-interface.cc +++ b/src/routing/global/global-router-interface.cc @@ -534,10 +534,6 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const Ptr GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const { -// -// Double-check that channel agrees with device that it's a point-to-point -// - NS_ASSERT(ch->GetType () == Channel::PointToPoint); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT_MSG(nDevices == 2, From de77db64fcb7b8cb4fdcaab031d07ba30738b567 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 3 Aug 2007 09:29:57 -0700 Subject: [PATCH 90/92] interim --- examples/wscript | 8 +++++--- src/internet-node/wscript | 2 +- src/routing/global/wscript | 8 ++------ src/wscript | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/examples/wscript b/examples/wscript index 03ca1de60..0f15f23df 100644 --- a/examples/wscript +++ b/examples/wscript @@ -10,7 +10,9 @@ def build(bld): return obj obj = create_ns_prog('simple-global-routing', 'simple-global-routing.cc', - deps=['p2p', 'internet-node', 'routing']) - obj = create_ns_prog('simple-point-to-point', 'simple-point-to-point.cc', deps=['point-to-point', 'internet-node']) - obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc', deps=['csma-cd', 'internet-node']) + deps=['point-to-point', 'internet-node', 'global-routing']) + obj = create_ns_prog('simple-point-to-point', 'simple-point-to-point.cc', + deps=['point-to-point', 'internet-node']) + obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc', + deps=['csma-cd', 'internet-node']) diff --git a/src/internet-node/wscript b/src/internet-node/wscript index 10b730016..7a1b1c10e 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -5,7 +5,7 @@ def build(bld): obj = bld.create_obj('cpp', 'shlib') obj.name = 'ns3-internet-node' obj.target = obj.name - obj.uselib_local = ['ns3-node', 'ns3-applications', 'ns3-routing'] + obj.uselib_local = ['ns3-node', 'ns3-applications'] obj.source = [ 'internet-node.cc', 'l3-demux.cc', diff --git a/src/routing/global/wscript b/src/routing/global/wscript index 130b633f2..787ef9308 100644 --- a/src/routing/global/wscript +++ b/src/routing/global/wscript @@ -1,12 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -def configure(conf): - conf.env.append_value('NS3_MODULES', 'ns3-routing') - - def build(bld): module = bld.create_obj('cpp', 'shlib') - module.name = 'ns3-routing' + module.name = 'ns3-global-routing' module.target = module.name module.uselib_local = ['ns3-node'] module.source = [ @@ -15,10 +11,10 @@ def build(bld): 'global-route-manager-impl.cc', 'candidate-queue.cc', ] - headers = bld.create_obj('ns3header') headers.source = [ 'global-router-interface.h', 'global-route-manager.h', 'candidate-queue.h', ] + diff --git a/src/wscript b/src/wscript index 5f18019c9..aa57364be 100644 --- a/src/wscript +++ b/src/wscript @@ -18,7 +18,7 @@ all_modules = ( 'devices/point-to-point', 'devices/csma-cd', 'applications', - 'routing/global', + 'routing/global-routing', 'mobility', ) From 5de2add9c3488ba056b32c76e9ddbdd600c7abb4 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 3 Aug 2007 09:49:02 -0700 Subject: [PATCH 91/92] fix compilation problems and test --- examples/simple-global-routing.cc | 6 +++--- src/routing/{global => global-routing}/candidate-queue.cc | 0 src/routing/{global => global-routing}/candidate-queue.h | 0 .../{global => global-routing}/global-route-manager-impl.cc | 0 .../{global => global-routing}/global-route-manager-impl.h | 0 .../{global => global-routing}/global-route-manager.cc | 0 .../{global => global-routing}/global-route-manager.h | 0 .../{global => global-routing}/global-router-interface.cc | 0 .../{global => global-routing}/global-router-interface.h | 0 src/routing/{global => global-routing}/wscript | 0 10 files changed, 3 insertions(+), 3 deletions(-) rename src/routing/{global => global-routing}/candidate-queue.cc (100%) rename src/routing/{global => global-routing}/candidate-queue.h (100%) rename src/routing/{global => global-routing}/global-route-manager-impl.cc (100%) rename src/routing/{global => global-routing}/global-route-manager-impl.h (100%) rename src/routing/{global => global-routing}/global-route-manager.cc (100%) rename src/routing/{global => global-routing}/global-route-manager.h (100%) rename src/routing/{global => global-routing}/global-router-interface.cc (100%) rename src/routing/{global => global-routing}/global-router-interface.h (100%) rename src/routing/{global => global-routing}/wscript (100%) diff --git a/examples/simple-global-routing.cc b/examples/simple-global-routing.cc index d5038f389..2a005589a 100644 --- a/examples/simple-global-routing.cc +++ b/examples/simple-global-routing.cc @@ -56,14 +56,14 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/internet-node.h" -#include "ns3/p2p-channel.h" -#include "ns3/p2p-net-device.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" #include "ns3/mac-address.h" #include "ns3/ipv4-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" -#include "ns3/p2p-topology.h" +#include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/global-route-manager.h" diff --git a/src/routing/global/candidate-queue.cc b/src/routing/global-routing/candidate-queue.cc similarity index 100% rename from src/routing/global/candidate-queue.cc rename to src/routing/global-routing/candidate-queue.cc diff --git a/src/routing/global/candidate-queue.h b/src/routing/global-routing/candidate-queue.h similarity index 100% rename from src/routing/global/candidate-queue.h rename to src/routing/global-routing/candidate-queue.h diff --git a/src/routing/global/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc similarity index 100% rename from src/routing/global/global-route-manager-impl.cc rename to src/routing/global-routing/global-route-manager-impl.cc diff --git a/src/routing/global/global-route-manager-impl.h b/src/routing/global-routing/global-route-manager-impl.h similarity index 100% rename from src/routing/global/global-route-manager-impl.h rename to src/routing/global-routing/global-route-manager-impl.h diff --git a/src/routing/global/global-route-manager.cc b/src/routing/global-routing/global-route-manager.cc similarity index 100% rename from src/routing/global/global-route-manager.cc rename to src/routing/global-routing/global-route-manager.cc diff --git a/src/routing/global/global-route-manager.h b/src/routing/global-routing/global-route-manager.h similarity index 100% rename from src/routing/global/global-route-manager.h rename to src/routing/global-routing/global-route-manager.h diff --git a/src/routing/global/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc similarity index 100% rename from src/routing/global/global-router-interface.cc rename to src/routing/global-routing/global-router-interface.cc diff --git a/src/routing/global/global-router-interface.h b/src/routing/global-routing/global-router-interface.h similarity index 100% rename from src/routing/global/global-router-interface.h rename to src/routing/global-routing/global-router-interface.h diff --git a/src/routing/global/wscript b/src/routing/global-routing/wscript similarity index 100% rename from src/routing/global/wscript rename to src/routing/global-routing/wscript From b080a339a6b5efd3589a9e02615209464141db62 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 3 Aug 2007 21:39:19 -0700 Subject: [PATCH 92/92] remove README.routing file --- README.routing | 133 ------------------------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 README.routing diff --git a/README.routing b/README.routing deleted file mode 100644 index f787371be..000000000 --- a/README.routing +++ /dev/null @@ -1,133 +0,0 @@ -Static routing overview ---------------- - -This is brief documentation of a proposal to add global static routing to ns-3 -Static routing is used to automatically populate the forwarding tables -in a topology without running a dynamic routing protocol or asking -the user to manually enter routes themselves. - -The previously announced roadmap: -* July 15: Support IPv4 static routing with PointToPoint numbered links -* August 15: Extend IPv4 static routing to Ethernet (shared links), -add static multicast forwarding over Ethernet and PointToPoint -* Sept 15: Add static multicast forwarding over wireless interface - -This code would provide the first bullet above. - -Note: This is orthogonal to Gustavo's OLSR code, but could also exist -as a static routing protocol in the framework that he proposes; right now, -this code just writes directly into the existing Ipv4 routing API - -1. Code: - -- source code is in a routing module src/routing/ -- an example script is in examples/simple-static-routing.cc. It produces the -same output as simple-p2p.cc -- StaticRouteManager is added in the run-tests unit tests - -2. API: - -The public API is very minimal. - -- user scripts include the following: -#include "ns3/routing-environment.h" -#include "ns3/static-route-manager.h" - -- A single default value (default false) enables static routing - Bind ("DoStaticRouting", "true"); - -- The call to build the static routes themselves is a single method, -called after the topology has been addressed: - - if (RoutingEnvironment::StaticRoutingEnabled ()) - { - StaticRouteManager::PopulateRoutingTables (); - } - -3. Approach: - -A singleton object (StaticRouteManager) is responsible for populating -the static routes on each node, using the public Ipv4 API of that node. -It queries each node in the topology for a "staticRouter" interface. -If found, it uses the API of that interface to obtain a "link state -advertisement (LSA)" for the router. Link State Advertisements -are used in OSPF routing, and we follow their formatting. - -The StaticRouteManager populates a link state database with LSAs -gathered from the entire topology. Then, for each router in the topology, -the StaticRouteManager executes the OSPF shortest path first (SPF) -computation on the database, and populates the routing tables on each -node. - -The quagga (http://www.quagga.net) OSPF implementation was used as the -basis for the routing computation logic. -One benefit of following an existing OSPF SPF implementation is that -OSPF already has defined link state advertisements for all common -types of network links: -- point-to-point (serial links) -- point-to-multipoint (Frame Relay, ad hoc wireless) -- non-broadcast multiple access (ATM) -- broadcast (Ethernet) -Therefore, we think that enabling these other link types will be more -straightforward now that the underlying OSPF SPF framework is in place. - -Presently, we can handle IPv4 point-to-point, numbered links, and we do -not do equal-cost multipath. We also do not allow for non-unit-cost -links, although it should be trivially extensible to do so. - -The support for this relies on the node object supporting a StaticRouter -interface. This can be manually added to each node, or alternatively, -we have modified InternetNode::Construct() as follows: - if (RoutingEnvironment::StaticRoutingEnabled()) - { - Ptr staticRouter = Create (this); - Object::AddInterface (staticRouter); - } - -4. Some open issues - -- trying to enable this with the default value framework raised some -questions. Access to an underlying default variable is required -across compilation units. The routing environment was designed -to put everything in one compilation unit. Whether this is good -practice or just overly paranoid is for further discussion. An -alternative may be to define some kind of test with the same default -value system such as -if (IsBound("DoStaticRouting", "true")) ... - -- along the same lines, Bind() is kind of an oddball in the present -system. We do NodeList::Begin (), Simulator::Run (), -CommandLine::Parse (); but simply Bind (). This isn't very consistent. - -(note: the choice of "bind()" was due to ns-2's methods of the same name) - -Perhaps it would be better to do something like, - -Configurator::Set ("DoStaticRouting", "true"); - -if (Configurator::IsEqual ("DoStaticRouting", "true")) - { - } - -- how transparent vs. explicit the enabling of static routing should be -(e.g., if we have a higher layer Inversion-of-Control framework, do these -static routing functions exist in some kind of Init() or Presimulate() -method?). Presently, it is explicitly enabled. - -- whether to add some kind of flag in an InternetNode that is equivalent -to /proc/sys/net/ipv4/ip_forward , so that every InternetNode is not -necessarily a router. - -- whether to continue to write to the existing IPv4 API or load a static -router component into the node such as Gustavo's OLSR code does - -- what to name this. Gustavo had suggestions to pick another name for -the StaticRouteManager. One possibility I would be fine with is to call -it GlobalRouteManager (although I would still argue it adds static routes -into the nodes in any case). - -- this method probably belongs in the Ipv4 (find InterfaceId corresponding -to the provided address) - uint32_t -StaticRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a) -