|
Lines 1058-1063
GlobalRouteManagerImpl::DebugSPFCalculat
|
Link Here
|
|---|
|
| 1058 |
SPFCalculate (root); |
1058 |
SPFCalculate (root); |
| 1059 |
} |
1059 |
} |
| 1060 |
|
1060 |
|
|
|
1061 |
// |
| 1062 |
// Used to test if a node is a stub, from an OSPF sense. |
| 1063 |
// If there is only one link of type 1 or 2, then a default route |
| 1064 |
// can safely be added to the next-hop router and SPF does not need |
| 1065 |
// to be run |
| 1066 |
// |
| 1067 |
bool |
| 1068 |
GlobalRouteManagerImpl::CheckForStubNode (Ipv4Address root) |
| 1069 |
{ |
| 1070 |
NS_LOG_FUNCTION (root); |
| 1071 |
GlobalRoutingLSA *rlsa = m_lsdb->GetLSA (root); |
| 1072 |
Ipv4Address myRouterId = rlsa->GetLinkStateId (); |
| 1073 |
int transits = 0; |
| 1074 |
GlobalRoutingLinkRecord *transitLink; |
| 1075 |
for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++) |
| 1076 |
{ |
| 1077 |
GlobalRoutingLinkRecord *l = rlsa->GetLinkRecord (i); |
| 1078 |
if (l->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork) |
| 1079 |
{ |
| 1080 |
transits++; |
| 1081 |
transitLink = l; |
| 1082 |
} |
| 1083 |
else if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint) |
| 1084 |
{ |
| 1085 |
transits++; |
| 1086 |
transitLink = l; |
| 1087 |
} |
| 1088 |
} |
| 1089 |
if (transits == 0) |
| 1090 |
{ |
| 1091 |
// This router is not connected to any router. Probably, global |
| 1092 |
// routing should not be called for this node, but we can just raise |
| 1093 |
// a warning here and return true. |
| 1094 |
NS_LOG_WARN ("all nodes should have at least one transit link:" << root ); |
| 1095 |
return true; |
| 1096 |
} |
| 1097 |
if (transits == 1) |
| 1098 |
{ |
| 1099 |
if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork) |
| 1100 |
{ |
| 1101 |
// Install default route to next hop router |
| 1102 |
// What is the next hop? We need to check all neighbors on the link. |
| 1103 |
// If there is a single router that has two transit links, then |
| 1104 |
// that is the default next hop. If there are more than one |
| 1105 |
// routers on link with multiple transit links, return false. |
| 1106 |
// Not yet implemented, so simply return false |
| 1107 |
NS_LOG_LOGIC ("TBD: Would have inserted default for transit"); |
| 1108 |
return false; |
| 1109 |
} |
| 1110 |
else if (transitLink->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint) |
| 1111 |
{ |
| 1112 |
// Install default route to next hop |
| 1113 |
// The link record LinkID is the router ID of the peer. |
| 1114 |
// The Link Data is the local IP interface address |
| 1115 |
GlobalRoutingLSA *w_lsa = m_lsdb->GetLSA (transitLink->GetLinkId ()); |
| 1116 |
uint32_t nLinkRecords = w_lsa->GetNLinkRecords (); |
| 1117 |
for (uint32_t j = 0; j < nLinkRecords; ++j) |
| 1118 |
{ |
| 1119 |
// |
| 1120 |
// We are only concerned about point-to-point links |
| 1121 |
// |
| 1122 |
GlobalRoutingLinkRecord *lr = w_lsa->GetLinkRecord (j); |
| 1123 |
if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint) |
| 1124 |
{ |
| 1125 |
continue; |
| 1126 |
} |
| 1127 |
// Find the link record that corresponds to our routerId |
| 1128 |
if (lr->GetLinkId () == myRouterId) |
| 1129 |
{ |
| 1130 |
// Next hop is stored in the LinkID field of lr |
| 1131 |
Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (rlsa->GetNode ()->GetId ()); |
| 1132 |
NS_ASSERT (gr); |
| 1133 |
gr->AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask ("0.0.0.0"), lr->GetLinkData (), FindOutgoingInterfaceId (transitLink->GetLinkData ())); |
| 1134 |
NS_LOG_LOGIC ("Inserting default route for node " << myRouterId << " to next hop " << lr->GetLinkData () << " via interface " << FindOutgoingInterfaceId(transitLink->GetLinkData())); |
| 1135 |
return true; |
| 1136 |
} |
| 1137 |
} |
| 1138 |
} |
| 1139 |
} |
| 1140 |
return false; |
| 1141 |
} |
| 1142 |
|
| 1061 |
// quagga ospf_spf_calculate |
1143 |
// quagga ospf_spf_calculate |
| 1062 |
void |
1144 |
void |
| 1063 |
GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) |
1145 |
GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root) |
|
Lines 1090-1095
GlobalRouteManagerImpl::SPFCalculate (Ip
|
Link Here
|
|---|
|
| 1090 |
v->SetDistanceFromRoot (0); |
1172 |
v->SetDistanceFromRoot (0); |
| 1091 |
v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE); |
1173 |
v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE); |
| 1092 |
NS_LOG_LOGIC ("Starting SPFCalculate for node " << root); |
1174 |
NS_LOG_LOGIC ("Starting SPFCalculate for node " << root); |
|
|
1175 |
|
| 1176 |
// |
| 1177 |
// Optimize SPF calculation, for ns-3. |
| 1178 |
// We do not need to calculate SPF for every node in the network if this |
| 1179 |
// node has only one interface through which another router can be |
| 1180 |
// reached. Instead, short-circuit this computation and just install |
| 1181 |
// a default route in the CheckForStubNode() method. |
| 1182 |
// |
| 1183 |
if (NodeList::GetNNodes () > 0 && CheckForStubNode (root)) |
| 1184 |
{ |
| 1185 |
NS_LOG_LOGIC ("SPFCalculate truncated for stub node " << root); |
| 1186 |
delete m_spfroot; |
| 1187 |
return; |
| 1188 |
} |
| 1093 |
|
1189 |
|
| 1094 |
for (;;) |
1190 |
for (;;) |
| 1095 |
{ |
1191 |
{ |