--- a/src/routing/global-routing/global-route-manager-impl.cc Fri Aug 10 13:49:41 2007 -0700
+++ b/src/routing/global-routing/global-route-manager-impl.cc Fri Aug 10 13:33:45 2007 -0700
@@ -48,8 +48,7 @@
{
}
-SPFVertex::SPFVertex (GlobalRouterLSA* lsa) :
- m_vertexType (VertexRouter),
+SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) :
m_vertexId (lsa->GetLinkStateId ()),
m_lsa (lsa),
m_distanceFromRoot (SPF_INFINITY),
@@ -58,6 +57,16 @@
m_parent (0),
m_children ()
{
+ if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexRouter");
+ m_vertexType = SPFVertex::VertexRouter;
+ }
+ else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA)
+ {
+ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexNetwork");
+ m_vertexType = SPFVertex::VertexNetwork;
+ }
}
SPFVertex::~SPFVertex ()
@@ -99,12 +108,12 @@
}
void
-SPFVertex::SetLSA (GlobalRouterLSA* lsa)
+SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
{
m_lsa = lsa;
}
- GlobalRouterLSA*
+ GlobalRoutingLSA*
SPFVertex::GetLSA (void) const
{
return m_lsa;
@@ -210,7 +219,7 @@
for (i= m_database.begin (); i!= m_database.end (); i++)
{
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA");
- GlobalRouterLSA* temp = i->second;
+ GlobalRoutingLSA* temp = i->second;
delete temp;
}
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB (): clear map");
@@ -225,19 +234,19 @@
LSDBMap_t::iterator i;
for (i= m_database.begin (); i!= m_database.end (); i++)
{
- GlobalRouterLSA* temp = i->second;
- temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
+ GlobalRoutingLSA* temp = i->second;
+ temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
}
}
void
-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa)
+GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
{
NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()");
m_database.insert (LSDBPair_t (addr, lsa));
}
- GlobalRouterLSA*
+ GlobalRoutingLSA*
GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
{
NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()");
@@ -255,6 +264,31 @@
return 0;
}
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
+{
+ NS_DEBUG ("GlobalRouteManagerLSDB::GetLSAByLinkData ()");
+//
+// Look up an LSA by its address.
+//
+ LSDBMap_t::const_iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ GlobalRoutingLSA* temp = i->second;
+// Iterate among temp's Link Records
+ for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
+ {
+ GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
+ if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
+ lr->GetLinkData () == addr)
+ {
+ return temp;
+ }
+ }
+ }
+ return 0;
+}
+
// ---------------------------------------------------------------------------
//
// GlobalRouteManagerImpl Implementation
@@ -359,13 +393,12 @@
for (uint32_t j = 0; j < numLSAs; ++j)
{
- GlobalRouterLSA* lsa = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
//
// This is the call to actually fetch a Link State Advertisement from the
// router.
//
rtr->GetLSA (j, *lsa);
- NS_DEBUG ("LSA " << j);
NS_DEBUG (*lsa);
//
// Write the newly discovered link state advertisement to the database.
@@ -453,52 +486,86 @@
GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
{
SPFVertex* w = 0;
- GlobalRouterLSA* w_lsa = 0;
+ GlobalRoutingLSA* w_lsa = 0;
+ GlobalRoutingLinkRecord *l = 0;
uint32_t distance = 0;
+ uint32_t numRecordsInVertex = 0;
NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()");
-//
-// Always true for now, since all our LSAs are RouterLSAs.
-//
- if (v->GetVertexType () == SPFVertex::VertexRouter)
+
+// V points to a Router-LSA or Network-LSA
+// Loop over the links in router LSA or attached routers in Network LSA
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
{
- if (true)
+ numRecordsInVertex = v->GetLSA ()->GetNLinkRecords ();
+ }
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters ();
+ }
+
+ for (uint32_t i = 0; i < numRecordsInVertex; i++)
+ {
+// Get w_lsa: In case of V is Router-LSA
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
{
NS_DEBUG ("SPFNext: Examining " << v->GetVertexId () << "'s " <<
v->GetLSA ()->GetNLinkRecords () << " link records");
//
-// Walk the list of link records in the link state advertisement associated
-// with the "current" router (represented by vertex <v>).
-//
- for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
- {
-//
// (a) If this is a link to a stub network, examine the next link in V's LSA.
// Links to stub networks will be considered in the second stage of the
// shortest path calculation.
//
- GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork)
- {
- NS_DEBUG ("SPFNext: Found a Stub record to " <<
- l->GetLinkId ());
- continue;
- }
+ l = v->GetLSA ()->GetLinkRecord (i);
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+ {
+ NS_DEBUG ("SPFNext: Found a Stub record to " <<
+ l->GetLinkId ());
+ continue;
+ }
//
// (b) Otherwise, W is a transit vertex (router or transit network). Look up
// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
// database.
//
- if (l->GetLinkType () == GlobalRouterLinkRecord::PointToPoint)
- {
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+ {
//
// Lookup the link state advertisement of the new link -- we call it <w> in
// the link state database.
//
- w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
- NS_ASSERT (w_lsa);
- NS_DEBUG ("SPFNext: Found a P2P record from " <<
- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_DEBUG ("SPFNext: Found a P2P record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else if (l->GetLinkType () ==
+ GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_DEBUG ("SPFNext: Found a Transit record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else
+ {
+ NS_ASSERT_MSG (0, "illegal Link Type");
+ }
+ }
+// Get w_lsa: In case of V is Network-LSA
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ w_lsa = m_lsdb->GetLSAByLinkData
+ (v->GetLSA ()->GetAttachedRouter (i));
+ if (!w_lsa)
+ {
+ continue;
+ }
+ NS_DEBUG ("SPFNext: Found a Network LSA from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+
+// Note: w_lsa at this point may be either RouterLSA or NetworkLSA
//
// (c) If vertex W is already on the shortest-path tree, examine the next
// link in the LSA.
@@ -506,57 +573,56 @@
// If the link is to a router that is already in the shortest path first tree
// then we have it covered -- ignore it.
//
- if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_IN_SPFTREE)
- {
- NS_DEBUG ("SPFNext: Skipping-> LSA "<<
- w_lsa->GetLinkStateId () << " already in SPF tree");
- continue;
- }
-//
-// The link is to a router we haven't dealt with yet.
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE)
+ {
+ NS_DEBUG ("SPFNext: Skipping-> LSA "<<
+ w_lsa->GetLinkStateId () << " already in SPF tree");
+ continue;
+ }
//
// (d) Calculate the link state cost D of the resulting path from the root to
// vertex W. D is equal to the sum of the link state cost of the (already
// calculated) shortest path to vertex V and the advertised cost of the link
// between vertices V and W.
//
- distance = v->GetDistanceFromRoot () + l->GetMetric ();
-
- NS_DEBUG ("SPFNext: Considering w_lsa " <<
- w_lsa->GetLinkStateId ());
+ if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ distance = v->GetDistanceFromRoot () + l->GetMetric ();
+ }
+ else
+ {
+ distance = v->GetDistanceFromRoot ();
+ }
- if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
- {
-//
-// If we haven't yet considered the link represented by <w> we have to create
-// a new SPFVertex to represent it.
-//
- w = new SPFVertex (w_lsa);
-//
+ NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// Is there already vertex w in candidate list?
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
+ {
+
+// prepare vertex w
+ w = new SPFVertex (w_lsa);
+// Calculate nexthop to w
// We need to figure out how to actually get to the new router represented
// by <w>. This will (among other things) find the next hop address to send
// packets destined for this network to, and also find the outbound interface
// used to forward the packets.
//
- if (SPFNexthopCalculation (v, w, l, distance))
- {
- w_lsa->SetStatus (
- GlobalRouterLSA::LSA_SPF_CANDIDATE);
+ if (SPFNexthopCalculation (v, w, l, distance))
+ {
+ w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
//
// Push this new vertex onto the priority queue (ordered by distance from the
// root node).
//
- candidate.Push (w);
- NS_DEBUG ("SPFNext: Pushing " <<
- w->GetVertexId () << ", parent vertexId: " <<
- v->GetVertexId ());
- }
- }
- } else if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_CANDIDATE)
- {
+ candidate.Push (w);
+ NS_DEBUG ("SPFNext: Pushing " <<
+ w->GetVertexId () << ", parent vertexId: " <<
+ v->GetVertexId ());
+ }
+ }
+ else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
+ {
//
// We have already considered the link represented by <w>. What wse have to
// do now is to decide if this new router represents a route with a shorter
@@ -564,23 +630,23 @@
//
// So, locate the vertex in the candidate queue and take a look at the
// distance.
- w = candidate.Find (w_lsa->GetLinkStateId ());
- if (w->GetDistanceFromRoot () < distance)
- {
+ w = candidate.Find (w_lsa->GetLinkStateId ());
+ if (w->GetDistanceFromRoot () < distance)
+ {
//
// This is not a shorter path, so don't do anything.
//
- continue;
- }
- else if (w->GetDistanceFromRoot () == distance)
- {
+ continue;
+ }
+ else if (w->GetDistanceFromRoot () == distance)
+ {
//
// This path is one with an equal cost. Do nothing for now -- we're not doing
// equal-cost multipath cases yet.
//
- }
- else
- {
+ }
+ else
+ {
//
// this path represents a new, lower-cost path to <w> (the vertex we found in
// the current link record of the link state advertisement of the current root
@@ -589,27 +655,26 @@
// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
// it will call spf_add_parents, which will flush the old parents
//
- if (SPFNexthopCalculation (v, w, l, distance))
- {
+ if (SPFNexthopCalculation (v, w, l, distance))
+ {
//
// If we've changed the cost to get to the vertex represented by <w>, we
// must reorder the priority queue keyed to that cost.
//
- candidate.Reorder ();
- }
- }
- } // point-to-point
- } // for loop
- }
- }
+ candidate.Reorder ();
+ }
+ } // new lower cost path found
+ } // end W is already on the candidate list
+ } // end loop over the links in V's LSA
}
//
// This method is derived from quagga ospf_next_hop_calculation() 16.1.1.
//
-// Calculate the next hop IP address and the outgoing interface required to
-// get packets from the root through <v> (parent) to vertex <w> (destination),
-// over a given distance.
+// Calculate nexthop from root through V (parent) to vertex W (destination)
+// with given distance from root->W.
+//
+// As appropriate, set w's parent, distance, and nexthop information
//
// For now, this is greatly simplified from the quagga code
//
@@ -617,10 +682,19 @@
GlobalRouteManagerImpl::SPFNexthopCalculation (
SPFVertex* v,
SPFVertex* w,
- GlobalRouterLinkRecord* l,
+ GlobalRoutingLinkRecord* l,
uint32_t distance)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()");
+
+// If w is a NetworkVertex, l should be null
+/*
+ if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
+ {
+ NS_ASSERT_MSG(0, "Error: SPFNexthopCalculation parameter problem");
+ }
+*/
+
//
// The vertex m_spfroot is a distinguished vertex representing the node at
// the root of the calculations. That is, it is the node for which we are
@@ -669,7 +743,8 @@
// return the link record describing the link from <w> to <v>. Think of it as
// SPFGetLink.
//
- GlobalRouterLinkRecord *linkRemote = 0;
+ NS_ASSERT(l);
+ GlobalRoutingLinkRecord *linkRemote = 0;
linkRemote = SPFGetNextLink (w, v, linkRemote);
//
// At this point, <l> is the Global Router Link Record describing the point-
@@ -695,6 +770,56 @@
v->GetVertexId () << " to " << w->GetVertexId () <<
" goes through next hop " << w->GetNextHop () <<
" via outgoing interface " << w->GetOutgoingInterfaceId ());
+ } // end W is a router vertes
+ else
+ {
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
+// W is a directly connected network; no next hop is required
+ GlobalRoutingLSA* w_lsa = w->GetLSA ();
+ NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
+// Find outgoing interface ID for this network
+ w->SetOutgoingInterfaceId (
+ FindOutgoingInterfaceId (w_lsa->GetLinkStateId (),
+ w_lsa->GetNetworkLSANetworkMask () ));
+ w->SetDistanceFromRoot (distance);
+ w->SetParent (v);
+ NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
+ v->GetVertexId () << " to network " << w->GetVertexId () <<
+ " via outgoing interface " << w->GetOutgoingInterfaceId ());
+ return 1;
+ }
+ } // end v is the root
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+// See if any of v's parents are the root
+ if (v->GetParent () == m_spfroot)
+ {
+// 16.1.1 para 5. ...the parent vertex is a network that
+// directly connects the calculating router to the destination
+// router. The list of next hops is then determined by
+// examining the destination's router-LSA...
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
+ GlobalRoutingLinkRecord *linkRemote = 0;
+ while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
+ {
+/* ...For each link in the router-LSA that points back to the
+ * parent network, the link's Link Data field provides the IP
+ * address of a next hop router. The outgoing interface to
+ * use can then be derived from the next hop IP address (or
+ * it can be inherited from the parent network).
+ */
+ w->SetNextHop(linkRemote->GetLinkData ());
+ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
+ NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
+ v->GetVertexId () << " to " << w->GetVertexId () <<
+ " goes through next hop " << w->GetNextHop () <<
+ " via outgoing interface " << w->GetOutgoingInterfaceId ());
+ }
+ }
+ else
+ {
+ w->SetNextHop (v->GetNextHop ());
+ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
}
}
else
@@ -739,16 +864,17 @@
// BUGBUG FIXME: This seems to be a bug. Shouldn't this function look for
// any link records after pre_link and not just after the first?
//
- GlobalRouterLinkRecord*
+ GlobalRoutingLinkRecord*
GlobalRouteManagerImpl::SPFGetNextLink (
SPFVertex* v,
SPFVertex* w,
- GlobalRouterLinkRecord* prev_link)
+ GlobalRoutingLinkRecord* prev_link)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()");
bool skip = true;
- GlobalRouterLinkRecord* l;
+ bool found_prev_link = false;
+ GlobalRoutingLinkRecord* l;
//
// If prev_link is 0, we are really looking for the first link, not the next
// link.
@@ -756,6 +882,7 @@
if (prev_link == 0)
{
skip = false;
+ found_prev_link = true;
}
//
// Iterate through the Global Router Link Records advertised by the vertex
@@ -765,10 +892,6 @@
for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
{
l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
- {
- continue;
- }
//
// The link ID of a link record representing a point-to-point link is set to
// the router ID of the neighboring router -- the router to which the link
@@ -777,8 +900,16 @@
// We're just checking to see if the link <l> is actually the link from <v> to
// <w>.
//
- if (l->GetLinkId () == w->GetVertexId ()) {
- NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
+ if (l->GetLinkId () == w->GetVertexId ())
+ {
+ if (!found_prev_link)
+ {
+ NS_DEBUG ("SPFGetNextLink: Skipping links before prev_link found");
+ found_prev_link = true;
+ continue;
+ }
+
+ NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
l->GetLinkId () << " linkData = " << l->GetLinkData ());
//
// If skip is false, don't (not too surprisingly) skip the link found -- it's
@@ -849,7 +980,7 @@
//
m_spfroot= v;
v->SetDistanceFromRoot (0);
- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
for (;;)
{
@@ -894,7 +1025,7 @@
// Update the status field of the vertex to indicate that it is in the SPF
// tree.
//
- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
//
// The current vertex has a parent pointer. By calling this rather oddly
// named method (blame quagga) we add the current vertex to the list of
@@ -932,7 +1063,18 @@
// through its point-to-point links, adding a *host* route to the local IP
// address (at the <v> side) for each of those links.
//
- SPFIntraAddRouter (v);
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ SPFIntraAddRouter (v);
+ }
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ SPFIntraAddTransit (v);
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "illegal SPFVertex type");
+ }
//
// RFC2328 16.1. (5).
//
@@ -1026,6 +1168,80 @@
}
//
+// XXX This should probably be a method on Ipv4
+//
+// Return the interface index corresponding to a given IP address
+//
+ uint32_t
+GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
+{
+//
+// We have an IP address <a> and a vertex ID of the root of the SPF tree.
+// The question is what interface index does this address correspond to.
+// The answer is a little complicated since we have to find a pointer to
+// the node corresponding to the vertex ID, find the Ipv4 interface on that
+// node in order to iterate the interfaces and find the one corresponding to
+// the address in question.
+//
+ 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.
+//
+ std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
+ for (; i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+
+ Ptr<GlobalRouter> rtr =
+ node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+//
+// If the node doesn't have a GlobalRouter interface it can't be the one
+// we're interested in.
+//
+ if (rtr == 0)
+ {
+ continue;
+ }
+
+ 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->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+ "QI 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.
+//
+ for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
+ {
+ if (ipv4->GetAddress (i).CombineMask(amask) ==
+ a.CombineMask(amask) )
+ {
+ NS_DEBUG (
+ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+ "Interface match for " << a);
+ return i;
+ }
+ }
+ }
+ }
+//
+// Couldn't find it.
+//
+ return 0;
+}
+
+//
// This method is derived from quagga ospf_intra_add_router ()
//
// This is where we are actually going to add the host routes to the routing
@@ -1109,7 +1325,7 @@
// 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.
//
- GlobalRouterLSA *lsa = v->GetLSA ();
+ GlobalRoutingLSA *lsa = v->GetLSA ();
NS_ASSERT_MSG (lsa,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
@@ -1128,8 +1344,8 @@
//
// We are only concerned about point-to-point links
//
- GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j);
- if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
+ GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
+ if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
{
continue;
}
@@ -1162,6 +1378,91 @@
}
}
}
+ void
+GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
+{
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit ()");
+
+ NS_ASSERT_MSG (m_spfroot,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
+//
+// 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_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "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.
+//
+ std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
+ for (; i != NodeList::End (); i++)
+ {
+ 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->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+
+ if (rtr == 0)
+ {
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "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_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "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->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "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.
+//
+ GlobalRoutingLSA *lsa = v->GetLSA ();
+ NS_ASSERT_MSG (lsa,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask = v->GetLSA ()->GetNetworkLSANetworkMask ();
+ Ipv4Address tempip = v->GetLSA ()->GetLinkStateId ();
+ tempip = tempip.CombineMask (tempmask);
+ ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
+ v->GetOutgoingInterfaceId ());
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddNetwork (): "
+ " Node " << node->GetId () <<
+ " add network route to " << tempip <<
+ " using next hop " << v->GetNextHop () <<
+ " via interface " << v->GetOutgoingInterfaceId ());
+ }
+ }
+}
// Derived from quagga ospf_vertex_add_parents ()
//
@@ -1275,81 +1576,81 @@
// link2: 10.1.3.1/30, 10.1.3.2/30
//
// Router 0
- GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2", // router ID 0.0.0.2
"10.1.1.1", // local ID
1); // metric
- GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa0 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
lsa0->SetLinkStateId ("0.0.0.0");
lsa0->SetAdvertisingRouter ("0.0.0.0");
lsa0->AddLinkRecord (lr0);
lsa0->AddLinkRecord (lr1);
// Router 1
- GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
- GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa1 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
lsa1->SetLinkStateId ("0.0.0.1");
lsa1->SetAdvertisingRouter ("0.0.0.1");
lsa1->AddLinkRecord (lr2);
lsa1->AddLinkRecord (lr3);
// Router 2
- GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.0",
"10.1.1.2",
1);
- GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.2",
"255.255.255.252",
1);
- GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.1",
"10.1.2.2",
1);
- GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.2",
"255.255.255.252",
1);
- GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.3",
"10.1.3.2",
1);
- GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.3.2",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa2 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
lsa2->SetLinkStateId ("0.0.0.2");
lsa2->SetAdvertisingRouter ("0.0.0.2");
lsa2->AddLinkRecord (lr4);
@@ -1360,19 +1661,19 @@
lsa2->AddLinkRecord (lr9);
// Router 3
- GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
- GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa3 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
lsa3->SetLinkStateId ("0.0.0.3");
lsa3->SetAdvertisingRouter ("0.0.0.3");
lsa3->AddLinkRecord (lr10);