diff --git a/examples/simple-alternate-routing.cc b/examples/simple-alternate-routing.cc new file mode 100644 index 000000000..e9cedff04 --- /dev/null +++ b/examples/simple-alternate-routing.cc @@ -0,0 +1,224 @@ +/* -*- 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 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 ------------------------n3 +// / / +// / 5 Mb/s, 2ms / +// n1-------------------------- +// 1.5 Mb/s, 100ms +// +// this is a modification of simple-global-routing to allow for +// a single hop but higher-cost path between n1 and n3 +// +// - Tracing of queues and packet receptions to file "simple-rerouting.tr" + +#include +#include +#include +#include + +#include "ns3/log.h" + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/inet-socket-address.h" +#include "ns3/ipv4-route.h" +#include "ns3/point-to-point-topology.h" +#include "ns3/onoff-application.h" +#include "ns3/packet-sink.h" +#include "ns3/global-route-manager.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("SimpleAlternateRoutingExample"); + +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("GlobalRouteManager", LOG_LOGIC); + LogComponentEnable("GlobalRouter", LOG_LOGIC); + LogComponentEnable("Object", LOG_LEVEL_ALL); + LogComponentEnable("Queue", LOG_LEVEL_ALL); + LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL); + LogComponentEnable("Channel", LOG_LEVEL_ALL); + LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL); + LogComponentEnable("NetDevice", LOG_LEVEL_ALL); + LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("PacketSocket", LOG_LEVEL_ALL); + LogComponentEnable("Socket", LOG_LEVEL_ALL); + LogComponentEnable("UdpSocket", LOG_LEVEL_ALL); + LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL); + LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL); + LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL); + LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL); + LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL); +#endif + // Set up some default values for the simulation. Use the + // DefaultValue::Bind () technique to tell the system what subclass of + // Queue to use, and what the queue limit is + + // The below Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + DefaultValue::Bind ("Queue", "DropTailQueue"); + + DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); + DefaultValue::Bind ("OnOffApplicationDataRate", "300b/s"); + + // The below metric, if set to 3 or higher, will cause packets between + // n1 and n3 to take the 2-hop route through n2 + // + // Additionally, we plumb this metric into the default value / command + // line argument system as well, for exemplary purposes. This means + // that it can be resettable at the command-line to the program, + // rather than recompiling + // e.g. waf --run "simple-alternate-routing --AlternateCost=5" + uint16_t sampleMetric = 1; + CommandLine::AddArgValue ("AlternateCost", + "This metric is used in the example script between n3 and n1 ", + sampleMetric); + + // Allow the user to override any of the defaults and the above + // DefaultValue::Bind ()s at run-time, via command-line arguments + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + NS_LOG_INFO ("Create nodes."); + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information + NS_LOG_INFO ("Create channels."); + Ptr channel0 = + PointToPointTopology::AddPointToPointLink ( + n0, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel1 = + PointToPointTopology::AddPointToPointLink ( + n1, n2, DataRate (5000000), MilliSeconds (2)); + + Ptr channel2 = + PointToPointTopology::AddPointToPointLink ( + n2, n3, DataRate (1500000), MilliSeconds (10)); + + Ptr channel3 = + PointToPointTopology::AddPointToPointLink ( + n1, n3, DataRate (1500000), MilliSeconds (100)); + + // Later, we add IP addresses. The middle two octets correspond to + // the channel number. + NS_LOG_INFO ("Assign IP Addresses."); + PointToPointTopology::AddIpv4Addresses ( + channel0, n0, Ipv4Address ("10.0.0.1"), + n2, Ipv4Address ("10.0.0.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel1, n1, Ipv4Address ("10.1.1.1"), + n2, Ipv4Address ("10.1.1.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel2, n2, Ipv4Address ("10.2.2.1"), + n3, Ipv4Address ("10.2.2.2")); + + PointToPointTopology::AddIpv4Addresses ( + channel3, n1, Ipv4Address ("10.3.3.1"), + n3, Ipv4Address ("10.3.3.2")); + + PointToPointTopology::SetIpv4Metric ( + channel3, n1, n3, sampleMetric); + + // Create router nodes, initialize routing database and set up the routing + // tables in the nodes. + GlobalRouteManager::PopulateRoutingTables (); + + // Create the OnOff application to send UDP datagrams + NS_LOG_INFO ("Create Application."); + uint16_t port = 9; // Discard port (RFC 863) + + // Create a flow from n3 to n1, starting at time 1.1 seconds + Ptr ooff = Create ( + n3, + InetSocketAddress ("10.1.1.1", port), + "Udp", + ConstantVariable (1), + ConstantVariable (0)); + // Start the application + ooff->Start (Seconds (1.1)); + ooff->Stop (Seconds (10.0)); + + // Create a packet sink to receive these packets + Ptr sink = Create ( + n1, + InetSocketAddress (Ipv4Address::GetAny (), port), + "Udp"); + // Start the sink + sink->Start (Seconds (1.1)); + sink->Stop (Seconds (10.0)); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-alternate-routing.tr file + NS_LOG_INFO ("Configure Tracing."); + AsciiTrace asciitrace ("simple-alternate-routing.tr"); + asciitrace.TraceAllQueues (); + asciitrace.TraceAllNetDeviceRx (); + + // Also configure some tcpdump traces; each interface will be traced + // The output files will be named simple-p2p.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + PcapTrace pcaptrace ("simple-alternate-routing.pcap"); + pcaptrace.TraceAllIp (); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} diff --git a/examples/wscript b/examples/wscript index d65ac22e0..f597225fb 100644 --- a/examples/wscript +++ b/examples/wscript @@ -6,6 +6,10 @@ def build(bld): ['point-to-point', 'internet-node', 'global-routing']) obj.source = 'simple-global-routing.cc' + obj = bld.create_ns3_program('simple-alternate-routing', + ['point-to-point', 'internet-node', 'global-routing']) + obj.source = 'simple-alternate-routing.cc' + obj = bld.create_ns3_program('simple-point-to-point', ['point-to-point', 'internet-node']) obj.source = 'simple-point-to-point.cc' diff --git a/src/devices/csma/csma-ipv4-topology.cc b/src/devices/csma/csma-ipv4-topology.cc index 750860f4d..43e8bcf42 100644 --- a/src/devices/csma/csma-ipv4-topology.cc +++ b/src/devices/csma/csma-ipv4-topology.cc @@ -96,7 +96,8 @@ CsmaIpv4Topology::AddIpv4Address( Ptr node, uint32_t netDeviceNumber, const Ipv4Address address, - const Ipv4Mask mask) + const Ipv4Mask mask, + uint16_t metric) { Ptr nd = node->GetDevice(netDeviceNumber); @@ -105,6 +106,7 @@ CsmaIpv4Topology::AddIpv4Address( ipv4->SetAddress (ifIndex, address); ipv4->SetNetworkMask (ifIndex, mask); + ipv4->SetMetric (ifIndex, metric); ipv4->SetUp (ifIndex); return ifIndex; } diff --git a/src/devices/csma/csma-ipv4-topology.h b/src/devices/csma/csma-ipv4-topology.h index 415ea6257..9cb4ab30a 100644 --- a/src/devices/csma/csma-ipv4-topology.h +++ b/src/devices/csma/csma-ipv4-topology.h @@ -103,6 +103,7 @@ public: * the address. * \param address The Ipv4 Address for the interface. * \param network The network mask for the interface + * \param metric (optional) metric (cost) to assign for routing calculations * * Add an Ipv4Address to the Ipv4 interface associated with the * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel @@ -110,7 +111,8 @@ public: static uint32_t AddIpv4Address(Ptr node, uint32_t netDeviceNumber, const Ipv4Address address, - const Ipv4Mask mask); + const Ipv4Mask mask, + uint16_t metric = 1); /** * \param nd1 Node diff --git a/src/devices/point-to-point/point-to-point-topology.cc b/src/devices/point-to-point/point-to-point-topology.cc index 4c99eaf88..7e0fd4efd 100644 --- a/src/devices/point-to-point/point-to-point-topology.cc +++ b/src/devices/point-to-point/point-to-point-topology.cc @@ -103,6 +103,59 @@ PointToPointTopology::AddIpv4Addresses( } +void +PointToPointTopology::SetIpv4Metric( + Ptr chan, + Ptr n1, Ptr n2, const uint16_t metric) +{ + + // The PointToPoint channel is used to find the relevant NetDevices + NS_ASSERT (chan->GetNDevices () == 2); + Ptr nd1 = chan->GetDevice (0); + Ptr nd2 = chan->GetDevice (1); + // Make sure that nd1 belongs to n1 and nd2 to n2 + if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && + (nd2->GetNode ()->GetId () == n1->GetId () ) ) + { + std::swap(nd1, nd2); + } + NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ()); + NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ()); + + // The NetDevice ifIndex does not correspond to the + // ifIndex used by Ipv4. Therefore, we have to iterate + // through the NetDevices until we find the Ipv4 ifIndex + // that corresponds to NetDevice nd1 + // Get interface indexes for both nodes corresponding to the right channel + uint32_t index = 0; + bool found = false; + Ptr ip1 = n1->QueryInterface (Ipv4::iid); + for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++) + { + if (ip1 ->GetNetDevice (i) == nd1) + { + index = i; + found = true; + } + } + NS_ASSERT(found); + ip1->SetMetric (index, metric); + + index = 0; + found = false; + Ptr ip2 = n2->QueryInterface (Ipv4::iid); + for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++) + { + if (ip2 ->GetNetDevice (i) == nd2) + { + index = i; + found = true; + } + } + NS_ASSERT(found); + ip2->SetMetric (index, metric); +} + void PointToPointTopology::AddIpv4Routes ( Ptr n1, Ptr n2, Ptr chan) diff --git a/src/devices/point-to-point/point-to-point-topology.h b/src/devices/point-to-point/point-to-point-topology.h index c1f037380..35a452269 100644 --- a/src/devices/point-to-point/point-to-point-topology.h +++ b/src/devices/point-to-point/point-to-point-topology.h @@ -70,6 +70,20 @@ public: Ptr n1, const Ipv4Address& addr1, Ptr n2, const Ipv4Address& addr2); + /** + * \param chan PointToPointChannel to use + * \param n1 Node + * \param n2 Node + * \param metric link metric to assign on Ipv4Link on chan between n1 and n2 + * + * Add a non-unit-cost link metric (bidirectionally) to the Ipv4 + * interfaces associated with the two PointToPointNetDevices on the + * provided PointToPointChannel + */ + static void SetIpv4Metric( + Ptr chan, + Ptr n1, Ptr n2, const uint16_t metric); + /** * \param channel PointToPointChannel to use * \param n1 Node diff --git a/src/internet-node/ipv4-impl.cc b/src/internet-node/ipv4-impl.cc index a67c6a4e8..bff1bfd0b 100644 --- a/src/internet-node/ipv4-impl.cc +++ b/src/internet-node/ipv4-impl.cc @@ -201,6 +201,18 @@ Ipv4Impl::GetAddress (uint32_t i) const return m_ipv4->GetAddress (i); } +void +Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) +{ + m_ipv4->SetMetric (i, metric); +} + +uint16_t +Ipv4Impl::GetMetric (uint32_t i) const +{ + return m_ipv4->GetMetric (i); +} + bool Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const { diff --git a/src/internet-node/ipv4-impl.h b/src/internet-node/ipv4-impl.h index 1f4a79f5c..0494c7c0a 100644 --- a/src/internet-node/ipv4-impl.h +++ b/src/internet-node/ipv4-impl.h @@ -88,6 +88,8 @@ public: virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask); virtual Ipv4Mask GetNetworkMask (uint32_t t) const; virtual Ipv4Address GetAddress (uint32_t i) const; + virtual void SetMetric (uint32_t i, uint16_t metric); + virtual uint16_t GetMetric (uint32_t i) const; virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const; virtual bool GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const; diff --git a/src/internet-node/ipv4-interface.cc b/src/internet-node/ipv4-interface.cc index e78d75c2d..bcc346394 100644 --- a/src/internet-node/ipv4-interface.cc +++ b/src/internet-node/ipv4-interface.cc @@ -37,7 +37,8 @@ namespace ns3 { */ Ipv4Interface::Ipv4Interface (Ptr nd) : m_netdevice (nd), - m_ifup(false) + m_ifup(false), + m_metric(1) { NS_LOG_FUNCTION; NS_LOG_PARAM ("(" << &nd << ")"); @@ -96,6 +97,21 @@ Ipv4Interface::GetNetworkMask (void) const return m_netmask; } +void +Ipv4Interface::SetMetric (uint16_t metric) +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << metric << ")"); + m_metric = metric; +} + +uint16_t +Ipv4Interface::GetMetric (void) const +{ + NS_LOG_FUNCTION; + return m_metric; +} + Ipv4Address Ipv4Interface::GetAddress (void) const { diff --git a/src/internet-node/ipv4-interface.h b/src/internet-node/ipv4-interface.h index 1836aa3b7..66e841746 100644 --- a/src/internet-node/ipv4-interface.h +++ b/src/internet-node/ipv4-interface.h @@ -96,6 +96,14 @@ public: * \returns the ipv4 netmask of this interface */ Ipv4Mask GetNetworkMask (void) const; + /** + * \param configured routing metric (cost) of this interface + */ + void SetMetric (uint16_t); + /** + * \returns configured routing metric (cost) of this interface + */ + uint16_t GetMetric (void) const; /** * \returns the ipv4 address of this interface */ @@ -147,6 +155,7 @@ private: bool m_ifup; Ipv4Address m_address; Ipv4Mask m_netmask; + uint16_t m_metric; }; }; // namespace ns3 diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 4691b977a..908a7bb99 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -821,6 +821,24 @@ Ipv4L3Protocol::GetAddress (uint32_t i) const return interface->GetAddress (); } +void +Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric) +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << i << ", " << metric << ")"); + Ptr interface = GetInterface (i); + interface->SetMetric (metric); +} + +uint16_t +Ipv4L3Protocol::GetMetric (uint32_t i) const +{ + NS_LOG_FUNCTION; + NS_LOG_PARAM ("(" << i << ")"); + Ptr interface = GetInterface (i); + return interface->GetMetric (); +} + bool Ipv4L3Protocol::GetIfIndexForDestination ( Ipv4Address destination, uint32_t& ifIndex) const diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index bea82707e..54dec0678 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -198,6 +198,8 @@ public: void SetNetworkMask (uint32_t i, Ipv4Mask mask); Ipv4Mask GetNetworkMask (uint32_t t) const; Ipv4Address GetAddress (uint32_t i) const; + void SetMetric (uint32_t i, uint16_t metric); + uint16_t GetMetric (uint32_t i) const; bool GetIfIndexForDestination (Ipv4Address destination, uint32_t& ifIndex) const; uint16_t GetMtu (uint32_t i) const; diff --git a/src/node/ipv4.h b/src/node/ipv4.h index ba4868a4a..4dba6b2a2 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -383,6 +383,20 @@ public: */ virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0; + /** + * \param i index of ipv4 interface + * \param metric routing metric (cost) associated to the underlying + * ipv4 interface + */ + virtual void SetMetric (uint32_t i, uint16_t metric) = 0; + + /** + * \param i index of ipv4 interface + * \returns routing metric (cost) associated to the underlying + * ipv4 interface + */ + virtual uint16_t GetMetric (uint32_t i) const = 0; + /** * \param i index of ipv4 interface * \returns the address associated to the underlying ipv4 interface diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 88d9def84..ed61f7f5c 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -529,7 +529,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) // Get w_lsa: In case of V is Router-LSA if (v->GetVertexType () == SPFVertex::VertexRouter) { - NS_LOG_LOGIC ("Examining " << v->GetVertexId () << "'s " << + NS_LOG_LOGIC ("Examining link " << i << " of " << + v->GetVertexId () << "'s " << v->GetLSA ()->GetNLinkRecords () << " link records"); // // (a) If this is a link to a stub network, examine the next link in V's LSA. @@ -637,7 +638,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) candidate.Push (w); NS_LOG_LOGIC ("Pushing " << w->GetVertexId () << ", parent vertexId: " << - v->GetVertexId ()); + v->GetVertexId () << ", distance: " << + w->GetDistanceFromRoot ()); } } else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE) @@ -688,7 +690,7 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate) } // -// This method is derived from quagga ospf_next_hop_calculation() 16.1.1. +// This method is derived from quagga ospf_nexthop_calculation() 16.1.1. // // Calculate nexthop from root through V (parent) to vertex W (destination) // with given distance from root->W. @@ -784,11 +786,13 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( // w->SetOutgoingInterfaceId ( FindOutgoingInterfaceId (l->GetLinkData ())); - + w->SetDistanceFromRoot (distance); + w->SetParent (v); NS_LOG_LOGIC ("Next hop from " << v->GetVertexId () << " to " << w->GetVertexId () << " goes through next hop " << w->GetNextHop () << - " via outgoing interface " << w->GetOutgoingInterfaceId ()); + " via outgoing interface " << w->GetOutgoingInterfaceId () << + " with distance " << distance); } // end W is a router vertes else { @@ -804,7 +808,8 @@ GlobalRouteManagerImpl::SPFNexthopCalculation ( w->SetParent (v); NS_LOG_LOGIC ("Next hop from " << v->GetVertexId () << " to network " << w->GetVertexId () << - " via outgoing interface " << w->GetOutgoingInterfaceId ()); + " via outgoing interface " << w->GetOutgoingInterfaceId () << + " with distance " << distance); return 1; } } // end v is the root @@ -997,6 +1002,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) m_spfroot= v; v->SetDistanceFromRoot (0); v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE); + NS_LOG_LOGIC ("Starting SPFCalculate for node " << root); for (;;) { diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 2819b7a24..ee49733c1 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -50,7 +50,7 @@ GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ( LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, - uint32_t metric) + uint16_t metric) : m_linkId (linkId), m_linkData (linkData), @@ -110,7 +110,7 @@ GlobalRoutingLinkRecord::SetLinkType ( m_linkType = linkType; } - uint32_t + uint16_t GlobalRoutingLinkRecord::GetMetric (void) const { NS_LOG_FUNCTION; @@ -118,7 +118,7 @@ GlobalRoutingLinkRecord::GetMetric (void) const } void -GlobalRoutingLinkRecord::SetMetric (uint32_t metric) +GlobalRoutingLinkRecord::SetMetric (uint16_t metric) { NS_LOG_FUNCTION; m_metric = metric; @@ -202,6 +202,7 @@ GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa) pDst->SetLinkType (pSrc->GetLinkType ()); pDst->SetLinkId (pSrc->GetLinkId ()); pDst->SetLinkData (pSrc->GetLinkData ()); + pDst->SetMetric (pSrc->GetMetric ()); m_linkRecords.push_back(pDst); pDst = 0; @@ -397,6 +398,7 @@ GlobalRoutingLSA::Print (std::ostream &os) const os << "----------" << std::endl; os << "m_linkId = " << p->GetLinkId () << std::endl; os << "m_linkData = " << p->GetLinkData () << std::endl; + os << "m_metric = " << p->GetMetric () << std::endl; } } else if (m_lsType == GlobalRoutingLSA::NetworkLSA) @@ -547,6 +549,7 @@ GlobalRouter::DiscoverLSAs (void) 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 @@ -566,8 +569,7 @@ GlobalRouter::DiscoverLSAs (void) Ipv4Address maskLocalAddr; maskLocalAddr.Set(maskLocal.GetHostOrder ()); plr->SetLinkData (maskLocalAddr); - // Cost is interface's configured output cost (NOTYET) - plr->SetMetric (1); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord(plr); plr = 0; continue; @@ -589,8 +591,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkId (desigRtr); // Link Data is router's own IP address plr->SetLinkData (addrLocal); - // Cost is interface's configured output cost (NOTYET) - plr->SetMetric (1); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; continue; @@ -613,6 +614,7 @@ GlobalRouter::DiscoverLSAs (void) 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 @@ -659,6 +661,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); plr->SetLinkId (rtrIdRemote); plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; @@ -666,6 +669,7 @@ GlobalRouter::DiscoverLSAs (void) plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork); plr->SetLinkId (addrRemote); plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown + plr->SetMetric (metricLocal); pLSA->AddLinkRecord (plr); plr = 0; } diff --git a/src/routing/global-routing/global-router-interface.h b/src/routing/global-routing/global-router-interface.h index cf3f94166..87626700b 100644 --- a/src/routing/global-routing/global-router-interface.h +++ b/src/routing/global-routing/global-router-interface.h @@ -82,7 +82,7 @@ public: LinkType linkType, Ipv4Address linkId, Ipv4Address linkData, - uint32_t metric); + uint16_t metric); /** * @brief Destroy a Global Routing Link Record. @@ -176,7 +176,7 @@ public: * * @returns The metric field of the Global Routing Link Record. */ - uint32_t GetMetric(void) const; + uint16_t GetMetric(void) const; /** * @brief Set the Metric Data field of the Global Routing Link Record. @@ -189,7 +189,7 @@ public: * * @param metric The new metric for the current Global Routing Link Record. */ - void SetMetric(uint32_t metric); + void SetMetric(uint16_t metric); private: /** @@ -230,7 +230,7 @@ private: * of two hops relate to the cost of sending a packet); rather you should * use something like delay. */ - uint32_t m_metric; + uint16_t m_metric; }; /**