internet: Add Ptr<Node> member to SPFVertex

This commit is contained in:
shashwat
2025-07-04 13:50:49 +05:30
committed by Shashwat Patni
parent 685c075a9d
commit fb3510cee2
2 changed files with 265 additions and 273 deletions

View File

@@ -104,6 +104,7 @@ SPFVertex::SPFVertex(GlobalRoutingLSA* lsa)
{
NS_LOG_LOGIC("Setting m_vertexType to VertexRouter");
m_vertexType = SPFVertex::VertexRouter;
m_node = lsa->GetNode();
}
else if (lsa->GetLSType() == GlobalRoutingLSA::NetworkLSA)
{
@@ -405,6 +406,12 @@ SPFVertex::ClearVertexProcessed()
this->SetVertexProcessed(false);
}
Ptr<Node>
SPFVertex::GetNode() const
{
return m_node;
}
// ---------------------------------------------------------------------------
//
// GlobalRouteManagerLSDB Implementation
@@ -1529,37 +1536,30 @@ GlobalRouteManagerImpl::SPFAddASExternal(GlobalRoutingLSA* extlsa, SPFVertex* v)
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.
// The node we need to add routes to is the node corresponding to the root vertex.
// This is the node for which we are building the routing table.
//
for (auto i = NodeList::Begin(); i != NodeList::End(); i++)
Ptr<Node> node = m_spfroot->GetNode();
if (!node)
{
NS_FATAL_ERROR("SPFAddASExternal():Can't find root node " << routerId);
return;
}
//
// 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> router = node->GetObject<GlobalRouter>();
NS_ASSERT_MSG(router, "No GlobalRouter interface on SPF root node " << node->GetId());
//
// 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.
//
if (router->GetRouterId() == routerId)
{
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)
{
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)
{
continue;
}
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to QI
@@ -1597,10 +1597,9 @@ GlobalRouteManagerImpl::SPFAddASExternal(GlobalRoutingLSA* extlsa, SPFVertex* v)
// which the packets should be send for forwarding.
//
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
{
continue;
}
NS_ASSERT_MSG(router, "No GlobalRouter interface on node " << node->GetId());
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all next-hop-IPs and out-going-interfaces for reaching
@@ -1628,6 +1627,8 @@ GlobalRouteManagerImpl::SPFAddASExternal(GlobalRoutingLSA* extlsa, SPFVertex* v)
}
return;
}
// This should never happen. The RouterId and vertexId should match
NS_FATAL_ERROR("SPFIntraAddRouter(): routerId and vertex ID do not match");
}
// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
@@ -1695,103 +1696,95 @@ GlobalRouteManagerImpl::SPFIntraAddStub(GlobalRoutingLinkRecord* l, SPFVertex* v
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.
// The node we need to add routes to is the node corresponding to the root vertex.
// This is the node for which we are building the routing table.
//
for (auto i = NodeList::Begin(); i != NodeList::End(); i++)
Ptr<Node> node = m_spfroot->GetNode();
if (!node)
{
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)
{
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(l->GetLinkData().Get());
Ipv4Address tempip = l->GetLinkId();
tempip = tempip.CombineMask(tempmask);
//
// 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)
{
continue;
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all next-hop-IPs and out-going-interfaces for reaching
// the stub network gateway 'v' from the root node
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddNetworkRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add network route to " << tempip
<< " using next hop " << nextHop << " via interface "
<< outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative");
}
}
return;
}
NS_LOG_ERROR("SPFIntraAddStub():Can't find root node " << routerId);
return;
}
//
// 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> router = node->GetObject<GlobalRouter>();
NS_ASSERT_MSG(router, "No GlobalRouter interface on node " << node->GetId());
//
// 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.
//
if (routerId == router->GetRouterId())
{
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(l->GetLinkData().Get());
Ipv4Address tempip = l->GetLinkId();
tempip = tempip.CombineMask(tempmask);
//
// 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>();
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all next-hop-IPs and out-going-interfaces for reaching
// the stub network gateway 'v' from the root node
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddNetworkRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add network route to " << tempip << " using next hop "
<< nextHop << " via interface " << outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative");
}
}
return;
}
// This should never happen. The RouterId and vertex Id should match
NS_LOG_ERROR("SPFIntraAddStub(): routerId and vertex ID do not match");
}
//
@@ -1815,42 +1808,44 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId(Ipv4Address a, Ipv4Mask amask)
//
Ipv4Address routerId = m_spfroot->GetVertexId();
//
// Walk the list of nodes in the system looking for the one corresponding to
// the node at the root of the SPF tree. This is the node for which we are
// building the routing table.
// The node we need to add routes to is the node corresponding to the root vertex.
// This is the node for which we are building the routing table.
//
for (auto i = NodeList::Begin(); i != NodeList::End(); i++)
Ptr<Node> node = m_spfroot->GetNode();
if (!node)
{
Ptr<Node> node = *i;
Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter>();
//
// If the node doesn't have a GlobalRouter interface it can't be the one
// we're interested in.
// Couldn't find it.
//
if (!rtr)
{
continue;
}
NS_LOG_LOGIC("FindOutgoingInterfaceId():Can't find root node " << routerId);
return -1;
}
if (rtr->GetRouterId() == routerId)
{
//
// This is the node we're building the routing table for. We're going to need
// the Ipv4 interface to look for the ipv4 interface index. Since this node
// is participating in routing IP version 4 packets, it certainly must have
// an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
"GetObject for <Ipv4> interface failed");
//
// Look through the interfaces on this node for one that has the IP address
// we're looking for. If we find one, return the corresponding interface
// index, or -1 if not found.
//
int32_t interface = ipv4->GetInterfaceForPrefix(a, amask);
Ptr<GlobalRouter> rtr = node->GetObject<GlobalRouter>();
NS_ASSERT_MSG(rtr, "No GlobalRouter interface on node " << node->GetId());
//
// If the node doesn't have a GlobalRouter interface it can't be the one
// we're interested in.
//
if (rtr->GetRouterId() == routerId)
{
//
// This is the node we're building the routing table for. We're going to need
// the Ipv4 interface to look for the ipv4 interface index. Since this node
// is participating in routing IP version 4 packets, it certainly must have
// an Ipv4 interface.
//
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
NS_ASSERT_MSG(ipv4,
"GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
"GetObject for <Ipv4> interface failed");
//
// Look through the interfaces on this node for one that has the IP address
// we're looking for. If we find one, return the corresponding interface
// index, or -1 if not found.
//
int32_t interface = ipv4->GetInterfaceForPrefix(a, amask);
#if 0
if (interface < 0)
@@ -1859,13 +1854,10 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId(Ipv4Address a, Ipv4Mask amask)
"Expected an interface associated with address a:" << a);
}
#endif
return interface;
}
return interface;
}
//
// Couldn't find it.
//
NS_LOG_LOGIC("FindOutgoingInterfaceId():Can't find root node " << routerId);
// This should never happen. The RouterId and vertex Id should match
NS_FATAL_ERROR("SPFIntraAddRouter(): routerId and vertex ID do not match");
return -1;
}
@@ -1902,37 +1894,31 @@ GlobalRouteManagerImpl::SPFIntraAddRouter(SPFVertex* v)
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.
// The node we need to add routes to is the node corresponding to the root vertex.
// This is the node for which we are building the routing table.
//
for (auto i = NodeList::Begin(); i != NodeList::End(); i++)
Ptr<Node> node = m_spfroot->GetNode();
if (!node)
{
Ptr<Node> node = *i;
//
// The router ID is accessible through the GlobalRouter interface, so we need
// to GetObject 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>();
NS_LOG_ERROR("SPFIntraAddRouter():Can't find root node " << routerId);
return;
}
if (!rtr)
{
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)
{
continue;
}
//
// The router ID is accessible through the GlobalRouter interface, so we need
// to GetObject 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>();
NS_ASSERT_MSG(rtr, "No GlobalRouter interface on node " << node->GetId());
//
// 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.
//
if (rtr->GetRouterId() == routerId)
{
NS_LOG_LOGIC("Setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to
@@ -2026,6 +2012,8 @@ GlobalRouteManagerImpl::SPFIntraAddRouter(SPFVertex* v)
//
return;
}
// This should never happen. The RouterId and vertex Id should match
NS_FATAL_ERROR("SPFIntraAddRouter(): routerId and vertex ID do not match");
}
void
@@ -2045,91 +2033,88 @@ GlobalRouteManagerImpl::SPFIntraAddTransit(SPFVertex* v)
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.
// The node we need to add routes to is the node corresponding to the root vertex.
// This is the node for which we are building the routing table.
//
for (auto i = NodeList::Begin(); i != NodeList::End(); i++)
Ptr<Node> node = m_spfroot->GetNode();
if (!node)
{
Ptr<Node> node = *i;
//
// The router ID is accessible through the GlobalRouter interface, so we need
// to GetObject 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)
{
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
// GetObject 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::SPFIntraAddTransit (): "
"GetObject 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.
//
GlobalRoutingLSA* lsa = v->GetLSA();
NS_ASSERT_MSG(lsa,
"GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"Expected valid LSA in SPFVertex* v");
Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask();
Ipv4Address tempip = lsa->GetLinkStateId();
tempip = tempip.CombineMask(tempmask);
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
if (!router)
{
continue;
}
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all available exit directions due to ECMP,
// and add host route for each of the exit direction toward
// the vertex 'v'
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddNetworkRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add network route to " << tempip
<< " using next hop " << nextHop << " via interface "
<< outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative " << outIf);
}
}
}
NS_LOG_ERROR("SPFIntraAddTransit():Can't find root node " << routerId);
return;
}
//
// The router ID is accessible through the GlobalRouter interface, so we need
// to GetObject 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>();
NS_ASSERT_MSG(rtr, "No GlobalRouter interface on node " << node->GetId());
//
// 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.
//
if (rtr->GetRouterId() == routerId)
{
NS_LOG_LOGIC("setting routes for node " << node->GetId());
//
// Routing information is updated using the Ipv4 interface. We need to
// GetObject 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::SPFIntraAddTransit (): "
"GetObject 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.
//
GlobalRoutingLSA* lsa = v->GetLSA();
NS_ASSERT_MSG(lsa,
"GlobalRouteManagerImpl::SPFIntraAddTransit (): "
"Expected valid LSA in SPFVertex* v");
Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask();
Ipv4Address tempip = lsa->GetLinkStateId();
tempip = tempip.CombineMask(tempmask);
Ptr<GlobalRouter> router = node->GetObject<GlobalRouter>();
Ptr<Ipv4GlobalRouting> gr = router->GetRoutingProtocol();
NS_ASSERT(gr);
// walk through all available exit directions due to ECMP,
// and add host route for each of the exit direction toward
// the vertex 'v'
for (uint32_t i = 0; i < v->GetNRootExitDirections(); i++)
{
SPFVertex::NodeExit_t exit = v->GetRootExitDirection(i);
Ipv4Address nextHop = exit.first;
int32_t outIf = exit.second;
if (outIf >= 0)
{
gr->AddNetworkRouteTo(tempip, tempmask, nextHop, outIf);
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " add network route to " << tempip << " using next hop "
<< nextHop << " via interface " << outIf);
}
else
{
NS_LOG_LOGIC("(Route " << i << ") Node " << node->GetId()
<< " NOT able to add network route to " << tempip
<< " using next hop " << nextHop
<< " since outgoing interface id is negative " << outIf);
}
}
//
// done adding routes for the root node.
//
return;
}
// This should never happen. The RouterId and vertex Id should match
NS_FATAL_ERROR("SPFIntraAddTransit(): routerId and vertex ID do not match");
}
// Derived from quagga ospf_vertex_add_parents ()

View File

@@ -522,6 +522,12 @@ class SPFVertex
*/
void ClearVertexProcessed();
/**
* @brief Get the node pointer corresponding to this Vertex
* @returns the node pointer corresponding to this Vertex
*/
Ptr<Node> GetNode() const;
private:
VertexType m_vertexType; //!< Vertex type
Ipv4Address m_vertexId; //!< Vertex ID
@@ -536,6 +542,7 @@ class SPFVertex
ListOfSPFVertex_t m_children; //!< Children list
bool m_vertexProcessed; //!< Flag to note whether vertex has been processed in stage two of SPF
//!< computation
Ptr<Node> m_node; //!< node pointer corresponding to the this Vertex
/**
* @brief Stream insertion operator.