From 655aa68d546e819c15607733eced97a5d52c22eb Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sun, 30 Nov 2008 21:21:23 -0800 Subject: [PATCH] Segregate Ipv4GlobalRouting from Ipv4StaticRouting; add API for deleting and recomputing global routes --- src/internet-stack/wscript | 2 + .../global-route-manager-impl.cc | 96 ++++++++++++++++++- .../global-route-manager-impl.h | 17 ++++ .../global-routing/global-route-manager.cc | 15 +++ .../global-routing/global-route-manager.h | 32 ++++++- .../global-routing/global-router-interface.cc | 33 ++++++- 6 files changed, 185 insertions(+), 10 deletions(-) diff --git a/src/internet-stack/wscript b/src/internet-stack/wscript index 5f3f5b09e..26348749f 100644 --- a/src/internet-stack/wscript +++ b/src/internet-stack/wscript @@ -131,6 +131,7 @@ def build(bld): 'ipv4-interface.cc', 'ipv4-l3-protocol.cc', 'ipv4-static-routing.cc', + 'ipv4-global-routing.cc', 'ipv4-end-point.cc', 'udp-l4-protocol.cc', 'tcp-l4-protocol.cc', @@ -164,6 +165,7 @@ def build(bld): 'ipv4-interface.h', 'ipv4-l3-protocol.h', 'ipv4-static-routing.h', + 'ipv4-global-routing.h', 'icmpv4.h', ] diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index eb9ff94c9..573b80739 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -30,6 +30,7 @@ #include "ns3/log.h" #include "ns3/node-list.h" #include "ns3/ipv4.h" +#include "ns3/ipv4-global-routing.h" #include "global-router-interface.h" #include "global-route-manager-impl.h" #include "candidate-queue.h" @@ -349,6 +350,35 @@ GlobalRouteManagerImpl::DebugUseLsdb (GlobalRouteManagerLSDB* lsdb) m_lsdb = lsdb; } + void +GlobalRouteManagerImpl::DeleteGlobalRoutes () +{ + NS_LOG_FUNCTION_NOARGS (); + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++) + { + Ptr node = *i; + Ptr gr = GetGlobalRoutingProtocol (node->GetId ()); + uint32_t j = 0; + uint32_t nRoutes = gr->GetNRoutes (); + NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ()); + // Each time we delete route 0, the route index shifts downward + // We can delete all routes if we delete the route numbered 0 + // nRoutes times + for (j = 0; j < nRoutes; j++) + { + NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ()); + gr->RemoveRoute (0); + } + NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ()); + } + if (m_lsdb) + { + NS_LOG_LOGIC ("Deleting LSDB, creating new one"); + delete m_lsdb; + m_lsdb = new GlobalRouteManagerLSDB (); + } +} + // // In order to build the routing database, we need at least one of the nodes // to participate as a router. This is a convenience function that makes @@ -362,11 +392,25 @@ GlobalRouteManagerImpl::SelectRouterNodes () for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++) { Ptr node = *i; - NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << - node->GetId ()); + NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << node->GetId ()); Ptr globalRouter = CreateObject (); node->AggregateObject (globalRouter); + + NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ()); + Ptr globalRouting = CreateObject (); + // This is the object that will keep the global routes. We insert it + // at slightly higher priority than static routing (which is at zero). + // This means that global routes (e.g. host routes) will be consulted + // before static routes + Ptr ipv4 = node->GetObject (); + NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): " + "GetObject for interface failed"); + // XXX make the below priority value an attribute + ipv4->AddRoutingProtocol (globalRouting, 3); + // Locally cache the globalRouting pointer; we'll need it later + // when we add routes + AddGlobalRoutingProtocol (node->GetId (), globalRouting); } } @@ -382,6 +426,21 @@ GlobalRouteManagerImpl::SelectRouterNodes (NodeContainer c) Ptr globalRouter = CreateObject (); node->AggregateObject (globalRouter); + + NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ()); + Ptr globalRouting = CreateObject (); + // This is the object that will keep the global routes. We insert it + // at slightly higher priority than static routing (which is at zero). + // This means that global routes (e.g. host routes) will be consulted + // before static routes + Ptr ipv4 = node->GetObject (); + NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): " + "GetObject for interface failed"); + // XXX make the below priority value an attribute + ipv4->AddRoutingProtocol (globalRouting, 3); + // Locally cache the globalRouting pointer; we'll need it later + // when we add routes + AddGlobalRoutingProtocol (node->GetId (), globalRouting); } } @@ -1289,6 +1348,8 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // the local side of the point-to-point links found on the node described by // the vertex . // + NS_LOG_LOGIC (" Node " << node->GetId () << + " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ()); for (uint32_t j = 0; j < nLinkRecords; ++j) { // @@ -1317,7 +1378,9 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v) // Similarly, the vertex has an m_rootOif (outbound interface index) to // which the packets should be send for forwarding. // - ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (), + Ptr gr = GetGlobalRoutingProtocol (node->GetId ()); + NS_ASSERT (gr); + gr->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (), v->GetOutgoingTypeId ()); } // @@ -1399,7 +1462,9 @@ GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v) Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask (); Ipv4Address tempip = lsa->GetLinkStateId (); tempip = tempip.CombineMask (tempmask); - ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), + Ptr gr = GetGlobalRoutingProtocol (node->GetId ()); + NS_ASSERT (gr); + gr->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingTypeId ()); NS_LOG_LOGIC ("Node " << node->GetId () << " add network route to " << tempip << @@ -1427,6 +1492,29 @@ GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v) v->GetParent ()->AddChild (v); } + void +GlobalRouteManagerImpl::AddGlobalRoutingProtocol (uint32_t nodeId, Ptr proto) +{ + NS_LOG_FUNCTION (nodeId); + m_routingProtocols.push_back + (std::pair > (nodeId, proto)); + m_routingProtocols.sort (); +} + + Ptr +GlobalRouteManagerImpl::GetGlobalRoutingProtocol (uint32_t nodeId) +{ + for (Ipv4GlobalRoutingList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++) + { + if ((*rprotoIter).first == nodeId) + { + return (*rprotoIter).second; + } + } + return 0; +} + + } // namespace ns3 #ifdef RUN_SELF_TESTS diff --git a/src/routing/global-routing/global-route-manager-impl.h b/src/routing/global-routing/global-route-manager-impl.h index 46c3247a8..238f7a484 100644 --- a/src/routing/global-routing/global-route-manager-impl.h +++ b/src/routing/global-routing/global-route-manager-impl.h @@ -37,6 +37,7 @@ namespace ns3 { const uint32_t SPF_INFINITY = 0xffffffff; class CandidateQueue; +class Ipv4GlobalRouting; /** * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328, @@ -700,6 +701,16 @@ class GlobalRouteManagerImpl public: GlobalRouteManagerImpl (); virtual ~GlobalRouteManagerImpl (); +/** + * @brief Delete all static routes on all nodes that have a + * GlobalRouterInterface + * + * TODO: separate manually assigned static routes from static routes that + * the global routing code injects, and only delete the latter + * @internal + * + */ + virtual void DeleteGlobalRoutes (); /** * @brief Select which nodes in the system are to be router nodes and * aggregate the appropriate interfaces onto those nodes. @@ -770,6 +781,12 @@ private: void SPFIntraAddTransit (SPFVertex* v); uint32_t FindOutgoingTypeId (Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255")); + + // Local cache of the Ipv4GlobalRouting objects, indexed by nodeId + typedef std::list< std::pair< uint32_t, Ptr > > Ipv4GlobalRoutingList; + void AddGlobalRoutingProtocol (uint32_t nodeId, Ptr proto); + Ptr GetGlobalRoutingProtocol (uint32_t nodeId); + Ipv4GlobalRoutingList m_routingProtocols; }; } // namespace ns3 diff --git a/src/routing/global-routing/global-route-manager.cc b/src/routing/global-routing/global-route-manager.cc index 5fc23f2f3..ac177ae84 100644 --- a/src/routing/global-routing/global-route-manager.cc +++ b/src/routing/global-routing/global-route-manager.cc @@ -49,6 +49,21 @@ GlobalRouteManager::PopulateRoutingTables (NodeContainer c) InitializeRoutes (); } + void +GlobalRouteManager::RecomputeRoutingTables () +{ + DeleteGlobalRoutes (); + BuildGlobalRoutingDatabase (); + InitializeRoutes (); +} + + void +GlobalRouteManager::DeleteGlobalRoutes () +{ + SimulationSingleton::Get ()-> + DeleteGlobalRoutes (); +} + void GlobalRouteManager::SelectRouterNodes (void) { diff --git a/src/routing/global-routing/global-route-manager.h b/src/routing/global-routing/global-route-manager.h index 8fe4c0471..1eb5d3210 100644 --- a/src/routing/global-routing/global-route-manager.h +++ b/src/routing/global-routing/global-route-manager.h @@ -45,14 +45,33 @@ public: * the nodes in the simulation. Makes all nodes in the simulation into * routers. * - * All this function does is call BuildGlobalRoutingDatabase () and + * All this function does is call the three private functions + * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and * InitializeRoutes (). * + * @see SelectRouterNodes (); * @see BuildGlobalRoutingDatabase (); * @see InitializeRoutes (); */ static void PopulateRoutingTables (); + /** + *@brief Remove all routes that were previously installed in a prior call + * to either PopulateRoutingTables() or RecomputeRoutingTables(), and + * add a new set of routes. + * + * This method does not change the set of nodes + * over which GlobalRouting is being used, but it will dynamically update + * its representation of the global topology before recomputing routes. + * Users must first call PopulateRoutingTables() and then may subsequently + * call RecomputeRoutingTables() at any later time in the simulation. + * + * @see DeleteGlobalRoutes (); + * @see BuildGlobalRoutingDatabase (); + * @see InitializeRoutes (); + */ + static void RecomputeRoutingTables (); + /** * @brief Build a routing database and initialize the routing tables of * the nodes in the simulation. Makes the nodes in the provided container @@ -72,6 +91,17 @@ public: static uint32_t AllocateRouterId (); private: + +/** + * @brief Delete all static routes on all nodes that have a + * GlobalRouterInterface + * + * TODO: separate manually assigned static routes from static routes that + * the global routing code injects, and only delete the latter + * @internal + */ + static void DeleteGlobalRoutes (); + /** * @brief Select which nodes in the system are to be router nodes and * aggregate the appropriate interfaces onto those nodes. diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 19558c05b..9f55c9b63 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -513,7 +513,7 @@ GlobalRouter::ClearLSAs () *i = 0; } - NS_LOG_LOGIC ("Clear list"); + NS_LOG_LOGIC ("Clear list of LSAs"); m_LSAs.clear(); } @@ -599,9 +599,9 @@ GlobalRouter::DiscoverLSAs (void) // IP addresses in routing. // bool isIp = false; - for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i ) + for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j ) { - if (ipv4Local->GetNetDevice (i) == ndLocal) + if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j)) { isIp = true; break; @@ -1007,6 +1007,12 @@ GlobalRouter::ProcessPointToPointLink (Ptr ndLocal, GlobalRoutingLSA rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote); NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device"); + if (!ipv4Remote->IsUp (ifIndexRemote)) + { + NS_LOG_LOGIC ("Remote side interface " << ifIndexRemote << " not up"); + return; + } + // // Now that we have the Ipv4 interface, we can get the (remote) address and // mask we need. @@ -1108,8 +1114,15 @@ GlobalRouter::BuildNetworkLSAs (NetDeviceContainer c) { Ptr tempIpv4 = tempNode->GetObject (); NS_ASSERT (tempIpv4); - Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); - pLSA->AddAttachedRouter (tempAddr); + if (!tempIpv4->IsUp (tempIfIndex)) + { + NS_LOG_LOGIC ("Remote side interface " << tempIfIndex << " not up"); + } + else + { + Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex); + pLSA->AddAttachedRouter (tempAddr); + } } } m_LSAs.push_back (pLSA); @@ -1180,6 +1193,11 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther)) { NS_LOG_LOGIC ("Found router on bridge net device " << bnd); + if (!ipv4->IsUp (ifIndexOther)) + { + NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up"); + continue; + } Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); desigRtr = addrOther < desigRtr ? addrOther : desigRtr; NS_LOG_LOGIC ("designated router now " << desigRtr); @@ -1223,6 +1241,11 @@ GlobalRouter::FindDesignatedRouterForLink (Ptr ndLocal, bool allowRec uint32_t ifIndexOther; if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther)) { + if (!ipv4->IsUp (ifIndexOther)) + { + NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up"); + continue; + } NS_LOG_LOGIC ("Found router on net device " << ndOther); Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther); desigRtr = addrOther < desigRtr ? addrOther : desigRtr;