# HG changeset patch # User Tom Henderson # Date 1227885686 28800 # Node ID 7658bcc28d8d601ff456bff5a35d402fd50897bc # Parent 0339a8ad59837efd97f4914a707009c6554e006c Drop packets in Ipv4L3Protocol::Receive if interface is down diff -r 0339a8ad5983 -r 7658bcc28d8d src/internet-stack/ipv4-l3-protocol.cc --- a/src/internet-stack/ipv4-l3-protocol.cc Fri Nov 28 06:05:27 2008 -0800 +++ b/src/internet-stack/ipv4-l3-protocol.cc Fri Nov 28 07:21:26 2008 -0800 @@ -522,8 +522,17 @@ Ipv4L3Protocol::Receive( Ptr ipv4Interface = *i; if (ipv4Interface->GetDevice () == device) { - m_rxTrace (packet, index); - break; + if (ipv4Interface->IsUp ()) + { + m_rxTrace (packet, index); + break; + } + else + { + NS_LOG_LOGIC ("Dropping received packet-- interface is down"); + m_dropTrace (packet); + return; + } } index++; } @@ -1075,7 +1084,7 @@ Ipv4L3Protocol::SetDown (uint32_t ifaceI Ptr interface = GetInterface (ifaceIndex); interface->SetDown (); - // Remove all routes that are going through this interface + // Remove all static routes that are going through this interface bool modified = true; while (modified) { # HG changeset patch # User Tom Henderson # Date 1228108883 28800 # Node ID ec65107df095b4a991e964fbb99e2ddcd8229c81 # Parent 7658bcc28d8d601ff456bff5a35d402fd50897bc Segregate Ipv4GlobalRouting from Ipv4StaticRouting; add API for deleting and recomputing global routes diff -r 7658bcc28d8d -r ec65107df095 src/internet-stack/wscript --- a/src/internet-stack/wscript Fri Nov 28 07:21:26 2008 -0800 +++ b/src/internet-stack/wscript Sun Nov 30 21:21:23 2008 -0800 @@ -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 -r 7658bcc28d8d -r ec65107df095 src/routing/global-routing/global-route-manager-impl.cc --- a/src/routing/global-routing/global-route-manager-impl.cc Fri Nov 28 07:21:26 2008 -0800 +++ b/src/routing/global-routing/global-route-manager-impl.cc Sun Nov 30 21:21:23 2008 -0800 @@ -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 (Gl 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::SelectRouterNode 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::SelectRouterNode 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::SPFIntraAddRoute // 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::SPFIntraAddRoute // 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::SPFIntraAddTrans 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 << @@ -1426,6 +1491,29 @@ GlobalRouteManagerImpl::SPFVertexAddPare NS_LOG_FUNCTION (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 diff -r 7658bcc28d8d -r ec65107df095 src/routing/global-routing/global-route-manager-impl.h --- a/src/routing/global-routing/global-route-manager-impl.h Fri Nov 28 07:21:26 2008 -0800 +++ b/src/routing/global-routing/global-route-manager-impl.h Sun Nov 30 21:21:23 2008 -0800 @@ -37,6 +37,7 @@ const uint32_t SPF_INFINITY = 0xffffffff const uint32_t SPF_INFINITY = 0xffffffff; class CandidateQueue; +class Ipv4GlobalRouting; /** * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328, @@ -701,6 +702,16 @@ 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. * @internal @@ -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 -r 7658bcc28d8d -r ec65107df095 src/routing/global-routing/global-route-manager.cc --- a/src/routing/global-routing/global-route-manager.cc Fri Nov 28 07:21:26 2008 -0800 +++ b/src/routing/global-routing/global-route-manager.cc Sun Nov 30 21:21:23 2008 -0800 @@ -50,6 +50,21 @@ GlobalRouteManager::PopulateRoutingTable } void +GlobalRouteManager::RecomputeRoutingTables () +{ + DeleteGlobalRoutes (); + BuildGlobalRoutingDatabase (); + InitializeRoutes (); +} + + void +GlobalRouteManager::DeleteGlobalRoutes () +{ + SimulationSingleton::Get ()-> + DeleteGlobalRoutes (); +} + + void GlobalRouteManager::SelectRouterNodes (void) { SimulationSingleton::Get ()-> diff -r 7658bcc28d8d -r ec65107df095 src/routing/global-routing/global-route-manager.h --- a/src/routing/global-routing/global-route-manager.h Fri Nov 28 07:21:26 2008 -0800 +++ b/src/routing/global-routing/global-route-manager.h Sun Nov 30 21:21:23 2008 -0800 @@ -45,13 +45,32 @@ 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 @@ -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 -r 7658bcc28d8d -r ec65107df095 src/routing/global-routing/global-router-interface.cc --- a/src/routing/global-routing/global-router-interface.cc Fri Nov 28 07:21:26 2008 -0800 +++ b/src/routing/global-routing/global-router-interface.cc Sun Nov 30 21:21:23 2008 -0800 @@ -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 (P 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 (NetDevic { 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::FindDesignatedRouterForLin 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::FindDesignatedRouterForLin 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; # HG changeset patch # User Tom Henderson # Date 1228117032 28800 # Node ID 34908804c029ec32eeddb9f894172b5ee0adb60b # Parent ec65107df095b4a991e964fbb99e2ddcd8229c81 Add processing logic for stub links in global routing code diff -r ec65107df095 -r 34908804c029 src/routing/global-routing/global-route-manager-impl.cc --- a/src/routing/global-routing/global-route-manager-impl.cc Sun Nov 30 21:21:23 2008 -0800 +++ b/src/routing/global-routing/global-route-manager-impl.cc Sun Nov 30 23:37:12 2008 -0800 @@ -53,7 +53,8 @@ SPFVertex::SPFVertex () : m_rootOif (SPF_INFINITY), m_nextHop ("0.0.0.0"), m_parent (0), - m_children () + m_children (), + m_vertexProcessed (false) { NS_LOG_FUNCTION_NOARGS (); } @@ -65,7 +66,8 @@ SPFVertex::SPFVertex (GlobalRoutingLSA* m_rootOif (SPF_INFINITY), m_nextHop ("0.0.0.0"), m_parent (0), - m_children () + m_children (), + m_vertexProcessed (false) { NS_LOG_FUNCTION_NOARGS (); if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) @@ -226,6 +228,19 @@ SPFVertex::AddChild (SPFVertex* child) m_children.push_back (child); return m_children.size (); } + +void +SPFVertex::SetVertexProcessed (bool value) +{ + m_vertexProcessed = value; +} + +bool +SPFVertex::IsVertexProcessed (void) const +{ + return m_vertexProcessed; +} + // --------------------------------------------------------------------------- // @@ -1174,11 +1189,11 @@ GlobalRouteManagerImpl::SPFCalculate (Ip // // Iterate the algorithm by returning to Step 2 until there are no more // candidate vertices. -// - } -// -// Second stage of SPF calculation procedure's -// NOTYET: ospf_spf_process_stubs (area, area->spf, new_table); + + } // end for loop + +// Second stage of SPF calculation procedure + SPFProcessStubs (m_spfroot); // // 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 @@ -1186,6 +1201,155 @@ GlobalRouteManagerImpl::SPFCalculate (Ip // delete m_spfroot; m_spfroot = 0; +} + +// 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 +void +GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v) +{ + NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ()); + if (v->GetVertexType () == SPFVertex::VertexRouter) + { + GlobalRoutingLSA *rlsa = v->GetLSA (); + NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ()); + for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++) + { + NS_LOG_LOGIC ("Examining link " << i << " of " << + v->GetVertexId () << "'s " << + v->GetLSA ()->GetNLinkRecords () << " link records"); + GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i); + if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork) + { + NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ()); + SPFIntraAddStub (l, v); + continue; + } + } + } + for (uint32_t i = 0; i < v->GetNChildren (); i++) + { + if (!v->GetChild (i)->IsVertexProcessed ()) + { + SPFProcessStubs (v->GetChild (i)); + v->GetChild (i)->SetVertexProcessed (true); + } + } +} + +// RFC2328 16.1. second stage. +void +GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v) +{ + NS_LOG_FUNCTION_NOARGS (); + + NS_ASSERT_MSG (m_spfroot, + "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set"); + + // XXX simplifed logic for the moment. There are two cases to consider: + // 1) the stub network is on this router; do nothing for now + // (already handled above) + // 2) the stub network is on a remote router, so I should use the + // same next hop that I use to get to vertex v + if (v->GetVertexId () == m_spfroot->GetVertexId ()) + { + NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning"); + return; + } + NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing"); +// +// The root of the Shortest Path First tree is the router to which we are +// going to write the actual routing table entries. The vertex corresponding +// to this router has a vertex ID which is the router ID of that node. We're +// going to use this ID to discover which node it is that we're actually going +// to update. +// + 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 = *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 == 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 = 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. +// + GlobalRoutingLSA *lsa = v->GetLSA (); + NS_ASSERT_MSG (lsa, + "GlobalRouteManagerImpl::SPFIntraAddRouter (): " + "Expected valid LSA in SPFVertex* v"); + //Address tempaddr = Address (l->GetLinkData); + Ipv4Mask tempmask ("255.255.255.0"); + Ipv4Address tempip = l->GetLinkId (); + 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->GetOutgoingTypeId ()); +// +// 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 gr = GetGlobalRoutingProtocol (node->GetId ()); + NS_ASSERT (gr); + gr->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingTypeId ()); + return; + } // if + } // for } // diff -r ec65107df095 -r 34908804c029 src/routing/global-routing/global-route-manager-impl.h --- a/src/routing/global-routing/global-route-manager-impl.h Sun Nov 30 21:21:23 2008 -0800 +++ b/src/routing/global-routing/global-route-manager-impl.h Sun Nov 30 23:37:12 2008 -0800 @@ -547,6 +547,23 @@ public: */ uint32_t AddChild (SPFVertex* child); + /** + * @brief Set the value of the VertexProcessed flag + * + * Flag to note whether vertex has been processed in stage two of + * SPF computation + * @param value boolean value to set the flag + */ + void SetVertexProcessed (bool value); + + /** + * @brief Check the value of the VertexProcessed flag + * + * Flag to note whether vertex has been processed in stage two of + * SPF computation + * @returns value of underlying flag + */ + bool IsVertexProcessed (void) const; private: VertexType m_vertexType; Ipv4Address m_vertexId; @@ -557,6 +574,7 @@ private: SPFVertex* m_parent; typedef std::list ListOfSPFVertex_t; ListOfSPFVertex_t m_children; + bool m_vertexProcessed; /** * @brief The SPFVertex copy construction is disallowed. There's no need for @@ -771,6 +789,7 @@ private: SPFVertex* m_spfroot; GlobalRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); + void SPFProcessStubs (SPFVertex* v); void SPFNext (SPFVertex*, CandidateQueue&); int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, GlobalRoutingLinkRecord* l, uint32_t distance); @@ -779,6 +798,7 @@ private: GlobalRoutingLinkRecord* prev_link); void SPFIntraAddRouter (SPFVertex* v); void SPFIntraAddTransit (SPFVertex* v); + void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v); uint32_t FindOutgoingTypeId (Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255")); diff -r ec65107df095 -r 34908804c029 src/routing/global-routing/global-route-manager.h --- a/src/routing/global-routing/global-route-manager.h Sun Nov 30 21:21:23 2008 -0800 +++ b/src/routing/global-routing/global-route-manager.h Sun Nov 30 23:37:12 2008 -0800 @@ -45,7 +45,7 @@ public: * the nodes in the simulation. Makes all nodes in the simulation into * routers. * - * All this function does is call the three private functions + * All this function does is call the three functions * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and * InitializeRoutes (). * @@ -54,6 +54,21 @@ public: * @see InitializeRoutes (); */ static void PopulateRoutingTables (); + +/** + * @brief Build a routing database and initialize the routing tables of + * the nodes in the simulation. Makes the nodes in the provided container + * into routers. + * + * All this function does is call the three functions + * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and + * InitializeRoutes (). + * + * @see SelectRouterNodes (Node Container c); + * @see BuildGlobalRoutingDatabase (); + * @see InitializeRoutes (); + */ + static void PopulateRoutingTables (NodeContainer c); /** *@brief Remove all routes that were previously installed in a prior call @@ -73,32 +88,9 @@ public: 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 - * into routers. - * - * All this function does is call BuildGlobalRoutingDatabase () and - * InitializeRoutes (). - * - * @see BuildGlobalRoutingDatabase (); - * @see InitializeRoutes (); - */ - static void PopulateRoutingTables (NodeContainer c); - -/** - * @brief Allocate a 32-bit router ID from monotonically increasing counter. - */ - 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 (); @@ -117,6 +109,13 @@ private: * */ static void SelectRouterNodes (NodeContainer c); + +/** + * @brief Allocate a 32-bit router ID from monotonically increasing counter. + */ + static uint32_t AllocateRouterId (); + +private: /** * @brief Build the routing database by gathering Link State Advertisements diff -r ec65107df095 -r 34908804c029 src/routing/global-routing/global-router-interface.cc --- a/src/routing/global-routing/global-router-interface.cc Sun Nov 30 21:21:23 2008 -0800 +++ b/src/routing/global-routing/global-router-interface.cc Sun Nov 30 23:37:12 2008 -0800 @@ -413,23 +413,30 @@ GlobalRoutingLSA::Print (std::ostream &o os << "---------- RouterLSA Link Record ----------" << std::endl; os << "m_linkType = " << p->m_linkType; - if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork) + if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint) + { + os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl; + os << "m_linkId = " << p->m_linkId << std::endl; + os << "m_linkData = " << p->m_linkData << std::endl; + os << "m_metric = " << p->m_metric << std::endl; + } + else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork) { os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl; os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl; os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl; os << "m_metric = " << p->m_metric << std::endl; } - else if (p->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork) + else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork) { - os << "(GlobalRoutingLinkRecord::StubNetwork)" << std::endl; + os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl; os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl; os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl; os << "m_metric = " << p->m_metric << std::endl; } else { - os << "(Unknown LinkType)" << std::endl; + os << " (Unknown LinkType)" << std::endl; os << "m_linkId = " << p->m_linkId << std::endl; os << "m_linkData = " << p->m_linkData << std::endl; os << "m_metric = " << p->m_metric << std::endl; @@ -621,7 +628,7 @@ GlobalRouter::DiscoverLSAs (void) // the segment. We add the appropriate link record to the LSA. // // If the device is a point to point link, we treat it separately. In - // that case, there always two link records added. + // that case, there may be one or two link records added. // if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { @@ -1007,12 +1014,6 @@ GlobalRouter::ProcessPointToPointLink (P 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. @@ -1026,15 +1027,22 @@ GlobalRouter::ProcessPointToPointLink (P // link records; the first is a point-to-point record describing the link and // the second is a stub network record with the network number. // - GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord; - NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record"); - plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); - plr->SetLinkId (rtrIdRemote); - plr->SetLinkData (addrLocal); - plr->SetMetric (metricLocal); - pLSA->AddLinkRecord (plr); - plr = 0; + GlobalRoutingLinkRecord *plr; + if (ipv4Remote->IsUp (ifIndexRemote)) + { + NS_LOG_LOGIC ("Remote side interface " << ifIndexRemote << " is up-- add a type 1 link"); + + plr = new GlobalRoutingLinkRecord; + NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record"); + plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint); + plr->SetLinkId (rtrIdRemote); + plr->SetLinkData (addrLocal); + plr->SetMetric (metricLocal); + pLSA->AddLinkRecord (plr); + plr = 0; + } + // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1) plr = new GlobalRoutingLinkRecord; NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record"); plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);