diff -crB global-routing-old/global-route-manager-impl.cc global-routing/global-route-manager-impl.cc *** global-routing-old/global-route-manager-impl.cc Sat Jun 27 10:54:05 2009 --- global-routing/global-route-manager-impl.cc Sat Jun 27 18:39:41 2009 *************** *** 252,258 **** GlobalRouteManagerLSDB::GlobalRouteManagerLSDB () : ! m_database () { NS_LOG_FUNCTION_NOARGS (); } --- 252,259 ---- GlobalRouteManagerLSDB::GlobalRouteManagerLSDB () : ! m_database (), ! m_extdatabase () { NS_LOG_FUNCTION_NOARGS (); } *************** *** 267,272 **** --- 268,279 ---- GlobalRoutingLSA* temp = i->second; delete temp; } + for (uint32_t j=0; jGetLSType() == GlobalRoutingLSA::ASExternalLSAs) { ! m_extdatabase.push_back (lsa); ! } else ! { ! m_database.insert (LSDBPair_t (addr, lsa)); ! } ! } ! ! GlobalRoutingLSA* ! GlobalRouteManagerLSDB::GetExtLSA (uint32_t index) const ! { ! return m_extdatabase.at(index); ! } ! ! uint32_t ! GlobalRouteManagerLSDB::GetNumExtLSAs () const ! { ! return m_extdatabase.size(); } GlobalRoutingLSA* *************** *** 438,444 **** // DiscoverLSAs () will get zero as the number since no routes have been // found. // ! uint32_t numLSAs = rtr->DiscoverLSAs (); NS_LOG_LOGIC ("Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) --- 462,469 ---- // DiscoverLSAs () will get zero as the number since no routes have been // found. // ! Ptr grouting = rtr->GetRoutingProtocol (); ! uint32_t numLSAs = rtr->DiscoverLSAs (grouting->GetInjectedRoutes()); NS_LOG_LOGIC ("Found " << numLSAs << " LSAs"); for (uint32_t j = 0; j < numLSAs; ++j) *************** *** 824,830 **** " via outgoing interface " << w->GetOutgoingInterfaceId () << " with distance " << distance); } // end W is a router vertes ! else { NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork); // W is a directly connected network; no next hop is required --- 848,854 ---- " via outgoing interface " << w->GetOutgoingInterfaceId () << " with distance " << distance); } // end W is a router vertes ! else { NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork); // W is a directly connected network; no next hop is required *************** *** 1136,1141 **** --- 1160,1166 ---- // Second stage of SPF calculation procedure SPFProcessStubs (m_spfroot); + ProcessASExternals (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 *************** *** 1145,1150 **** --- 1170,1301 ---- m_spfroot = 0; } + void + GlobalRouteManagerImpl::ProcessASExternals (SPFVertex* v) + { + NS_LOG_FUNCTION_NOARGS (); + NS_LOG_LOGIC ("Processing externals for " << v->GetVertexId()); + for (uint32_t i = 0;iGetNumExtLSAs();i++) + { + GlobalRoutingLSA *rlsa = m_lsdb->GetExtLSA(i); + NS_LOG_LOGIC ("Processing External LSA with id " << rlsa->GetLinkStateId()); + SPFAddASExternal (rlsa, v); + } + return; + } + + // This is mostly copy-pasted from SPFAddStub with certain key changes + + void + GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *rlsa, SPFVertex *v) + { + NS_LOG_FUNCTION_NOARGS (); + + NS_ASSERT_MSG (m_spfroot, + "GlobalRouteManagerImpl::SPFAddASExternal (): Root pointer not set"); + // Two cases to consider: We are advertising the external ourselves + // => No need to add anything + // OR find best path to the advertising router + if (v->GetVertexId () == rlsa->GetAdvertisingRouter()) + { + NS_LOG_LOGIC ("External is on local host: " + << v->GetVertexId () << "; returning"); + return; + } + NS_LOG_LOGIC ("External is on remote host: " + << rlsa->GetAdvertisingRouter () << "; installing"); + + Ipv4Address routerId = m_spfroot->GetVertexId (); + + NS_LOG_LOGIC ("Vertex ID = " << routerId); + NodeList::Iterator i = NodeList::Begin (); + for (; i != NodeList::End (); i++) + { + Ptr node = *i; + Ptr rtr = + node->GetObject (); + + if (rtr == 0) + { + NS_LOG_LOGIC ("No GlobalRouter interface on node " << + node->GetId ()); + continue; + } + NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ()); + if (rtr->GetRouterId () == routerId) + { + NS_LOG_LOGIC ("Setting routes for node " << node->GetId ()); + + Ptr ipv4 = node->GetObject (); + NS_ASSERT_MSG (ipv4, + "GlobalRouteManagerImpl::SPFAddASExternalRouter (): " + "QI for interface failed"); + + Ipv4Mask tempmask= rlsa->GetNetworkLSANetworkMask (); + Ipv4Address tempip = rlsa->GetLinkStateId (); + // Probably not needed unless user has injected non-network addresses + tempip = tempip.CombineMask (tempmask); + + Ipv4Address viaid = rlsa->GetAdvertisingRouter (); + // Need to find IP address that we can do recursive lookup for + // Anything that the router HAS advertised should do fine + + // Let's find first P2P link of the advertising router and use that + v = new SPFVertex (m_lsdb->GetLSA (viaid)); + GlobalRoutingLinkRecord *l = 0; + GlobalRoutingLSA* w_lsa = 0; + uint32_t numRecordsInVertex=0; + if (v->GetVertexType () == SPFVertex::VertexRouter) + { + numRecordsInVertex = v->GetLSA ()->GetNLinkRecords (); + } + for (uint32_t j = 0; j < numRecordsInVertex; j++) + { + if (v->GetVertexType () == SPFVertex::VertexRouter) + { + NS_LOG_LOGIC ("Examining link " << j << " of " << + v->GetVertexId () << "'s " << + v->GetLSA ()->GetNLinkRecords () << " link records"); + + l = v->GetLSA ()->GetLinkRecord (j); + if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork) + { + NS_LOG_LOGIC ("Found a Stub record, ignoring"); + continue; + } + w_lsa = m_lsdb->GetLSA (l->GetLinkId ()); + NS_ASSERT (w_lsa); + NS_LOG_LOGIC ("Found a link from " << v->GetVertexId () << + " to " << w_lsa->GetLinkStateId () << " - using it for nexthop"); + break; + } + } + + SPFVertex* w = new SPFVertex (w_lsa); + GlobalRoutingLinkRecord *linkRemote = 0; + linkRemote = SPFGetNextLink (w, v, linkRemote); + Ipv4Address viaaddr = linkRemote->GetLinkData (); + delete w; delete v; + + NS_LOG_LOGIC (" Node " << node->GetId () << + " add route to " << tempip << + " with mask " << tempmask << + " via router id " << viaid << + ", IP address " << viaaddr); + Ptr router = node->GetObject (); + if (router == 0) + { + continue; + } + Ptr gr = router->GetRoutingProtocol (); + NS_ASSERT (gr); + gr->AddASExternalRouteTo (tempip, tempmask, viaaddr); + + return; + } + } + } + // 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 Only in global-routing/: global-route-manager-impl.cc~ diff -crB global-routing-old/global-route-manager-impl.h global-routing/global-route-manager-impl.h *** global-routing-old/global-route-manager-impl.h Sat Jun 27 10:54:05 2009 --- global-routing/global-route-manager-impl.h Sat Jun 27 18:38:36 2009 *************** *** 26,31 **** --- 26,32 ---- #include #include #include + #include #include "ns3/object.h" #include "ns3/ptr.h" #include "ns3/ipv4-address.h" *************** *** 76,82 **** enum VertexType { VertexUnknown = 0, /**< Uninitialized Link Record */ VertexRouter, /**< Vertex representing a router in the topology */ ! VertexNetwork /**< Vertex representing a network in the topology */ }; /** --- 77,83 ---- enum VertexType { VertexUnknown = 0, /**< Uninitialized Link Record */ VertexRouter, /**< Vertex representing a router in the topology */ ! VertexNetwork /**< Vertex representing a network in the topology */ }; /** *************** *** 683,694 **** --- 684,701 ---- * @see SPFVertex */ void Initialize (); + + GlobalRoutingLSA* GetExtLSA (uint32_t index) const; + uint32_t GetNumExtLSAs () const; + private: typedef std::map LSDBMap_t; typedef std::pair LSDBPair_t; LSDBMap_t m_database; + std::vector m_extdatabase; + /** * @brief GlobalRouteManagerLSDB copy construction is disallowed. There's no * need for it and a compiler provided shallow copy would be wrong. *************** *** 774,779 **** --- 781,787 ---- GlobalRouteManagerLSDB* m_lsdb; void SPFCalculate (Ipv4Address root); void SPFProcessStubs (SPFVertex* v); + void ProcessASExternals (SPFVertex* v); void SPFNext (SPFVertex*, CandidateQueue&); int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, GlobalRoutingLinkRecord* l, uint32_t distance); *************** *** 783,788 **** --- 791,797 ---- void SPFIntraAddRouter (SPFVertex* v); void SPFIntraAddTransit (SPFVertex* v); void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v); + void SPFAddASExternal (GlobalRoutingLSA *rlsa, SPFVertex *v); int32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255")); }; Only in global-routing/: global-route-manager-impl.h~ diff -crB global-routing-old/global-router-interface.cc global-routing/global-router-interface.cc *** global-routing-old/global-router-interface.cc Sat Jun 27 10:54:05 2009 --- global-routing/global-router-interface.cc Sat Jun 27 12:26:12 2009 *************** *** 394,399 **** --- 394,403 ---- { os << " (GlobalRoutingLSA::NetworkLSA)"; } + else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs) + { + os << " (GlobalRoutingLSA::ASExternalLSA)"; + } else { os << "(Unknown LSType)"; *************** *** 455,460 **** --- 459,470 ---- } os << "---------- End NetworkLSA Link Record ----------" << std::endl; } + else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs) + { + os << "---------- ASExternalLSA Link Record --------" << std::endl; + os << "m_linkStateId = " << m_linkStateId << std::endl; + os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl; + } else { NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType); *************** *** 549,556 **** // and build the Link State Advertisements that reflect them and their associated // networks. // ! uint32_t ! GlobalRouter::DiscoverLSAs (void) { NS_LOG_FUNCTION_NOARGS (); Ptr node = GetObject (); --- 559,566 ---- // and build the Link State Advertisements that reflect them and their associated // networks. // ! uint32_t ! GlobalRouter::DiscoverLSAs (std::list injectedRoutes) { NS_LOG_FUNCTION_NOARGS (); Ptr node = GetObject (); *************** *** 676,681 **** --- 686,707 ---- BuildNetworkLSAs (c); } + // + // Build injected route LSAs as external routes + // RFC 2328, section 12.4.4 + // + for (std::list::iterator i = injectedRoutes.begin(); + i != injectedRoutes.end(); + i++) + { + GlobalRoutingLSA *pLSA = new GlobalRoutingLSA; + pLSA->SetLSType (GlobalRoutingLSA::ASExternalLSAs); + pLSA->SetLinkStateId ((*i)->GetDestNetwork()); + pLSA->SetAdvertisingRouter (m_routerId); + pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask()); + pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED); + m_LSAs.push_back (pLSA); + } return m_LSAs.size (); } diff -crB global-routing-old/global-router-interface.h global-routing/global-router-interface.h *** global-routing-old/global-router-interface.h Sat Jun 27 10:54:05 2009 --- global-routing/global-router-interface.h Sat Jun 27 10:59:16 2009 *************** *** 32,37 **** --- 32,38 ---- #include "ns3/net-device-container.h" #include "ns3/bridge-net-device.h" #include "ns3/global-route-manager.h" + #include "ns3/ipv4-routing-table-entry.h" namespace ns3 { *************** *** 601,611 **** * advertisements after a network topology change by calling DiscoverLSAs * and then by reading those advertisements. * * @see GlobalRoutingLSA * @see GlobalRouter::GetLSA () * @returns The number of Global Routing Link State Advertisements. */ ! uint32_t DiscoverLSAs (void); /** * @brief Get the Number of Global Routing Link State Advertisements that this --- 602,614 ---- * advertisements after a network topology change by calling DiscoverLSAs * and then by reading those advertisements. * + * \param List of routing table entries of external routes to be injected. + * * @see GlobalRoutingLSA * @see GlobalRouter::GetLSA () * @returns The number of Global Routing Link State Advertisements. */ ! uint32_t DiscoverLSAs (std::list injectedRoutes); /** * @brief Get the Number of Global Routing Link State Advertisements that this diff -crB global-routing-old/ipv4-global-routing.cc global-routing/ipv4-global-routing.cc *** global-routing-old/ipv4-global-routing.cc Sat Jun 27 10:54:05 2009 --- global-routing/ipv4-global-routing.cc Sat Jun 27 17:57:39 2009 *************** *** 98,103 **** --- 98,118 ---- m_networkRoutes.push_back (route); } + void + Ipv4GlobalRouting::AddASExternalRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address forwardingRouter) + { + NS_LOG_FUNCTION (network << networkMask << forwardingRouter); + Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry (); + *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, + networkMask, + forwardingRouter, + 1); // Interface number never used + m_ASexternalRoutes.push_back (route); + } + + Ptr Ipv4GlobalRouting::LookupGlobal (Ipv4Address dest) { *************** *** 137,142 **** --- 152,173 ---- } } } + if (found == false) + { + for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); + k != m_ASexternalRoutes.end (); + k++) + { + Ipv4Mask mask = (*k)->GetDestNetworkMask (); + Ipv4Address entry = (*k)->GetDestNetwork (); + if (mask.IsMatch (dest, entry)) + { + NS_LOG_LOGIC ("Found external route" << *k << + ", recursing for gateway " << (*k)->GetGateway()); + return(LookupGlobal((*k)->GetGateway())); + } + } + } if (found == true) { rtentry = Create (); *************** *** 161,166 **** --- 192,198 ---- uint32_t n = 0; n += m_hostRoutes.size (); n += m_networkRoutes.size (); + n += m_ASexternalRoutes.size (); return n; } *************** *** 184,199 **** } index -= m_hostRoutes.size (); uint32_t tmp = 0; ! for (NetworkRoutesI j = m_networkRoutes.begin (); ! j != m_networkRoutes.end (); ! j++) { ! if (tmp == index) { ! return *j; } - tmp++; } NS_ASSERT (false); // quiet compiler. return 0; --- 216,246 ---- } index -= m_hostRoutes.size (); uint32_t tmp = 0; ! if (index < m_networkRoutes.size()) { ! for (NetworkRoutesI j = m_networkRoutes.begin (); ! j != m_networkRoutes.end (); ! j++) { ! if (tmp == index) ! { ! return *j; ! } ! tmp++; } } + index -= m_networkRoutes.size(); + tmp = 0; + for (ASExternalRoutesI k = m_ASexternalRoutes.begin (); + k != m_ASexternalRoutes.end (); + k++) + { + if (tmp == index) + { + return *k; + } + tmp++; + } NS_ASSERT (false); // quiet compiler. return 0; *************** *** 258,263 **** --- 305,331 ---- Ipv4RoutingProtocol::DoDispose (); } + void + Ipv4GlobalRouting::InjectRoute (Ipv4Address network, + Ipv4Mask networkMask) + { + NS_LOG_FUNCTION (network << networkMask); + Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry (); + // + // Interface number does not matter here, using 1. + // + *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network, + networkMask, + 1); + m_injectedRoutes.push_back (route); + } + + std::list + Ipv4GlobalRouting::GetInjectedRoutes () + { + return m_injectedRoutes; + } + Ptr Ipv4GlobalRouting::RouteOutput (Ptr p, const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { diff -crB global-routing-old/ipv4-global-routing.h global-routing/ipv4-global-routing.h *** global-routing-old/ipv4-global-routing.h Sat Jun 27 10:54:05 2009 --- global-routing/ipv4-global-routing.h Sat Jun 27 18:44:08 2009 *************** *** 146,151 **** --- 146,165 ---- Ipv4Mask networkMask, uint32_t interface); + /** + * \brief Add a network route to the global routing table. + * + * \param network The Ipv4Address network for this route. + * \param networkMask The Ipv4Mask to extract the network. + * \param interface The network interface index used to send packets to the + * destination. + * + * \see Ipv4Address + */ + void AddASExternalRouteTo (Ipv4Address network, + Ipv4Mask networkMask, + Ipv4Address forwardingRouter); + /** * \brief Get the number of individual unicast routes that have been added * to the routing table. *************** *** 194,199 **** --- 208,236 ---- */ void RemoveRoute (uint32_t i); + /** + * \brief Inject a route to the global routing protocol as an external route + * + * Using AddNetworkRouteTo and similar functions only change the table on single node. + * Changes made here propagate throughout the GlobalRouting cloud. + * After packet reaches the local node, other routing protocol should be able to + * handle it, or the packets will be null-routed (discarded). + * + * \param Network The Network to inject + * \param Mask The Network Mask to inject + * + */ + void InjectRoute (Ipv4Address network, + Ipv4Mask networkMask); + + /** + * \brief Request a list of Injected Routes. Used by Global-route-manager. + * + * Obtain the list of routes injected with InjectRoute method. + * + */ + std::list GetInjectedRoutes (); + protected: void DoDispose (void); *************** *** 204,215 **** typedef std::list NetworkRoutes; typedef std::list::const_iterator NetworkRoutesCI; typedef std::list::iterator NetworkRoutesI; Ptr LookupGlobal (Ipv4Address dest); HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; ! Ptr m_ipv4; }; --- 241,261 ---- typedef std::list NetworkRoutes; typedef std::list::const_iterator NetworkRoutesCI; typedef std::list::iterator NetworkRoutesI; + typedef std::list InjectedRoutes; + typedef std::list::const_iterator InjectedRoutesCI; + typedef std::list::iterator InjectedRoutesI; + typedef std::list ASExternalRoutes; + typedef std::list::const_iterator ASExternalRoutesCI; + typedef std::list::iterator ASExternalRoutesI; + Ptr LookupGlobal (Ipv4Address dest); HostRoutes m_hostRoutes; NetworkRoutes m_networkRoutes; ! InjectedRoutes m_injectedRoutes; // Routes we are exporting ! ASExternalRoutes m_ASexternalRoutes; // External routes imported ! Ptr m_ipv4; }; Only in global-routing/: ipv4-global-routing.h~