From 1e42d9bae7290bc88be3d253c716521fed946633 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 18 Nov 2008 15:46:46 -0800 Subject: [PATCH 01/14] add bridged routing example --- examples/csma-bridge-one-hop.cc | 209 ++++++++++++++++++++++++++++++++ examples/wscript | 4 + 2 files changed, 213 insertions(+) create mode 100644 examples/csma-bridge-one-hop.cc diff --git a/examples/csma-bridge-one-hop.cc b/examples/csma-bridge-one-hop.cc new file mode 100644 index 000000000..a0e5acc21 --- /dev/null +++ b/examples/csma-bridge-one-hop.cc @@ -0,0 +1,209 @@ +/* -*- 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 + */ + +// Network topology +// +// n0 n1 +// | | +// ----------- +// | bridge1 | +// ----------- +// | +// n2 +// | +// ----------- +// | bridge2 | +// ----------- +// | | +// n3 n4 +// +// This example shows two broadcast domains, each interconnected by a bridge +// with a router node (n2) interconnecting the layer-2 broadcast domains +// +// It is meant to mirror somewhat the csma-bridge example but adds another +// bridged link separated by a router. +// +// - CBR/UDP flows from n0 to n1 and from n3 to n0 +// - DropTail queues +// - Global static routing +// - Tracing of queues and packet receptions to file "csma-bridge-one-hop.tr" + +#include +#include + +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/core-module.h" +#include "ns3/helper-module.h" +#include "ns3/bridge-module.h" +#include "ns3/global-route-manager.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("CsmaBridgeOneHopExample"); + +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 + LogComponentEnable ("CsmaBridgeOneHopExample", LOG_LEVEL_INFO); +#endif + + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // + // Allow the user to override any of the defaults and the above Bind() at + // run-time, via command-line arguments + // + CommandLine cmd; + cmd.Parse (argc, argv); + + // + // Explicitly create the nodes required by the topology (shown above). + // + NS_LOG_INFO ("Create nodes."); + + Ptr n0 = CreateObject (); + Ptr n1 = CreateObject (); + Ptr n2 = CreateObject (); + Ptr n3 = CreateObject (); + Ptr n4 = CreateObject (); + + Ptr bridge1 = CreateObject (); + Ptr bridge2 = CreateObject (); + + NS_LOG_INFO ("Build Topology"); + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); + csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + + // Create the csma links, from each terminal to the bridge + // This will create six network devices; we'll keep track separately + // of the devices on and off the bridge respectively, for later configuration + NetDeviceContainer topLanDevices; + NetDeviceContainer topBridgeDevices; + + // It is easier to iterate the nodes in C++ if we put them into a container + NodeContainer topLan (n2, n0, n1); + + for (int i = 0; i < 3; i++) + { + NetDeviceContainer link = csma.Install (NodeContainer (topLan.Get (i), bridge1)); + topLanDevices.Add (link.Get (0)); + topBridgeDevices.Add (link.Get (1)); + } + + // Create the bridge netdevice, which will do the packet switching + BridgeHelper bridge; + bridge.Install (bridge1, topBridgeDevices); + + // Add internet stack to the topLan nodes + InternetStackHelper internet; + internet.Install (topLan); + + // Repeat for bottom bridged LAN + NetDeviceContainer bottomLanDevices; + NetDeviceContainer bottomBridgeDevices; + NodeContainer bottomLan (n2, n3, n4); + for (int i = 0; i < 3; i++) + { + NetDeviceContainer link = csma.Install (NodeContainer (bottomLan.Get (i), bridge2)); + bottomLanDevices.Add (link.Get (0)); + bottomBridgeDevices.Add (link.Get (1)); + } + bridge.Install (bridge2, bottomBridgeDevices); + internet.Install (NodeContainer (n3, n4)); + + + // We've got the "hardware" in place. Now we need to add IP addresses. + // + NS_LOG_INFO ("Assign IP Addresses."); + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + ipv4.Assign (topLanDevices); + ipv4.SetBase ("10.1.2.0", "255.255.255.0"); + ipv4.Assign (bottomLanDevices); + + // Create router nodes, initialize routing database and set up the routing + // tables in the nodes. + GlobalRouteManager::PopulateRoutingTables (); + + // + // Create an OnOff application to send UDP datagrams from node zero to node 1. + // + NS_LOG_INFO ("Create Applications."); + uint16_t port = 9; // Discard port (RFC 863) + + OnOffHelper onoff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address ("10.1.1.3"), port))); + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + ApplicationContainer app = onoff.Install (n0); + // Start the application + app.Start (Seconds (1.0)); + app.Stop (Seconds (10.0)); + + // Create an optional packet sink to receive these packets + PacketSinkHelper sink ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + sink.Install (n1); + + // + // Create a similar flow from n3 to n0, starting at time 1.1 seconds + // + onoff.SetAttribute ("Remote", + AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.2"), port))); + ApplicationContainer app2 = onoff.Install (n3); + + sink.Install (n0); + + app2.Start (Seconds (1.1)); + app2.Stop (Seconds (10.0)); + + // + // Configure tracing of all enqueue, dequeue, and NetDevice receive events. + // Trace output will be sent to the file "csma-bridge-one-hop.tr" + // + NS_LOG_INFO ("Configure Tracing."); + std::ofstream ascii; + ascii.open ("csma-bridge-one-hop.tr"); + CsmaHelper::EnableAsciiAll (ascii); + + // + // Also configure some tcpdump traces; each interface will be traced. + // The output files will be named: + // csma-bridge.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + // + CsmaHelper::EnablePcapAll ("csma-bridge-one-hop"); + + // + // Now, do the actual simulation. + // + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); +} diff --git a/examples/wscript b/examples/wscript index 189c8d740..7f1318574 100644 --- a/examples/wscript +++ b/examples/wscript @@ -28,6 +28,10 @@ def build(bld): ['bridge', 'csma', 'internet-stack']) obj.source = 'csma-bridge.cc' + obj = bld.create_ns3_program('csma-bridge-one-hop', + ['bridge', 'csma', 'internet-stack']) + obj.source = 'csma-bridge-one-hop.cc' + obj = bld.create_ns3_program('udp-echo', ['csma', 'internet-stack']) obj.source = 'udp-echo.cc' From 179ef212093ccb9ca29b94d60d161272501ed9b6 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 18 Nov 2008 16:23:31 -0800 Subject: [PATCH 02/14] implement IsBridged for net devices --- src/devices/bridge/bridge-net-device.cc | 6 ++++++ src/devices/bridge/bridge-net-device.h | 1 + src/devices/csma/csma-net-device.cc | 7 +++++++ src/devices/csma/csma-net-device.h | 6 ++++++ src/devices/emu/emu-net-device.cc | 6 ++++++ src/devices/emu/emu-net-device.h | 6 ++++++ src/devices/point-to-point/point-to-point-net-device.cc | 6 ++++++ src/devices/point-to-point/point-to-point-net-device.h | 1 + src/devices/wifi/wifi-net-device.cc | 5 +++++ src/devices/wifi/wifi-net-device.h | 1 + src/node/net-device.h | 9 +++++++++ src/node/simple-net-device.cc | 7 +++++++ src/node/simple-net-device.h | 1 + 13 files changed, 62 insertions(+) diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index e85ab5f78..a042cd0f3 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -305,6 +305,12 @@ BridgeNetDevice::IsPointToPoint (void) const return false; } +bool +BridgeNetDevice::IsBridge (void) const +{ + return true; +} + bool BridgeNetDevice::Send (Ptr packet, const Address& dest, uint16_t protocolNumber) diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index d8532c4b9..2d2d0a6d0 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -98,6 +98,7 @@ public: virtual bool IsMulticast (void) const; virtual Address GetMulticast (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; + virtual bool IsBridge (void) const; virtual bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 5e6766518..11e9ee49d 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -832,6 +832,13 @@ CsmaNetDevice::GetMulticast (Ipv4Address multicastGroup) const bool CsmaNetDevice::IsPointToPoint (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return false; +} + + bool +CsmaNetDevice::IsBridge (void) const { NS_LOG_FUNCTION_NOARGS (); return false; diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 59b7d59a7..e77b5e02e 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -350,6 +350,12 @@ public: */ virtual bool IsPointToPoint (void) const; + /** + * Is this a bridge? + * \returns false. + */ + virtual bool IsBridge (void) const; + /** * Start sending a packet down the channel. */ diff --git a/src/devices/emu/emu-net-device.cc b/src/devices/emu/emu-net-device.cc index 6e81f4bc1..95c620c48 100644 --- a/src/devices/emu/emu-net-device.cc +++ b/src/devices/emu/emu-net-device.cc @@ -882,6 +882,12 @@ EmuNetDevice::IsPointToPoint (void) const return false; } +bool +EmuNetDevice::IsBridge (void) const +{ + return false; +} + void EmuNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) { diff --git a/src/devices/emu/emu-net-device.h b/src/devices/emu/emu-net-device.h index a2a04277f..b2147f3b8 100644 --- a/src/devices/emu/emu-net-device.h +++ b/src/devices/emu/emu-net-device.h @@ -165,6 +165,12 @@ public: */ virtual bool IsPointToPoint (void) const; + /** + * Is this a bridge? + * \returns false. + */ + virtual bool IsBridge (void) const; + virtual bool Send(Ptr packet, const Address &dest, uint16_t protocolNumber); virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 9d3628663..60972851a 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -391,6 +391,12 @@ PointToPointNetDevice::IsPointToPoint (void) const return true; } + bool +PointToPointNetDevice::IsBridge (void) const +{ + return false; +} + bool PointToPointNetDevice::Send( Ptr packet, diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index c57241573..f8ce2e3ae 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -252,6 +252,7 @@ public: virtual Address GetMulticast (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; + virtual bool IsBridge (void) const; virtual bool Send(Ptr packet, const Address &dest, uint16_t protocolNumber); virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index d9d04207b..c6c62bba8 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -267,6 +267,11 @@ WifiNetDevice::IsPointToPoint (void) const return false; } bool +WifiNetDevice::IsBridge (void) const +{ + return false; +} +bool WifiNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) { NS_ASSERT (Mac48Address::IsMatchingType (dest)); diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 818b550c3..1f7396a32 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -94,6 +94,7 @@ public: virtual bool IsMulticast (void) const; virtual Address GetMulticast (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; + virtual bool IsBridge (void) const; virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; virtual void SetNode (Ptr node); diff --git a/src/node/net-device.h b/src/node/net-device.h index 490f3225e..ced6c9dff 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -184,6 +184,15 @@ public: virtual Address GetMulticast (Ipv6Address addr) const = 0; /** + * \brief Return true if the net device is acting as a bridge. + * + * \return value of m_isBridge flag + */ + virtual bool IsBridge (void) const = 0; + + /** + * \brief Return true if the net device is on a point-to-point link. + * * \return value of m_isPointToPoint flag */ virtual bool IsPointToPoint (void) const = 0; diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index 970ca74db..d13bd53fe 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -163,6 +163,13 @@ SimpleNetDevice::IsPointToPoint (void) const { return false; } + +bool +SimpleNetDevice::IsBridge (void) const +{ + return false; +} + bool SimpleNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) { diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index 2dac82c96..1e1f15323 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -61,6 +61,7 @@ public: virtual bool IsMulticast (void) const; virtual Address GetMulticast (Ipv4Address multicastGroup) const; virtual bool IsPointToPoint (void) const; + virtual bool IsBridge (void) const; virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); virtual bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); virtual Ptr GetNode (void) const; From 23b216a600fbfcc68b55f971f3be397b7af79fd1 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 19 Nov 2008 15:54:12 -0800 Subject: [PATCH 03/14] convince global routing not to crash in the presence of bridges --- examples/csma-bridge-one-hop.cc | 49 ++- src/core/abort.h | 10 + src/devices/bridge/bridge-net-device.cc | 45 ++- src/devices/bridge/bridge-net-device.h | 4 + src/helper/bridge-helper.cc | 28 +- src/helper/node-container.cc | 11 + src/helper/node-container.h | 2 + .../global-route-manager-impl.cc | 18 +- .../global-route-manager-impl.h | 9 + .../global-routing/global-route-manager.cc | 26 +- .../global-routing/global-route-manager.h | 26 +- .../global-routing/global-router-interface.cc | 298 ++++++++++++++---- .../global-routing/global-router-interface.h | 2 +- 13 files changed, 444 insertions(+), 84 deletions(-) diff --git a/examples/csma-bridge-one-hop.cc b/examples/csma-bridge-one-hop.cc index a0e5acc21..fac58fa4f 100644 --- a/examples/csma-bridge-one-hop.cc +++ b/examples/csma-bridge-one-hop.cc @@ -16,21 +16,46 @@ // Network topology // +// bridge1 The node named bridge1 (node 5 in the nodelist) +// ------------------ has three CMSA net devices that are bridged +// CSMA CSMA CSMA together using a BridgeNetDevice. +// | | | +// | | | The bridge node talks over three CSMA channels +// | | | +// CSMA CSMA CSMA to three other CSMA net devices +// ---- ---- ---- +// n0 n1 n2 Node two acts as a router and talks to another +// ---- bridge that connects the remaining nodes. +// CSMA +// | +// n3 n4 | +// ---- ---- | +// CSMA CSMA | +// | | | +// | | | +// | | | +// CSMA CSMA CSMA The node named bridge2 (node 6 in the nodelist) +// ------------------ has three CMSA net devices that are bridged +// bridge2 together using a BridgeNetDevice. +// +// Or, more abstractly, recognizing that bridge 1 and bridge 2 are nodes +// with three net devices: +// // n0 n1 // | | // ----------- -// | bridge1 | +// | bridge1 | <- n5 // ----------- // | -// n2 +// router <- n2 // | // ----------- -// | bridge2 | +// | bridge2 | <- n6 // ----------- // | | // n3 n4 // -// This example shows two broadcast domains, each interconnected by a bridge +// So, this example shows two broadcast domains, each interconnected by a bridge // with a router node (n2) interconnecting the layer-2 broadcast domains // // It is meant to mirror somewhat the csma-bridge example but adds another @@ -108,12 +133,17 @@ main (int argc, char *argv[]) for (int i = 0; i < 3; i++) { + // install a csma channel between the ith toplan node and the bridge node NetDeviceContainer link = csma.Install (NodeContainer (topLan.Get (i), bridge1)); topLanDevices.Add (link.Get (0)); topBridgeDevices.Add (link.Get (1)); } - // Create the bridge netdevice, which will do the packet switching + // + // Now, Create the bridge netdevice, which will do the packet switching. The + // bridge lives on the node bridge1 and bridges together the topBridgeDevices + // which are the three CSMA net devices on the node in the diagram above. + // BridgeHelper bridge; bridge.Install (bridge1, topBridgeDevices); @@ -132,11 +162,11 @@ main (int argc, char *argv[]) bottomBridgeDevices.Add (link.Get (1)); } bridge.Install (bridge2, bottomBridgeDevices); + + // Add internet stack to the bottomLan nodes internet.Install (NodeContainer (n3, n4)); - // We've got the "hardware" in place. Now we need to add IP addresses. - // NS_LOG_INFO ("Assign IP Addresses."); Ipv4AddressHelper ipv4; ipv4.SetBase ("10.1.1.0", "255.255.255.0"); @@ -144,9 +174,12 @@ main (int argc, char *argv[]) ipv4.SetBase ("10.1.2.0", "255.255.255.0"); ipv4.Assign (bottomLanDevices); + // // Create router nodes, initialize routing database and set up the routing // tables in the nodes. - GlobalRouteManager::PopulateRoutingTables (); + // + NodeContainer routerNodes (n0, n1, n2, n3, n4); + GlobalRouteManager::PopulateRoutingTables (routerNodes); // // Create an OnOff application to send UDP datagrams from node zero to node 1. diff --git a/src/core/abort.h b/src/core/abort.h index 306058df3..6f52e684c 100644 --- a/src/core/abort.h +++ b/src/core/abort.h @@ -21,6 +21,16 @@ #include "fatal-error.h" +#define NS_ABORT_MSG(msg) \ + do { \ + std::cerr << "file=" << __FILE__ << \ + ", line=" << __LINE__ << ", abort, msg=\"" << \ + msg << "\"" << std::endl; \ + int *a = 0; \ + *a = 0; \ + } while (false) + + #define NS_ABORT_IF(cond) \ do { \ if (cond) \ diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index a042cd0f3..413540157 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -57,6 +57,7 @@ BridgeNetDevice::BridgeNetDevice () m_ifIndex (0), m_mtu (0xffff) { + NS_LOG_FUNCTION_NOARGS (); m_channel = CreateObject (); } @@ -100,6 +101,7 @@ void BridgeNetDevice::ForwardUnicast (Ptr incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst) { + NS_LOG_FUNCTION_NOARGS (); NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName () << ", packet=" << packet << ", protocol="< incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst) { + NS_LOG_FUNCTION_NOARGS (); NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName () << ", packet=" << packet << ", protocol="< incomingPort, Ptr port) { + NS_LOG_FUNCTION_NOARGS (); if (m_enableLearning) { LearnedState &state = m_learnState[source]; @@ -164,6 +168,7 @@ void BridgeNetDevice::Learn (Mac48Address source, Ptr port) Ptr BridgeNetDevice::GetLearnedState (Mac48Address source) { + NS_LOG_FUNCTION_NOARGS (); if (m_enableLearning) { Time now = Simulator::Now (); @@ -185,9 +190,25 @@ Ptr BridgeNetDevice::GetLearnedState (Mac48Address source) return NULL; } +uint32_t +BridgeNetDevice::GetNBridgePorts (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_ports.size (); +} + + +Ptr +BridgeNetDevice::GetBridgePort (uint32_t n) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_ports[n]; +} + void BridgeNetDevice::AddBridgePort (Ptr bridgePort) { + NS_LOG_FUNCTION_NOARGS (); NS_ASSERT (bridgePort != this); if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ())) { @@ -212,42 +233,49 @@ BridgeNetDevice::AddBridgePort (Ptr bridgePort) void BridgeNetDevice::SetName(const std::string name) { + NS_LOG_FUNCTION_NOARGS (); m_name = name; } std::string BridgeNetDevice::GetName(void) const { + NS_LOG_FUNCTION_NOARGS (); return m_name; } void BridgeNetDevice::SetIfIndex(const uint32_t index) { + NS_LOG_FUNCTION_NOARGS (); m_ifIndex = index; } uint32_t BridgeNetDevice::GetIfIndex(void) const { + NS_LOG_FUNCTION_NOARGS (); return m_ifIndex; } Ptr BridgeNetDevice::GetChannel (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_channel; } Address BridgeNetDevice::GetAddress (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_address; } bool BridgeNetDevice::SetMtu (const uint16_t mtu) { + NS_LOG_FUNCTION_NOARGS (); m_mtu = mtu; return true; } @@ -255,6 +283,7 @@ BridgeNetDevice::SetMtu (const uint16_t mtu) uint16_t BridgeNetDevice::GetMtu (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_mtu; } @@ -262,6 +291,7 @@ BridgeNetDevice::GetMtu (void) const bool BridgeNetDevice::IsLinkUp (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } @@ -274,6 +304,7 @@ BridgeNetDevice::SetLinkChangeCallback (Callback callback) bool BridgeNetDevice::IsBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } @@ -281,12 +312,14 @@ BridgeNetDevice::IsBroadcast (void) const Address BridgeNetDevice::GetBroadcast (void) const { + NS_LOG_FUNCTION_NOARGS (); return Mac48Address ("ff:ff:ff:ff:ff:ff"); } bool BridgeNetDevice::IsMulticast (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } @@ -302,12 +335,14 @@ BridgeNetDevice::GetMulticast (Ipv4Address multicastGroup) const bool BridgeNetDevice::IsPointToPoint (void) const { + NS_LOG_FUNCTION_NOARGS (); return false; } bool BridgeNetDevice::IsBridge (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } @@ -315,6 +350,7 @@ BridgeNetDevice::IsBridge (void) const bool BridgeNetDevice::Send (Ptr packet, const Address& dest, uint16_t protocolNumber) { + NS_LOG_FUNCTION_NOARGS (); for (std::vector< Ptr >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++) { @@ -328,6 +364,7 @@ BridgeNetDevice::Send (Ptr packet, const Address& dest, uint16_t protoco bool BridgeNetDevice::SendFrom (Ptr packet, const Address& src, const Address& dest, uint16_t protocolNumber) { + NS_LOG_FUNCTION_NOARGS (); for (std::vector< Ptr >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++) { @@ -342,6 +379,7 @@ BridgeNetDevice::SendFrom (Ptr packet, const Address& src, const Address Ptr BridgeNetDevice::GetNode (void) const { + NS_LOG_FUNCTION_NOARGS (); return m_node; } @@ -349,6 +387,7 @@ BridgeNetDevice::GetNode (void) const void BridgeNetDevice::SetNode (Ptr node) { + NS_LOG_FUNCTION_NOARGS (); m_node = node; } @@ -356,6 +395,7 @@ BridgeNetDevice::SetNode (Ptr node) bool BridgeNetDevice::NeedsArp (void) const { + NS_LOG_FUNCTION_NOARGS (); return true; } @@ -363,25 +403,28 @@ BridgeNetDevice::NeedsArp (void) const void BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { + NS_LOG_FUNCTION_NOARGS (); m_rxCallback = cb; } void BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb) { + NS_LOG_FUNCTION_NOARGS (); m_promiscRxCallback = cb; } bool BridgeNetDevice::SupportsSendFrom () const { + NS_LOG_FUNCTION_NOARGS (); return true; } - void BridgeNetDevice::DoDispose (void) { + NS_LOG_FUNCTION_NOARGS (); m_node = 0; NetDevice::DoDispose (); } diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index 2d2d0a6d0..4353a5f58 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -82,6 +82,10 @@ public: */ void AddBridgePort (Ptr bridgePort); + uint32_t GetNBridgePorts (void) const; + + Ptr GetBridgePort (uint32_t n) const; + // inherited from NetDevice base class. virtual void SetName(const std::string name); virtual std::string GetName(void) const; diff --git a/src/helper/bridge-helper.cc b/src/helper/bridge-helper.cc index 720dfb86d..4c7f8e553 100644 --- a/src/helper/bridge-helper.cc +++ b/src/helper/bridge-helper.cc @@ -1,24 +1,49 @@ -#include "bridge-helper.h" +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) + * + * 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 "bridge-helper.h" +#include "ns3/log.h" #include "ns3/bridge-net-device.h" #include "ns3/node.h" +NS_LOG_COMPONENT_DEFINE ("BridgeHelper"); + namespace ns3 { BridgeHelper::BridgeHelper () { + NS_LOG_FUNCTION_NOARGS (); m_deviceFactory.SetTypeId ("ns3::BridgeNetDevice"); } void BridgeHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1) { + NS_LOG_FUNCTION_NOARGS (); m_deviceFactory.Set (n1, v1); } NetDeviceContainer BridgeHelper::Install (Ptr node, NetDeviceContainer c) { + NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("**** Install bridge device on node " << node->GetId ()); + NetDeviceContainer devs; Ptr dev = m_deviceFactory.Create (); devs.Add (dev); @@ -26,6 +51,7 @@ BridgeHelper::Install (Ptr node, NetDeviceContainer c) for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i) { + NS_LOG_LOGIC ("**** Add BridgePort "<< *i); dev->AddBridgePort (*i); } return devs; diff --git a/src/helper/node-container.cc b/src/helper/node-container.cc index 333737e9c..5e3018046 100644 --- a/src/helper/node-container.cc +++ b/src/helper/node-container.cc @@ -50,6 +50,17 @@ NodeContainer::NodeContainer (const NodeContainer &a, const NodeContainer &b, Add (d); } +NodeContainer::NodeContainer (const NodeContainer &a, const NodeContainer &b, + const NodeContainer &c, const NodeContainer &d, + const NodeContainer &e) +{ + Add (a); + Add (b); + Add (c); + Add (d); + Add (e); +} + NodeContainer::Iterator NodeContainer::Begin (void) const { diff --git a/src/helper/node-container.h b/src/helper/node-container.h index a4d9bbf9a..efeaaa96b 100644 --- a/src/helper/node-container.h +++ b/src/helper/node-container.h @@ -64,6 +64,8 @@ public: NodeContainer (const NodeContainer &a, const NodeContainer &b, const NodeContainer &c); NodeContainer (const NodeContainer &a, const NodeContainer &b, const NodeContainer &c, const NodeContainer &d); + NodeContainer (const NodeContainer &a, const NodeContainer &b, const NodeContainer &c, const NodeContainer &d, + const NodeContainer &e); /** * \returns an iterator to the start of the vector of node pointers. diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 8230c2a7f..0ea20f5b9 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -351,8 +351,7 @@ GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* 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 +// to participate as a router. This is a convenience function that makes // 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. // @@ -371,6 +370,21 @@ GlobalRouteManagerImpl::SelectRouterNodes () } } + void +GlobalRouteManagerImpl::SelectRouterNodes (NodeContainer c) +{ + NS_LOG_FUNCTION_NOARGS (); + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) + { + Ptr node = *i; + NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << + node->GetId ()); + + Ptr globalRouter = CreateObject (); + node->AggregateObject (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-routing/global-route-manager-impl.h b/src/routing/global-routing/global-route-manager-impl.h index 139b25178..46c3247a8 100644 --- a/src/routing/global-routing/global-route-manager-impl.h +++ b/src/routing/global-routing/global-route-manager-impl.h @@ -29,6 +29,7 @@ #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/ipv4-address.h" +#include "ns3/node-container.h" #include "global-router-interface.h" namespace ns3 { @@ -707,6 +708,14 @@ public: */ virtual void SelectRouterNodes (); +/** + * @brief Select which nodes in the system are to be router nodes and + * aggregate the appropriate interfaces onto those nodes. + * @internal + * + */ + virtual void SelectRouterNodes (NodeContainer c); + /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. diff --git a/src/routing/global-routing/global-route-manager.cc b/src/routing/global-routing/global-route-manager.cc index 4349f0df8..5fc23f2f3 100644 --- a/src/routing/global-routing/global-route-manager.cc +++ b/src/routing/global-routing/global-route-manager.cc @@ -21,6 +21,7 @@ #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/simulation-singleton.h" +#include "ns3/node-container.h" #include "global-route-manager.h" #include "global-route-manager-impl.h" @@ -33,7 +34,7 @@ namespace ns3 { // --------------------------------------------------------------------------- void -GlobalRouteManager::PopulateRoutingTables () +GlobalRouteManager::PopulateRoutingTables (void) { SelectRouterNodes (); BuildGlobalRoutingDatabase (); @@ -41,28 +42,43 @@ GlobalRouteManager::PopulateRoutingTables () } void -GlobalRouteManager::SelectRouterNodes () +GlobalRouteManager::PopulateRoutingTables (NodeContainer c) +{ + SelectRouterNodes (c); + BuildGlobalRoutingDatabase (); + InitializeRoutes (); +} + + void +GlobalRouteManager::SelectRouterNodes (void) { SimulationSingleton::Get ()-> SelectRouterNodes (); } void -GlobalRouteManager::BuildGlobalRoutingDatabase () +GlobalRouteManager::SelectRouterNodes (NodeContainer c) +{ + SimulationSingleton::Get ()-> + SelectRouterNodes (c); +} + + void +GlobalRouteManager::BuildGlobalRoutingDatabase (void) { SimulationSingleton::Get ()-> BuildGlobalRoutingDatabase (); } void -GlobalRouteManager::InitializeRoutes () +GlobalRouteManager::InitializeRoutes (void) { SimulationSingleton::Get ()-> InitializeRoutes (); } uint32_t -GlobalRouteManager::AllocateRouterId () +GlobalRouteManager::AllocateRouterId (void) { static uint32_t routerId = 0; return routerId++; diff --git a/src/routing/global-routing/global-route-manager.h b/src/routing/global-routing/global-route-manager.h index 333aff78c..8fe4c0471 100644 --- a/src/routing/global-routing/global-route-manager.h +++ b/src/routing/global-routing/global-route-manager.h @@ -22,6 +22,8 @@ #ifndef GLOBAL_ROUTE_MANAGER_H #define GLOBAL_ROUTE_MANAGER_H +#include "ns3/node-container.h" + namespace ns3 { /** @@ -40,7 +42,8 @@ class GlobalRouteManager public: /** * @brief Build a routing database and initialize the routing tables of - * the nodes in the simulation. + * the nodes in the simulation. Makes all nodes in the simulation into + * routers. * * All this function does is call BuildGlobalRoutingDatabase () and * InitializeRoutes (). @@ -50,6 +53,19 @@ public: */ static void PopulateRoutingTables (); +/** + * @brief Build a routing database and initialize the routing tables of + * the nodes in the simulation. Makes the nodes in the provided container + * into routers. + * + * All this function does is call BuildGlobalRoutingDatabase () and + * InitializeRoutes (). + * + * @see BuildGlobalRoutingDatabase (); + * @see InitializeRoutes (); + */ + static void PopulateRoutingTables (NodeContainer c); + /** * @brief Allocate a 32-bit router ID from monotonically increasing counter. */ @@ -64,6 +80,14 @@ private: */ static void SelectRouterNodes (); +/** + * @brief Select which nodes in the system are to be router nodes and + * aggregate the appropriate interfaces onto those nodes. + * @internal + * + */ + static void SelectRouterNodes (NodeContainer c); + /** * @brief Build the routing database by gathering Link State Advertisements * from each node exporting a GlobalRouter interface. diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 441863726..27a463bed 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -20,11 +20,14 @@ #include "ns3/log.h" #include "ns3/assert.h" +#include "ns3/abort.h" #include "ns3/channel.h" #include "ns3/net-device.h" #include "ns3/node.h" #include "ns3/ipv4.h" +#include "ns3/bridge-net-device.h" #include "global-router-interface.h" +#include NS_LOG_COMPONENT_DEFINE ("GlobalRouter"); @@ -365,8 +368,7 @@ GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const return *i; } } - NS_ASSERT_MSG(false, - "GlobalRoutingLSA::GetAttachedRouter (): invalid index"); + NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index"); return Ipv4Address("0.0.0.0"); } @@ -495,45 +497,108 @@ GlobalRouter::DiscoverLSAs (void) { NS_LOG_FUNCTION_NOARGS (); Ptr node = GetObject (); - NS_LOG_LOGIC("For node " << node->GetId () ); - NS_ASSERT_MSG(node, - "GlobalRouter::DiscoverLSAs (): interface not set"); + NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for interface failed"); + NS_LOG_LOGIC ("For node " << node->GetId () ); ClearLSAs (); - +// // While building the router-LSA, keep a list of those NetDevices for // which I am the designated router and need to later build a NetworkLSA +// std::list > listOfDRInterfaces; // // We're aggregated to a node. We need to ask the node for a pointer to its // Ipv4 interface. This is where the information regarding the attached -// interfaces lives. +// interfaces lives. If we're a router, we had better have an Ipv4 interface. // Ptr ipv4Local = node->GetObject (); - NS_ASSERT_MSG(ipv4Local, - "GlobalRouter::DiscoverLSAs (): QI for interface failed"); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for interface failed"); // -// Each node originates a Router-LSA +// Each node is a router and so originates a Router-LSA // GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; pLSA->SetLSType (GlobalRoutingLSA::RouterLSA); pLSA->SetLinkStateId (m_routerId); pLSA->SetAdvertisingRouter (m_routerId); pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); + // -// We need to ask the node for the number of net devices attached. This isn't -// necessarily equal to the number of links to adjacent nodes (other routers) -// as the number of devices may include those for stub networks (e.g., -// ethernets, etc.). +// 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.) and +// bridge devices also take up an "extra" net device. // uint32_t numDevices = node->GetNDevices(); NS_LOG_LOGIC ("numDevices = " << numDevices); + +// +// There are two broad classes of devices: bridges in combination with the +// devices they bridge and everything else. We need to first discover all of +// the "everything else" class of devices. +// +// To do this, we wander through all of the devices on the node looking for +// bridge net devices. We then add any net devices associated to a bridge +// to a list of bridged devices. These devices will not be treated as stand- +// alone devices later. +// + std::vector > bridgedDevices; + + NS_LOG_LOGIC ("*************************"); + + NS_LOG_LOGIC ("numDevices = " << numDevices); + for (uint32_t i = 0; i < numDevices; ++i) + { + Ptr nd = node->GetDevice(i); + if (nd->IsBridge ()) + { + NS_LOG_LOGIC ("**** Net device " << nd << "is a bridge"); + // + // XXX There is only one kind of bridge device so far. We agreed to + // assume that it is Gustavo's learning bridge until there is a need + // to deal with another. At that time, we'll have to break out a + // bridge interface. + // + Ptr bnd = nd->GetObject (); + NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); + + for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) + { + NS_LOG_LOGIC ("**** Net device " << bnd << "is a bridged device"); + bridgedDevices.push_back (bnd->GetBridgePort (j)); + } + } + } + + // + // Iterate through the devices on the node and walk the channel to see what's + // on the other side of the standalone devices.. + // for (uint32_t i = 0; i < numDevices; ++i) { Ptr ndLocal = node->GetDevice(i); + // + // If the device in question is on our list of bridged devices, then we + // just ignore it. It will be dealt with correctly when we probe the + // bridge device it belongs to. It is the case that the bridge code + // assumes that bridged devices must not have IP interfaces, and so it + // may actually sufficient to perform the test for IP interface below, + // but that struck me as too indirect a condition. + // + for (uint32_t j = 0; j < bridgedDevices.size (); ++j) + { + if (ndLocal == bridgedDevices[j]) + { + NS_LOG_LOGIC ("**** Skipping Bridged Device"); - // Check if it is an IP interface (could be a pure L2 NetDevice) + continue; + } + } + + // + // Check to see if the net device we just got has a corresponding IP + // interface (could be a pure L2 NetDevice). + // bool isIp = false; for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) { @@ -543,26 +608,29 @@ GlobalRouter::DiscoverLSAs (void) break; } } + if (!isIp) { + NS_LOG_LOGIC ("**** Net device " << ndLocal << "has no IP interface, skipping"); continue; } if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { - NS_LOG_LOGIC ("Broadcast link"); + NS_LOG_LOGIC ("**** Broadcast link"); GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; // // We need to determine whether we are on a transit or stub network // If we find at least one more router on this channel, we are a transit -// +// network. If we're the only router, we're on a stub. // // Now, we have to find the Ipv4 interface whose netdevice is the one we -// just found. This is still the IP on the local side of the channel. There -// is a function to do this used down in the guts of the stack, but it's not -// exported so we had to whip up an equivalent. +// just found. This is still the IP on the local side of the channel. // - uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); NS_LOG_LOGIC ("Working with local address " << addrLocal); @@ -577,7 +645,7 @@ GlobalRouter::DiscoverLSAs (void) if (nDevices == 1) { // This is a stub broadcast interface - NS_LOG_LOGIC("Router-LSA stub broadcast link"); + NS_LOG_LOGIC("**** Router-LSA stub broadcast link"); // XXX in future, need to consider if >1 includes other routers plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); // Link ID is IP network number of attached network @@ -593,7 +661,7 @@ GlobalRouter::DiscoverLSAs (void) } else { - NS_LOG_LOGIC ("Router-LSA Broadcast link"); + NS_LOG_LOGIC ("**** Router-LSA Broadcast link"); // multiple routers on a broadcast interface // lowest IP address is designated router plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); @@ -616,14 +684,16 @@ GlobalRouter::DiscoverLSAs (void) } else if (ndLocal->IsPointToPoint () ) { - NS_LOG_LOGIC ("Router-LSA Point-to-point device"); + NS_LOG_LOGIC ("**** Router-LSA Point-to-point device"); // // Now, we have to find the Ipv4 interface whose netdevice is the one we // just found. This is still the IP on the local side of the channel. There // is a function to do this used down in the guts of the stack, but it's not // exported so we had to whip up an equivalent. // - uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); // // Now that we have the Ipv4 interface index, we can get the address and mask // we need. @@ -642,30 +712,43 @@ GlobalRouter::DiscoverLSAs (void) { continue; } +// +// Get the net device on the other side of the point-to-point channel. +// 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. +// device for its node, then ask that node for its Ipv4 interface. Note a +// requirement that nodes on either side of a point-to-point link must have +// internet stacks. // Ptr nodeRemote = ndRemote->GetNode(); Ptr ipv4Remote = nodeRemote->GetObject (); - NS_ASSERT_MSG(ipv4Remote, - "GlobalRouter::DiscoverLSAs (): QI for remote failed"); + NS_ABORT_MSG_UNLESS (ipv4Remote, + "GlobalRouter::DiscoverLSAs (): GetObject 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->GetObject (); - NS_ASSERT_MSG(srRemote, - "GlobalRouter::DiscoverLSAs():QI for remote failed"); +// While we're at it, further note the requirement that nodes on either side of +// a point-to-point link must participateg in global routing and therefore have +// a GlobalRouter interface aggregated. +// + Ptr srRemote = nodeRemote->GetObject (); + NS_ABORT_MSG_UNLESS(srRemote, + "GlobalRouter::DiscoverLSAs(): GetObject for remote failed"); + Ipv4Address rtrIdRemote = srRemote->GetRouterId(); NS_LOG_LOGIC ("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. +// net device on the other end of the point-to-point channel. We have yet another +// assumption that point to point devices are incompatible with bridges and that +// the remote device must have an associated ip interface. // - uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote); + uint32_t ifIndexRemote; + rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with remote device"); // // Now that we have the Ipv4 interface, we can get the (remote) address and // mask we need. @@ -698,23 +781,38 @@ GlobalRouter::DiscoverLSAs (void) { NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type"); } - } // // The LSA goes on a list of LSAs in case we want to begin exporting other // kinds of advertisements (than Router LSAs). +// m_LSAs.push_back (pLSA); NS_LOG_LOGIC (*pLSA); -// Now, determine whether we need to build a NetworkLSA +// +// Now, determine whether we need to build a NetworkLSA. This is the case if +// we found at least one designated router. +// if (listOfDRInterfaces.size () > 0) { for (std::list >::iterator i = listOfDRInterfaces.begin (); i != listOfDRInterfaces.end (); i++) { +// // Build one NetworkLSA for each interface that is a DR +// Ptr ndLocal = *i; - uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); + + // + // We are working with a list of net devices off of the local node + // on which we found a designated router. We assume there must be + // an associated ipv4 interface index. + // + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); @@ -724,7 +822,13 @@ GlobalRouter::DiscoverLSAs (void) pLSA->SetAdvertisingRouter (m_routerId); pLSA->SetNetworkLSANetworkMask (maskLocal); pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); -// Build list of AttachedRouters +// +// XXX Doesn't deal with bridging +// +// Build a list of AttachedRouters by walking the devices in the channel +// and, if we find an IPv4 interface associated with that device, we +// call it an attached router. +// Ptr ch = ndLocal->GetChannel(); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); @@ -733,11 +837,16 @@ GlobalRouter::DiscoverLSAs (void) Ptr tempNd = ch->GetDevice (i); NS_ASSERT (tempNd); Ptr tempNode = tempNd->GetNode (); - uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); - Ptr tempIpv4 = tempNode->GetObject (); - NS_ASSERT (tempIpv4); - Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); - pLSA->AddAttachedRouter (tempAddr); + uint32_t tempIfIndex; + if (FindIfIndexForDevice (tempNode, tempNd, tempIfIndex)) + { + + Ptr tempIpv4 = tempNode->GetObject (); + NS_ASSERT (tempIpv4); + Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); + pLSA->AddAttachedRouter (tempAddr); + + } } m_LSAs.push_back (pLSA); NS_LOG_LOGIC (*pLSA); @@ -747,33 +856,80 @@ GlobalRouter::DiscoverLSAs (void) return m_LSAs.size (); } +// +// Given a node and an attached net device, we need to walk the channel to which +// the net device is attached and look for the lowest IP address on all of the +// devices attached to that channel. This process is complicated by the fact +// there may be bridge devices associated with any of the net devices attached +// to the channel. +// Ipv4Address -GlobalRouter::FindDesignatedRouterForLink (Ptr node, - Ptr ndLocal) const + GlobalRouter::FindDesignatedRouterForLink (Ptr node, Ptr ndLocal) const { - uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal); + NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC("**** For node " << node->GetId () << " for net device " << ndLocal ); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); + Ptr ipv4Local = GetObject (); - NS_ASSERT (ipv4Local); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::FindDesignatedRouterForLink(): GetObject for interface failed" + " on node " << node->GetId ()); + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); Ptr ch = ndLocal->GetChannel(); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); + + NS_LOG_LOGIC("**** channel " << ch << " has " << nDevices << " net devices"); + + // + // We now have the channel associated with the net device in question. We + // need to iterate over all of the net devices attached to that channel. + // + Ipv4Address lowest = addrLocal; - // iterate all NetDevices and return the lowest numbered IP address + for (uint32_t i = 0; i < nDevices; i++) { - Ptr tempNd = ch->GetDevice (i); - NS_ASSERT (tempNd); - Ptr tempNode = tempNd->GetNode (); - uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd); - Ptr tempIpv4 = tempNode->GetObject (); - NS_ASSERT (tempIpv4); - Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); - if (tempAddr < addrLocal) + Ptr ndTemp = ch->GetDevice (i); + NS_ASSERT_MSG (ndTemp, "GlobalRouter::FindDesignatedRouterForLink(): Null device attached to channel"); + + if (ndTemp == ndLocal) { - addrLocal = tempAddr; + continue; + } + + Ptr nodeTemp = ndTemp->GetNode (); + + NS_LOG_LOGIC("**** channel connects to node " << nodeTemp->GetId () << " with net device " << ndTemp); + + // + // XXX doesn't admit the possibility of a bridge + // + // If the remote device doesn't have an ipv4 interface index associated + // with it, it cannot be a designated router. + // + uint32_t ifIndexTemp; + bool rc = FindIfIndexForDevice(nodeTemp, ndTemp, ifIndexTemp); + if (rc == false) + { + continue; + } + + Ptr ipv4Temp = nodeTemp->GetObject (); + NS_ASSERT_MSG (ipv4Temp, "GlobalRouter::FindDesignatedRouterForLink(): GetObject for interface failed" + " on node " << node->GetId ()); + + Ipv4Address addrTemp = ipv4Temp->GetAddress(ifIndexTemp); + + NS_LOG_LOGIC("**** net device " << ndTemp << " has Ipv4Address " << addrTemp); + if (addrTemp < addrLocal) + { + addrLocal = addrTemp; } } return addrLocal; @@ -852,25 +1008,37 @@ GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const } // -// Given a node and a net device, find the IPV4 interface index that -// corresponds to that net device. +// Given a node and a net device, find an IPV4 interface index that corresponds +// to that net device. This function may fail for various reasons. If a node +// does not have an internet stack (for example if it is a bridge) we won't have +// an IPv4 at all. If the node does have a stack, but the net device in question +// is bridged, there will not be an interface associated directly with the device. // - uint32_t -GlobalRouter::FindIfIndexForDevice(Ptr node, Ptr nd) const + bool +GlobalRouter::FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const { NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd ); + Ptr ipv4 = node->GetObject (); - NS_ASSERT_MSG(ipv4, "QI for interface failed"); + if (ipv4 == 0) + { + NS_LOG_LOGIC ("**** No Ipv4 interface on node " << node->GetId ()); + return false; + } + for (uint32_t i = 0; i < ipv4->GetNInterfaces(); ++i ) { if (ipv4->GetNetDevice(i) == nd) { - return i; + NS_LOG_LOGIC ("**** Device " << nd << " has associated ipv4 index " << i); + index = i; + return true; } } - NS_ASSERT_MSG(0, "Cannot find interface for device"); - return 0; + NS_LOG_LOGIC ("**** Device " << nd << " has no associated ipv4 index"); + return false; } } // namespace ns3 diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index bd5dddfda..e2e42d400 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -639,7 +639,7 @@ private: void ClearLSAs (void); Ptr GetAdjacent(Ptr nd, Ptr ch) const; - uint32_t FindIfIndexForDevice(Ptr node, Ptr nd) const; + bool FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const; Ipv4Address FindDesignatedRouterForLink (Ptr node, Ptr ndLocal) const; From 0f468c97e7ef62d59f6f09d199929ccee8df51bb Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 19 Nov 2008 18:44:20 -0800 Subject: [PATCH 04/14] Admit possibility that not all nodes are routers. --- examples/csma-bridge-one-hop.cc | 3 +- .../global-routing/global-router-interface.cc | 222 +++++++++++------- .../global-routing/global-router-interface.h | 4 +- 3 files changed, 140 insertions(+), 89 deletions(-) diff --git a/examples/csma-bridge-one-hop.cc b/examples/csma-bridge-one-hop.cc index fac58fa4f..812b1dd7c 100644 --- a/examples/csma-bridge-one-hop.cc +++ b/examples/csma-bridge-one-hop.cc @@ -176,7 +176,8 @@ main (int argc, char *argv[]) // // Create router nodes, initialize routing database and set up the routing - // tables in the nodes. + // tables in the nodes. We excuse the bridge nodes from having to serve as + // routers, since they don't even have internet stacks on them. // NodeContainer routerNodes (n0, n1, n2, n3, n4); GlobalRouteManager::PopulateRoutingTables (routerNodes); diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 27a463bed..9c8db191e 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -530,6 +530,7 @@ GlobalRouter::DiscoverLSAs (void) // bridge devices also take up an "extra" net device. // uint32_t numDevices = node->GetNDevices(); + NS_LOG_LOGIC ("*************************"); NS_LOG_LOGIC ("numDevices = " << numDevices); // @@ -538,18 +539,16 @@ GlobalRouter::DiscoverLSAs (void) // the "everything else" class of devices. // // To do this, we wander through all of the devices on the node looking for -// bridge net devices. We then add any net devices associated to a bridge -// to a list of bridged devices. These devices will not be treated as stand- -// alone devices later. +// bridge net devices. We then add any net devices associated with each bridge +// to a list of bridged devices. These devices will be treated as a special +// case later. // std::vector > bridgedDevices; - NS_LOG_LOGIC ("*************************"); - - NS_LOG_LOGIC ("numDevices = " << numDevices); for (uint32_t i = 0; i < numDevices; ++i) { Ptr nd = node->GetDevice(i); + if (nd->IsBridge ()) { NS_LOG_LOGIC ("**** Net device " << nd << "is a bridge"); @@ -597,7 +596,7 @@ GlobalRouter::DiscoverLSAs (void) // // Check to see if the net device we just got has a corresponding IP - // interface (could be a pure L2 NetDevice). + // interface (could be a pure L2 NetDevice that is not a bridge). // bool isIp = false; for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) @@ -615,6 +614,11 @@ GlobalRouter::DiscoverLSAs (void) continue; } +// +// We have a net device that we need to check out. If it suports broadcast and +// is not a point-point link, then it will be either a stub network or a transit +// network depending on the number of routers. +// if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { NS_LOG_LOGIC ("**** Broadcast link"); @@ -636,21 +640,26 @@ GlobalRouter::DiscoverLSAs (void) NS_LOG_LOGIC ("Working with local address " << addrLocal); uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); // -// 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. +// Check to see if the net device is connected to a channel/network that has +// another router on it. If there is no other router on the link (but us) then +// this is a stub network. If we find another router, then what we have here +// is a transit network. // - Ptr ch = ndLocal->GetChannel(); - uint32_t nDevices = ch->GetNDevices(); - if (nDevices == 1) + if (AnotherRouterOnLink (ndLocal) == false) { - // This is a stub broadcast interface - NS_LOG_LOGIC("**** Router-LSA stub broadcast link"); - // XXX in future, need to consider if >1 includes other routers + // + // This is a net device connected to a stub network + // + NS_LOG_LOGIC("**** Router-LSA Stub Network"); plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); - // Link ID is IP network number of attached network + // + // According to OSPF, the Link ID is the IP network number of + // the attached network. + // plr->SetLinkId (addrLocal.CombineMask(maskLocal)); - // Link Data is network mask; convert to Ipv4Address + // + // and the Link Data is the network mask; converted to Ipv4Address + // Ipv4Address maskLocalAddr; maskLocalAddr.Set(maskLocal.Get ()); plr->SetLinkData (maskLocalAddr); @@ -661,20 +670,28 @@ GlobalRouter::DiscoverLSAs (void) } else { - NS_LOG_LOGIC ("**** Router-LSA Broadcast link"); - // multiple routers on a broadcast interface - // lowest IP address is designated router + // + // We have multiple routers on a broadcast interface, so this is + // a transit network. + // + NS_LOG_LOGIC ("**** Router-LSA Transit Network"); plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); - // Link ID is IP interface address of designated router - Ipv4Address desigRtr = - FindDesignatedRouterForLink (node, ndLocal); + // + // By definition, the router with the lowest IP address is the + // designated router for the network. OSPF says that the Link ID + // gets the IP interface address of the designated router in this + // case. + // + Ipv4Address desigRtr = FindDesignatedRouterForLink (ndLocal); if (desigRtr == addrLocal) { listOfDRInterfaces.push_back (ndLocal); NS_LOG_LOGIC (node->GetId () << " is a DR"); } plr->SetLinkId (desigRtr); - // Link Data is router's own IP address + // + // OSPF says that the Link Data is this router's own IP address. + // plr->SetLinkData (addrLocal); plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); @@ -787,6 +804,7 @@ GlobalRouter::DiscoverLSAs (void) // kinds of advertisements (than Router LSAs). // m_LSAs.push_back (pLSA); + NS_LOG_LOGIC ("========== Link State Advertisement for node " << node->GetId () << " =========="); NS_LOG_LOGIC (*pLSA); // @@ -795,20 +813,16 @@ GlobalRouter::DiscoverLSAs (void) // if (listOfDRInterfaces.size () > 0) { + NS_LOG_LOGIC ("Build Network LSA"); for (std::list >::iterator i = listOfDRInterfaces.begin (); i != listOfDRInterfaces.end (); i++) { // -// Build one NetworkLSA for each interface that is a DR +// Build one NetworkLSA for each net device talking to a netwok that we are the +// designated router for. // Ptr ndLocal = *i; - // - // We are working with a list of net devices off of the local node - // on which we found a designated router. We assume there must be - // an associated ipv4 interface index. - // - uint32_t ifIndexLocal; bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); @@ -823,11 +837,9 @@ GlobalRouter::DiscoverLSAs (void) pLSA->SetNetworkLSANetworkMask (maskLocal); pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); // -// XXX Doesn't deal with bridging -// // Build a list of AttachedRouters by walking the devices in the channel -// and, if we find an IPv4 interface associated with that device, we -// call it an attached router. +// and, if we find a node with a GlobalRouter interface and an IPv4 +// interface associated with that device, we call it an attached router. // Ptr ch = ndLocal->GetChannel(); uint32_t nDevices = ch->GetNDevices(); @@ -837,15 +849,27 @@ GlobalRouter::DiscoverLSAs (void) Ptr tempNd = ch->GetDevice (i); NS_ASSERT (tempNd); Ptr tempNode = tempNd->GetNode (); +// +// Does the node in question have a GlobalRouter interface? If not it can +// hardly be considered an attached router. +// + Ptr rtr = tempNode->GetObject (); + if (rtr == 0) + { + continue; + } + +// +// Does the attached node have an ipv4 interface for the device we're probing? +// If not, it can't play router. +// uint32_t tempIfIndex; if (FindIfIndexForDevice (tempNode, tempNd, tempIfIndex)) { - Ptr tempIpv4 = tempNode->GetObject (); NS_ASSERT (tempIpv4); Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); pLSA->AddAttachedRouter (tempAddr); - } } m_LSAs.push_back (pLSA); @@ -857,82 +881,108 @@ GlobalRouter::DiscoverLSAs (void) } // -// Given a node and an attached net device, we need to walk the channel to which -// the net device is attached and look for the lowest IP address on all of the -// devices attached to that channel. This process is complicated by the fact -// there may be bridge devices associated with any of the net devices attached -// to the channel. +// Given a local net device, we need to walk the channel to which the net device is +// attached and look for nodes with GlobalRouter interfaces on them (one of them +// will be us). Of these, the router with the lowest IP address on the net device +// connecting to the channel becomes the designated router for the link. // Ipv4Address - GlobalRouter::FindDesignatedRouterForLink (Ptr node, Ptr ndLocal) const +GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal) const { NS_LOG_FUNCTION_NOARGS (); - NS_LOG_LOGIC("**** For node " << node->GetId () << " for net device " << ndLocal ); - - uint32_t ifIndexLocal; - bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); - - Ptr ipv4Local = GetObject (); - NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::FindDesignatedRouterForLink(): GetObject for interface failed" - " on node " << node->GetId ()); - - Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); - Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); Ptr ch = ndLocal->GetChannel(); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); - NS_LOG_LOGIC("**** channel " << ch << " has " << nDevices << " net devices"); - - // - // We now have the channel associated with the net device in question. We - // need to iterate over all of the net devices attached to that channel. - // - - Ipv4Address lowest = addrLocal; + Ipv4Address addr ("255.255.255.255"); for (uint32_t i = 0; i < nDevices; i++) { - Ptr ndTemp = ch->GetDevice (i); - NS_ASSERT_MSG (ndTemp, "GlobalRouter::FindDesignatedRouterForLink(): Null device attached to channel"); + Ptr currentNd = ch->GetDevice (i); + NS_ASSERT (currentNd); - if (ndTemp == ndLocal) + Ptr currentNode = currentNd->GetNode (); + NS_ASSERT (currentNode); + // + // We require a designated router to have a GlobalRouter interface and + // an internet stack that includes the Ipv4 interface. + // + Ptr rtr = currentNode->GetObject (); + Ptr ipv4 = currentNode->GetObject (); + if (rtr == 0 || ipv4 == 0 ) { continue; } - Ptr nodeTemp = ndTemp->GetNode (); - - NS_LOG_LOGIC("**** channel connects to node " << nodeTemp->GetId () << " with net device " << ndTemp); - // - // XXX doesn't admit the possibility of a bridge + // This node could be a designated router, so we can check and see if + // it has a lower IP address than the one we have. In order to have + // an IP address, it needs to have an interface index. If it doesen't + // have an interface index directly, it's probably part of a bridge + // net device XXX which is not yet handled. // - // If the remote device doesn't have an ipv4 interface index associated - // with it, it cannot be a designated router. - // - uint32_t ifIndexTemp; - bool rc = FindIfIndexForDevice(nodeTemp, ndTemp, ifIndexTemp); + uint32_t currentIfIndex; + bool rc = FindIfIndexForDevice(currentNode, currentNd, currentIfIndex); if (rc == false) { continue; } - Ptr ipv4Temp = nodeTemp->GetObject (); - NS_ASSERT_MSG (ipv4Temp, "GlobalRouter::FindDesignatedRouterForLink(): GetObject for interface failed" - " on node " << node->GetId ()); + // + // Okay, get the IP address corresponding to the interface we're + // examining and if it's the lowest so far, remember it. + // + Ipv4Address currentAddr = ipv4->GetAddress(currentIfIndex); - Ipv4Address addrTemp = ipv4Temp->GetAddress(ifIndexTemp); - - NS_LOG_LOGIC("**** net device " << ndTemp << " has Ipv4Address " << addrTemp); - if (addrTemp < addrLocal) + if (currentAddr < addr) { - addrLocal = addrTemp; + addr = currentAddr; } } - return addrLocal; + + // + // Return the lowest IP address found, which will become the designated router + // for the link. + // + NS_ASSERT_MSG (addr.IsBroadcast() == false, "GlobalRouter::FindDesignatedRouterForLink(): Bogus address"); + return addr; +} + +// +// Given a node and an attached net device, take a look off in the channel to +// which the net device is attached and look for a node on the other side +// that has a GlobalRouter interface aggregated. +// + bool +GlobalRouter::AnotherRouterOnLink (Ptr nd) const +{ + NS_LOG_FUNCTION_NOARGS (); + + Ptr ch = nd->GetChannel(); + uint32_t nDevices = ch->GetNDevices(); + NS_ASSERT (nDevices); + + for (uint32_t i = 0; i < nDevices; i++) + { + Ptr ndTemp = ch->GetDevice (i); + NS_ASSERT (ndTemp); + + if (ndTemp == nd) + { + continue; + } + + Ptr nodeTemp = ndTemp->GetNode (); + NS_ASSERT (nodeTemp); + + Ptr rtr = nodeTemp->GetObject (); + if (rtr) + { + return true; + } + } + return false; } uint32_t diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index e2e42d400..c56f0c0c6 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -640,8 +640,8 @@ private: Ptr GetAdjacent(Ptr nd, Ptr ch) const; bool FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const; - Ipv4Address FindDesignatedRouterForLink (Ptr node, - Ptr ndLocal) const; + Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal) const; + bool AnotherRouterOnLink (Ptr nd) const; typedef std::list ListOfLSAs_t; ListOfLSAs_t m_LSAs; From 7d71822e3b99a624a98ce2e6e295947a3906791a Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 19 Nov 2008 21:21:14 -0800 Subject: [PATCH 05/14] factor DiscoverLSAs into understandable modules --- .../global-route-manager-impl.cc | 6 +- .../global-routing/global-router-interface.cc | 695 +++++++++--------- .../global-routing/global-router-interface.h | 6 + 3 files changed, 376 insertions(+), 331 deletions(-) diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 0ea20f5b9..267e53f09 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -399,14 +399,14 @@ GlobalRouteManagerImpl::BuildGlobalRoutingDatabase () { NS_LOG_FUNCTION_NOARGS (); // -// Walk the list of nodes looking for the GlobalRouter Interface. +// Walk the list of nodes looking for the GlobalRouter Interface. Nodes with +// global router interfaces are, not too surprisingly, our routers. // for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++) { Ptr node = *i; - Ptr rtr = - node->GetObject (); + Ptr rtr = node->GetObject (); // // Ignore nodes that aren't participating in routing. // diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 9c8db191e..ff68807cc 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -26,6 +26,7 @@ #include "ns3/node.h" #include "ns3/ipv4.h" #include "ns3/bridge-net-device.h" +#include "ns3/net-device-container.h" #include "global-router-interface.h" #include @@ -489,8 +490,10 @@ GlobalRouter::GetRouterId (void) const } // -// Go out and discover any adjacent routers and build the Link State -// Advertisements that reflect them and their associated networks. +// DiscoverLSAs is called on all nodes in the system that have a GlobalRouter +// interface aggregated. We need to go out and discover any adjacent routers +// and build the Link State Advertisements that reflect them and their associated +// networks. // uint32_t GlobalRouter::DiscoverLSAs (void) @@ -501,73 +504,38 @@ GlobalRouter::DiscoverLSAs (void) NS_LOG_LOGIC ("For node " << node->GetId () ); ClearLSAs (); -// -// While building the router-LSA, keep a list of those NetDevices for -// which I am the designated router and need to later build a NetworkLSA -// - std::list > listOfDRInterfaces; -// -// We're aggregated to a node. We need to ask the node for a pointer to its -// Ipv4 interface. This is where the information regarding the attached -// interfaces lives. If we're a router, we had better have an Ipv4 interface. -// + // + // While building the Router-LSA, keep a list of those NetDevices for + // which the current node is the designated router and we will later build + // a NetworkLSA for. + // + NetDeviceContainer c; + + // + // 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. If we're a router, we had better have an Ipv4 interface. + // Ptr ipv4Local = node->GetObject (); NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for interface failed"); -// -// Each node is a router and so originates a Router-LSA -// + + // + // Every router node originates a Router-LSA + // GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; pLSA->SetLSType (GlobalRoutingLSA::RouterLSA); pLSA->SetLinkStateId (m_routerId); pLSA->SetAdvertisingRouter (m_routerId); pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); -// -// 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.) and -// bridge devices also take up an "extra" net device. -// + // + // 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.) and + // bridge devices also take up an "extra" net device. + // uint32_t numDevices = node->GetNDevices(); - NS_LOG_LOGIC ("*************************"); - NS_LOG_LOGIC ("numDevices = " << numDevices); - -// -// There are two broad classes of devices: bridges in combination with the -// devices they bridge and everything else. We need to first discover all of -// the "everything else" class of devices. -// -// To do this, we wander through all of the devices on the node looking for -// bridge net devices. We then add any net devices associated with each bridge -// to a list of bridged devices. These devices will be treated as a special -// case later. -// - std::vector > bridgedDevices; - - for (uint32_t i = 0; i < numDevices; ++i) - { - Ptr nd = node->GetDevice(i); - - if (nd->IsBridge ()) - { - NS_LOG_LOGIC ("**** Net device " << nd << "is a bridge"); - // - // XXX There is only one kind of bridge device so far. We agreed to - // assume that it is Gustavo's learning bridge until there is a need - // to deal with another. At that time, we'll have to break out a - // bridge interface. - // - Ptr bnd = nd->GetObject (); - NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); - - for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) - { - NS_LOG_LOGIC ("**** Net device " << bnd << "is a bridged device"); - bridgedDevices.push_back (bnd->GetBridgePort (j)); - } - } - } // // Iterate through the devices on the node and walk the channel to see what's @@ -576,27 +544,10 @@ GlobalRouter::DiscoverLSAs (void) for (uint32_t i = 0; i < numDevices; ++i) { Ptr ndLocal = node->GetDevice(i); - // - // If the device in question is on our list of bridged devices, then we - // just ignore it. It will be dealt with correctly when we probe the - // bridge device it belongs to. It is the case that the bridge code - // assumes that bridged devices must not have IP interfaces, and so it - // may actually sufficient to perform the test for IP interface below, - // but that struck me as too indirect a condition. - // - for (uint32_t j = 0; j < bridgedDevices.size (); ++j) - { - if (ndLocal == bridgedDevices[j]) - { - NS_LOG_LOGIC ("**** Skipping Bridged Device"); - - continue; - } - } // // Check to see if the net device we just got has a corresponding IP - // interface (could be a pure L2 NetDevice that is not a bridge). + // interface (could be a pure L2 NetDevice). // bool isIp = false; for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) @@ -614,272 +565,325 @@ GlobalRouter::DiscoverLSAs (void) continue; } -// -// We have a net device that we need to check out. If it suports broadcast and -// is not a point-point link, then it will be either a stub network or a transit -// network depending on the number of routers. -// + // + // We have a net device that we need to check out. If it suports + // broadcast and is not a point-point link, then it will be either a stub + // network or a transit network depending on the number of routers on + // the segment. We add the appropriate link record to the LSA. + // + // If the device is a point to point link, we treat it separately. In + // that case, there always two link records added. + // if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { NS_LOG_LOGIC ("**** Broadcast link"); - GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; -// -// We need to determine whether we are on a transit or stub network -// If we find at least one more router on this channel, we are a transit -// network. If we're the only router, we're on a stub. -// -// 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. -// - uint32_t ifIndexLocal; - bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); - - Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); - Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); - NS_LOG_LOGIC ("Working with local address " << addrLocal); - uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); -// -// Check to see if the net device is connected to a channel/network that has -// another router on it. If there is no other router on the link (but us) then -// this is a stub network. If we find another router, then what we have here -// is a transit network. -// - if (AnotherRouterOnLink (ndLocal) == false) - { - // - // This is a net device connected to a stub network - // - NS_LOG_LOGIC("**** Router-LSA Stub Network"); - plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); - // - // According to OSPF, the Link ID is the IP network number of - // the attached network. - // - plr->SetLinkId (addrLocal.CombineMask(maskLocal)); - // - // and the Link Data is the network mask; converted to Ipv4Address - // - Ipv4Address maskLocalAddr; - maskLocalAddr.Set(maskLocal.Get ()); - plr->SetLinkData (maskLocalAddr); - plr->SetMetric (metricLocal); - pLSA->AddLinkRecord(plr); - plr = 0; - continue; - } - else - { - // - // We have multiple routers on a broadcast interface, so this is - // a transit network. - // - NS_LOG_LOGIC ("**** Router-LSA Transit Network"); - plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); - // - // By definition, the router with the lowest IP address is the - // designated router for the network. OSPF says that the Link ID - // gets the IP interface address of the designated router in this - // case. - // - Ipv4Address desigRtr = FindDesignatedRouterForLink (ndLocal); - if (desigRtr == addrLocal) - { - listOfDRInterfaces.push_back (ndLocal); - NS_LOG_LOGIC (node->GetId () << " is a DR"); - } - plr->SetLinkId (desigRtr); - // - // OSPF says that the Link Data is this router's own IP address. - // - plr->SetLinkData (addrLocal); - plr->SetMetric (metricLocal); - pLSA->AddLinkRecord (plr); - plr = 0; - continue; - } + ProcessBroadcastLink (ndLocal, pLSA, c); } else if (ndLocal->IsPointToPoint () ) { - NS_LOG_LOGIC ("**** Router-LSA Point-to-point device"); -// -// Now, we have to find the Ipv4 interface whose netdevice is the one we -// just found. This is still the IP on the local side of the channel. There -// is a function to do this used down in the guts of the stack, but it's not -// exported so we had to whip up an equivalent. -// - uint32_t ifIndexLocal; - bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); -// -// 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_LOG_LOGIC ("Working with local address " << addrLocal); - uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); -// -// Now, we're going to walk over to the remote net device on the other end of -// the point-to-point channel we now know we have. This is where our adjacent -// router (to use OSPF lingo) is running. -// - Ptr ch = ndLocal->GetChannel(); - if (ch == NULL) - { - continue; - } -// -// Get the net device on the other side of the point-to-point channel. -// - 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. Note a -// requirement that nodes on either side of a point-to-point link must have -// internet stacks. -// - Ptr nodeRemote = ndRemote->GetNode(); - Ptr ipv4Remote = nodeRemote->GetObject (); - NS_ABORT_MSG_UNLESS (ipv4Remote, - "GlobalRouter::DiscoverLSAs (): GetObject for remote failed"); -// -// Per the OSPF spec, we're going to need the remote router ID, so we might as -// well get it now. -// -// While we're at it, further note the requirement that nodes on either side of -// a point-to-point link must participateg in global routing and therefore have -// a GlobalRouter interface aggregated. -// - Ptr srRemote = nodeRemote->GetObject (); - NS_ABORT_MSG_UNLESS(srRemote, - "GlobalRouter::DiscoverLSAs(): GetObject for remote failed"); - - Ipv4Address rtrIdRemote = srRemote->GetRouterId(); - NS_LOG_LOGIC ("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. We have yet another -// assumption that point to point devices are incompatible with bridges and that -// the remote device must have an associated ip interface. -// - uint32_t ifIndexRemote; - rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with remote device"); -// -// Now that we have the Ipv4 interface, we can get the (remote) address and -// mask we need. -// - Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); - Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); - NS_LOG_LOGIC ("Working with remote address " << addrRemote); -// -// Now we can fill out the link records for this link. There are always two -// link records; the first is a point-to-point record describing the link and -// the second is a stub network record with the network number. -// - GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; - plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); - plr->SetLinkId (rtrIdRemote); - plr->SetLinkData (addrLocal); - plr->SetMetric (metricLocal); - pLSA->AddLinkRecord (plr); - plr = 0; - - plr = new GlobalRoutingLinkRecord; - plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); - plr->SetLinkId (addrRemote); - plr->SetLinkData (Ipv4Address(maskRemote.Get())); // Frown - plr->SetMetric (metricLocal); - pLSA->AddLinkRecord (plr); - plr = 0; + NS_LOG_LOGIC ("**** Point=to-point link"); + ProcessPointToPointLink (ndLocal, pLSA); } else { NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type"); } } -// -// The LSA goes on a list of LSAs in case we want to begin exporting other -// kinds of advertisements (than Router LSAs). -// - m_LSAs.push_back (pLSA); - NS_LOG_LOGIC ("========== Link State Advertisement for node " << node->GetId () << " =========="); + + NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " =========="); NS_LOG_LOGIC (*pLSA); + m_LSAs.push_back (pLSA); + pLSA = 0; -// -// Now, determine whether we need to build a NetworkLSA. This is the case if -// we found at least one designated router. -// - if (listOfDRInterfaces.size () > 0) + // + // Now, determine whether we need to build a NetworkLSA. This is the case if + // we found at least one designated router. + // + uint32_t nDesignatedRouters = c.GetN (); + if (nDesignatedRouters > 0) { - NS_LOG_LOGIC ("Build Network LSA"); - for (std::list >::iterator i = listOfDRInterfaces.begin (); - i != listOfDRInterfaces.end (); i++) - { -// -// Build one NetworkLSA for each net device talking to a netwok that we are the -// designated router for. -// - Ptr ndLocal = *i; - - uint32_t ifIndexLocal; - bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::DiscoverLSAs (): No interface index associated with device"); - - Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); - Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); - - GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; - pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA); - pLSA->SetLinkStateId (addrLocal); - pLSA->SetAdvertisingRouter (m_routerId); - pLSA->SetNetworkLSANetworkMask (maskLocal); - pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); -// -// Build a list of AttachedRouters by walking the devices in the channel -// and, if we find a node with a GlobalRouter interface and an IPv4 -// interface associated with that device, we call it an attached router. -// - Ptr ch = ndLocal->GetChannel(); - uint32_t nDevices = ch->GetNDevices(); - NS_ASSERT (nDevices); - for (uint32_t i = 0; i < nDevices; i++) - { - Ptr tempNd = ch->GetDevice (i); - NS_ASSERT (tempNd); - Ptr tempNode = tempNd->GetNode (); -// -// Does the node in question have a GlobalRouter interface? If not it can -// hardly be considered an attached router. -// - Ptr rtr = tempNode->GetObject (); - if (rtr == 0) - { - continue; - } - -// -// Does the attached node have an ipv4 interface for the device we're probing? -// If not, it can't play router. -// - uint32_t tempIfIndex; - if (FindIfIndexForDevice (tempNode, tempNd, tempIfIndex)) - { - Ptr tempIpv4 = tempNode->GetObject (); - NS_ASSERT (tempIpv4); - Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); - pLSA->AddAttachedRouter (tempAddr); - } - } - m_LSAs.push_back (pLSA); - NS_LOG_LOGIC (*pLSA); - } + NS_LOG_LOGIC ("Build Network LSAs"); + BuildNetworkLSAs (c); } return m_LSAs.size (); } + void +GlobalRouter::ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c) +{ + NS_LOG_FUNCTION (nd << pLSA << &c); + + GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBroadcastLink(): Can't alloc link record"); + + // + // We have some preliminaries to do to get enough information to proceed. + // This information we need comes from the internet stack, so notice that + // there is an implied assumption that global routing is only going to + // work with devices attached to the internet stack (have an ipv4 interface + // associated to them. + // + Ptr node = nd->GetNode (); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBroadcastLink(): No interface index associated with device"); + + Ptr ipv4Local = node->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBroadcastLink (): GetObject for interface failed"); + + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); + + // + // Check to see if the net device is connected to a channel/network that has + // another router on it. If there is no other router on the link (but us) then + // this is a stub network. If we find another router, then what we have here + // is a transit network. + // + if (AnotherRouterOnLink (nd) == false) + { + // + // This is a net device connected to a stub network + // + NS_LOG_LOGIC("**** Router-LSA Stub Network"); + plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); + + // + // According to OSPF, the Link ID is the IP network number of + // the attached network. + // + plr->SetLinkId (addrLocal.CombineMask(maskLocal)); + + // + // and the Link Data is the network mask; converted to Ipv4Address + // + Ipv4Address maskLocalAddr; + maskLocalAddr.Set(maskLocal.Get ()); + plr->SetLinkData (maskLocalAddr); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord(plr); + plr = 0; + } + else + { + // + // We have multiple routers on a broadcast interface, so this is + // a transit network. + // + NS_LOG_LOGIC ("**** Router-LSA Transit Network"); + plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); + + // + // By definition, the router with the lowest IP address is the + // designated router for the network. OSPF says that the Link ID + // gets the IP interface address of the designated router in this + // case. + // + Ipv4Address desigRtr = FindDesignatedRouterForLink (nd); + if (desigRtr == addrLocal) + { + c.Add (nd); + NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router"); + } + plr->SetLinkId (desigRtr); + + // + // OSPF says that the Link Data is this router's own IP address. + // + plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord (plr); + plr = 0; + } +} + + void +GlobalRouter::ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA *pLSA) +{ + NS_LOG_FUNCTION (ndLocal << pLSA); + + // + // We have some preliminaries to do to get enough information to proceed. + // This information we need comes from the internet stack, so notice that + // there is an implied assumption that global routing is only going to + // work with devices attached to the internet stack (have an ipv4 interface + // associated to them. + // + Ptr nodeLocal = ndLocal->GetNode (); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(nodeLocal, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device"); + + Ptr ipv4Local = nodeLocal->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for interface failed"); + + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); + + // + // Now, we're going to walk over 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 = ndLocal->GetChannel(); + + // + // Get the net device on the other side of the point-to-point channel. + // + 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. Note a + // requirement that nodes on either side of a point-to-point link must have + // internet stacks; and an assumption that point-to-point links are incompatible + // with bridging. + // + Ptr nodeRemote = ndRemote->GetNode(); + Ptr ipv4Remote = nodeRemote->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Remote, + "GlobalRouter::ProcessPointToPointLink(): GetObject for remote failed"); + + // + // Further note the requirement that nodes on either side of a point-to-point + // link must participate in global routing and therefore have a GlobalRouter + // interface aggregated. + // + Ptr rtrRemote = nodeRemote->GetObject (); + NS_ABORT_MSG_UNLESS(rtrRemote, + "GlobalRouter::ProcessPointToPointLinks(): GetObject for remote failed"); + + // + // We're going to need the remote router ID, so we might as well get it now. + // + Ipv4Address rtrIdRemote = rtrRemote->GetRouterId(); + NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote); + + // + // Now, just like we did above, we need to get the IP interface index for the + // net device on the other end of the point-to-point channel. + // + uint32_t ifIndexRemote; + rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device"); + + // + // Now that we have the Ipv4 interface, we can get the (remote) address and + // mask we need. + // + Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote); + Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote); + NS_LOG_LOGIC ("Working with remote address " << addrRemote); + + // + // Now we can fill out the link records for this link. There are always two + // link records; the first is a point-to-point record describing the link and + // the second is a stub network record with the network number. + // + GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record"); + plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); + plr->SetLinkId (rtrIdRemote); + plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord (plr); + plr = 0; + + plr = new GlobalRoutingLinkRecord; + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record"); + plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); + plr->SetLinkId (addrRemote); + plr->SetLinkData (Ipv4Address(maskRemote.Get())); // Frown + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord (plr); + plr = 0; +} + + void +GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c) +{ + NS_LOG_FUNCTION (&c); + + uint32_t nDesignatedRouters = c.GetN (); + + for (uint32_t i = 0; i < nDesignatedRouters; ++i) + { + // + // Build one NetworkLSA for each net device talking to a network that we are the + // designated router for. These devices are in the provided container. + // + Ptr ndLocal = c.Get (i); + Ptr node = ndLocal->GetNode (); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device"); + + Ptr ipv4Local = node->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for interface failed"); + + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + + GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; + NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record"); + + pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA); + pLSA->SetLinkStateId (addrLocal); + pLSA->SetAdvertisingRouter (m_routerId); + pLSA->SetNetworkLSANetworkMask (maskLocal); + pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); + + // + // Build a list of AttachedRouters by walking the devices in the channel + // and, if we find a node with a GlobalRouter interface and an IPv4 + // interface associated with that device, we call it an attached router. + // + Ptr ch = ndLocal->GetChannel(); + uint32_t nDevices = ch->GetNDevices(); + NS_ASSERT (nDevices); + + for (uint32_t i = 0; i < nDevices; i++) + { + Ptr tempNd = ch->GetDevice (i); + NS_ASSERT (tempNd); + Ptr tempNode = tempNd->GetNode (); + + // + // Does the node in question have a GlobalRouter interface? If not it can + // hardly be considered an attached router. + // + Ptr rtr = tempNode->GetObject (); + if (rtr == 0) + { + continue; + } + + // + // Does the attached node have an ipv4 interface for the device we're probing? + // If not, it can't play router. + // + uint32_t tempIfIndex; + if (FindIfIndexForDevice (tempNode, tempNd, tempIfIndex)) + { + Ptr tempIpv4 = tempNode->GetObject (); + NS_ASSERT (tempIpv4); + Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); + pLSA->AddAttachedRouter (tempAddr); + } + } + m_LSAs.push_back (pLSA); + pLSA = 0; + } +} + // // Given a local net device, we need to walk the channel to which the net device is // attached and look for nodes with GlobalRouter interfaces on them (one of them @@ -1026,11 +1030,10 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const // other end. This only makes sense with a point-to-point channel. // Ptr -GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const +GlobalRouter::GetAdjacent (Ptr nd, Ptr ch) const { NS_LOG_FUNCTION_NOARGS (); - NS_ASSERT_MSG(ch->GetNDevices() == 2, - "GlobalRouter::GetAdjacent (): Channel with other than two devices"); + NS_ASSERT_MSG(ch->GetNDevices() == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices"); // // This is a point to point channel with two endpoints. Get both of them. // @@ -1065,7 +1068,7 @@ GlobalRouter::GetAdjacent(Ptr nd, Ptr ch) const // is bridged, there will not be an interface associated directly with the device. // bool -GlobalRouter::FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const +GlobalRouter::FindIfIndexForDevice (Ptr node, Ptr nd, uint32_t &index) const { NS_LOG_FUNCTION_NOARGS (); NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd ); @@ -1087,7 +1090,43 @@ GlobalRouter::FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t & } } - NS_LOG_LOGIC ("**** Device " << nd << " has no associated ipv4 index"); + NS_LOG_LOGIC ("**** Device " << nd << " has no associated ipv4 index"); + return false; +} + +// +// Decide whether or not a given net device is being bridged by a BridgeNetDevice. +// + bool +GlobalRouter::IsNetDeviceBridged (Ptr nd) const +{ + Ptr node = nd->GetNode (); + uint32_t nDevices = node->GetNDevices(); + + // + // There is no bit on a net device that says it is being bridged, so we have + // to look for bridges on the node to which the device is attached. If we + // find a bridge, we need to look through its bridge ports (the devices it + // bridges) to see if we find the device in question. + // + for (uint32_t i = 0; i < nDevices; ++i) + { + Ptr nd = node->GetDevice(i); + + if (nd->IsBridge ()) + { + Ptr bnd = nd->GetObject (); + NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); + + for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) + { + if (bnd->GetBridgePort (j) == nd) + { + return true; + } + } + } + } return false; } diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index c56f0c0c6..4710a6cf7 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -29,6 +29,7 @@ #include "ns3/node.h" #include "ns3/channel.h" #include "ns3/ipv4-address.h" +#include "ns3/net-device-container.h" #include "ns3/global-route-manager.h" namespace ns3 { @@ -642,6 +643,11 @@ private: bool FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const; Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal) const; bool AnotherRouterOnLink (Ptr nd) const; + void ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); + void ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA *pLSA); + void BuildNetworkLSAs (NetDeviceContainer c); + bool IsNetDeviceBridged (Ptr nd) const; + typedef std::list ListOfLSAs_t; ListOfLSAs_t m_LSAs; From c178314bbf9dfa57b87c104ed75185d9ba724c26 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 19 Nov 2008 22:16:43 -0800 Subject: [PATCH 06/14] deal with bridged stub/transit networks on routers --- .../global-routing/global-router-interface.cc | 162 +++++++++++++++++- .../global-routing/global-router-interface.h | 3 + 2 files changed, 162 insertions(+), 3 deletions(-) diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index ff68807cc..33e1a115f 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -614,8 +614,23 @@ GlobalRouter::ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, N { NS_LOG_FUNCTION (nd << pLSA << &c); + if (nd->IsBridge ()) + { + ProcessBridgedBroadcastLink (nd, pLSA, c); + } + else + { + ProcessSingleBroadcastLink (nd, pLSA, c); + } +} + + void +GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c) +{ + NS_LOG_FUNCTION (nd << pLSA << &c); + GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; - NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBroadcastLink(): Can't alloc link record"); + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record"); // // We have some preliminaries to do to get enough information to proceed. @@ -628,10 +643,10 @@ GlobalRouter::ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, N uint32_t ifIndexLocal; bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBroadcastLink(): No interface index associated with device"); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device"); Ptr ipv4Local = node->GetObject (); - NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBroadcastLink (): GetObject for interface failed"); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for interface failed"); Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); @@ -701,6 +716,147 @@ GlobalRouter::ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, N } } + void +GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c) +{ + NS_LOG_FUNCTION (nd << pLSA << &c); + + NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device"); + + Ptr bnd = nd->GetObject (); + NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); + + // + // We need to handle a bridge on the router. This means that we have been + // given a net device that is a BridgeNetDevice. It has an associated Ipv4 + // interface index and address. Some number of other net devices live "under" + // the bridge device as so-called bridge ports. In a nutshell, what we have + // to do is to repeat what is done for a single broadcast link on all of + // those net devices living under the bridge (trolls?) + // + bool areTransitNetwork = false; + Ipv4Address desigRtr ("255.255.255.255"); + + for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i) + { + Ptr ndTemp = bnd->GetBridgePort (i); + GlobalRoutingLSA *pLsaTest = new GlobalRoutingLSA; + NetDeviceContainer cTest; + ProcessSingleBroadcastLink (ndTemp, pLsaTest, cTest); + + // + // The GlobalRoutingLSA pLsaTest will now have a link record attached to + // it indicating what was found. If another router is found on any one + // of the bridged networks, we need to treat the whole bridge as a transit + // network. + // + // If the link type is a transit network, then we have got to do some work + // to figure out what to do about the other routers on the bridge. + // + if (pLsaTest->GetLinkRecord (0)->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork) + { + areTransitNetwork = true; + + // + // If we're going to be a transit network, then we have got to elect + // a designated router for the whole bridge. This means finding the + // router with the lowest IP address on the whole bridge. We ask + // for the lowest address on each segment and pick the lowest of them + // all. + // + Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp); + if (desigRtrTemp < desigRtr) + { + desigRtr = desigRtrTemp; + } + } + } + + // + // That's all the information we need to put it all together, just like we did + // in the case of a single broadcast link. + // + + GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record"); + + // + // We have some preliminaries to do to get enough information to proceed. + // This information we need comes from the internet stack, so notice that + // there is an implied assumption that global routing is only going to + // work with devices attached to the internet stack (have an ipv4 interface + // associated to them. + // + Ptr node = nd->GetNode (); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device"); + + Ptr ipv4Local = node->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for interface failed"); + + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); + + if (areTransitNetwork == false) + { + // + // This is a net device connected to a bridge of stub networks + // + NS_LOG_LOGIC("**** Router-LSA Stub Network"); + plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); + + // + // According to OSPF, the Link ID is the IP network number of + // the attached network. + // + plr->SetLinkId (addrLocal.CombineMask(maskLocal)); + + // + // and the Link Data is the network mask; converted to Ipv4Address + // + Ipv4Address maskLocalAddr; + maskLocalAddr.Set(maskLocal.Get ()); + plr->SetLinkData (maskLocalAddr); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord(plr); + plr = 0; + } + else + { + // + // We have multiple routers on a bridged broadcast interface, so this is + // a transit network. + // + NS_LOG_LOGIC ("**** Router-LSA Transit Network"); + plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); + + // + // By definition, the router with the lowest IP address is the + // designated router for the network. OSPF says that the Link ID + // gets the IP interface address of the designated router in this + // case. + // + if (desigRtr == addrLocal) + { + c.Add (nd); + NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router"); + } + plr->SetLinkId (desigRtr); + + // + // OSPF says that the Link Data is this router's own IP address. + // + plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord (plr); + plr = 0; + } +} + void GlobalRouter::ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA *pLSA) { diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index 4710a6cf7..83a93aaed 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -644,6 +644,9 @@ private: Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal) const; bool AnotherRouterOnLink (Ptr nd) const; void ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); + void ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); + void ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); + void ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA *pLSA); void BuildNetworkLSAs (NetDeviceContainer c); bool IsNetDeviceBridged (Ptr nd) const; From d26abb0c1008a959a1c481f4f078416e5a7e114e Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 19 Nov 2008 23:38:01 -0800 Subject: [PATCH 07/14] teach global routing about bridges --- .../global-routing/global-router-interface.cc | 102 +++++++++++++----- .../global-routing/global-router-interface.h | 5 +- 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 33e1a115f..65120bf66 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -547,7 +547,8 @@ GlobalRouter::DiscoverLSAs (void) // // Check to see if the net device we just got has a corresponding IP - // interface (could be a pure L2 NetDevice). + // interface (could be a pure L2 NetDevice) -- for example a net device + // associated with a bridge. // bool isIp = false; for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) @@ -659,7 +660,7 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p // this is a stub network. If we find another router, then what we have here // is a transit network. // - if (AnotherRouterOnLink (nd) == false) + if (AnotherRouterOnLink (nd, true) == false) { // // This is a net device connected to a stub network @@ -740,20 +741,13 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i) { Ptr ndTemp = bnd->GetBridgePort (i); - GlobalRoutingLSA *pLsaTest = new GlobalRoutingLSA; - NetDeviceContainer cTest; - ProcessSingleBroadcastLink (ndTemp, pLsaTest, cTest); // - // The GlobalRoutingLSA pLsaTest will now have a link record attached to - // it indicating what was found. If another router is found on any one - // of the bridged networks, we need to treat the whole bridge as a transit - // network. + // We have to decide if we are a transit network. This is characterized + // by the presence of another router on the network segment. If we find + // another router on any of our bridged links, we are a transit network. // - // If the link type is a transit network, then we have got to do some work - // to figure out what to do about the other routers on the bridge. - // - if (pLsaTest->GetLinkRecord (0)->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork) + if (AnotherRouterOnLink (ndTemp, true)) { areTransitNetwork = true; @@ -1112,36 +1106,83 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal) const // // Given a node and an attached net device, take a look off in the channel to // which the net device is attached and look for a node on the other side -// that has a GlobalRouter interface aggregated. +// that has a GlobalRouter interface aggregated. Life gets more complicated +// when there is a bridged net device on the other side. // bool -GlobalRouter::AnotherRouterOnLink (Ptr nd) const +GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (nd << allowRecursion); Ptr ch = nd->GetChannel(); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); + // + // Look through all of the devices on the channel to which the net device + // in questin is attached. + // for (uint32_t i = 0; i < nDevices; i++) { - Ptr ndTemp = ch->GetDevice (i); - NS_ASSERT (ndTemp); + NS_LOG_LOGIC ("**** Examine device " << i << "on node " << nd->GetNode ()->GetId ()); - if (ndTemp == nd) + Ptr ndOther = ch->GetDevice (i); + NS_ASSERT (ndOther); + + // + // Ignore the net device itself. + // + if (ndOther == nd) { + NS_LOG_LOGIC ("**** Self"); continue; } - Ptr nodeTemp = ndTemp->GetNode (); + // + // For all other net devices, we need to check and see if a router + // is present. If the net device on the other side is a bridged + // device, we need to consider all of the other devices on the + // bridge. + // + Ptr bnd = NetDeviceIsBridged (ndOther); + if (bnd) + { + NS_LOG_LOGIC ("**** Device is bridged"); + for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) + { + NS_LOG_LOGIC ("**** Examining bridge port " << j); + Ptr ndBridged = bnd->GetBridgePort (j); + if (ndBridged == ndOther) + { + NS_LOG_LOGIC ("**** Self"); + continue; + } + if (allowRecursion) + { + NS_LOG_LOGIC ("**** Recursing"); + if (AnotherRouterOnLink (ndBridged, false)) + { + NS_LOG_LOGIC ("**** Return true"); + return true; + } + } + } + NS_LOG_LOGIC ("**** Return false"); + return false; + } + + NS_LOG_LOGIC ("**** Device is not bridged"); + Ptr nodeTemp = ndOther->GetNode (); NS_ASSERT (nodeTemp); Ptr rtr = nodeTemp->GetObject (); if (rtr) { + NS_LOG_LOGIC ("**** Return true"); return true; } } + NS_LOG_LOGIC ("**** Return false"); return false; } @@ -1253,9 +1294,11 @@ GlobalRouter::FindIfIndexForDevice (Ptr node, Ptr nd, uint32_t // // Decide whether or not a given net device is being bridged by a BridgeNetDevice. // - bool -GlobalRouter::IsNetDeviceBridged (Ptr nd) const + Ptr +GlobalRouter::NetDeviceIsBridged (Ptr nd) const { + NS_LOG_FUNCTION (nd); + Ptr node = nd->GetNode (); uint32_t nDevices = node->GetNDevices(); @@ -1267,23 +1310,28 @@ GlobalRouter::IsNetDeviceBridged (Ptr nd) const // for (uint32_t i = 0; i < nDevices; ++i) { - Ptr nd = node->GetDevice(i); + Ptr ndTest = node->GetDevice(i); + NS_LOG_LOGIC ("**** Examine device " << i << " " << ndTest); - if (nd->IsBridge ()) + if (ndTest->IsBridge ()) { - Ptr bnd = nd->GetObject (); + NS_LOG_LOGIC ("**** device " << i << " is a bridge net device"); + Ptr bnd = ndTest->GetObject (); NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) { + NS_LOG_LOGIC ("**** Examine bridge port " << j << " " << bnd->GetBridgePort (j)); if (bnd->GetBridgePort (j) == nd) { - return true; + NS_LOG_LOGIC ("**** Net device " << nd << " is bridged by " << bnd); + return bnd; } } } } - return false; + NS_LOG_LOGIC ("**** Net device " << nd << " is not bridged"); + return 0; } } // namespace ns3 diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index 83a93aaed..24a155ecc 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -30,6 +30,7 @@ #include "ns3/channel.h" #include "ns3/ipv4-address.h" #include "ns3/net-device-container.h" +#include "ns3/bridge-net-device.h" #include "ns3/global-route-manager.h" namespace ns3 { @@ -642,14 +643,14 @@ private: Ptr GetAdjacent(Ptr nd, Ptr ch) const; bool FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const; Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal) const; - bool AnotherRouterOnLink (Ptr nd) const; + bool AnotherRouterOnLink (Ptr nd, bool allowRecursion) const; void ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); void ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); void ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); void ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA *pLSA); void BuildNetworkLSAs (NetDeviceContainer c); - bool IsNetDeviceBridged (Ptr nd) const; + Ptr NetDeviceIsBridged (Ptr nd) const; typedef std::list ListOfLSAs_t; From b66f046916e9876d3b7deb1525c83ef91b784990 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 20 Nov 2008 16:48:21 -0800 Subject: [PATCH 08/14] fix bug 114 and bug 66 --- examples/csma-bridge-one-hop.cc | 27 +- .../global-routing/global-router-interface.cc | 234 ++++++++++++------ .../global-routing/global-router-interface.h | 5 +- 3 files changed, 182 insertions(+), 84 deletions(-) diff --git a/examples/csma-bridge-one-hop.cc b/examples/csma-bridge-one-hop.cc index 812b1dd7c..e9876cffe 100644 --- a/examples/csma-bridge-one-hop.cc +++ b/examples/csma-bridge-one-hop.cc @@ -41,19 +41,19 @@ // Or, more abstractly, recognizing that bridge 1 and bridge 2 are nodes // with three net devices: // -// n0 n1 -// | | -// ----------- -// | bridge1 | <- n5 +// n0 n1 (n0 = 10.1.1.2) +// | | (n1 = 10.1.1.3) Note odd addressing +// ----------- (n2 = 10.1.1.1) +// | bridge1 | <- n5 // ----------- // | // router <- n2 // | // ----------- // | bridge2 | <- n6 -// ----------- -// | | -// n3 n4 +// ----------- (n2 = 10.1.2.1) +// | | (n3 = 10.1.2.2) +// n3 n4 (n4 = 10.1.2.3) // // So, this example shows two broadcast domains, each interconnected by a bridge // with a router node (n2) interconnecting the layer-2 broadcast domains @@ -61,7 +61,7 @@ // It is meant to mirror somewhat the csma-bridge example but adds another // bridged link separated by a router. // -// - CBR/UDP flows from n0 to n1 and from n3 to n0 +// - CBR/UDP flows from n0 (10.1.1.2) to n1 (10.1.1.3) and from n3 (10.1.2.2) to n0 (10.1.1.3) // - DropTail queues // - Global static routing // - Tracing of queues and packet receptions to file "csma-bridge-one-hop.tr" @@ -201,7 +201,9 @@ main (int argc, char *argv[]) // Create an optional packet sink to receive these packets PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (Ipv4Address::GetAny (), port))); - sink.Install (n1); + ApplicationContainer sink1 = sink.Install (n1); + sink1.Start (Seconds (1.0)); + sink1.Stop (Seconds (10.0)); // // Create a similar flow from n3 to n0, starting at time 1.1 seconds @@ -209,12 +211,13 @@ main (int argc, char *argv[]) onoff.SetAttribute ("Remote", AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.2"), port))); ApplicationContainer app2 = onoff.Install (n3); - - sink.Install (n0); - app2.Start (Seconds (1.1)); app2.Stop (Seconds (10.0)); + ApplicationContainer sink2 = sink.Install (n0); + sink2.Start (Seconds (1.1)); + sink2.Stop (Seconds (10.0)); + // // Configure tracing of all enqueue, dequeue, and NetDevice receive events. // Trace output will be sent to the file "csma-bridge-one-hop.tr" diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 65120bf66..f3632d7a4 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -383,9 +383,25 @@ GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status) void GlobalRoutingLSA::Print (std::ostream &os) const { - os << "m_lsType = " << m_lsType << std::endl << - "m_linkStateId = " << m_linkStateId << std::endl << - "m_advertisingRtr = " << m_advertisingRtr << std::endl; + os << std::endl; + os << "========== Global Routing LSA ==========" << std::endl; + os << "m_lsType = " << m_lsType; + if (m_lsType == GlobalRoutingLSA::RouterLSA) + { + os << " (GlobalRoutingLSA::RouterLSA)"; + } + else if (m_lsType == GlobalRoutingLSA::NetworkLSA) + { + os << " (GlobalRoutingLSA::NetworkLSA)"; + } + else + { + os << "(Unknown LSType)"; + } + os << std::endl; + + os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl; + os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl; if (m_lsType == GlobalRoutingLSA::RouterLSA) { @@ -394,30 +410,49 @@ GlobalRoutingLSA::Print (std::ostream &os) const i++) { GlobalRoutingLinkRecord *p = *i; - os << "----------" << std::endl; - os << "m_linkId = " << p->GetLinkId () << std::endl; - os << "m_linkData = " << p->GetLinkData () << std::endl; - os << "m_metric = " << p->GetMetric () << std::endl; + + os << "---------- RouterLSA Link Record ----------" << std::endl; + os << "m_linkType = " << p->m_linkType; + if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork) + { + os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl; + os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl; + os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl; + os << "m_metric = " << p->m_metric << std::endl; + } + else if (p->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork) + { + os << "(GlobalRoutingLinkRecord::StubNetwork)" << std::endl; + os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl; + os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl; + os << "m_metric = " << p->m_metric << std::endl; + } + else + { + os << "(Unknown LinkType)" << std::endl; + os << "m_linkId = " << p->m_linkId << std::endl; + os << "m_linkData = " << p->m_linkData << std::endl; + os << "m_metric = " << p->m_metric << std::endl; + } + os << "---------- End RouterLSA Link Record ----------" << std::endl; } } else if (m_lsType == GlobalRoutingLSA::NetworkLSA) { - os << "----------" << std::endl; - os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask - << std::endl; - for ( ListOfAttachedRouters_t::const_iterator i = - m_attachedRouters.begin (); - i != m_attachedRouters.end (); - i++) + os << "---------- NetworkLSA Link Record ----------" << std::endl; + os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl; + for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++) { Ipv4Address p = *i; os << "attachedRouter = " << p << std::endl; } + os << "---------- End NetworkLSA Link Record ----------" << std::endl; } else { NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType); } + os << "========== End Global Routing LSA ==========" << std::endl; } std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa) @@ -699,7 +734,7 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p // gets the IP interface address of the designated router in this // case. // - Ipv4Address desigRtr = FindDesignatedRouterForLink (nd); + Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true); if (desigRtr == addrLocal) { c.Add (nd); @@ -758,7 +793,7 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * // for the lowest address on each segment and pick the lowest of them // all. // - Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp); + Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true); if (desigRtrTemp < desigRtr) { desigRtr = desigRtrTemp; @@ -1041,66 +1076,114 @@ GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c) // connecting to the channel becomes the designated router for the link. // Ipv4Address -GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal) const +GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRecursion) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (ndLocal << allowRecursion); Ptr ch = ndLocal->GetChannel(); uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); - Ipv4Address addr ("255.255.255.255"); + NS_LOG_LOGIC ("**** Looking for designated router off of net device " << ndLocal << " on node " << + ndLocal->GetNode ()->GetId ()); + Ipv4Address desigRtr ("255.255.255.255"); + + // + // Look through all of the devices on the channel to which the net device + // in question is attached. + // for (uint32_t i = 0; i < nDevices; i++) { - Ptr currentNd = ch->GetDevice (i); - NS_ASSERT (currentNd); + Ptr ndOther = ch->GetDevice (i); + NS_ASSERT (ndOther); + + Ptr nodeOther = ndOther->GetNode (); + + NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << nodeOther->GetId ()); - Ptr currentNode = currentNd->GetNode (); - NS_ASSERT (currentNode); // - // We require a designated router to have a GlobalRouter interface and - // an internet stack that includes the Ipv4 interface. + // For all other net devices, we need to check and see if a router + // is present. If the net device on the other side is a bridged + // device, we need to consider all of the other devices on the + // bridge as well (all of the bridge ports. // - Ptr rtr = currentNode->GetObject (); - Ptr ipv4 = currentNode->GetObject (); - if (rtr == 0 || ipv4 == 0 ) + NS_LOG_LOGIC ("**** checking to see if the device is bridged"); + Ptr bnd = NetDeviceIsBridged (ndOther); + if (bnd) { - continue; + NS_LOG_LOGIC ("**** Device is bridged by BridgeNetDevice " << bnd); + + // + // It is possible that the bridge net device is sitting under a + // router, so we have to check for the presence of that router + // before we run off and follow all the links + // + // We require a designated router to have a GlobalRouter interface and + // an internet stack that includes the Ipv4 interface. If it doesn't + // it can't play router. + // + NS_LOG_LOGIC ("**** Checking for router on bridge net device " << bnd); + Ptr rtr = nodeOther->GetObject (); + Ptr ipv4 = nodeOther->GetObject (); + if (rtr && ipv4) + { + uint32_t ifIndexOther; + if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther)) + { + NS_LOG_LOGIC ("**** Found router on bridge net device " << bnd); + Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); + desigRtr = addrOther < desigRtr ? addrOther : desigRtr; + NS_LOG_LOGIC ("**** designated router now " << desigRtr); + } + } + + NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd); + for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) + { + Ptr ndBridged = bnd->GetBridgePort (j); + NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged); + if (ndBridged == ndOther) + { + NS_LOG_LOGIC ("**** That bridge port is me, don't walk backward"); + continue; + } + + if (allowRecursion) + { + NS_LOG_LOGIC ("**** Recursively looking for routers down bridge port " << ndBridged); + Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false); + desigRtr = addrOther < desigRtr ? addrOther : desigRtr; + NS_LOG_LOGIC ("**** designated router now " << desigRtr); + } + } } - - // - // This node could be a designated router, so we can check and see if - // it has a lower IP address than the one we have. In order to have - // an IP address, it needs to have an interface index. If it doesen't - // have an interface index directly, it's probably part of a bridge - // net device XXX which is not yet handled. - // - uint32_t currentIfIndex; - bool rc = FindIfIndexForDevice(currentNode, currentNd, currentIfIndex); - if (rc == false) + else { - continue; - } + NS_LOG_LOGIC ("**** This device is not bridged"); + Ptr nodeOther = ndOther->GetNode (); + NS_ASSERT (nodeOther); - // - // Okay, get the IP address corresponding to the interface we're - // examining and if it's the lowest so far, remember it. - // - Ipv4Address currentAddr = ipv4->GetAddress(currentIfIndex); - - if (currentAddr < addr) - { - addr = currentAddr; + // + // We require a designated router to have a GlobalRouter interface and + // an internet stack that includes the Ipv4 interface. If it doesn't + // + Ptr rtr = nodeOther->GetObject (); + Ptr ipv4 = nodeOther->GetObject (); + if (rtr && ipv4) + { + uint32_t ifIndexOther; + if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther)) + { + NS_LOG_LOGIC ("**** Found router on net device " << ndOther); + Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); + desigRtr = addrOther < desigRtr ? addrOther : desigRtr; + NS_LOG_LOGIC ("**** designated router now " << desigRtr); + } + } } } - - // - // Return the lowest IP address found, which will become the designated router - // for the link. - // - NS_ASSERT_MSG (addr.IsBroadcast() == false, "GlobalRouter::FindDesignatedRouterForLink(): Bogus address"); - return addr; + return desigRtr; } // @@ -1118,23 +1201,25 @@ GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); + NS_LOG_LOGIC ("**** Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ()); + // // Look through all of the devices on the channel to which the net device - // in questin is attached. + // in question is attached. // for (uint32_t i = 0; i < nDevices; i++) { - NS_LOG_LOGIC ("**** Examine device " << i << "on node " << nd->GetNode ()->GetId ()); - Ptr ndOther = ch->GetDevice (i); NS_ASSERT (ndOther); + NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ()); + // // Ignore the net device itself. // if (ndOther == nd) { - NS_LOG_LOGIC ("**** Self"); + NS_LOG_LOGIC ("**** Myself, skip"); continue; } @@ -1144,45 +1229,52 @@ GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const // device, we need to consider all of the other devices on the // bridge. // + NS_LOG_LOGIC ("**** checking to see if device is bridged"); Ptr bnd = NetDeviceIsBridged (ndOther); if (bnd) { - NS_LOG_LOGIC ("**** Device is bridged"); + NS_LOG_LOGIC ("**** Device is bridged by net device " << bnd); + NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd); for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) { - NS_LOG_LOGIC ("**** Examining bridge port " << j); Ptr ndBridged = bnd->GetBridgePort (j); + NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged); if (ndBridged == ndOther) { - NS_LOG_LOGIC ("**** Self"); + NS_LOG_LOGIC ("**** That bridge port is me, skip"); continue; } + if (allowRecursion) { - NS_LOG_LOGIC ("**** Recursing"); + NS_LOG_LOGIC ("**** Recursively looking for routers on bridge port " << ndBridged); if (AnotherRouterOnLink (ndBridged, false)) { - NS_LOG_LOGIC ("**** Return true"); + NS_LOG_LOGIC ("**** Found routers on bridge port, return true"); return true; } } } - NS_LOG_LOGIC ("**** Return false"); + NS_LOG_LOGIC ("**** No routers on bridged net device, return false"); return false; } - NS_LOG_LOGIC ("**** Device is not bridged"); + NS_LOG_LOGIC ("**** This device is not bridged"); Ptr nodeTemp = ndOther->GetNode (); NS_ASSERT (nodeTemp); Ptr rtr = nodeTemp->GetObject (); if (rtr) { - NS_LOG_LOGIC ("**** Return true"); + NS_LOG_LOGIC ("**** Found GlobalRouter interface, return true"); return true; } + else + { + NS_LOG_LOGIC ("**** No GlobalRouter interface on device, continue search"); + } } - NS_LOG_LOGIC ("**** Return false"); + NS_LOG_LOGIC ("**** No routers found, return false"); return false; } diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index 24a155ecc..80116172a 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -35,6 +35,8 @@ namespace ns3 { +class GlobalRouter; + /** * @brief A single link record for a link state advertisement. * @@ -45,6 +47,7 @@ namespace ns3 { class GlobalRoutingLinkRecord { public: + friend class GlobalRoutingLSA; /** * @enum LinkType * @brief Enumeration of the possible types of Global Routing Link Records. @@ -642,7 +645,7 @@ private: Ptr GetAdjacent(Ptr nd, Ptr ch) const; bool FindIfIndexForDevice(Ptr node, Ptr nd, uint32_t &index) const; - Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal) const; + Ipv4Address FindDesignatedRouterForLink (Ptr ndLocal, bool allowRecursion) const; bool AnotherRouterOnLink (Ptr nd, bool allowRecursion) const; void ProcessBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); void ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c); From 46b8c8c9fca53ca9f0c81920fd0626ec2efb13a5 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Thu, 20 Nov 2008 20:50:17 -0800 Subject: [PATCH 09/14] remove some hey-look-here debugging flags --- .../global-routing/global-router-interface.cc | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index f3632d7a4..be23d311c 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -597,7 +597,7 @@ GlobalRouter::DiscoverLSAs (void) if (!isIp) { - NS_LOG_LOGIC ("**** Net device " << ndLocal << "has no IP interface, skipping"); + NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface, skipping"); continue; } @@ -612,12 +612,12 @@ GlobalRouter::DiscoverLSAs (void) // if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { - NS_LOG_LOGIC ("**** Broadcast link"); + NS_LOG_LOGIC ("Broadcast link"); ProcessBroadcastLink (ndLocal, pLSA, c); } else if (ndLocal->IsPointToPoint () ) { - NS_LOG_LOGIC ("**** Point=to-point link"); + NS_LOG_LOGIC ("Point=to-point link"); ProcessPointToPointLink (ndLocal, pLSA); } else @@ -700,7 +700,7 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p // // This is a net device connected to a stub network // - NS_LOG_LOGIC("**** Router-LSA Stub Network"); + NS_LOG_LOGIC("Router-LSA Stub Network"); plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); // @@ -725,7 +725,7 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p // We have multiple routers on a broadcast interface, so this is // a transit network. // - NS_LOG_LOGIC ("**** Router-LSA Transit Network"); + NS_LOG_LOGIC ("Router-LSA Transit Network"); plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); // @@ -835,7 +835,7 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * // // This is a net device connected to a bridge of stub networks // - NS_LOG_LOGIC("**** Router-LSA Stub Network"); + NS_LOG_LOGIC("Router-LSA Stub Network"); plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); // @@ -860,7 +860,7 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * // We have multiple routers on a bridged broadcast interface, so this is // a transit network. // - NS_LOG_LOGIC ("**** Router-LSA Transit Network"); + NS_LOG_LOGIC ("Router-LSA Transit Network"); plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork); // @@ -1084,7 +1084,7 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); - NS_LOG_LOGIC ("**** Looking for designated router off of net device " << ndLocal << " on node " << + NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " << ndLocal->GetNode ()->GetId ()); Ipv4Address desigRtr ("255.255.255.255"); @@ -1100,7 +1100,7 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec Ptr nodeOther = ndOther->GetNode (); - NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << nodeOther->GetId ()); + NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ()); // // For all other net devices, we need to check and see if a router @@ -1108,11 +1108,11 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec // device, we need to consider all of the other devices on the // bridge as well (all of the bridge ports. // - NS_LOG_LOGIC ("**** checking to see if the device is bridged"); + NS_LOG_LOGIC ("checking to see if the device is bridged"); Ptr bnd = NetDeviceIsBridged (ndOther); if (bnd) { - NS_LOG_LOGIC ("**** Device is bridged by BridgeNetDevice " << bnd); + NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd); // // It is possible that the bridge net device is sitting under a @@ -1123,7 +1123,7 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec // an internet stack that includes the Ipv4 interface. If it doesn't // it can't play router. // - NS_LOG_LOGIC ("**** Checking for router on bridge net device " << bnd); + NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd); Ptr rtr = nodeOther->GetObject (); Ptr ipv4 = nodeOther->GetObject (); if (rtr && ipv4) @@ -1131,36 +1131,36 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec uint32_t ifIndexOther; if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther)) { - NS_LOG_LOGIC ("**** Found router on bridge net device " << bnd); + NS_LOG_LOGIC ("Found router on bridge net device " << bnd); Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); desigRtr = addrOther < desigRtr ? addrOther : desigRtr; - NS_LOG_LOGIC ("**** designated router now " << desigRtr); + NS_LOG_LOGIC ("designated router now " << desigRtr); } } - NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd); + NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd); for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) { Ptr ndBridged = bnd->GetBridgePort (j); - NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged); + NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged); if (ndBridged == ndOther) { - NS_LOG_LOGIC ("**** That bridge port is me, don't walk backward"); + NS_LOG_LOGIC ("That bridge port is me, don't walk backward"); continue; } if (allowRecursion) { - NS_LOG_LOGIC ("**** Recursively looking for routers down bridge port " << ndBridged); + NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged); Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false); desigRtr = addrOther < desigRtr ? addrOther : desigRtr; - NS_LOG_LOGIC ("**** designated router now " << desigRtr); + NS_LOG_LOGIC ("designated router now " << desigRtr); } } } else { - NS_LOG_LOGIC ("**** This device is not bridged"); + NS_LOG_LOGIC ("This device is not bridged"); Ptr nodeOther = ndOther->GetNode (); NS_ASSERT (nodeOther); @@ -1175,10 +1175,10 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec uint32_t ifIndexOther; if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther)) { - NS_LOG_LOGIC ("**** Found router on net device " << ndOther); + NS_LOG_LOGIC ("Found router on net device " << ndOther); Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); desigRtr = addrOther < desigRtr ? addrOther : desigRtr; - NS_LOG_LOGIC ("**** designated router now " << desigRtr); + NS_LOG_LOGIC ("designated router now " << desigRtr); } } } @@ -1201,7 +1201,7 @@ GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const uint32_t nDevices = ch->GetNDevices(); NS_ASSERT (nDevices); - NS_LOG_LOGIC ("**** Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ()); + NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ()); // // Look through all of the devices on the channel to which the net device @@ -1212,14 +1212,14 @@ GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const Ptr ndOther = ch->GetDevice (i); NS_ASSERT (ndOther); - NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ()); + NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ()); // // Ignore the net device itself. // if (ndOther == nd) { - NS_LOG_LOGIC ("**** Myself, skip"); + NS_LOG_LOGIC ("Myself, skip"); continue; } @@ -1229,52 +1229,52 @@ GlobalRouter::AnotherRouterOnLink (Ptr nd, bool allowRecursion) const // device, we need to consider all of the other devices on the // bridge. // - NS_LOG_LOGIC ("**** checking to see if device is bridged"); + NS_LOG_LOGIC ("checking to see if device is bridged"); Ptr bnd = NetDeviceIsBridged (ndOther); if (bnd) { - NS_LOG_LOGIC ("**** Device is bridged by net device " << bnd); - NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd); + NS_LOG_LOGIC ("Device is bridged by net device " << bnd); + NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd); for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) { Ptr ndBridged = bnd->GetBridgePort (j); - NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged); + NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged); if (ndBridged == ndOther) { - NS_LOG_LOGIC ("**** That bridge port is me, skip"); + NS_LOG_LOGIC ("That bridge port is me, skip"); continue; } if (allowRecursion) { - NS_LOG_LOGIC ("**** Recursively looking for routers on bridge port " << ndBridged); + NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged); if (AnotherRouterOnLink (ndBridged, false)) { - NS_LOG_LOGIC ("**** Found routers on bridge port, return true"); + NS_LOG_LOGIC ("Found routers on bridge port, return true"); return true; } } } - NS_LOG_LOGIC ("**** No routers on bridged net device, return false"); + NS_LOG_LOGIC ("No routers on bridged net device, return false"); return false; } - NS_LOG_LOGIC ("**** This device is not bridged"); + NS_LOG_LOGIC ("This device is not bridged"); Ptr nodeTemp = ndOther->GetNode (); NS_ASSERT (nodeTemp); Ptr rtr = nodeTemp->GetObject (); if (rtr) { - NS_LOG_LOGIC ("**** Found GlobalRouter interface, return true"); + NS_LOG_LOGIC ("Found GlobalRouter interface, return true"); return true; } else { - NS_LOG_LOGIC ("**** No GlobalRouter interface on device, continue search"); + NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search"); } } - NS_LOG_LOGIC ("**** No routers found, return false"); + NS_LOG_LOGIC ("No routers found, return false"); return false; } @@ -1365,7 +1365,7 @@ GlobalRouter::FindIfIndexForDevice (Ptr node, Ptr nd, uint32_t Ptr ipv4 = node->GetObject (); if (ipv4 == 0) { - NS_LOG_LOGIC ("**** No Ipv4 interface on node " << node->GetId ()); + NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ()); return false; } @@ -1373,13 +1373,13 @@ GlobalRouter::FindIfIndexForDevice (Ptr node, Ptr nd, uint32_t { if (ipv4->GetNetDevice(i) == nd) { - NS_LOG_LOGIC ("**** Device " << nd << " has associated ipv4 index " << i); + NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i); index = i; return true; } } - NS_LOG_LOGIC ("**** Device " << nd << " has no associated ipv4 index"); + NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index"); return false; } @@ -1403,26 +1403,26 @@ GlobalRouter::NetDeviceIsBridged (Ptr nd) const for (uint32_t i = 0; i < nDevices; ++i) { Ptr ndTest = node->GetDevice(i); - NS_LOG_LOGIC ("**** Examine device " << i << " " << ndTest); + NS_LOG_LOGIC ("Examine device " << i << " " << ndTest); if (ndTest->IsBridge ()) { - NS_LOG_LOGIC ("**** device " << i << " is a bridge net device"); + NS_LOG_LOGIC ("device " << i << " is a bridge net device"); Ptr bnd = ndTest->GetObject (); NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j) { - NS_LOG_LOGIC ("**** Examine bridge port " << j << " " << bnd->GetBridgePort (j)); + NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j)); if (bnd->GetBridgePort (j) == nd) { - NS_LOG_LOGIC ("**** Net device " << nd << " is bridged by " << bnd); + NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd); return bnd; } } } } - NS_LOG_LOGIC ("**** Net device " << nd << " is not bridged"); + NS_LOG_LOGIC ("Net device " << nd << " is not bridged"); return 0; } From 8e049d919463d7e0195b67e68058ecd8959a3e73 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Mon, 24 Nov 2008 21:39:00 -0800 Subject: [PATCH 10/14] document wifi-wired-bridging a little and add aborts if bridged net devices with IP addresses found --- examples/wifi-wired-bridging.cc | 40 +++++++++ .../global-route-manager-impl.cc | 44 +++++----- .../global-routing/global-router-interface.cc | 83 ++++++++++++++----- 3 files changed, 122 insertions(+), 45 deletions(-) diff --git a/examples/wifi-wired-bridging.cc b/examples/wifi-wired-bridging.cc index 2852ae9b6..8cade4c45 100644 --- a/examples/wifi-wired-bridging.cc +++ b/examples/wifi-wired-bridging.cc @@ -1,4 +1,44 @@ /* -*- 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 + */ + +// Default network topology +// +// +-----+ +-----+ +-----+ +-----+ +// | sta | | sta | | sta | | sta | +// +-----+ +-----+ +-----+ +-----+ +// 192.168.1.2 192.168.1.3 192.168.2.2 192.168.2.3 +// -------- -------- -------- -------- +// WIFI STA WIFI STA WIFI STA WIFI STA +// -------- -------- | -------- -------- +// ((*)) ((*)) | ((*)) ((*)) +// | +// ((*)) | ((*)) +// ------- | ------- +// ######## WIFI AP WIFI AP ######### +// # ------- ------- # +// B # 102.168.1.1 102.168.2.1 # B +// R # +----------+ +----------+ # R +// I # | backbone | | backbone | # I +// D # +----------+ +----------+ # D +// G # 192.168.0.1 192.168.0.2 # G +// E # ---- ---- # E +// ########## CSMA CSMA ########## +// | | +// ================================ +// #include "ns3/core-module.h" #include "ns3/simulator-module.h" diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 267e53f09..66192c2d0 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -97,7 +97,7 @@ SPFVertex::~SPFVertex () void SPFVertex::SetVertexType (SPFVertex::VertexType type) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (type); m_vertexType = type; } @@ -111,7 +111,7 @@ SPFVertex::GetVertexType (void) const void SPFVertex::SetVertexId (Ipv4Address id) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (id); m_vertexId = id; } @@ -125,7 +125,7 @@ SPFVertex::GetVertexId (void) const void SPFVertex::SetLSA (GlobalRoutingLSA* lsa) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (lsa); m_lsa = lsa; } @@ -139,7 +139,7 @@ SPFVertex::GetLSA (void) const void SPFVertex::SetDistanceFromRoot (uint32_t distance) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (distance); m_distanceFromRoot = distance; } @@ -153,7 +153,7 @@ SPFVertex::GetDistanceFromRoot (void) const void SPFVertex::SetOutgoingTypeId (uint32_t id) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (id); m_rootOif = id; } @@ -167,7 +167,7 @@ SPFVertex::GetOutgoingTypeId (void) const void SPFVertex::SetNextHop (Ipv4Address nextHop) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (nextHop); m_nextHop = nextHop; } @@ -181,7 +181,7 @@ SPFVertex::GetNextHop (void) const void SPFVertex::SetParent (SPFVertex* parent) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (parent); m_parent = parent; } @@ -202,7 +202,7 @@ SPFVertex::GetNChildren (void) const SPFVertex* SPFVertex::GetChild (uint32_t n) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (n); uint32_t j = 0; for ( ListOfSPFVertex_t::const_iterator i = m_children.begin (); @@ -221,7 +221,7 @@ SPFVertex::GetChild (uint32_t n) const uint32_t SPFVertex::AddChild (SPFVertex* child) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (child); m_children.push_back (child); return m_children.size (); } @@ -268,14 +268,14 @@ GlobalRouteManagerLSDB::Initialize () void GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (addr << lsa); m_database.insert (LSDBPair_t (addr, lsa)); } GlobalRoutingLSA* GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (addr); // // Look up an LSA by its address. // @@ -293,7 +293,7 @@ GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const GlobalRoutingLSA* GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (addr); // // Look up an LSA by its address. // @@ -341,7 +341,7 @@ GlobalRouteManagerImpl::~GlobalRouteManagerImpl () void GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (lsdb); if (m_lsdb) { delete m_lsdb; @@ -373,7 +373,7 @@ GlobalRouteManagerImpl::SelectRouterNodes () void GlobalRouteManagerImpl::SelectRouterNodes (NodeContainer c) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (&c); for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) { Ptr node = *i; @@ -518,7 +518,7 @@ GlobalRouteManagerImpl::InitializeRoutes () void GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v << &candidate); SPFVertex* w = 0; GlobalRoutingLSA* w_lsa = 0; @@ -720,7 +720,7 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( GlobalRoutingLinkRecord* l, uint32_t distance) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v << w << l << distance); // // If w is a NetworkVertex, l should be null /* @@ -905,7 +905,7 @@ GlobalRouteManagerImpl::SPFGetNextLink ( SPFVertex* w, GlobalRoutingLinkRecord* prev_link) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v << w << prev_link); bool skip = true; bool found_prev_link = false; @@ -980,7 +980,7 @@ GlobalRouteManagerImpl::SPFGetNextLink ( void GlobalRouteManagerImpl::DebugSPFCalculate (Ipv4Address root) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (root); SPFCalculate (root); } @@ -1137,7 +1137,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) uint32_t GlobalRouteManagerImpl::FindOutgoingTypeId (Ipv4Address a, Ipv4Mask amask) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (a << amask); // // We have an IP address and a vertex ID of the root of the SPF tree. // The question is what interface index does this address correspond to. @@ -1213,7 +1213,7 @@ GlobalRouteManagerImpl::FindOutgoingTypeId (Ipv4Address a, Ipv4Mask amask) void GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v); NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set"); @@ -1330,7 +1330,7 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) void GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v); NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set"); @@ -1423,7 +1423,7 @@ GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v) void GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (v); v->GetParent ()->AddChild (v); } diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index be23d311c..179512e71 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -580,10 +580,24 @@ GlobalRouter::DiscoverLSAs (void) { Ptr ndLocal = node->GetDevice(i); + // + // There is an assumption that bridge ports must never have an IP address + // associated with them. This turns out to be a very convenient place to + // check and make sure that this is the case. + // + if (NetDeviceIsBridged (ndLocal)) + { + uint32_t ifIndexBridge; + bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexBridge); + NS_ABORT_MSG_IF (rc, "GlobalRouter::ProcessBridgedBroadcastLink(): " + "Bridge ports must not have an IPv4 interface index"); + } + // // Check to see if the net device we just got has a corresponding IP // interface (could be a pure L2 NetDevice) -- for example a net device - // associated with a bridge. + // associated with a bridge. We are only going to involve devices with + // IP addresses in routing. // bool isIp = false; for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) @@ -735,6 +749,18 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p // case. // Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true); + + // + // Let's double-check that any designated router we find out on our + // network is really on our network. + // + if (desigRtr != "255.255.255.255") + { + Ipv4Address networkHere = addrLocal.CombineMask (maskLocal); + Ipv4Address networkThere = desigRtr.CombineMask (maskLocal); + NS_ABORT_MSG_UNLESS (networkHere == networkThere, + "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion"); + } if (desigRtr == addrLocal) { c.Add (nd); @@ -762,6 +788,27 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * Ptr bnd = nd->GetObject (); NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); + // + // We have some preliminaries to do to get enough information to proceed. + // This information we need comes from the internet stack, so notice that + // there is an implied assumption that global routing is only going to + // work with devices attached to the internet stack (have an ipv4 interface + // associated to them. + // + Ptr node = nd->GetNode (); + + uint32_t ifIndexLocal; + bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal); + NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device"); + + Ptr ipv4Local = node->GetObject (); + NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for interface failed"); + + Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); + Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); + NS_LOG_LOGIC ("Working with local address " << addrLocal); + uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); + // // We need to handle a bridge on the router. This means that we have been // given a net device that is a BridgeNetDevice. It has an associated Ipv4 @@ -794,13 +841,24 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * // all. // Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true); + + // + // Let's double-check that any designated router we find out on our + // network is really on our network. + // + if (desigRtrTemp != "255.255.255.255") + { + Ipv4Address networkHere = addrLocal.CombineMask (maskLocal); + Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal); + NS_ABORT_MSG_UNLESS (networkHere == networkThere, + "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion"); + } if (desigRtrTemp < desigRtr) { desigRtr = desigRtrTemp; } } } - // // That's all the information we need to put it all together, just like we did // in the case of a single broadcast link. @@ -809,27 +867,6 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record"); - // - // We have some preliminaries to do to get enough information to proceed. - // This information we need comes from the internet stack, so notice that - // there is an implied assumption that global routing is only going to - // work with devices attached to the internet stack (have an ipv4 interface - // associated to them. - // - Ptr node = nd->GetNode (); - - uint32_t ifIndexLocal; - bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal); - NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device"); - - Ptr ipv4Local = node->GetObject (); - NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for interface failed"); - - Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal); - Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal); - NS_LOG_LOGIC ("Working with local address " << addrLocal); - uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal); - if (areTransitNetwork == false) { // From f69d0dfffd803eeee340a336ed7320c4bd8ff24e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Wed, 26 Nov 2008 04:27:10 -0800 Subject: [PATCH 11/14] bug 421: memory leak in csma-ping --- src/applications/v4ping/v4ping.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/applications/v4ping/v4ping.cc b/src/applications/v4ping/v4ping.cc index e70917e60..2e53e5e64 100644 --- a/src/applications/v4ping/v4ping.cc +++ b/src/applications/v4ping/v4ping.cc @@ -149,6 +149,7 @@ void V4Ping::StopApplication (void) { NS_LOG_FUNCTION (this); + m_socket->Close (); } From 80b1ce258da9e62d27a9929be5406a083f388fe1 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Wed, 26 Nov 2008 14:55:35 +0000 Subject: [PATCH 12/14] Fix waf problem running programs with arguments. --- wscript | 9 +++------ wutils.py | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/wscript b/wscript index 85097f941..894310e68 100644 --- a/wscript +++ b/wscript @@ -447,16 +447,13 @@ def build(bld): if Params.g_options.run: # Check that the requested program name is valid - try: - wutils.find_program(Params.g_options.run, env) - except ValueError, ex: - Params.fatal(str(ex)) - + program_name, dummy_program_argv = wutils.get_run_program(Params.g_options.run, get_command_template()) + # When --run'ing a program, tell WAF to only build that program, # nothing more; this greatly speeds up compilation when all you # want to do is run a test program. if not Params.g_options.compile_targets: - Params.g_options.compile_targets = Params.g_options.run + Params.g_options.compile_targets = program_name diff --git a/wutils.py b/wutils.py index 2baf21ae2..fe89dd579 100644 --- a/wutils.py +++ b/wutils.py @@ -94,13 +94,12 @@ def run_argv(argv, os_env=None): Params.fatal("Command %s exited with code %i" % (argv, retval)) return retval -def run_program(program_string, command_template=None): +def get_run_program(program_string, command_template=None): """ - if command_template is not None, then program_string == program - name and argv is given by command_template with %s replaced by the - full path to the program. Else, program_string is interpreted as - a shell command with first name being the program name. + Return the program name and argv of the process that would be executed by + run_program(program_string, command_template). """ + #print "get_run_program_argv(program_string=%r, command_template=%r)" % (program_string, command_template) env = Params.g_build.env_of_name('default') if command_template in (None, '%s'): @@ -132,7 +131,16 @@ def run_program(program_string, command_template=None): Params.fatal("%s does not appear to be a program" % (program_name,)) execvec = shlex.split(command_template % (program_node.abspath(env),)) + return program_name, execvec +def run_program(program_string, command_template=None): + """ + if command_template is not None, then program_string == program + name and argv is given by command_template with %s replaced by the + full path to the program. Else, program_string is interpreted as + a shell command with first name being the program name. + """ + dummy_program_name, execvec = get_run_program(program_string, command_template) former_cwd = os.getcwd() if (Params.g_options.cwd_launch): os.chdir(Params.g_options.cwd_launch) From d27274e9585ec05cea5ddeae2cc33470d4ce4765 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 26 Nov 2008 13:48:53 -0800 Subject: [PATCH 13/14] disallow routing on bridge devices with IP address, fix wifi-wired-bridging --- examples/wifi-wired-bridging.cc | 46 ++++++++++--------- .../global-route-manager-impl.cc | 14 +++--- .../global-routing/global-router-interface.cc | 17 +++++-- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/examples/wifi-wired-bridging.cc b/examples/wifi-wired-bridging.cc index 8cade4c45..3d0ffb69e 100644 --- a/examples/wifi-wired-bridging.cc +++ b/examples/wifi-wired-bridging.cc @@ -14,30 +14,32 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// Default network topology +// Default network topology includes some number of AP nodes specified by +// the variable nWifis (defaults to two). Off of each AP node, there are some +// number of STA nodes specified by the variable nStas (defaults to two). +// Each AP talks to its associated STA nodes. There are bridge net devices +// on each AP node that bridge the whole thing into one network. // // +-----+ +-----+ +-----+ +-----+ -// | sta | | sta | | sta | | sta | +// | STA | | STA | | STA | | STA | // +-----+ +-----+ +-----+ +-----+ -// 192.168.1.2 192.168.1.3 192.168.2.2 192.168.2.3 +// 192.168.0.3 192.168.0.4 192.168.0.5 192.168.0.6 // -------- -------- -------- -------- // WIFI STA WIFI STA WIFI STA WIFI STA -// -------- -------- | -------- -------- +// -------- -------- -------- -------- // ((*)) ((*)) | ((*)) ((*)) // | -// ((*)) | ((*)) -// ------- | ------- -// ######## WIFI AP WIFI AP ######### -// # ------- ------- # -// B # 102.168.1.1 102.168.2.1 # B -// R # +----------+ +----------+ # R -// I # | backbone | | backbone | # I -// D # +----------+ +----------+ # D -// G # 192.168.0.1 192.168.0.2 # G -// E # ---- ---- # E -// ########## CSMA CSMA ########## -// | | -// ================================ +// ((*)) | ((*)) +// ------- ------- +// WIFI AP CSMA ========= CSMA WIFI AP +// ------- ---- ---- ------- +// ############## ############## +// BRIDGE BRIDGE +// ############## ############## +// 192.168.0.1 192.168.0.2 +// +---------+ +---------+ +// | AP Node | | AP Node | +// +---------+ +---------+ // #include "ns3/core-module.h" @@ -86,7 +88,6 @@ int main (int argc, char *argv[]) stack.Install (backboneNodes); backboneDevices = csma.Install (backboneNodes); - backboneInterfaces = ip.Assign (backboneDevices); double wifiX = 0.0; for (uint32_t i = 0; i < nWifis; ++i) @@ -109,7 +110,6 @@ int main (int argc, char *argv[]) wifiPhy.SetChannel (wifiChannel.Create ()); sta.Create (nStas); - ip.NewNetwork (); mobility.SetPositionAllocator ("ns3::GridPositionAllocator", "MinX", DoubleValue (wifiX), "MinY", DoubleValue (0.0), @@ -127,8 +127,12 @@ int main (int argc, char *argv[]) "BeaconGeneration", BooleanValue (true), "BeaconInterval", TimeValue (Seconds (2.5))); apDev = wifi.Install (wifiPhy, backboneNodes.Get (i)); - apInterface = ip.Assign (apDev); - bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i))); + + NetDeviceContainer bridgeDev; + bridgeDev = bridge.Install (backboneNodes.Get (i), NetDeviceContainer (apDev, backboneDevices.Get (i))); + + // assign AP IP address to bridge, not wifi + apInterface = ip.Assign (bridgeDev); // setup the STAs stack.Install (sta); diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 66192c2d0..eb9ff94c9 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -214,7 +214,7 @@ SPFVertex::GetChild (uint32_t n) const return *i; } } - NS_ASSERT_MSG(false, "Index out of range."); + NS_ASSERT_MSG (false, "Index out of range."); return 0; } @@ -726,7 +726,7 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( /* if (w->GetVertexType () == SPFVertex::VertexNetwork && l) { - NS_ASSERT_MSG(0, "Error: SPFNexthopCalculation parameter problem"); + NS_ASSERT_MSG (0, "Error: SPFNexthopCalculation parameter problem"); } */ @@ -778,7 +778,7 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( // return the link record describing the link from to . Think of it as // SPFGetLink. // - NS_ASSERT(l); + NS_ASSERT (l); GlobalRoutingLinkRecord *linkRemote = 0; linkRemote = SPFGetNextLink (w, v, linkRemote); // @@ -792,7 +792,7 @@ GlobalRouteManagerImpl::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->SetNextHop(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" @@ -846,7 +846,7 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( * use can then be derived from the next hop IP address (or * it can be inherited from the parent network). */ - w->SetNextHop(linkRemote->GetLinkData ()); + w->SetNextHop (linkRemote->GetLinkData ()); w->SetOutgoingTypeId (v->GetOutgoingTypeId ()); NS_LOG_LOGIC ("Next hop from " << v->GetVertexId () << " to " << w->GetVertexId () << @@ -1001,7 +1001,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) // of the tree. Initially, this queue is empty. // CandidateQueue candidate; - NS_ASSERT(candidate.Size () == 0); + 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 @@ -1108,7 +1108,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) } else { - NS_ASSERT_MSG(0, "illegal SPFVertex type"); + NS_ASSERT_MSG (0, "illegal SPFVertex type"); } // // RFC2328 16.1. (5). diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 179512e71..19558c05b 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -589,8 +589,7 @@ GlobalRouter::DiscoverLSAs (void) { uint32_t ifIndexBridge; bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexBridge); - NS_ABORT_MSG_IF (rc, "GlobalRouter::ProcessBridgedBroadcastLink(): " - "Bridge ports must not have an IPv4 interface index"); + NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index"); } // @@ -782,9 +781,19 @@ GlobalRouter::ProcessSingleBroadcastLink (Ptr nd, GlobalRoutingLSA *p GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c) { NS_LOG_FUNCTION (nd << pLSA << &c); - NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device"); +#if 0 + // + // It is possible to admit the possibility that a bridge device on a node + // can also participate in routing. This would surprise people who don't + // come from Microsoft-land where they do use such a construct. Based on + // the principle of least-surprise, we will leave the relatively simple + // code in place to do this, but not enable it until someone really wants + // the capability. Even then, we will not enable this code as a default + // but rather something you will have to go and turn on. + // + Ptr bnd = nd->GetObject (); NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for failed"); @@ -817,6 +826,7 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * // to do is to repeat what is done for a single broadcast link on all of // those net devices living under the bridge (trolls?) // + bool areTransitNetwork = false; Ipv4Address desigRtr ("255.255.255.255"); @@ -921,6 +931,7 @@ GlobalRouter::ProcessBridgedBroadcastLink (Ptr nd, GlobalRoutingLSA * pLSA->AddLinkRecord (plr); plr = 0; } +#endif } void From 4913060911d25eea4adfb0bf82b0a37a83e5754f Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 26 Nov 2008 14:00:05 -0800 Subject: [PATCH 14/14] CHANGES.html for global routing supporting bridges --- CHANGES.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.html b/CHANGES.html index 82e79eb9b..00d1fcb26 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -106,6 +106,14 @@ assignment of /32 addresses. +
  • 17-11-2008; changeset +756887a9bbea
  • +
      +
    • +Global routing supports bridge devices. +
    • +
    +

    changes from ns-3.1 to ns-3.2