Internet: GlobalRouting: Unable to compute routes when ECMP to a LAN Network with attached routers
I was working on a sample topology for a test and i came across an additional bug in GlobalRouting related to ECMP, this one makes the program assert and fail.This Bug will occur if you run GlobalRouting on a ECMP Topology and a Lan Network with atleast one router attached to it outside the loop.
Here is an example fileNetworkExitInheritanceissue.cc
I will explain with the topology of the example file
/*
// Creating a Simple topology with 4 nodes and 3 links
//
//
//
// ------n1------
// / \
// / \
// n0 n3----n4----n5
// \ /
// \ /
// ------n2------
//
// Link n0-n1: 10.1.1.1/30,10.1.1.2/30
// Link n0-n2: 10.1.2.1/30,10.1.2.2/30
// Link n1-n3: 10.1.3.1/30,10.1.3.2/30
// Link n2-n3: 10.1.4.1/30,10.1.4.2/30
// Link n3-n4: 10.1.5.1/24,10.1.5.2/24
// Link n4-n5: 10.1.6.1/24,10.1.6.2/24
//
// Note: Link n4-n5 is a LAN LINK
*/
If you run the example file the following assert error will pop up:
NS_ASSERT failed, cond="m_ecmpRootExits.size() <= 1", msg="Assumed there is at most one exit from the root to this vertex", +0.000000000s -1
when doing the route computation for a root node (say root node is 0 in our case)
Each SPF vertex Is Considered and we calculate the exit direction (i.e the next hop and interface index ) from the root node to that vertex and store it in a list m_ecmpRootExits
.
Right now the problem is in SPFNextHopCalculation() method where these exit directions are set.
If we call SPFNextHopCalculation() from a network vertex to a routervertex and if we have multiple root exit directions to the network vertex. All of these root exit directions should be inherited by the attached router right? well the code fails to do that corrently. it assumes that there is only one exit direction and tries to inherit that.
This assumptions leads it to call SPFVertex::GetRootExitDirection()
this method has an assert to prevent people from calling it if we have multiple root exit directions.
Incase of multiple root exit directions the method to be used is w->InheritAllRootExitDirections(v);
and not the GET method. (SEE line 1101 of the global-route-manager-impl.cc
)