1.1 --- a/CHANGES.html Mon Aug 31 15:29:20 2009 +0200
1.2 +++ b/CHANGES.html Mon Aug 31 23:05:26 2009 -0700
1.3 @@ -52,6 +52,12 @@
1.4
1.5 <h2>New API:</h2>
1.6 <ul>
1.7 +<li><b>Route injection for global routing</b>
1.8 +<p>Add ability to inject and withdraw routes to Ipv4GlobalRouting. This
1.9 +allows a user to insert a route and have it redistributed like an OSPF
1.10 +external LSA to the rest of the topology.
1.11 +</p>
1.12 +</li>
1.13 <li><b>Athstats</b>
1.14 <p>New classes AthstatsWifiTraceSink and AthstatsHelper.
1.15 </p>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/examples/global-injection-slash32.cc Mon Aug 31 23:05:26 2009 -0700
2.3 @@ -0,0 +1,158 @@
2.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2.5 +/*
2.6 + * This program is free software; you can redistribute it and/or modify
2.7 + * it under the terms of the GNU General Public License version 2 as
2.8 + * published by the Free Software Foundation;
2.9 + *
2.10 + * This program is distributed in the hope that it will be useful,
2.11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.13 + * GNU General Public License for more details.
2.14 + *
2.15 + * You should have received a copy of the GNU General Public License
2.16 + * along with this program; if not, write to the Free Software
2.17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.18 + *
2.19 + */
2.20 +
2.21 +// Test program for this 3-router scenario, using global routing
2.22 +//
2.23 +// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
2.24 +
2.25 +#include <iostream>
2.26 +#include <fstream>
2.27 +#include <string>
2.28 +#include <cassert>
2.29 +
2.30 +#include "ns3/csma-net-device.h"
2.31 +#include "ns3/core-module.h"
2.32 +#include "ns3/simulator-module.h"
2.33 +#include "ns3/node-module.h"
2.34 +#include "ns3/helper-module.h"
2.35 +#include "ns3/ipv4-static-routing.h"
2.36 +#include "ns3/ipv4-global-routing.h"
2.37 +#include "ns3/ipv4-list-routing.h"
2.38 +#include "ns3/ipv4-routing-table-entry.h"
2.39 +#include "ns3/global-router-interface.h"
2.40 +
2.41 +using namespace ns3;
2.42 +using std::cout;
2.43 +
2.44 +NS_LOG_COMPONENT_DEFINE ("GlobalRouterInjectionTest");
2.45 +
2.46 +int
2.47 +main (int argc, char *argv[])
2.48 +{
2.49 +
2.50 + // Allow the user to override any of the defaults and the above
2.51 + // DefaultValue::Bind ()s at run-time, via command-line arguments
2.52 + CommandLine cmd;
2.53 + cmd.Parse (argc, argv);
2.54 +
2.55 + Ptr<Node> nA = CreateObject<Node> ();
2.56 + Ptr<Node> nB = CreateObject<Node> ();
2.57 + Ptr<Node> nC = CreateObject<Node> ();
2.58 +
2.59 + NodeContainer c = NodeContainer (nA, nB, nC);
2.60 +
2.61 + InternetStackHelper internet;
2.62 +
2.63 + // Point-to-point links
2.64 + NodeContainer nAnB = NodeContainer (nA, nB);
2.65 + NodeContainer nBnC = NodeContainer (nB, nC);
2.66 +
2.67 + internet.Install (nAnB);
2.68 + Ipv4ListRoutingHelper staticonly;
2.69 + Ipv4ListRoutingHelper staticRouting;
2.70 + staticonly.Add(staticRouting, 0);
2.71 + internet.SetRoutingHelper(staticonly);
2.72 + internet.Install(NodeContainer(nC));
2.73 +
2.74 + // We create the channels first without any IP addressing information
2.75 + PointToPointHelper p2p;
2.76 + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
2.77 + p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
2.78 + NetDeviceContainer dAdB = p2p.Install (nAnB);
2.79 +
2.80 + NetDeviceContainer dBdC = p2p.Install (nBnC);;
2.81 +
2.82 + Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
2.83 + deviceA->SetAddress (Mac48Address::Allocate ());
2.84 + nA->AddDevice (deviceA);
2.85 +
2.86 + Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
2.87 + deviceC->SetAddress (Mac48Address::Allocate ());
2.88 + nC->AddDevice (deviceC);
2.89 +
2.90 + // Later, we add IP addresses.
2.91 + Ipv4AddressHelper ipv4;
2.92 + ipv4.SetBase ("10.1.1.0", "255.255.255.252");
2.93 + Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
2.94 +
2.95 + ipv4.SetBase ("10.1.1.4", "255.255.255.252");
2.96 + Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
2.97 +
2.98 + Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
2.99 + Ptr<Ipv4> ipv4B = nB->GetObject<Ipv4> ();
2.100 + Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
2.101 +
2.102 + int32_t ifIndexA = ipv4A->AddInterface (deviceA);
2.103 + int32_t ifIndexC = ipv4C->AddInterface (deviceC);
2.104 +
2.105 + Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
2.106 + ipv4A->AddAddress (ifIndexA, ifInAddrA);
2.107 + ipv4A->SetMetric (ifIndexA, 1);
2.108 + ipv4A->SetUp (ifIndexA);
2.109 +
2.110 + Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
2.111 + ipv4C->AddAddress (ifIndexC, ifInAddrC);
2.112 + ipv4C->SetMetric (ifIndexC, 1);
2.113 + ipv4C->SetUp (ifIndexC);
2.114 +
2.115 + // Create router nodes, initialize routing database and set up the routing
2.116 + // tables in the nodes.
2.117 +
2.118 + // Populate routing tables for nodes nA and nB
2.119 + Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
2.120 + // Inject global routes from Node B, including transit network...
2.121 + Ptr<GlobalRouter> globalRouterB = nB->GetObject<GlobalRouter> ();
2.122 + globalRouterB->InjectRoute ("10.1.1.4", "255.255.255.252");
2.123 + // ...and the host in network "C"
2.124 + globalRouterB->InjectRoute ("192.168.1.1", "255.255.255.255");
2.125 +
2.126 + Ipv4GlobalRoutingHelper::RecomputeRoutingTables();
2.127 + // In addition, nB needs a static route to nC so it knows what to do with stuff
2.128 + // going to 192.168.1.1
2.129 + Ipv4StaticRoutingHelper ipv4RoutingHelper;
2.130 + Ptr<Ipv4StaticRouting> staticRoutingB = ipv4RoutingHelper.GetStaticRouting(ipv4B);
2.131 + staticRoutingB->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.6"),2);
2.132 +
2.133 + // Create the OnOff application to send UDP datagrams of size
2.134 + // 210 bytes at a rate of 448 Kb/s
2.135 + uint16_t port = 9; // Discard port (RFC 863)
2.136 + OnOffHelper onoff ("ns3::UdpSocketFactory",
2.137 + Address (InetSocketAddress (ifInAddrC.GetLocal(), port)));
2.138 + onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
2.139 + onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
2.140 + onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
2.141 + ApplicationContainer apps = onoff.Install (nA);
2.142 + apps.Start (Seconds (1.0));
2.143 + apps.Stop (Seconds (10.0));
2.144 +
2.145 + // Create a packet sink to receive these packets
2.146 + PacketSinkHelper sink ("ns3::UdpSocketFactory",
2.147 + Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
2.148 + apps = sink.Install (nC);
2.149 + apps.Start (Seconds (1.0));
2.150 + apps.Stop (Seconds (10.0));
2.151 +
2.152 + std::ofstream ascii;
2.153 + ascii.open ("global-routing-injection32.tr", std::ios_base::binary | std::ios_base::out);
2.154 + PointToPointHelper::EnablePcapAll ("global-routing-injection32");
2.155 + PointToPointHelper::EnableAsciiAll (ascii);
2.156 +
2.157 + Simulator::Run ();
2.158 + Simulator::Destroy ();
2.159 +
2.160 + return 0;
2.161 +}
3.1 --- a/examples/wscript Mon Aug 31 15:29:20 2009 +0200
3.2 +++ b/examples/wscript Mon Aug 31 23:05:26 2009 -0700
3.3 @@ -36,6 +36,10 @@
3.4 ['point-to-point', 'internet-stack', 'global-routing'])
3.5 obj.source = 'global-routing-slash32.cc'
3.6
3.7 + obj = bld.create_ns3_program('global-injection-slash32',
3.8 + ['point-to-point', 'internet-stack', 'global-routing'])
3.9 + obj.source = 'global-injection-slash32.cc'
3.10 +
3.11 obj = bld.create_ns3_program('simple-global-routing',
3.12 ['point-to-point', 'internet-stack', 'global-routing'])
3.13 obj.source = 'simple-global-routing.cc'
4.1 --- a/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 31 15:29:20 2009 +0200
4.2 +++ b/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 31 23:05:26 2009 -0700
4.3 @@ -243,6 +243,15 @@
4.4 return m_vertexProcessed;
4.5 }
4.6
4.7 +void
4.8 +SPFVertex::ClearVertexProcessed (void)
4.9 +{
4.10 + for (uint32_t i = 0; i < this->GetNChildren (); i++)
4.11 + {
4.12 + this->GetChild (i)->ClearVertexProcessed ();
4.13 + }
4.14 + this->SetVertexProcessed (false);
4.15 +}
4.16
4.17 // ---------------------------------------------------------------------------
4.18 //
4.19 @@ -252,7 +261,8 @@
4.20
4.21 GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
4.22 :
4.23 - m_database ()
4.24 + m_database (),
4.25 + m_extdatabase ()
4.26 {
4.27 NS_LOG_FUNCTION_NOARGS ();
4.28 }
4.29 @@ -267,6 +277,12 @@
4.30 GlobalRoutingLSA* temp = i->second;
4.31 delete temp;
4.32 }
4.33 + for (uint32_t j = 0; j < m_extdatabase.size (); j++)
4.34 + {
4.35 + NS_LOG_LOGIC ("free ASexternalLSA");
4.36 + GlobalRoutingLSA* temp = m_extdatabase.at (j);
4.37 + delete temp;
4.38 + }
4.39 NS_LOG_LOGIC ("clear map");
4.40 m_database.clear ();
4.41 }
4.42 @@ -287,7 +303,26 @@
4.43 GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
4.44 {
4.45 NS_LOG_FUNCTION (addr << lsa);
4.46 - m_database.insert (LSDBPair_t (addr, lsa));
4.47 + if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs)
4.48 + {
4.49 + m_extdatabase.push_back (lsa);
4.50 + }
4.51 + else
4.52 + {
4.53 + m_database.insert (LSDBPair_t (addr, lsa));
4.54 + }
4.55 +}
4.56 +
4.57 + GlobalRoutingLSA*
4.58 +GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
4.59 +{
4.60 + return m_extdatabase.at (index);
4.61 +}
4.62 +
4.63 + uint32_t
4.64 +GlobalRouteManagerLSDB::GetNumExtLSAs () const
4.65 +{
4.66 + return m_extdatabase.size ();
4.67 }
4.68
4.69 GlobalRoutingLSA*
4.70 @@ -438,6 +473,7 @@
4.71 // DiscoverLSAs () will get zero as the number since no routes have been
4.72 // found.
4.73 //
4.74 + Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
4.75 uint32_t numLSAs = rtr->DiscoverLSAs ();
4.76 NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
4.77
4.78 @@ -1237,6 +1273,14 @@
4.79
4.80 // Second stage of SPF calculation procedure
4.81 SPFProcessStubs (m_spfroot);
4.82 + for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
4.83 + {
4.84 + m_spfroot->ClearVertexProcessed ();
4.85 + GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
4.86 + NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
4.87 + ProcessASExternals (m_spfroot, extlsa);
4.88 + }
4.89 +
4.90 //
4.91 // We're all done setting the routing information for the node at the root of
4.92 // the SPF tree. Delete all of the vertices and corresponding resources. Go
4.93 @@ -1246,6 +1290,160 @@
4.94 m_spfroot = 0;
4.95 }
4.96
4.97 +void
4.98 +GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
4.99 +{
4.100 + NS_LOG_FUNCTION_NOARGS ();
4.101 + NS_LOG_LOGIC ("Processing external for destination " <<
4.102 + extlsa->GetLinkStateId () <<
4.103 + ", for router " << v->GetVertexId () <<
4.104 + ", advertised by " << extlsa->GetAdvertisingRouter ());
4.105 + if (v->GetVertexType () == SPFVertex::VertexRouter)
4.106 + {
4.107 + GlobalRoutingLSA *rlsa = v->GetLSA ();
4.108 + NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
4.109 + if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
4.110 + {
4.111 + NS_LOG_LOGIC ("Found advertising router to destination");
4.112 + SPFAddASExternal(extlsa,v);
4.113 + }
4.114 + }
4.115 + for (uint32_t i = 0; i < v->GetNChildren (); i++)
4.116 + {
4.117 + if (!v->GetChild (i)->IsVertexProcessed ())
4.118 + {
4.119 + NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
4.120 + ProcessASExternals (v->GetChild (i), extlsa);
4.121 + v->GetChild (i)->SetVertexProcessed (true);
4.122 + }
4.123 + }
4.124 +}
4.125 +
4.126 +//
4.127 +// Adding external routes to routing table - modeled after
4.128 +// SPFAddIntraAddStub()
4.129 +//
4.130 +
4.131 +void
4.132 +GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
4.133 +{
4.134 + NS_LOG_FUNCTION_NOARGS ();
4.135 +
4.136 + NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
4.137 +// Two cases to consider: We are advertising the external ourselves
4.138 +// => No need to add anything
4.139 +// OR find best path to the advertising router
4.140 + if (v->GetVertexId () == m_spfroot->GetVertexId ())
4.141 + {
4.142 + NS_LOG_LOGIC ("External is on local host: "
4.143 + << v->GetVertexId () << "; returning");
4.144 + return;
4.145 + }
4.146 + NS_LOG_LOGIC ("External is on remote host: "
4.147 + << extlsa->GetAdvertisingRouter () << "; installing");
4.148 +
4.149 + Ipv4Address routerId = m_spfroot->GetVertexId ();
4.150 +
4.151 + NS_LOG_LOGIC ("Vertex ID = " << routerId);
4.152 +//
4.153 +// We need to walk the list of nodes looking for the one that has the router
4.154 +// ID corresponding to the root vertex. This is the one we're going to write
4.155 +// the routing information to.
4.156 +//
4.157 + NodeList::Iterator i = NodeList::Begin ();
4.158 + for (; i != NodeList::End (); i++)
4.159 + {
4.160 + Ptr<Node> node = *i;
4.161 +//
4.162 +// The router ID is accessible through the GlobalRouter interface, so we need
4.163 +// to QI for that interface. If there's no GlobalRouter interface, the node
4.164 +// in question cannot be the router we want, so we continue.
4.165 +//
4.166 + Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
4.167 +
4.168 + if (rtr == 0)
4.169 + {
4.170 + NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
4.171 + continue;
4.172 + }
4.173 +//
4.174 +// If the router ID of the current node is equal to the router ID of the
4.175 +// root of the SPF tree, then this node is the one for which we need to
4.176 +// write the routing tables.
4.177 +//
4.178 + NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
4.179 +
4.180 + if (rtr->GetRouterId () == routerId)
4.181 + {
4.182 + NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
4.183 +//
4.184 +// Routing information is updated using the Ipv4 interface. We need to QI
4.185 +// for that interface. If the node is acting as an IP version 4 router, it
4.186 +// should absolutely have an Ipv4 interface.
4.187 +//
4.188 + Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
4.189 + NS_ASSERT_MSG (ipv4,
4.190 + "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
4.191 + "QI for <Ipv4> interface failed");
4.192 +//
4.193 +// Get the Global Router Link State Advertisement from the vertex we're
4.194 +// adding the routes to. The LSA will have a number of attached Global Router
4.195 +// Link Records corresponding to links off of that vertex / node. We're going
4.196 +// to be interested in the records corresponding to point-to-point links.
4.197 +//
4.198 + NS_ASSERT_MSG (v->GetLSA (),
4.199 + "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
4.200 + "Expected valid LSA in SPFVertex* v");
4.201 + Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
4.202 + Ipv4Address tempip = extlsa->GetLinkStateId ();
4.203 + tempip = tempip.CombineMask (tempmask);
4.204 +
4.205 + NS_LOG_LOGIC (" Node " << node->GetId () <<
4.206 + " add route to " << tempip <<
4.207 + " with mask " << tempmask <<
4.208 + " using next hop " << v->GetNextHop () <<
4.209 + " via interface " << v->GetOutgoingInterfaceId ());
4.210 +//
4.211 +// Here's why we did all of that work. We're going to add a host route to the
4.212 +// host address found in the m_linkData field of the point-to-point link
4.213 +// record. In the case of a point-to-point link, this is the local IP address
4.214 +// of the node connected to the link. Each of these point-to-point links
4.215 +// will correspond to a local interface that has an IP address to which
4.216 +// the node at the root of the SPF tree can send packets. The vertex <v>
4.217 +// (corresponding to the node that has these links and interfaces) has
4.218 +// an m_nextHop address precalculated for us that is the address to which the
4.219 +// root node should send packets to be forwarded to these IP addresses.
4.220 +// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
4.221 +// which the packets should be send for forwarding.
4.222 +//
4.223 + Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
4.224 + if (router == 0)
4.225 + {
4.226 + continue;
4.227 + }
4.228 + Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
4.229 + NS_ASSERT (gr);
4.230 + if (v->GetOutgoingInterfaceId () >= 0)
4.231 + {
4.232 + gr->AddASExternalRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingInterfaceId ());
4.233 + NS_LOG_LOGIC ("Node " << node->GetId () <<
4.234 + " add network route to " << tempip <<
4.235 + " using next hop " << v->GetNextHop () <<
4.236 + " via interface " << v->GetOutgoingInterfaceId ());
4.237 + }
4.238 + else
4.239 + {
4.240 + NS_LOG_LOGIC ("Node " << node->GetId () <<
4.241 + " NOT able to add network route to " << tempip <<
4.242 + " using next hop " << v->GetNextHop () <<
4.243 + " since outgoing interface id is negative");
4.244 + }
4.245 + return;
4.246 + } // if
4.247 + } // for
4.248 +}
4.249 +
4.250 +
4.251 // Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
4.252 // stub link records will exist for point-to-point interfaces and for
4.253 // broadcast interfaces for which no neighboring router can be found
5.1 --- a/src/routing/global-routing/global-route-manager-impl.h Mon Aug 31 15:29:20 2009 +0200
5.2 +++ b/src/routing/global-routing/global-route-manager-impl.h Mon Aug 31 23:05:26 2009 -0700
5.3 @@ -26,6 +26,7 @@
5.4 #include <list>
5.5 #include <queue>
5.6 #include <map>
5.7 +#include <vector>
5.8 #include "ns3/object.h"
5.9 #include "ns3/ptr.h"
5.10 #include "ns3/ipv4-address.h"
5.11 @@ -563,6 +564,9 @@
5.12 * @returns value of underlying flag
5.13 */
5.14 bool IsVertexProcessed (void) const;
5.15 +
5.16 + void ClearVertexProcessed (void);
5.17 +
5.18 private:
5.19 VertexType m_vertexType;
5.20 Ipv4Address m_vertexId;
5.21 @@ -683,12 +687,18 @@
5.22 * @see SPFVertex
5.23 */
5.24 void Initialize ();
5.25 +
5.26 + GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
5.27 + uint32_t GetNumExtLSAs () const;
5.28 +
5.29
5.30 private:
5.31 typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
5.32 typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
5.33
5.34 LSDBMap_t m_database;
5.35 + std::vector<GlobalRoutingLSA*> m_extdatabase;
5.36 +
5.37 /**
5.38 * @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no
5.39 * need for it and a compiler provided shallow copy would be wrong.
5.40 @@ -775,6 +785,7 @@
5.41 bool CheckForStubNode (Ipv4Address root);
5.42 void SPFCalculate (Ipv4Address root);
5.43 void SPFProcessStubs (SPFVertex* v);
5.44 + void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
5.45 void SPFNext (SPFVertex*, CandidateQueue&);
5.46 int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
5.47 GlobalRoutingLinkRecord* l, uint32_t distance);
5.48 @@ -784,6 +795,7 @@
5.49 void SPFIntraAddRouter (SPFVertex* v);
5.50 void SPFIntraAddTransit (SPFVertex* v);
5.51 void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
5.52 + void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
5.53 int32_t FindOutgoingInterfaceId (Ipv4Address a,
5.54 Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
5.55 };
6.1 --- a/src/routing/global-routing/global-router-interface.cc Mon Aug 31 15:29:20 2009 +0200
6.2 +++ b/src/routing/global-routing/global-router-interface.cc Mon Aug 31 23:05:26 2009 -0700
6.3 @@ -413,6 +413,10 @@
6.4 {
6.5 os << " (GlobalRoutingLSA::NetworkLSA)";
6.6 }
6.7 + else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
6.8 + {
6.9 + os << " (GlobalRoutingLSA::ASExternalLSA)";
6.10 + }
6.11 else
6.12 {
6.13 os << "(Unknown LSType)";
6.14 @@ -474,6 +478,12 @@
6.15 }
6.16 os << "---------- End NetworkLSA Link Record ----------" << std::endl;
6.17 }
6.18 + else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
6.19 + {
6.20 + os << "---------- ASExternalLSA Link Record --------" << std::endl;
6.21 + os << "m_linkStateId = " << m_linkStateId << std::endl;
6.22 + os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
6.23 + }
6.24 else
6.25 {
6.26 NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
6.27 @@ -532,6 +542,12 @@
6.28 {
6.29 NS_LOG_FUNCTION_NOARGS ();
6.30 m_routingProtocol = 0;
6.31 + for (InjectedRoutesI k = m_injectedRoutes.begin ();
6.32 + k != m_injectedRoutes.end ();
6.33 + k = m_injectedRoutes.erase (k))
6.34 + {
6.35 + delete (*k);
6.36 + }
6.37 Object::DoDispose ();
6.38 }
6.39
6.40 @@ -568,8 +584,8 @@
6.41 // and build the Link State Advertisements that reflect them and their associated
6.42 // networks.
6.43 //
6.44 - uint32_t
6.45 -GlobalRouter::DiscoverLSAs (void)
6.46 +uint32_t
6.47 +GlobalRouter::DiscoverLSAs ()
6.48 {
6.49 NS_LOG_FUNCTION_NOARGS ();
6.50 Ptr<Node> node = GetObject<Node> ();
6.51 @@ -696,6 +712,22 @@
6.52 BuildNetworkLSAs (c);
6.53 }
6.54
6.55 + //
6.56 + // Build injected route LSAs as external routes
6.57 + // RFC 2328, section 12.4.4
6.58 + //
6.59 + for (InjectedRoutesCI i = m_injectedRoutes.begin();
6.60 + i != m_injectedRoutes.end();
6.61 + i++)
6.62 + {
6.63 + GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
6.64 + pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
6.65 + pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
6.66 + pLSA->SetAdvertisingRouter (m_routerId);
6.67 + pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
6.68 + pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
6.69 + m_LSAs.push_back (pLSA);
6.70 + }
6.71 return m_LSAs.size ();
6.72 }
6.73
6.74 @@ -1467,6 +1499,86 @@
6.75 return false;
6.76 }
6.77
6.78 +void
6.79 +GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
6.80 +{
6.81 + NS_LOG_FUNCTION (network << networkMask);
6.82 + Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
6.83 +//
6.84 +// Interface number does not matter here, using 1.
6.85 +//
6.86 + *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
6.87 + networkMask,
6.88 + 1);
6.89 + m_injectedRoutes.push_back (route);
6.90 +}
6.91 +
6.92 +Ipv4RoutingTableEntry *
6.93 +GlobalRouter::GetInjectedRoute (uint32_t index)
6.94 +{
6.95 + NS_LOG_FUNCTION (index);
6.96 + if (index < m_injectedRoutes.size ())
6.97 + {
6.98 + uint32_t tmp = 0;
6.99 + for (InjectedRoutesCI i = m_injectedRoutes.begin ();
6.100 + i != m_injectedRoutes.end ();
6.101 + i++)
6.102 + {
6.103 + if (tmp == index)
6.104 + {
6.105 + return *i;
6.106 + }
6.107 + tmp++;
6.108 + }
6.109 + }
6.110 + NS_ASSERT (false);
6.111 + // quiet compiler.
6.112 + return 0;
6.113 +}
6.114 +
6.115 +uint32_t
6.116 +GlobalRouter::GetNInjectedRoutes ()
6.117 +{
6.118 + return m_injectedRoutes.size ();
6.119 +}
6.120 +
6.121 +void
6.122 +GlobalRouter::RemoveInjectedRoute (uint32_t index)
6.123 +{
6.124 + NS_LOG_FUNCTION (index);
6.125 + NS_ASSERT (index < m_injectedRoutes.size ());
6.126 + uint32_t tmp = 0;
6.127 + for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
6.128 + {
6.129 + if (tmp == index)
6.130 + {
6.131 + NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
6.132 + delete *i;
6.133 + m_injectedRoutes.erase (i);
6.134 + return;
6.135 + }
6.136 + tmp++;
6.137 + }
6.138 +}
6.139 +
6.140 +bool
6.141 +GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
6.142 +{
6.143 + NS_LOG_FUNCTION (index);
6.144 + for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
6.145 + {
6.146 + if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
6.147 + {
6.148 + NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
6.149 + delete *i;
6.150 + m_injectedRoutes.erase (i);
6.151 + return true;
6.152 + }
6.153 + }
6.154 + return false;
6.155 +}
6.156 +
6.157 +
6.158 //
6.159 // Link through the given channel and find the net device that's on the
6.160 // other end. This only makes sense with a point-to-point channel.
7.1 --- a/src/routing/global-routing/global-router-interface.h Mon Aug 31 15:29:20 2009 +0200
7.2 +++ b/src/routing/global-routing/global-router-interface.h Mon Aug 31 23:05:26 2009 -0700
7.3 @@ -32,6 +32,7 @@
7.4 #include "ns3/net-device-container.h"
7.5 #include "ns3/bridge-net-device.h"
7.6 #include "ns3/global-route-manager.h"
7.7 +#include "ns3/ipv4-routing-table-entry.h"
7.8
7.9 namespace ns3 {
7.10
7.11 @@ -614,6 +615,8 @@
7.12 * advertisements after a network topology change by calling DiscoverLSAs
7.13 * and then by reading those advertisements.
7.14 *
7.15 + * \param List of routing table entries of external routes to be injected.
7.16 + *
7.17 * @see GlobalRoutingLSA
7.18 * @see GlobalRouter::GetLSA ()
7.19 * @returns The number of Global Routing Link State Advertisements.
7.20 @@ -657,6 +660,59 @@
7.21 */
7.22 bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
7.23
7.24 +/**
7.25 + * @brief Inject a route to be circulated to other routers as an external
7.26 + * route
7.27 + *
7.28 + * @param network The Network to inject
7.29 + * @param networkMask The Network Mask to inject
7.30 + */
7.31 + void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
7.32 +
7.33 +/**
7.34 + * @brief Get the number of injected routes that have been added
7.35 + * to the routing table.
7.36 + * @return number of injected routes
7.37 + */
7.38 + uint32_t GetNInjectedRoutes (void);
7.39 +
7.40 +/**
7.41 + * @brief Return the injected route indexed by i
7.42 + * @param i the index of the route
7.43 + * @return a pointer to that Ipv4RoutingTableEntry is returned
7.44 + *
7.45 + */
7.46 + Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
7.47 +
7.48 +/**
7.49 + * @brief Withdraw a route from the global unicast routing table.
7.50 + *
7.51 + * Calling this function will cause all indexed routes numbered above
7.52 + * index i to have their index decremented. For instance, it is possible to
7.53 + * remove N injected routes by calling RemoveInjectedRoute (0) N times.
7.54 + *
7.55 + * @param i The index (into the injected routing list) of the route to remove.
7.56 + *
7.57 + * @see GlobalRouter::WithdrawRoute ()
7.58 + */
7.59 + void RemoveInjectedRoute (uint32_t i);
7.60 +
7.61 +/**
7.62 + * @brief Withdraw a route from the global unicast routing table.
7.63 + *
7.64 + * Calling this function will cause all indexed routes numbered above
7.65 + * index i to have their index decremented. For instance, it is possible to
7.66 + * remove N injected routes by calling RemoveInjectedRoute (0) N times.
7.67 + *
7.68 + * @param i The index (into the injected routing list) of the route to remove.
7.69 + * @param network The Network to inject
7.70 + * @param networkMask The Network Mask to inject
7.71 + * @return whether the operation succeeded (will return false if no such route)
7.72 + *
7.73 + * @see GlobalRouter::RemoveInjectedRoute ()
7.74 + */
7.75 + bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
7.76 +
7.77 private:
7.78 virtual ~GlobalRouter ();
7.79 void ClearLSAs (void);
7.80 @@ -680,6 +736,11 @@
7.81 Ipv4Address m_routerId;
7.82 Ptr<Ipv4GlobalRouting> m_routingProtocol;
7.83
7.84 + typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
7.85 + typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
7.86 + typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
7.87 + InjectedRoutes m_injectedRoutes; // Routes we are exporting
7.88 +
7.89 // inherited from Object
7.90 virtual void DoDispose (void);
7.91
8.1 --- a/src/routing/global-routing/ipv4-global-routing.cc Mon Aug 31 15:29:20 2009 +0200
8.2 +++ b/src/routing/global-routing/ipv4-global-routing.cc Mon Aug 31 23:05:26 2009 -0700
8.3 @@ -98,10 +98,27 @@
8.4 m_networkRoutes.push_back (route);
8.5 }
8.6
8.7 +void
8.8 +Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
8.9 + Ipv4Mask networkMask,
8.10 + Ipv4Address nextHop,
8.11 + uint32_t interface)
8.12 +{
8.13 + NS_LOG_FUNCTION (network << networkMask << nextHop);
8.14 + Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
8.15 + *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
8.16 + networkMask,
8.17 + nextHop,
8.18 + interface);
8.19 + m_ASexternalRoutes.push_back (route);
8.20 +}
8.21 +
8.22 +
8.23 Ptr<Ipv4Route>
8.24 Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest)
8.25 {
8.26 NS_LOG_FUNCTION_NOARGS ();
8.27 + NS_LOG_LOGIC ("Looking for route for destination " << dest);
8.28 Ptr<Ipv4Route> rtentry = 0;
8.29 bool found = false;
8.30 Ipv4RoutingTableEntry* route = 0;
8.31 @@ -137,6 +154,23 @@
8.32 }
8.33 }
8.34 }
8.35 + if (found == false)
8.36 + {
8.37 + for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
8.38 + k != m_ASexternalRoutes.end ();
8.39 + k++)
8.40 + {
8.41 + Ipv4Mask mask = (*k)->GetDestNetworkMask ();
8.42 + Ipv4Address entry = (*k)->GetDestNetwork ();
8.43 + if (mask.IsMatch (dest, entry))
8.44 + {
8.45 + NS_LOG_LOGIC ("Found external route" << *k);
8.46 + route = (*k);
8.47 + found = true;
8.48 + break;
8.49 + }
8.50 + }
8.51 + }
8.52 if (found == true)
8.53 {
8.54 rtentry = Create<Ipv4Route> ();
8.55 @@ -161,6 +195,7 @@
8.56 uint32_t n = 0;
8.57 n += m_hostRoutes.size ();
8.58 n += m_networkRoutes.size ();
8.59 + n += m_ASexternalRoutes.size ();
8.60 return n;
8.61 }
8.62
8.63 @@ -184,16 +219,31 @@
8.64 }
8.65 index -= m_hostRoutes.size ();
8.66 uint32_t tmp = 0;
8.67 - for (NetworkRoutesI j = m_networkRoutes.begin ();
8.68 - j != m_networkRoutes.end ();
8.69 - j++)
8.70 + if (index < m_networkRoutes.size())
8.71 {
8.72 - if (tmp == index)
8.73 + for (NetworkRoutesI j = m_networkRoutes.begin ();
8.74 + j != m_networkRoutes.end ();
8.75 + j++)
8.76 {
8.77 - return *j;
8.78 + if (tmp == index)
8.79 + {
8.80 + return *j;
8.81 + }
8.82 + tmp++;
8.83 }
8.84 - tmp++;
8.85 }
8.86 + index -= m_networkRoutes.size();
8.87 + tmp = 0;
8.88 + for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
8.89 + k != m_ASexternalRoutes.end ();
8.90 + k++)
8.91 + {
8.92 + if (tmp == index)
8.93 + {
8.94 + return *k;
8.95 + }
8.96 + tmp++;
8.97 + }
8.98 NS_ASSERT (false);
8.99 // quiet compiler.
8.100 return 0;
8.101 @@ -236,6 +286,22 @@
8.102 }
8.103 tmp++;
8.104 }
8.105 + index -= m_networkRoutes.size ();
8.106 + tmp = 0;
8.107 + for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
8.108 + k != m_ASexternalRoutes.end ();
8.109 + k++)
8.110 + {
8.111 + if (tmp == index)
8.112 + {
8.113 + NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
8.114 + delete *k;
8.115 + m_ASexternalRoutes.erase (k);
8.116 + NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
8.117 + return;
8.118 + }
8.119 + tmp++;
8.120 + }
8.121 NS_ASSERT (false);
8.122 }
8.123
8.124 @@ -255,6 +321,13 @@
8.125 {
8.126 delete (*j);
8.127 }
8.128 + for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
8.129 + l != m_ASexternalRoutes.end ();
8.130 + l = m_ASexternalRoutes.erase (l))
8.131 + {
8.132 + delete (*l);
8.133 + }
8.134 +
8.135 Ipv4RoutingProtocol::DoDispose ();
8.136 }
8.137
9.1 --- a/src/routing/global-routing/ipv4-global-routing.h Mon Aug 31 15:29:20 2009 +0200
9.2 +++ b/src/routing/global-routing/ipv4-global-routing.h Mon Aug 31 23:05:26 2009 -0700
9.3 @@ -147,6 +147,20 @@
9.4 uint32_t interface);
9.5
9.6 /**
9.7 + * \brief Add an external route to the global routing table.
9.8 + *
9.9 + * \param network The Ipv4Address network for this route.
9.10 + * \param networkMask The Ipv4Mask to extract the network.
9.11 + * \param nextHop The next hop Ipv4Address
9.12 + * \param interface The network interface index used to send packets to the
9.13 + * destination.
9.14 + */
9.15 + void AddASExternalRouteTo (Ipv4Address network,
9.16 + Ipv4Mask networkMask,
9.17 + Ipv4Address nextHop,
9.18 + uint32_t interface);
9.19 +
9.20 +/**
9.21 * \brief Get the number of individual unicast routes that have been added
9.22 * to the routing table.
9.23 *
9.24 @@ -204,12 +218,16 @@
9.25 typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
9.26 typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
9.27 typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
9.28 + typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
9.29 + typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
9.30 + typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
9.31
9.32 Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest);
9.33
9.34 HostRoutes m_hostRoutes;
9.35 NetworkRoutes m_networkRoutes;
9.36 -
9.37 + ASExternalRoutes m_ASexternalRoutes; // External routes imported
9.38 +
9.39 Ptr<Ipv4> m_ipv4;
9.40 };
9.41