30 #include "ns3/assert.h"
31 #include "ns3/fatal-error.h"
33 #include "ns3/node-list.h"
35 #include "ns3/ipv4-routing-protocol.h"
36 #include "ns3/ipv4-list-routing.h"
56 os <<
"(" << exit.first <<
" ," << exit.second <<
")";
63 typedef SPFVertex::ListOfSPFVertex_t::const_iterator CIter_t;
65 for (CIter_t iter = vs.begin (); iter != vs.end ();)
67 os << (*iter)->m_vertexId;
68 if (++iter != vs.end ())
88 m_vertexType (VertexUnknown),
89 m_vertexId (
"255.255.255.255"),
93 m_nextHop (
"0.0.0.0"),
96 m_vertexProcessed (false)
102 m_vertexId (lsa->GetLinkStateId ()),
106 m_nextHop (
"0.0.0.0"),
109 m_vertexProcessed (false)
134 for (ListOfSPFVertex_t::iterator piter =
m_parents.begin ();
141 uint32_t orgCount = (*piter)->m_children.size ();
142 (*piter)->m_children.remove (
this);
143 uint32_t newCount = (*piter)->m_children.size ();
144 if (orgCount > newCount)
146 NS_ASSERT_MSG (orgCount > newCount,
"Unable to find the current vertex from its parents --- impossible!");
162 if (p == 0)
continue;
250 NS_LOG_LOGIC (
"Index to SPFVertex's parent is out-of-range.");
253 ListOfSPFVertex_t::const_iterator iter =
m_parents.begin ();
301 typedef ListOfNodeExit_t::const_iterator CIter_t;
305 while (i-- > 0) { iter++; }
329 extList.begin (), extList.end ());
343 NS_LOG_WARN (
"x root exit directions in this vertex are going to be discarded");
370 for ( ListOfSPFVertex_t::const_iterator i =
m_children.begin ();
433 LSDBMap_t::iterator i;
454 LSDBMap_t::iterator i;
497 LSDBMap_t::const_iterator i;
500 if (i->first == addr)
515 LSDBMap_t::const_iterator i;
582 uint32_t nRoutes = gr->GetNRoutes ();
583 NS_LOG_LOGIC (
"Deleting " << gr->GetNRoutes ()<<
" routes from node " << node->
GetId ());
587 for (j = 0; j < nRoutes; j++)
641 uint32_t numLSAs = rtr->DiscoverLSAs ();
644 for (uint32_t j = 0; j < numLSAs; ++j)
651 rtr->GetLSA (j, *lsa);
724 if (rtr && rtr->GetNumLSAs () )
753 uint32_t distance = 0;
754 uint32_t numRecordsInVertex = 0;
768 for (uint32_t i = 0; i < numRecordsInVertex; i++)
888 <<
"return false, but it does now!");
1071 " goes through next hop " << nextHop <<
1072 " via outgoing interface " << outIf <<
1073 " with distance " << distance);
1091 " via outgoing interface " << outIf <<
1092 " with distance " << distance);
1120 " goes through next hop " << nextHop <<
1121 " via outgoing interface " << outIf);
1176 bool found_prev_link =
false;
1185 found_prev_link =
true;
1192 for (uint32_t i = 0; i < v->
GetLSA ()->GetNLinkRecords (); ++i)
1205 if (!found_prev_link)
1207 NS_LOG_LOGIC (
"Skipping links before prev_link found");
1208 found_prev_link =
true;
1285 NS_LOG_WARN (
"all nodes should have at least one transit link:" << root );
1298 NS_LOG_LOGIC (
"TBD: Would have inserted default for transit");
1308 for (uint32_t j = 0; j < nLinkRecords; ++j)
1328 NS_LOG_LOGIC (
"Inserting default route for node " << myRouterId <<
" to next hop " <<
1370 NS_LOG_LOGIC (
"Starting SPFCalculate for node " << root);
1381 NS_LOG_LOGIC (
"SPFCalculate truncated for stub node " << root);
1410 if (candidate.
Size () == 0)
1424 v = candidate.
Pop ();
1510 NS_LOG_LOGIC (
"Processing external for destination " <<
1520 NS_LOG_LOGIC (
"Found advertising router to destination");
1528 NS_LOG_LOGIC (
"Vertex's child " << i <<
" not yet processed, processing...");
1568 for (; i != listEnd; i++)
1588 NS_LOG_LOGIC (
"Considering router " << rtr->GetRouterId ());
1590 if (rtr->GetRouterId () == routerId)
1600 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1601 "QI for <Ipv4> interface failed");
1609 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1610 "Expected valid LSA in SPFVertex* v");
1641 int32_t outIf = exit.second;
1644 gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf);
1646 " add external network route to " << tempip <<
1647 " using next hop " << nextHop <<
1648 " via interface " << outIf);
1653 " NOT able to add network route to " << tempip <<
1654 " using next hop " << nextHop <<
1655 " since outgoing interface id is negative");
1707 "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
1737 for (; i != listEnd; i++)
1759 NS_LOG_LOGIC (
"Considering router " << rtr->GetRouterId ());
1761 if (rtr->GetRouterId () == routerId)
1771 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1772 "QI for <Ipv4> interface failed");
1780 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1781 "Expected valid LSA in SPFVertex* v");
1812 int32_t outIf = exit.second;
1815 gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
1817 " add network route to " << tempip <<
1818 " using next hop " << nextHop <<
1819 " via interface " << outIf);
1824 " NOT able to add network route to " << tempip <<
1825 " using next hop " << nextHop <<
1826 " since outgoing interface id is negative");
1861 for (; i != listEnd; i++)
1876 if (rtr->GetRouterId () == routerId)
1886 "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
1887 "GetObject for <Ipv4> interface failed");
1893 int32_t
interface = ipv4->GetInterfaceForPrefix (a, amask);
1898 NS_FATAL_ERROR (
"GlobalRouteManagerImpl::FindOutgoingInterfaceId(): "
1899 "Expected an interface associated with address a:" << a);
1908 NS_LOG_LOGIC (
"FindOutgoingInterfaceId():Can't find root node " << routerId);
1934 "GlobalRouteManagerImpl::SPFIntraAddRouter (): Root pointer not set");
1952 for (; i != listEnd; i++)
1974 NS_LOG_LOGIC (
"Considering router " << rtr->GetRouterId ());
1976 if (rtr->GetRouterId () == routerId)
1986 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1987 "GetObject for <Ipv4> interface failed");
1996 "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
1997 "Expected valid LSA in SPFVertex* v");
2009 " found " << nLinkRecords <<
" link records in LSA " << lsa <<
"with LinkStateId "<< lsa->
GetLinkStateId ());
2010 for (uint32_t j = 0; j < nLinkRecords; ++j)
2047 int32_t outIf = exit.second;
2054 " using next hop " << nextHop <<
2055 " and outgoing interface " << outIf);
2060 " NOT able to add host route to " << lr->
GetLinkData () <<
2061 " using next hop " << nextHop <<
2062 " since outgoing interface id is negative " << outIf);
2079 "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
2097 for (; i != listEnd; i++)
2119 NS_LOG_LOGIC (
"Considering router " << rtr->GetRouterId ());
2121 if (rtr->GetRouterId () == routerId)
2131 "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
2132 "GetObject for <Ipv4> interface failed");
2141 "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
2142 "Expected valid LSA in SPFVertex* v");
2160 int32_t outIf = exit.second;
2164 gr->AddNetworkRouteTo (tempip, tempmask, nextHop, outIf);
2166 " add network route to " << tempip <<
2167 " using next hop " << nextHop <<
2168 " via interface " << outIf);
2173 " NOT able to add network route to " << tempip <<
2174 " using next hop " << nextHop <<
2175 " since outgoing interface id is negative " << outIf);
2196 for (uint32_t i=0;;)
2200 if ((parent = v->
GetParent (i++)) == 0)
break;
A Candidate Queue used in routing calculations.
void Push(SPFVertex *vNew)
Push a Shortest Path First Vertex pointer onto the queue according to the priority scheme.
SPFVertex * Pop(void)
Pop the Shortest Path First Vertex pointer at the top of the queue.
uint32_t Size(void) const
Return the number of Shortest Path First Vertex pointers presently stored in the Candidate Queue.
SPFVertex * Find(const Ipv4Address addr) const
Searches the Candidate Queue for a Shortest Path First Vertex pointer that points to a vertex having ...
void Reorder(void)
Reorders the Candidate Queue according to the priority scheme.
void SPFCalculate(Ipv4Address root)
Calculate the shortest path first (SPF) tree.
void SPFAddASExternal(GlobalRoutingLSA *extlsa, SPFVertex *v)
Add an external route to the routing tables.
virtual ~GlobalRouteManagerImpl()
void ProcessASExternals(SPFVertex *v, GlobalRoutingLSA *extlsa)
Process Autonomous Systems (AS) External LSA.
virtual void InitializeRoutes()
Compute routes using a Dijkstra SPF computation and populate per-node forwarding tables.
void SPFProcessStubs(SPFVertex *v)
Process Stub nodes.
virtual void BuildGlobalRoutingDatabase()
Build the routing database by gathering Link State Advertisements from each node exporting a GlobalRo...
GlobalRoutingLinkRecord * SPFGetNextLink(SPFVertex *v, SPFVertex *w, GlobalRoutingLinkRecord *prev_link)
Search for a link between two vertices.
int32_t FindOutgoingInterfaceId(Ipv4Address a, Ipv4Mask amask=Ipv4Mask("255.255.255.255"))
Return the interface number corresponding to a given IP address and mask.
virtual void DeleteGlobalRoutes()
Delete all static routes on all nodes that have a GlobalRouterInterface.
GlobalRouteManagerLSDB * m_lsdb
the Link State DataBase (LSDB) of the Global Route Manager
bool CheckForStubNode(Ipv4Address root)
Test if a node is a stub, from an OSPF sense.
void DebugUseLsdb(GlobalRouteManagerLSDB *lsdb)
Debugging routine; allow client code to supply a pre-built LSDB.
SPFVertex * m_spfroot
the root node
void SPFNext(SPFVertex *v, CandidateQueue &candidate)
Examine the links in v's LSA and update the list of candidates with any vertices not already on the l...
void DebugSPFCalculate(Ipv4Address root)
Debugging routine; call the core SPF from the unit tests.
void SPFIntraAddTransit(SPFVertex *v)
Add a transit to the routing tables.
int SPFNexthopCalculation(SPFVertex *v, SPFVertex *w, GlobalRoutingLinkRecord *l, uint32_t distance)
Calculate nexthop from root through V (parent) to vertex W (destination) with given distance from roo...
void SPFIntraAddStub(GlobalRoutingLinkRecord *l, SPFVertex *v)
Add a stub to the routing tables.
void SPFIntraAddRouter(SPFVertex *v)
Add a host route to the routing tables.
void SPFVertexAddParent(SPFVertex *v)
Adds a vertex to the list of children in each of its parents.
The Link State DataBase (LSDB) of the Global Route Manager.
void Initialize()
Set all LSA flags to an initialized state, for SPF computation.
std::pair< Ipv4Address, GlobalRoutingLSA * > LSDBPair_t
pair of IPv4 addresses / Link State Advertisements
~GlobalRouteManagerLSDB()
Destroy an empty Global Router Manager Link State Database.
uint32_t GetNumExtLSAs() const
Get the number of External Link State Advertisements.
GlobalRoutingLSA * GetLSA(Ipv4Address addr) const
Look up the Link State Advertisement associated with the given link state ID (address).
std::vector< GlobalRoutingLSA * > m_extdatabase
database of External Link State Advertisements
void Insert(Ipv4Address addr, GlobalRoutingLSA *lsa)
Insert an IP address / Link State Advertisement pair into the Link State Database.
LSDBMap_t m_database
database of IPv4 addresses / Link State Advertisements
GlobalRoutingLSA * GetExtLSA(uint32_t index) const
Look up the External Link State Advertisement associated with the given index.
GlobalRouteManagerLSDB()
Construct an empty Global Router Manager Link State Database.
GlobalRoutingLSA * GetLSAByLinkData(Ipv4Address addr) const
Look up the Link State Advertisement associated with the given link state ID (address).
An interface aggregated to a node to provide global routing info.
a Link State Advertisement (LSA) for a router, used in global routing.
void SetStatus(SPFStatus status)
Set the SPF status of the advertisement.
@ LSA_SPF_NOT_EXPLORED
New vertex not yet considered.
@ LSA_SPF_IN_SPFTREE
Vertex is in the SPF tree.
@ LSA_SPF_CANDIDATE
Vertex is in the SPF candidate queue.
SPFStatus GetStatus(void) const
Get the SPF status of the advertisement.
uint32_t GetNLinkRecords(void) const
Return the number of Global Routing Link Records in the LSA.
uint32_t GetNAttachedRouters(void) const
Return the number of attached routers listed in the NetworkLSA.
LSType GetLSType(void) const
Return the LSType field of the LSA.
Ipv4Address GetAdvertisingRouter(void) const
Get the Advertising Router as defined by the OSPF spec.
Ptr< Node > GetNode(void) const
Get the Node pointer of the node that originated this LSA.
Ipv4Address GetAttachedRouter(uint32_t n) const
Return an Ipv4Address corresponding to the specified attached router.
Ipv4Mask GetNetworkLSANetworkMask(void) const
For a Network LSA, get the Network Mask field that precedes the list of attached routers.
GlobalRoutingLinkRecord * GetLinkRecord(uint32_t n) const
Return a pointer to the specified Global Routing Link Record.
Ipv4Address GetLinkStateId(void) const
Get the Link State ID as defined by the OSPF spec.
A single link record for a link state advertisement.
uint16_t GetMetric(void) const
Get the Metric Data field of the Global Routing Link Record.
LinkType GetLinkType(void) const
Get the Link Type field of the Global Routing Link Record.
@ StubNetwork
Record represents a leaf node network.
@ PointToPoint
Record representing a point to point channel.
@ TransitNetwork
Unused – for future OSPF compatibility
Ipv4Address GetLinkId(void) const
Get the Link ID field of the Global Routing Link Record.
Ipv4Address GetLinkData(void) const
Get the Link Data field of the Global Routing Link Record.
Ipv4 addresses are stored in host order in this class.
uint32_t Get(void) const
Get the host-order 32-bit IP address.
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
static Ipv4Address GetZero(void)
Access to the IPv4 forwarding table, interfaces, and configuration.
a class to represent an Ipv4 address mask
uint32_t GetId(void) const
uint32_t GetSystemId(void) const
static Iterator End(void)
static uint32_t GetNNodes(void)
static Iterator Begin(void)
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Vertex used in shortest path first (SPF) computations.
NodeExit_t GetRootExitDirection(uint32_t i) const
Obtain a pair indicating the exit direction from the root.
std::pair< Ipv4Address, int32_t > NodeExit_t
IPv4 / interface container for exit nodes.
Ipv4Address m_nextHop
next hop
void SetVertexId(Ipv4Address id)
Set the Vertex ID field of a SPFVertex object.
void MergeParent(const SPFVertex *v)
Merge the Parent list from the v into this vertex.
VertexType
Enumeration of the possible types of SPFVertex objects.
@ VertexNetwork
Vertex representing a network in the topology.
@ VertexRouter
Vertex representing a router in the topology.
void InheritAllRootExitDirections(const SPFVertex *vertex)
Inherit all root exit directions from a given vertex to 'this' vertex.
void SetDistanceFromRoot(uint32_t distance)
Set the distance from the root vertex to "this" SPFVertex object.
SPFVertex * GetChild(uint32_t n) const
Get a borrowed SPFVertex pointer to the specified child of "this" SPFVertex.
GlobalRoutingLSA * GetLSA(void) const
Get the Global Router Link State Advertisement returned by the Global Router represented by this SPFV...
void SetParent(SPFVertex *parent)
Set the pointer to the SPFVector that is the parent of "this" SPFVertex.
void MergeRootExitDirections(const SPFVertex *vertex)
Merge into 'this' vertex the list of exit directions from another vertex.
std::list< SPFVertex * > ListOfSPFVertex_t
container of SPFVertexes
std::list< NodeExit_t > ListOfNodeExit_t
container of Exit nodes
GlobalRoutingLSA * m_lsa
Link State Advertisement.
~SPFVertex()
Destroy an SPFVertex (Shortest Path First Vertex).
VertexType GetVertexType(void) const
Get the Vertex Type field of a SPFVertex object.
void SetRootExitDirection(Ipv4Address nextHop, int32_t id=SPF_INFINITY)
Set the IP address and outgoing interface index that should be used to begin forwarding packets from ...
void SetVertexProcessed(bool value)
Set the value of the VertexProcessed flag.
uint32_t GetNChildren(void) const
Get the number of children of "this" SPFVertex.
void SetVertexType(VertexType type)
Set the Vertex Type field of a SPFVertex object.
void SetLSA(GlobalRoutingLSA *lsa)
Set the Global Router Link State Advertisement returned by the Global Router represented by this SPFV...
uint32_t GetNRootExitDirections() const
Get the number of exit directions from root for reaching 'this' vertex.
int32_t m_rootOif
root Output Interface
uint32_t m_distanceFromRoot
Distance from root node.
uint32_t GetDistanceFromRoot(void) const
Get the distance from the root vertex to "this" SPFVertex object.
bool IsVertexProcessed(void) const
Check the value of the VertexProcessed flag.
bool m_vertexProcessed
Flag to note whether vertex has been processed in stage two of SPF computation.
Ipv4Address m_vertexId
Vertex ID.
void ClearVertexProcessed(void)
Clear the value of the VertexProcessed flag.
uint32_t AddChild(SPFVertex *child)
Get a borrowed SPFVertex pointer to the specified child of "this" SPFVertex.
NodeExit_t GetRootExitDirection() const
Obtain a pair indicating the exit direction from the root.
Ipv4Address GetVertexId(void) const
Get the Vertex ID field of a SPFVertex object.
ListOfNodeExit_t m_ecmpRootExits
store the multiple root's exits for supporting ECMP
SPFVertex * GetParent(uint32_t i=0) const
Get a pointer to the SPFVector that is the parent of "this" SPFVertex.
ListOfSPFVertex_t m_children
Children list.
VertexType m_vertexType
Vertex type.
ListOfSPFVertex_t m_parents
parent list
SPFVertex()
Construct an empty ("uninitialized") SPFVertex (Shortest Path First Vertex).
static uint32_t GetSystemId(void)
Get the system id of this simulator.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const uint32_t SPF_INFINITY
"infinite" distance between nodes
std::ostream & operator<<(std::ostream &os, const Angles &a)