#include <OSPFRouting.h>
Public Member Functions | |
OSPFRouting () | |
virtual | ~OSPFRouting (void) |
Protected Member Functions | |
virtual int | numInitStages () const |
virtual void | initialize (int stage) |
virtual void | handleMessage (cMessage *msg) |
Private Member Functions | |
int | ResolveInterfaceName (const std::string &name) const |
void | GetAreaListFromXML (const cXMLElement &routerNode, std::map< std::string, int > &areaList) const |
void | LoadAreaFromXML (const cXMLElement &asConfig, const std::string &areaID) |
void | LoadInterfaceParameters (const cXMLElement &ifConfig) |
void | LoadExternalRoute (const cXMLElement &externalRouteConfig) |
void | LoadHostRoute (const cXMLElement &hostRouteConfig) |
void | LoadVirtualLink (const cXMLElement &virtualLinkConfig) |
bool | LoadConfigFromXML (const char *filename) |
Private Attributes | |
InterfaceTable * | ift |
Provides access to the interface table. | |
RoutingTable * | rt |
Provides access to the IP routing table. | |
OSPF::Router * | ospfRouter |
Root object of the OSPF datastructure. |
|
00041 { 00042 ospfRouter = NULL; 00043 }
|
|
Destructor. Deletes the whole OSPF datastructure. 00050 { 00051 delete ospfRouter; 00052 }
|
|
Loads a list of OSPF Areas connected to this router from the config XML.
00113 { 00114 cXMLElementList routerConfig = routerNode.getChildren (); 00115 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin (); routerConfigIt != routerConfig.end (); routerConfigIt++) { 00116 std::string nodeName = (*routerConfigIt)->getTagName (); 00117 if ((nodeName == "PointToPointInterface") || 00118 (nodeName == "BroadcastInterface") || 00119 (nodeName == "NBMAInterface") || 00120 (nodeName == "PointToMultiPointInterface")) 00121 { 00122 std::string areaId = (*routerConfigIt)->getChildrenByTagName ("AreaID")[0]->getNodeValue (); 00123 if (areaList.find (areaId) == areaList.end ()) { 00124 areaList[areaId] = 1; 00125 } 00126 } 00127 } 00128 }
|
|
Forwards OSPF messages to the message handler object of the OSPF datastructure.
00089 { 00090 // if (simulation.eventNumber () == 90591) { 00091 // __asm int 3; 00092 // } 00093 ospfRouter->GetMessageHandler ()->MessageReceived (msg); 00094 }
|
|
OMNeT++ init method. Runs at stage 2 after interfaces are registered (stage 0) and the routing table is initialized (stage 1). Loads OSPF configuration information from the config XML.
00063 { 00064 // we have to wait for stage 2 until interfaces get registered (stage 0) 00065 // and routerId gets assigned (stage 3) 00066 if (stage == 4) 00067 { 00068 rt = RoutingTableAccess ().get (); 00069 ift = InterfaceTableAccess ().get (); 00070 00071 // Get routerId 00072 ospfRouter = new OSPF::Router (rt->routerId ().getInt (), this); 00073 00074 // read the OSPF AS configuration 00075 const char *fileName = par ("ospfConfigFile"); 00076 if (fileName == NULL || (!strcmp(fileName, "")) || !LoadConfigFromXML (fileName)) 00077 error ("Error reading AS configuration from file %s", fileName); 00078 00079 ospfRouter->AddWatches (); 00080 } 00081 }
|
|
Loads basic configuration information for a given area from the config XML. Reads the configured address ranges, and whether this Area should be handled as a stub Area.
00138 { 00139 std::string areaXPath ("Area[@id='"); 00140 areaXPath += areaID; 00141 areaXPath += "']"; 00142 00143 cXMLElement* areaConfig = asConfig.getElementByPath (areaXPath.c_str ()); 00144 if (areaConfig == NULL) { 00145 error ("No configuration for Area ID: %s", areaID.c_str ()); 00146 } 00147 else { 00148 EV << " loading info for Area id = " << areaID << "\n"; 00149 } 00150 00151 OSPF::Area* area = new OSPF::Area (ULongFromAddressString (areaID.c_str ())); 00152 cXMLElementList areaDetails = areaConfig->getChildren (); 00153 for (cXMLElementList::iterator arIt = areaDetails.begin (); arIt != areaDetails.end (); arIt++) { 00154 std::string nodeName = (*arIt)->getTagName (); 00155 if (nodeName == "AddressRange") { 00156 OSPF::IPv4AddressRange addressRange; 00157 addressRange.address = IPv4AddressFromAddressString ((*arIt)->getChildrenByTagName ("Address")[0]->getNodeValue ()); 00158 addressRange.mask = IPv4AddressFromAddressString ((*arIt)->getChildrenByTagName ("Mask")[0]->getNodeValue ()); 00159 std::string status = (*arIt)->getChildrenByTagName ("Status")[0]->getNodeValue (); 00160 if (status == "Advertise") { 00161 area->AddAddressRange (addressRange, true); 00162 } else { 00163 area->AddAddressRange (addressRange, false); 00164 } 00165 } 00166 if ((nodeName == "Stub") && (areaID != "0.0.0.0")) { // the backbone cannot be configured as a stub 00167 area->SetExternalRoutingCapability (false); 00168 area->SetStubDefaultCost (atoi ((*arIt)->getChildrenByTagName ("DefaultCost")[0]->getNodeValue ())); 00169 } 00170 } 00171 // Add the Area to the router 00172 ospfRouter->AddArea (area); 00173 }
|
|
Loads the configuration of the OSPF datastructure from the config XML.
00468 { 00469 cXMLElement* asConfig = ev.getXMLDocument (filename); 00470 if (asConfig == NULL) { 00471 error ("Cannot read AS configuration from file: %s", filename); 00472 } 00473 00474 // load information on this router 00475 std::string routerXPath ("Router[@id='"); 00476 IPAddress routerId (ospfRouter->GetRouterID ()); 00477 routerXPath += routerId.str (); 00478 routerXPath += "']"; 00479 00480 cXMLElement* routerNode = asConfig->getElementByPath (routerXPath.c_str ()); 00481 if (routerNode == NULL) { 00482 error ("No configuration for Router ID: %s", routerId.str ().c_str ()); 00483 } 00484 else { 00485 EV << "OSPFRouting: Loading info for Router id = " << routerId.str () << "\n"; 00486 } 00487 00488 if (routerNode->getChildrenByTagName ("RFC1583Compatible").size () > 0) { 00489 ospfRouter->SetRFC1583Compatibility (true); 00490 } 00491 00492 std::map<std::string, int> areaList; 00493 GetAreaListFromXML (*routerNode, areaList); 00494 00495 // load area information 00496 for (std::map<std::string, int>::iterator areaIt = areaList.begin (); areaIt != areaList.end (); areaIt++) { 00497 LoadAreaFromXML (*asConfig, areaIt->first); 00498 } 00499 // if the router is an area border router then it MUST be part of the backbone (area 0) 00500 if ((areaList.size () > 1) && (areaList.find ("0.0.0.0") == areaList.end ())) { 00501 LoadAreaFromXML (*asConfig, "0.0.0.0"); 00502 } 00503 00504 // load interface information 00505 cXMLElementList routerConfig = routerNode->getChildren (); 00506 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin (); routerConfigIt != routerConfig.end (); routerConfigIt++) { 00507 std::string nodeName = (*routerConfigIt)->getTagName (); 00508 if ((nodeName == "PointToPointInterface") || 00509 (nodeName == "BroadcastInterface") || 00510 (nodeName == "NBMAInterface") || 00511 (nodeName == "PointToMultiPointInterface")) 00512 { 00513 LoadInterfaceParameters (*(*routerConfigIt)); 00514 } 00515 if (nodeName == "ExternalInterface") { 00516 LoadExternalRoute (*(*routerConfigIt)); 00517 } 00518 if (nodeName == "HostInterface") { 00519 LoadHostRoute (*(*routerConfigIt)); 00520 } 00521 if (nodeName == "VirtualLink") { 00522 LoadVirtualLink (*(*routerConfigIt)); 00523 } 00524 } 00525 return true; 00526 }
|
|
Loads the configuration information of a route outside of the Autonomous System (external route).
00298 { 00299 std::string ifName = externalRouteConfig.getAttribute ("ifName"); 00300 int ifIndex = ResolveInterfaceName (ifName); 00301 OSPFASExternalLSAContents asExternalRoute; 00302 OSPF::RoutingTableEntry externalRoutingEntry; // only used here to keep the path cost calculation in one place 00303 OSPF::IPv4AddressRange networkAddress; 00304 00305 EV << " loading ExternalInterface " << ifName << " ifIndex[" << ifIndex << "]\n"; 00306 00307 cXMLElementList ifDetails = externalRouteConfig.getChildren (); 00308 for (cXMLElementList::iterator exElemIt = ifDetails.begin (); exElemIt != ifDetails.end (); exElemIt++) { 00309 std::string nodeName = (*exElemIt)->getTagName (); 00310 if (nodeName == "AdvertisedExternalNetwork") { 00311 networkAddress.address = IPv4AddressFromAddressString ((*exElemIt)->getChildrenByTagName ("Address")[0]->getNodeValue ()); 00312 networkAddress.mask = IPv4AddressFromAddressString ((*exElemIt)->getChildrenByTagName ("Mask")[0]->getNodeValue ()); 00313 asExternalRoute.setNetworkMask (ULongFromIPv4Address (networkAddress.mask)); 00314 } 00315 if (nodeName == "ExternalInterfaceOutputParameters") { 00316 std::string metricType = (*exElemIt)->getChildrenByTagName ("ExternalInterfaceOutputType")[0]->getNodeValue (); 00317 int routeCost = atoi ((*exElemIt)->getChildrenByTagName ("ExternalInterfaceOutputCost")[0]->getNodeValue ()); 00318 00319 asExternalRoute.setRouteCost (routeCost); 00320 if (metricType == "Type2") { 00321 asExternalRoute.setE_ExternalMetricType (true); 00322 externalRoutingEntry.SetType2Cost (routeCost); 00323 externalRoutingEntry.SetPathType (OSPF::RoutingTableEntry::Type2External); 00324 } else { 00325 asExternalRoute.setE_ExternalMetricType (false); 00326 externalRoutingEntry.SetCost (routeCost); 00327 externalRoutingEntry.SetPathType (OSPF::RoutingTableEntry::Type1External); 00328 } 00329 } 00330 if (nodeName == "ForwardingAddress") { 00331 asExternalRoute.setForwardingAddress (ULongFromAddressString ((*exElemIt)->getNodeValue ())); 00332 } 00333 if (nodeName == "ExternalRouteTag") { 00334 std::string externalRouteTag = (*exElemIt)->getNodeValue (); 00335 char externalRouteTagValue[4]; 00336 00337 memset (externalRouteTagValue, 0, 4 * sizeof (char)); 00338 int externalRouteTagLength = externalRouteTag.length (); 00339 if ((externalRouteTagLength > 4) && (externalRouteTagLength <= 10) && (externalRouteTagLength % 2 == 0) && (externalRouteTag[0] == '0') && (externalRouteTag[1] == 'x')) { 00340 for (int i = externalRouteTagLength; (i > 2); i -= 2) { 00341 externalRouteTagValue[(i - 2) / 2] = HexPairToByte (externalRouteTag[i - 1], externalRouteTag[i]); 00342 } 00343 } 00344 asExternalRoute.setExternalRouteTag ((externalRouteTagValue[0] << 24) + (externalRouteTagValue[1] << 16) + (externalRouteTagValue[2] << 8) + externalRouteTagValue[3]); 00345 } 00346 } 00347 // add the external route to the OSPF datastructure 00348 ospfRouter->UpdateExternalRoute (networkAddress.address, asExternalRoute, ifIndex); 00349 }
|
|
Loads the configuration of a host route (a host directly connected to the router).
00357 { 00358 OSPF::HostRouteParameters hostParameters; 00359 OSPF::AreaID hostArea; 00360 00361 std::string ifName = hostRouteConfig.getAttribute ("ifName"); 00362 hostParameters.ifIndex = ResolveInterfaceName (ifName); 00363 00364 EV << " loading HostInterface " << ifName << " ifIndex[" << static_cast<short> (hostParameters.ifIndex) << "]\n"; 00365 00366 cXMLElementList ifDetails = hostRouteConfig.getChildren (); 00367 for (cXMLElementList::iterator hostElemIt = ifDetails.begin (); hostElemIt != ifDetails.end (); hostElemIt++) { 00368 std::string nodeName = (*hostElemIt)->getTagName (); 00369 if (nodeName == "AreaID") { 00370 hostArea = ULongFromAddressString ((*hostElemIt)->getNodeValue ()); 00371 } 00372 if (nodeName == "AttachedHost") { 00373 hostParameters.address = IPv4AddressFromAddressString ((*hostElemIt)->getNodeValue ()); 00374 } 00375 if (nodeName == "LinkCost") { 00376 hostParameters.linkCost = atoi ((*hostElemIt)->getNodeValue ()); 00377 } 00378 } 00379 // add the host route to the OSPF datastructure. 00380 OSPF::Area* area = ospfRouter->GetArea (hostArea); 00381 if (area != NULL) { 00382 area->AddHostRoute (hostParameters); 00383 00384 } else { 00385 error ("Loading HostInterface ifIndex[%d] in Area %d aborted", hostParameters.ifIndex, hostArea); 00386 } 00387 }
|
|
Loads OSPF configuration information for a router interface. Handles PointToPoint, Broadcast, NBMA and PointToMultiPoint interfaces.
00182 { 00183 OSPF::Interface* intf = new OSPF::Interface; 00184 std::string ifName = ifConfig.getAttribute ("ifName"); 00185 int ifIndex = ResolveInterfaceName (ifName); 00186 std::string interfaceType = ifConfig.getTagName (); 00187 00188 EV << " loading " << interfaceType << " " << ifName << " ifIndex[" << ifIndex << "]\n"; 00189 00190 intf->SetIfIndex (ifIndex); 00191 if (interfaceType == "PointToPointInterface") { 00192 intf->SetType (OSPF::Interface::PointToPoint); 00193 } else if (interfaceType == "BroadcastInterface") { 00194 intf->SetType (OSPF::Interface::Broadcast); 00195 } else if (interfaceType == "NBMAInterface") { 00196 intf->SetType (OSPF::Interface::NBMA); 00197 } else if (interfaceType == "PointToMultiPointInterface") { 00198 intf->SetType (OSPF::Interface::PointToMultiPoint); 00199 } else { 00200 delete intf; 00201 error ("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex); 00202 } 00203 00204 OSPF::AreaID areaID = 0; 00205 cXMLElementList ifDetails = ifConfig.getChildren (); 00206 00207 for (cXMLElementList::iterator ifElemIt = ifDetails.begin (); ifElemIt != ifDetails.end (); ifElemIt++) { 00208 std::string nodeName = (*ifElemIt)->getTagName (); 00209 if (nodeName == "AreaID") { 00210 areaID = ULongFromAddressString ((*ifElemIt)->getNodeValue ()); 00211 intf->SetAreaID (areaID); 00212 } 00213 if (nodeName == "InterfaceOutputCost") { 00214 intf->SetOutputCost (atoi ((*ifElemIt)->getNodeValue ())); 00215 } 00216 if (nodeName == "RetransmissionInterval") { 00217 intf->SetRetransmissionInterval (atoi ((*ifElemIt)->getNodeValue ())); 00218 } 00219 if (nodeName == "InterfaceTransmissionDelay") { 00220 intf->SetTransmissionDelay (atoi ((*ifElemIt)->getNodeValue ())); 00221 } 00222 if (nodeName == "RouterPriority") { 00223 intf->SetRouterPriority (atoi ((*ifElemIt)->getNodeValue ())); 00224 } 00225 if (nodeName == "HelloInterval") { 00226 intf->SetHelloInterval (atoi ((*ifElemIt)->getNodeValue ())); 00227 } 00228 if (nodeName == "RouterDeadInterval") { 00229 intf->SetRouterDeadInterval (atoi ((*ifElemIt)->getNodeValue ())); 00230 } 00231 if (nodeName == "AuthenticationType") { 00232 std::string authenticationType = (*ifElemIt)->getNodeValue (); 00233 if (authenticationType == "SimplePasswordType") { 00234 intf->SetAuthenticationType (OSPF::SimplePasswordType); 00235 } else if (authenticationType == "CrytographicType") { 00236 intf->SetAuthenticationType (OSPF::CrytographicType); 00237 } else { 00238 intf->SetAuthenticationType (OSPF::NullType); 00239 } 00240 } 00241 if (nodeName == "AuthenticationKey") { 00242 std::string key = (*ifElemIt)->getNodeValue (); 00243 OSPF::AuthenticationKeyType keyValue; 00244 memset (keyValue.bytes, 0, 8 * sizeof (char)); 00245 int keyLength = key.length (); 00246 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) { 00247 for (int i = keyLength; (i > 2); i -= 2) { 00248 keyValue.bytes[(i - 2) / 2] = HexPairToByte (key[i - 1], key[i]); 00249 } 00250 } 00251 intf->SetAuthenticationKey (keyValue); 00252 } 00253 if (nodeName == "PollInterval") { 00254 intf->SetPollInterval (atoi ((*ifElemIt)->getNodeValue ())); 00255 } 00256 if ((interfaceType == "NBMAInterface") && (nodeName == "NBMANeighborList")) { 00257 cXMLElementList neighborList = (*ifElemIt)->getChildren (); 00258 for (cXMLElementList::iterator neighborIt = neighborList.begin (); neighborIt != neighborList.end (); neighborIt++) { 00259 std::string neighborNodeName = (*neighborIt)->getTagName (); 00260 if (neighborNodeName == "NBMANeighbor") { 00261 OSPF::Neighbor* neighbor = new OSPF::Neighbor; 00262 neighbor->SetAddress (IPv4AddressFromAddressString ((*neighborIt)->getChildrenByTagName ("NetworkInterfaceAddress")[0]->getNodeValue ())); 00263 neighbor->SetPriority (atoi ((*neighborIt)->getChildrenByTagName ("NeighborPriority")[0]->getNodeValue ())); 00264 intf->AddNeighbor (neighbor); 00265 } 00266 } 00267 } 00268 if ((interfaceType == "PointToMultiPointInterface") && (nodeName == "PointToMultiPointNeighborList")) { 00269 cXMLElementList neighborList = (*ifElemIt)->getChildren (); 00270 for (cXMLElementList::iterator neighborIt = neighborList.begin (); neighborIt != neighborList.end (); neighborIt++) { 00271 std::string neighborNodeName = (*neighborIt)->getTagName (); 00272 if (neighborNodeName == "PointToMultiPointNeighbor") { 00273 OSPF::Neighbor* neighbor = new OSPF::Neighbor; 00274 neighbor->SetAddress (IPv4AddressFromAddressString ((*neighborIt)->getNodeValue ())); 00275 intf->AddNeighbor (neighbor); 00276 } 00277 } 00278 } 00279 00280 } 00281 // add the interface to it's Area 00282 OSPF::Area* area = ospfRouter->GetArea (areaID); 00283 if (area != NULL) { 00284 area->AddInterface (intf); 00285 intf->ProcessEvent (OSPF::Interface::InterfaceUp); // notification should come from the blackboard... 00286 } else { 00287 delete intf; 00288 error ("Loading %s ifIndex[%d] in Area %d aborted", interfaceType.c_str(), ifIndex, areaID); 00289 } 00290 }
|
|
Loads the configuration of an OSPf virtual link (virtual connection between two backbone routers).
00395 { 00396 OSPF::Interface* intf = new OSPF::Interface; 00397 std::string endPoint = virtualLinkConfig.getAttribute ("endPointRouterID"); 00398 OSPF::Neighbor* neighbor = new OSPF::Neighbor; 00399 00400 EV << " loading VirtualLink to " << endPoint << "\n"; 00401 00402 intf->SetType (OSPF::Interface::Virtual); 00403 neighbor->SetNeighborID (ULongFromAddressString (endPoint.c_str ())); 00404 intf->AddNeighbor (neighbor); 00405 00406 cXMLElementList ifDetails = virtualLinkConfig.getChildren (); 00407 for (cXMLElementList::iterator ifElemIt = ifDetails.begin (); ifElemIt != ifDetails.end (); ifElemIt++) { 00408 std::string nodeName = (*ifElemIt)->getTagName (); 00409 if (nodeName == "TransitAreaID") { 00410 intf->SetTransitAreaID (ULongFromAddressString ((*ifElemIt)->getNodeValue ())); 00411 } 00412 if (nodeName == "RetransmissionInterval") { 00413 intf->SetRetransmissionInterval (atoi ((*ifElemIt)->getNodeValue ())); 00414 } 00415 if (nodeName == "InterfaceTransmissionDelay") { 00416 intf->SetTransmissionDelay (atoi ((*ifElemIt)->getNodeValue ())); 00417 } 00418 if (nodeName == "HelloInterval") { 00419 intf->SetHelloInterval (atoi ((*ifElemIt)->getNodeValue ())); 00420 } 00421 if (nodeName == "RouterDeadInterval") { 00422 intf->SetRouterDeadInterval (atoi ((*ifElemIt)->getNodeValue ())); 00423 } 00424 if (nodeName == "AuthenticationType") { 00425 std::string authenticationType = (*ifElemIt)->getNodeValue (); 00426 if (authenticationType == "SimplePasswordType") { 00427 intf->SetAuthenticationType (OSPF::SimplePasswordType); 00428 } else if (authenticationType == "CrytographicType") { 00429 intf->SetAuthenticationType (OSPF::CrytographicType); 00430 } else { 00431 intf->SetAuthenticationType (OSPF::NullType); 00432 } 00433 } 00434 if (nodeName == "AuthenticationKey") { 00435 std::string key = (*ifElemIt)->getNodeValue (); 00436 OSPF::AuthenticationKeyType keyValue; 00437 memset (keyValue.bytes, 0, 8 * sizeof (char)); 00438 int keyLength = key.length (); 00439 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) { 00440 for (int i = keyLength; (i > 2); i -= 2) { 00441 keyValue.bytes[(i - 2) / 2] = HexPairToByte (key[i - 1], key[i]); 00442 } 00443 } 00444 intf->SetAuthenticationKey (keyValue); 00445 } 00446 } 00447 00448 // add the virtual link to the OSPF datastructure. 00449 OSPF::Area* transitArea = ospfRouter->GetArea (intf->GetAreaID ()); 00450 OSPF::Area* backbone = ospfRouter->GetArea (OSPF::BackboneAreaID); 00451 00452 if ((backbone != NULL) && (transitArea != NULL) && (transitArea->GetExternalRoutingCapability ())) { 00453 backbone->AddInterface (intf); 00454 } else { 00455 delete intf; 00456 error ("Loading VirtualLink to %s through Area %d aborted", endPoint.c_str (), intf->GetAreaID ()); 00457 } 00458 }
|
|
00052 {return 5;}
|
|
Looks up the interface name in InterfaceTable, and returns interfaceId a.k.a ifIndex. 00100 { 00101 InterfaceEntry* ie = ift->interfaceByName (name.c_str()); 00102 if (!ie) 00103 opp_error ("error reading XML config: InterfaceTable contains no interface named '%s'", name.c_str()); 00104 return ie->interfaceId (); 00105 }
|
|
Provides access to the interface table.
|
|
Root object of the OSPF datastructure.
|
|
Provides access to the IP routing table.
|