From fb3510cee2c3b302706639f4a98aa00fe7bce4e6 Mon Sep 17 00:00:00 2001 From: shashwat Date: Fri, 4 Jul 2025 13:50:49 +0530 Subject: [PATCH] internet: Add Ptr member to SPFVertex --- .../model/global-route-manager-impl.cc | 531 +++++++++--------- .../model/global-route-manager-impl.h | 7 + 2 files changed, 265 insertions(+), 273 deletions(-) diff --git a/src/internet/model/global-route-manager-impl.cc b/src/internet/model/global-route-manager-impl.cc index 775ffc4df..9684dc9d6 100644 --- a/src/internet/model/global-route-manager-impl.cc +++ b/src/internet/model/global-route-manager-impl.cc @@ -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 +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 = 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 router = node->GetObject(); + 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 = *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 rtr = node->GetObject(); - - 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 router = node->GetObject(); - if (!router) - { - continue; - } + + NS_ASSERT_MSG(router, "No GlobalRouter interface on node " << node->GetId()); + Ptr 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 = m_spfroot->GetNode(); + if (!node) { - Ptr 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 rtr = node->GetObject(); - - 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 = node->GetObject(); - NS_ASSERT_MSG(ipv4, - "GlobalRouteManagerImpl::SPFIntraAddRouter (): " - "QI for 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 - // (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 has an m_rootOif (outbound interface index) to - // which the packets should be send for forwarding. - // - - Ptr router = node->GetObject(); - if (!router) - { - continue; - } - Ptr 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 router = node->GetObject(); + 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 = node->GetObject(); + NS_ASSERT_MSG(ipv4, + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "QI for 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 + // (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 has an m_rootOif (outbound interface index) to + // which the packets should be send for forwarding. + // + + Ptr router = node->GetObject(); + + Ptr 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 = m_spfroot->GetNode(); + if (!node) { - Ptr node = *i; - - Ptr rtr = node->GetObject(); // - // 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 = node->GetObject(); - NS_ASSERT_MSG(ipv4, - "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " - "GetObject for 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 rtr = node->GetObject(); + 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 = node->GetObject(); + NS_ASSERT_MSG(ipv4, + "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): " + "GetObject for 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 = m_spfroot->GetNode(); + if (!node) { - Ptr 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 rtr = node->GetObject(); + 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 rtr = node->GetObject(); + 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 = m_spfroot->GetNode(); + if (!node) { - Ptr 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 rtr = node->GetObject(); - - 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 = node->GetObject(); - NS_ASSERT_MSG(ipv4, - "GlobalRouteManagerImpl::SPFIntraAddTransit (): " - "GetObject for 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 router = node->GetObject(); - if (!router) - { - continue; - } - Ptr 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 rtr = node->GetObject(); + 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 = node->GetObject(); + NS_ASSERT_MSG(ipv4, + "GlobalRouteManagerImpl::SPFIntraAddTransit (): " + "GetObject for 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 router = node->GetObject(); + Ptr 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 () diff --git a/src/internet/model/global-route-manager-impl.h b/src/internet/model/global-route-manager-impl.h index ae1f1b165..e06a29f61 100644 --- a/src/internet/model/global-route-manager-impl.h +++ b/src/internet/model/global-route-manager-impl.h @@ -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 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 m_node; //!< node pointer corresponding to the this Vertex /** * @brief Stream insertion operator.