--- a/CHANGES.html Mon Aug 31 15:29:20 2009 +0200
+++ b/CHANGES.html Mon Aug 31 23:05:26 2009 -0700
@@ -52,6 +52,12 @@
<h2>New API:</h2>
<ul>
+<li><b>Route injection for global routing</b>
+<p>Add ability to inject and withdraw routes to Ipv4GlobalRouting. This
+allows a user to insert a route and have it redistributed like an OSPF
+external LSA to the rest of the topology.
+</p>
+</li>
<li><b>Athstats</b>
<p>New classes AthstatsWifiTraceSink and AthstatsHelper.
</p>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/global-injection-slash32.cc Mon Aug 31 23:05:26 2009 -0700
@@ -0,0 +1,158 @@
+/* -*- 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
+ *
+ */
+
+// Test program for this 3-router scenario, using global routing
+//
+// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/csma-net-device.h"
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/ipv4-global-routing.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/ipv4-routing-table-entry.h"
+#include "ns3/global-router-interface.h"
+
+using namespace ns3;
+using std::cout;
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouterInjectionTest");
+
+int
+main (int argc, char *argv[])
+{
+
+ // Allow the user to override any of the defaults and the above
+ // DefaultValue::Bind ()s at run-time, via command-line arguments
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ Ptr<Node> nA = CreateObject<Node> ();
+ Ptr<Node> nB = CreateObject<Node> ();
+ Ptr<Node> nC = CreateObject<Node> ();
+
+ NodeContainer c = NodeContainer (nA, nB, nC);
+
+ InternetStackHelper internet;
+
+ // Point-to-point links
+ NodeContainer nAnB = NodeContainer (nA, nB);
+ NodeContainer nBnC = NodeContainer (nB, nC);
+
+ internet.Install (nAnB);
+ Ipv4ListRoutingHelper staticonly;
+ Ipv4ListRoutingHelper staticRouting;
+ staticonly.Add(staticRouting, 0);
+ internet.SetRoutingHelper(staticonly);
+ internet.Install(NodeContainer(nC));
+
+ // We create the channels first without any IP addressing information
+ PointToPointHelper p2p;
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+ NetDeviceContainer dAdB = p2p.Install (nAnB);
+
+ NetDeviceContainer dBdC = p2p.Install (nBnC);;
+
+ Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
+ deviceA->SetAddress (Mac48Address::Allocate ());
+ nA->AddDevice (deviceA);
+
+ Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
+ deviceC->SetAddress (Mac48Address::Allocate ());
+ nC->AddDevice (deviceC);
+
+ // Later, we add IP addresses.
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("10.1.1.0", "255.255.255.252");
+ Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
+
+ ipv4.SetBase ("10.1.1.4", "255.255.255.252");
+ Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
+
+ Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
+ Ptr<Ipv4> ipv4B = nB->GetObject<Ipv4> ();
+ Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
+
+ int32_t ifIndexA = ipv4A->AddInterface (deviceA);
+ int32_t ifIndexC = ipv4C->AddInterface (deviceC);
+
+ Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
+ ipv4A->AddAddress (ifIndexA, ifInAddrA);
+ ipv4A->SetMetric (ifIndexA, 1);
+ ipv4A->SetUp (ifIndexA);
+
+ Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
+ ipv4C->AddAddress (ifIndexC, ifInAddrC);
+ ipv4C->SetMetric (ifIndexC, 1);
+ ipv4C->SetUp (ifIndexC);
+
+ // Create router nodes, initialize routing database and set up the routing
+ // tables in the nodes.
+
+ // Populate routing tables for nodes nA and nB
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ // Inject global routes from Node B, including transit network...
+ Ptr<GlobalRouter> globalRouterB = nB->GetObject<GlobalRouter> ();
+ globalRouterB->InjectRoute ("10.1.1.4", "255.255.255.252");
+ // ...and the host in network "C"
+ globalRouterB->InjectRoute ("192.168.1.1", "255.255.255.255");
+
+ Ipv4GlobalRoutingHelper::RecomputeRoutingTables();
+ // In addition, nB needs a static route to nC so it knows what to do with stuff
+ // going to 192.168.1.1
+ Ipv4StaticRoutingHelper ipv4RoutingHelper;
+ Ptr<Ipv4StaticRouting> staticRoutingB = ipv4RoutingHelper.GetStaticRouting(ipv4B);
+ staticRoutingB->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.6"),2);
+
+ // Create the OnOff application to send UDP datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ uint16_t port = 9; // Discard port (RFC 863)
+ OnOffHelper onoff ("ns3::UdpSocketFactory",
+ Address (InetSocketAddress (ifInAddrC.GetLocal(), port)));
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
+ ApplicationContainer apps = onoff.Install (nA);
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ // Create a packet sink to receive these packets
+ PacketSinkHelper sink ("ns3::UdpSocketFactory",
+ Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+ apps = sink.Install (nC);
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ std::ofstream ascii;
+ ascii.open ("global-routing-injection32.tr", std::ios_base::binary | std::ios_base::out);
+ PointToPointHelper::EnablePcapAll ("global-routing-injection32");
+ PointToPointHelper::EnableAsciiAll (ascii);
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
--- a/examples/wscript Mon Aug 31 15:29:20 2009 +0200
+++ b/examples/wscript Mon Aug 31 23:05:26 2009 -0700
@@ -36,6 +36,10 @@
['point-to-point', 'internet-stack', 'global-routing'])
obj.source = 'global-routing-slash32.cc'
+ obj = bld.create_ns3_program('global-injection-slash32',
+ ['point-to-point', 'internet-stack', 'global-routing'])
+ obj.source = 'global-injection-slash32.cc'
+
obj = bld.create_ns3_program('simple-global-routing',
['point-to-point', 'internet-stack', 'global-routing'])
obj.source = 'simple-global-routing.cc'
--- a/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.cc Mon Aug 31 23:05:26 2009 -0700
@@ -243,6 +243,15 @@
return m_vertexProcessed;
}
+void
+SPFVertex::ClearVertexProcessed (void)
+{
+ for (uint32_t i = 0; i < this->GetNChildren (); i++)
+ {
+ this->GetChild (i)->ClearVertexProcessed ();
+ }
+ this->SetVertexProcessed (false);
+}
// ---------------------------------------------------------------------------
//
@@ -252,7 +261,8 @@
GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
:
- m_database ()
+ m_database (),
+ m_extdatabase ()
{
NS_LOG_FUNCTION_NOARGS ();
}
@@ -267,6 +277,12 @@
GlobalRoutingLSA* temp = i->second;
delete temp;
}
+ for (uint32_t j = 0; j < m_extdatabase.size (); j++)
+ {
+ NS_LOG_LOGIC ("free ASexternalLSA");
+ GlobalRoutingLSA* temp = m_extdatabase.at (j);
+ delete temp;
+ }
NS_LOG_LOGIC ("clear map");
m_database.clear ();
}
@@ -287,7 +303,26 @@
GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
{
NS_LOG_FUNCTION (addr << lsa);
- m_database.insert (LSDBPair_t (addr, lsa));
+ if (lsa->GetLSType () == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ m_extdatabase.push_back (lsa);
+ }
+ else
+ {
+ m_database.insert (LSDBPair_t (addr, lsa));
+ }
+}
+
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const
+{
+ return m_extdatabase.at (index);
+}
+
+ uint32_t
+GlobalRouteManagerLSDB::GetNumExtLSAs () const
+{
+ return m_extdatabase.size ();
}
GlobalRoutingLSA*
@@ -438,6 +473,7 @@
// DiscoverLSAs () will get zero as the number since no routes have been
// found.
//
+ Ptr<Ipv4GlobalRouting> grouting = rtr->GetRoutingProtocol ();
uint32_t numLSAs = rtr->DiscoverLSAs ();
NS_LOG_LOGIC ("Found " << numLSAs << " LSAs");
@@ -1237,6 +1273,14 @@
// Second stage of SPF calculation procedure
SPFProcessStubs (m_spfroot);
+ for (uint32_t i = 0; i < m_lsdb->GetNumExtLSAs (); i++)
+ {
+ m_spfroot->ClearVertexProcessed ();
+ GlobalRoutingLSA *extlsa = m_lsdb->GetExtLSA (i);
+ NS_LOG_LOGIC ("Processing External LSA with id " << extlsa->GetLinkStateId ());
+ ProcessASExternals (m_spfroot, extlsa);
+ }
+
//
// We're all done setting the routing information for the node at the root of
// the SPF tree. Delete all of the vertices and corresponding resources. Go
@@ -1246,6 +1290,160 @@
m_spfroot = 0;
}
+void
+GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC ("Processing external for destination " <<
+ extlsa->GetLinkStateId () <<
+ ", for router " << v->GetVertexId () <<
+ ", advertised by " << extlsa->GetAdvertisingRouter ());
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ GlobalRoutingLSA *rlsa = v->GetLSA ();
+ NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
+ if ((rlsa->GetLinkStateId ()) == (extlsa->GetAdvertisingRouter ()))
+ {
+ NS_LOG_LOGIC ("Found advertising router to destination");
+ SPFAddASExternal(extlsa,v);
+ }
+ }
+ for (uint32_t i = 0; i < v->GetNChildren (); i++)
+ {
+ if (!v->GetChild (i)->IsVertexProcessed ())
+ {
+ NS_LOG_LOGIC ("Vertex's child " << i << " not yet processed, processing...");
+ ProcessASExternals (v->GetChild (i), extlsa);
+ v->GetChild (i)->SetVertexProcessed (true);
+ }
+ }
+}
+
+//
+// Adding external routes to routing table - modeled after
+// SPFAddIntraAddStub()
+//
+
+void
+GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT_MSG (m_spfroot, "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set");
+// Two cases to consider: We are advertising the external ourselves
+// => No need to add anything
+// OR find best path to the advertising router
+ if (v->GetVertexId () == m_spfroot->GetVertexId ())
+ {
+ NS_LOG_LOGIC ("External is on local host: "
+ << v->GetVertexId () << "; returning");
+ return;
+ }
+ NS_LOG_LOGIC ("External is on remote host: "
+ << extlsa->GetAdvertisingRouter () << "; installing");
+
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_LOG_LOGIC ("Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ NodeList::Iterator i = NodeList::Begin ();
+ for (; i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface. If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter> ();
+
+ if (rtr == 0)
+ {
+ NS_LOG_LOGIC ("No GlobalRouter interface on node " << node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to QI
+// for that interface. If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ NS_ASSERT_MSG (v->GetLSA (),
+ "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask = extlsa->GetNetworkLSANetworkMask ();
+ Ipv4Address tempip = extlsa->GetLinkStateId ();
+ tempip = tempip.CombineMask (tempmask);
+
+ NS_LOG_LOGIC (" Node " << node->GetId () <<
+ " add route to " << tempip <<
+ " with mask " << tempmask <<
+ " using next hop " << v->GetNextHop () <<
+ " via interface " << v->GetOutgoingInterfaceId ());
+//
+// Here's why we did all of that work. We're going to add a host route to the
+// host address found in the m_linkData field of the point-to-point link
+// record. In the case of a point-to-point link, this is the local IP address
+// of the node connected to the link. Each of these point-to-point links
+// will correspond to a local interface that has an IP address to which
+// the node at the root of the SPF tree can send packets. The vertex <v>
+// (corresponding to the node that has these links and interfaces) has
+// an m_nextHop address precalculated for us that is the address to which the
+// root node should send packets to be forwarded to these IP addresses.
+// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
+// which the packets should be send for forwarding.
+//
+ Ptr<GlobalRouter> router = node->GetObject<GlobalRouter> ();
+ if (router == 0)
+ {
+ continue;
+ }
+ Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol ();
+ NS_ASSERT (gr);
+ if (v->GetOutgoingInterfaceId () >= 0)
+ {
+ gr->AddASExternalRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingInterfaceId ());
+ NS_LOG_LOGIC ("Node " << node->GetId () <<
+ " add network route to " << tempip <<
+ " using next hop " << v->GetNextHop () <<
+ " via interface " << v->GetOutgoingInterfaceId ());
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Node " << node->GetId () <<
+ " NOT able to add network route to " << tempip <<
+ " using next hop " << v->GetNextHop () <<
+ " since outgoing interface id is negative");
+ }
+ return;
+ } // if
+ } // for
+}
+
+
// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
// stub link records will exist for point-to-point interfaces and for
// broadcast interfaces for which no neighboring router can be found
--- a/src/routing/global-routing/global-route-manager-impl.h Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.h Mon Aug 31 23:05:26 2009 -0700
@@ -26,6 +26,7 @@
#include <list>
#include <queue>
#include <map>
+#include <vector>
#include "ns3/object.h"
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
@@ -563,6 +564,9 @@
* @returns value of underlying flag
*/
bool IsVertexProcessed (void) const;
+
+ void ClearVertexProcessed (void);
+
private:
VertexType m_vertexType;
Ipv4Address m_vertexId;
@@ -683,12 +687,18 @@
* @see SPFVertex
*/
void Initialize ();
+
+ GlobalRoutingLSA* GetExtLSA (uint32_t index) const;
+ uint32_t GetNumExtLSAs () const;
+
private:
typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
LSDBMap_t m_database;
+ std::vector<GlobalRoutingLSA*> m_extdatabase;
+
/**
* @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no
* need for it and a compiler provided shallow copy would be wrong.
@@ -775,6 +785,7 @@
bool CheckForStubNode (Ipv4Address root);
void SPFCalculate (Ipv4Address root);
void SPFProcessStubs (SPFVertex* v);
+ void ProcessASExternals (SPFVertex* v, GlobalRoutingLSA* extlsa);
void SPFNext (SPFVertex*, CandidateQueue&);
int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
GlobalRoutingLinkRecord* l, uint32_t distance);
@@ -784,6 +795,7 @@
void SPFIntraAddRouter (SPFVertex* v);
void SPFIntraAddTransit (SPFVertex* v);
void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
+ void SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v);
int32_t FindOutgoingInterfaceId (Ipv4Address a,
Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
};
--- a/src/routing/global-routing/global-router-interface.cc Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/global-router-interface.cc Mon Aug 31 23:05:26 2009 -0700
@@ -413,6 +413,10 @@
{
os << " (GlobalRoutingLSA::NetworkLSA)";
}
+ else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ os << " (GlobalRoutingLSA::ASExternalLSA)";
+ }
else
{
os << "(Unknown LSType)";
@@ -474,6 +478,12 @@
}
os << "---------- End NetworkLSA Link Record ----------" << std::endl;
}
+ else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
+ {
+ os << "---------- ASExternalLSA Link Record --------" << std::endl;
+ os << "m_linkStateId = " << m_linkStateId << std::endl;
+ os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+ }
else
{
NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
@@ -532,6 +542,12 @@
{
NS_LOG_FUNCTION_NOARGS ();
m_routingProtocol = 0;
+ for (InjectedRoutesI k = m_injectedRoutes.begin ();
+ k != m_injectedRoutes.end ();
+ k = m_injectedRoutes.erase (k))
+ {
+ delete (*k);
+ }
Object::DoDispose ();
}
@@ -568,8 +584,8 @@
// and build the Link State Advertisements that reflect them and their associated
// networks.
//
- uint32_t
-GlobalRouter::DiscoverLSAs (void)
+uint32_t
+GlobalRouter::DiscoverLSAs ()
{
NS_LOG_FUNCTION_NOARGS ();
Ptr<Node> node = GetObject<Node> ();
@@ -696,6 +712,22 @@
BuildNetworkLSAs (c);
}
+ //
+ // Build injected route LSAs as external routes
+ // RFC 2328, section 12.4.4
+ //
+ for (InjectedRoutesCI i = m_injectedRoutes.begin();
+ i != m_injectedRoutes.end();
+ i++)
+ {
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs);
+ pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
+ pLSA->SetAdvertisingRouter (m_routerId);
+ pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+ m_LSAs.push_back (pLSA);
+ }
return m_LSAs.size ();
}
@@ -1467,6 +1499,86 @@
return false;
}
+void
+GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+ NS_LOG_FUNCTION (network << networkMask);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+//
+// Interface number does not matter here, using 1.
+//
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ 1);
+ m_injectedRoutes.push_back (route);
+}
+
+Ipv4RoutingTableEntry *
+GlobalRouter::GetInjectedRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ if (index < m_injectedRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (InjectedRoutesCI i = m_injectedRoutes.begin ();
+ i != m_injectedRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+uint32_t
+GlobalRouter::GetNInjectedRoutes ()
+{
+ return m_injectedRoutes.size ();
+}
+
+void
+GlobalRouter::RemoveInjectedRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (index);
+ NS_ASSERT (index < m_injectedRoutes.size ());
+ uint32_t tmp = 0;
+ for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size());
+ delete *i;
+ m_injectedRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+}
+
+bool
+GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
+{
+ NS_LOG_FUNCTION (index);
+ for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
+ {
+ if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
+ {
+ NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
+ delete *i;
+ m_injectedRoutes.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+
//
// Link through the given channel and find the net device that's on the
// other end. This only makes sense with a point-to-point channel.
--- a/src/routing/global-routing/global-router-interface.h Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/global-router-interface.h Mon Aug 31 23:05:26 2009 -0700
@@ -32,6 +32,7 @@
#include "ns3/net-device-container.h"
#include "ns3/bridge-net-device.h"
#include "ns3/global-route-manager.h"
+#include "ns3/ipv4-routing-table-entry.h"
namespace ns3 {
@@ -614,6 +615,8 @@
* advertisements after a network topology change by calling DiscoverLSAs
* and then by reading those advertisements.
*
+ * \param List of routing table entries of external routes to be injected.
+ *
* @see GlobalRoutingLSA
* @see GlobalRouter::GetLSA ()
* @returns The number of Global Routing Link State Advertisements.
@@ -657,6 +660,59 @@
*/
bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
+/**
+ * @brief Inject a route to be circulated to other routers as an external
+ * route
+ *
+ * @param network The Network to inject
+ * @param networkMask The Network Mask to inject
+ */
+ void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
+
+/**
+ * @brief Get the number of injected routes that have been added
+ * to the routing table.
+ * @return number of injected routes
+ */
+ uint32_t GetNInjectedRoutes (void);
+
+/**
+ * @brief Return the injected route indexed by i
+ * @param i the index of the route
+ * @return a pointer to that Ipv4RoutingTableEntry is returned
+ *
+ */
+ Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * Calling this function will cause all indexed routes numbered above
+ * index i to have their index decremented. For instance, it is possible to
+ * remove N injected routes by calling RemoveInjectedRoute (0) N times.
+ *
+ * @param i The index (into the injected routing list) of the route to remove.
+ *
+ * @see GlobalRouter::WithdrawRoute ()
+ */
+ void RemoveInjectedRoute (uint32_t i);
+
+/**
+ * @brief Withdraw a route from the global unicast routing table.
+ *
+ * Calling this function will cause all indexed routes numbered above
+ * index i to have their index decremented. For instance, it is possible to
+ * remove N injected routes by calling RemoveInjectedRoute (0) N times.
+ *
+ * @param i The index (into the injected routing list) of the route to remove.
+ * @param network The Network to inject
+ * @param networkMask The Network Mask to inject
+ * @return whether the operation succeeded (will return false if no such route)
+ *
+ * @see GlobalRouter::RemoveInjectedRoute ()
+ */
+ bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
+
private:
virtual ~GlobalRouter ();
void ClearLSAs (void);
@@ -680,6 +736,11 @@
Ipv4Address m_routerId;
Ptr<Ipv4GlobalRouting> m_routingProtocol;
+ typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI;
+ InjectedRoutes m_injectedRoutes; // Routes we are exporting
+
// inherited from Object
virtual void DoDispose (void);
--- a/src/routing/global-routing/ipv4-global-routing.cc Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/ipv4-global-routing.cc Mon Aug 31 23:05:26 2009 -0700
@@ -98,10 +98,27 @@
m_networkRoutes.push_back (route);
}
+void
+Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ NS_LOG_FUNCTION (network << networkMask << nextHop);
+ Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
+ *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_ASexternalRoutes.push_back (route);
+}
+
+
Ptr<Ipv4Route>
Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest)
{
NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC ("Looking for route for destination " << dest);
Ptr<Ipv4Route> rtentry = 0;
bool found = false;
Ipv4RoutingTableEntry* route = 0;
@@ -137,6 +154,23 @@
}
}
}
+ if (found == false)
+ {
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ Ipv4Mask mask = (*k)->GetDestNetworkMask ();
+ Ipv4Address entry = (*k)->GetDestNetwork ();
+ if (mask.IsMatch (dest, entry))
+ {
+ NS_LOG_LOGIC ("Found external route" << *k);
+ route = (*k);
+ found = true;
+ break;
+ }
+ }
+ }
if (found == true)
{
rtentry = Create<Ipv4Route> ();
@@ -161,6 +195,7 @@
uint32_t n = 0;
n += m_hostRoutes.size ();
n += m_networkRoutes.size ();
+ n += m_ASexternalRoutes.size ();
return n;
}
@@ -184,16 +219,31 @@
}
index -= m_hostRoutes.size ();
uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
+ if (index < m_networkRoutes.size())
{
- if (tmp == index)
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
{
- return *j;
+ if (tmp == index)
+ {
+ return *j;
+ }
+ tmp++;
}
- tmp++;
}
+ index -= m_networkRoutes.size();
+ tmp = 0;
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ if (tmp == index)
+ {
+ return *k;
+ }
+ tmp++;
+ }
NS_ASSERT (false);
// quiet compiler.
return 0;
@@ -236,6 +286,22 @@
}
tmp++;
}
+ index -= m_networkRoutes.size ();
+ tmp = 0;
+ for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
+ k != m_ASexternalRoutes.end ();
+ k++)
+ {
+ if (tmp == index)
+ {
+ NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size());
+ delete *k;
+ m_ASexternalRoutes.erase (k);
+ NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size());
+ return;
+ }
+ tmp++;
+ }
NS_ASSERT (false);
}
@@ -255,6 +321,13 @@
{
delete (*j);
}
+ for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
+ l != m_ASexternalRoutes.end ();
+ l = m_ASexternalRoutes.erase (l))
+ {
+ delete (*l);
+ }
+
Ipv4RoutingProtocol::DoDispose ();
}
--- a/src/routing/global-routing/ipv4-global-routing.h Mon Aug 31 15:29:20 2009 +0200
+++ b/src/routing/global-routing/ipv4-global-routing.h Mon Aug 31 23:05:26 2009 -0700
@@ -147,6 +147,20 @@
uint32_t interface);
/**
+ * \brief Add an external route to the global routing table.
+ *
+ * \param network The Ipv4Address network for this route.
+ * \param networkMask The Ipv4Mask to extract the network.
+ * \param nextHop The next hop Ipv4Address
+ * \param interface The network interface index used to send packets to the
+ * destination.
+ */
+ void AddASExternalRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+
+/**
* \brief Get the number of individual unicast routes that have been added
* to the routing table.
*
@@ -204,12 +218,16 @@
typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
+ typedef std::list<Ipv4RoutingTableEntry *> ASExternalRoutes;
+ typedef std::list<Ipv4RoutingTableEntry *>::const_iterator ASExternalRoutesCI;
+ typedef std::list<Ipv4RoutingTableEntry *>::iterator ASExternalRoutesI;
Ptr<Ipv4Route> LookupGlobal (Ipv4Address dest);
HostRoutes m_hostRoutes;
NetworkRoutes m_networkRoutes;
-
+ ASExternalRoutes m_ASexternalRoutes; // External routes imported
+
Ptr<Ipv4> m_ipv4;
};