Allow injection of routes to Ipv4GlobalRouting
This commit is contained in:
@@ -52,6 +52,12 @@ us a note on ns-developers mailing list. </p>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -36,6 +36,10 @@ def build(bld):
|
||||
['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'
|
||||
|
||||
@@ -243,6 +243,15 @@ SPFVertex::IsVertexProcessed (void) const
|
||||
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 @@ SPFVertex::IsVertexProcessed (void) const
|
||||
|
||||
GlobalRouteManagerLSDB::GlobalRouteManagerLSDB ()
|
||||
:
|
||||
m_database ()
|
||||
m_database (),
|
||||
m_extdatabase ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
}
|
||||
@@ -267,6 +277,12 @@ GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
|
||||
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::Initialize ()
|
||||
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 @@ GlobalRouteManagerImpl::BuildGlobalRoutingDatabase ()
|
||||
// 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 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
|
||||
|
||||
// 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 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
|
||||
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
|
||||
|
||||
@@ -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 @@ public:
|
||||
* @returns value of underlying flag
|
||||
*/
|
||||
bool IsVertexProcessed (void) const;
|
||||
|
||||
void ClearVertexProcessed (void);
|
||||
|
||||
private:
|
||||
VertexType m_vertexType;
|
||||
Ipv4Address m_vertexId;
|
||||
@@ -683,12 +687,18 @@ public:
|
||||
* @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 @@ private:
|
||||
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 @@ private:
|
||||
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"));
|
||||
};
|
||||
|
||||
@@ -413,6 +413,10 @@ GlobalRoutingLSA::Print (std::ostream &os) const
|
||||
{
|
||||
os << " (GlobalRoutingLSA::NetworkLSA)";
|
||||
}
|
||||
else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
|
||||
{
|
||||
os << " (GlobalRoutingLSA::ASExternalLSA)";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "(Unknown LSType)";
|
||||
@@ -474,6 +478,12 @@ GlobalRoutingLSA::Print (std::ostream &os) const
|
||||
}
|
||||
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 @@ GlobalRouter::DoDispose ()
|
||||
{
|
||||
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 @@ GlobalRouter::GetRouterId (void) const
|
||||
// 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 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
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 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
|
||||
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.
|
||||
|
||||
@@ -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 @@ public:
|
||||
* 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 @@ public:
|
||||
*/
|
||||
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 @@ private:
|
||||
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);
|
||||
|
||||
|
||||
@@ -98,10 +98,27 @@ Ipv4GlobalRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
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 @@ Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
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 @@ Ipv4GlobalRouting::GetNRoutes (void)
|
||||
uint32_t n = 0;
|
||||
n += m_hostRoutes.size ();
|
||||
n += m_networkRoutes.size ();
|
||||
n += m_ASexternalRoutes.size ();
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -184,16 +219,31 @@ Ipv4GlobalRouting::GetRoute (uint32_t index)
|
||||
}
|
||||
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 @@ Ipv4GlobalRouting::RemoveRoute (uint32_t index)
|
||||
}
|
||||
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 @@ Ipv4GlobalRouting::DoDispose (void)
|
||||
{
|
||||
delete (*j);
|
||||
}
|
||||
for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
|
||||
l != m_ASexternalRoutes.end ();
|
||||
l = m_ASexternalRoutes.erase (l))
|
||||
{
|
||||
delete (*l);
|
||||
}
|
||||
|
||||
Ipv4RoutingProtocol::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,20 @@ public:
|
||||
Ipv4Mask networkMask,
|
||||
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 @@ private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user