|
INET Framework for OMNeT++/OMNEST
|
00001 /******************************************************************* 00002 * 00003 * This library is free software, you can redistribute it 00004 * and/or modify 00005 * it under the terms of the GNU Lesser General Public License 00006 * as published by the Free Software Foundation; 00007 * either version 2 of the License, or any later version. 00008 * The library is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 * See the GNU Lesser General Public License for more details. 00012 * 00013 * 00014 *********************************************************************/ 00015 00016 #include "AnsaOSPFRouting.h" 00017 #include "IPAddress.h" 00018 #include "IPAddressResolver.h" 00019 #include "IPControlInfo.h" 00020 #include "AnsaOSPFcommon.h" 00021 #include "AnsaOSPFArea.h" 00022 #include "AnsaMessageHandler.h" 00023 #include "RoutingTableAccess.h" 00024 #include "InterfaceTableAccess.h" 00025 #include "IPv4InterfaceData.h" 00026 #include <string> 00027 #include <stdlib.h> 00028 #include <memory.h> 00029 //#include <iostream> 00030 00031 00032 Define_Module(AnsaOSPFRouting); 00033 00034 00035 AnsaOSPFRouting::AnsaOSPFRouting() 00036 { 00037 ospfRouter = NULL; 00038 ospfEnabled = false; 00039 } 00040 00045 AnsaOSPFRouting::~AnsaOSPFRouting(void) 00046 { 00047 if(ospfEnabled) 00048 delete ospfRouter; 00049 } 00050 00051 00059 void AnsaOSPFRouting::initialize(int stage) 00060 { if (stage==0) 00061 { 00062 // get a pointer to the NotificationBoard module 00063 nb = NotificationBoardAccess().get(); 00064 00065 // subscribe interface change notifications 00066 nb->subscribe(this, NF_INTERFACE_STATE_CHANGED); 00067 00068 } 00069 else 00070 // we have to wait for stage 2 until interfaces get registered(stage 0) 00071 // and routerId gets assigned(stage 3) 00072 if (stage == 4) 00073 { 00074 rt = RoutingTableAccess().get(); 00075 ift = InterfaceTableAccess().get(); 00076 00077 // Get routerId 00078 ospfRouter = new AnsaOSPF::Router(rt->getRouterId().getInt(), this); 00079 00080 // read the OSPF AS configuration 00081 const char *fileName = par("configFile"); 00082 00083 if(par("AnsaLoadingStyle")) 00084 { 00085 if (fileName == NULL || (!strcmp(fileName, "")) || !AnsaLoadConfigFromXML(fileName)) 00086 error("Error reading AS configuration from file %s", fileName); 00087 } 00088 else 00089 { 00090 if (fileName == NULL || (!strcmp(fileName, "")) || !LoadConfigFromXML(fileName)) 00091 error("Error reading AS configuration from file %s", fileName); 00092 } 00093 if(ospfEnabled) 00094 ospfRouter->AddWatches(); 00095 } 00096 } 00097 00098 00103 void AnsaOSPFRouting::handleMessage(cMessage *msg) 00104 { 00105 // if (simulation.getEventNumber() == 90591) { 00106 // __asm int 3; 00107 // } 00108 00109 if(ospfEnabled) 00110 ospfRouter->GetMessageHandler()->MessageReceived(msg); 00111 else 00112 delete msg; 00113 } 00114 00115 00116 void AnsaOSPFRouting::receiveChangeNotification(int category, const cPolymorphic *details) 00117 { 00118 if (simulation.getContextType()==CTX_INITIALIZE) 00119 return; // ignore notifications during initialize 00120 00121 Enter_Method_Silent(); 00122 printNotificationBanner(category, details); 00123 00124 if (category==NF_INTERFACE_STATE_CHANGED) // change state of notified interface 00125 { 00126 InterfaceEntry *entry = check_and_cast<InterfaceEntry*>(details); 00127 00128 AnsaOSPF::Interface* intf = ospfRouter->GetNonVirtualInterface(entry->getInterfaceId()); 00129 00130 if(intf != NULL) 00131 { 00132 EV << "Changing state of interface in OSPF\n"; 00133 if (entry->isDown()) 00134 { 00135 intf->ProcessEvent(AnsaOSPF::Interface::InterfaceDown); 00136 } 00137 else 00138 { 00139 intf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp); 00140 } 00141 } 00142 } 00143 00144 } 00145 00146 void AnsaOSPFRouting::finish() 00147 { 00148 recordScalar("helloPacketSend", ospfRouter->stat.GetHelloPacketSend()); 00149 recordScalar("ospfPacketSend", ospfRouter->stat.GetOspfPacketSend()); 00150 recordScalar("helloPacketReceived", ospfRouter->stat.GetHelloPacketReceived()); 00151 recordScalar("ospfPacketReceived", ospfRouter->stat.GetOspfPacketReceived()); 00152 } 00153 00157 int AnsaOSPFRouting::ResolveInterfaceName(const std::string& name) const 00158 { 00159 InterfaceEntry* ie = ift->getInterfaceByName(name.c_str()); 00160 if (!ie) 00161 opp_error("error reading XML config: IInterfaceTable contains no interface named '%s'", name.c_str()); 00162 return ie->getInterfaceId(); 00163 } 00164 00170 void AnsaOSPFRouting::GetAreaListFromXML(const cXMLElement& routerNode, std::map<std::string, int>& areaList) const 00171 { 00172 cXMLElementList routerConfig = routerNode.getChildren(); 00173 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) { 00174 std::string nodeName = (*routerConfigIt)->getTagName(); 00175 if ((nodeName == "PointToPointInterface") || 00176 (nodeName == "BroadcastInterface") || 00177 (nodeName == "NBMAInterface") || 00178 (nodeName == "PointToMultiPointInterface")) 00179 { 00180 std::string areaId = (*routerConfigIt)->getChildrenByTagName("AreaID")[0]->getNodeValue(); 00181 if (areaList.find(areaId) == areaList.end()) { 00182 areaList[areaId] = 1; 00183 } 00184 } 00185 } 00186 } 00187 00188 00195 void AnsaOSPFRouting::LoadAreaFromXML(const cXMLElement& asConfig, const std::string& areaID) 00196 { 00197 std::string areaXPath("Area[@id='"); 00198 areaXPath += areaID; 00199 areaXPath += "']"; 00200 00201 cXMLElement* areaConfig = asConfig.getElementByPath(areaXPath.c_str()); 00202 if (areaConfig == NULL) { 00203 error("No configuration for Area ID: %s", areaID.c_str()); 00204 } 00205 else { 00206 EV << " loading info for Area id = " << areaID << "\n"; 00207 } 00208 00209 AnsaOSPF::Area* area = new AnsaOSPF::Area(ULongFromAddressString(areaID.c_str())); 00210 00211 cXMLElementList areaDetails = areaConfig->getChildren(); 00212 for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) { 00213 std::string nodeName = (*arIt)->getTagName(); 00214 if (nodeName == "AddressRange") { 00215 AnsaOSPF::IPv4AddressRange addressRange; 00216 addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue()); 00217 addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue()); 00218 std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue(); 00219 if (status == "Advertise") { 00220 area->AddAddressRange(addressRange, true); 00221 } else { 00222 area->AddAddressRange(addressRange, false); 00223 } 00224 } 00225 if ((nodeName == "Stub") && (areaID != "0.0.0.0")) { // the backbone cannot be configured as a stub 00226 area->SetExternalRoutingCapability(false); 00227 area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue())); 00228 } 00229 } 00230 // Add the Area to the router 00231 ospfRouter->AddArea(area); 00232 } 00233 00234 00240 void AnsaOSPFRouting::LoadInterfaceParameters(const cXMLElement& ifConfig) 00241 { 00242 AnsaOSPF::Interface* intf = new AnsaOSPF::Interface; 00243 std::string ifName = ifConfig.getAttribute("ifName"); 00244 int ifIndex = ResolveInterfaceName(ifName); 00245 std::string interfaceType = ifConfig.getTagName(); 00246 00247 EV << " loading " << interfaceType << " " << ifName << " ifIndex[" << ifIndex << "]\n"; 00248 00249 intf->SetIfIndex(ifIndex); 00250 if (interfaceType == "PointToPointInterface") { 00251 intf->SetType(AnsaOSPF::Interface::PointToPoint); 00252 } else if (interfaceType == "BroadcastInterface") { 00253 intf->SetType(AnsaOSPF::Interface::Broadcast); 00254 } else if (interfaceType == "NBMAInterface") { 00255 intf->SetType(AnsaOSPF::Interface::NBMA); 00256 } else if (interfaceType == "PointToMultiPointInterface") { 00257 intf->SetType(AnsaOSPF::Interface::PointToMultiPoint); 00258 } else { 00259 delete intf; 00260 error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex); 00261 } 00262 00263 AnsaOSPF::AreaID areaID = 0; 00264 cXMLElementList ifDetails = ifConfig.getChildren(); 00265 00266 for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) { 00267 std::string nodeName = (*ifElemIt)->getTagName(); 00268 if (nodeName == "AreaID") { 00269 areaID = ULongFromAddressString((*ifElemIt)->getNodeValue()); 00270 intf->SetAreaID(areaID); 00271 } 00272 if (nodeName == "InterfaceOutputCost") { 00273 intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue())); 00274 } 00275 if (nodeName == "RetransmissionInterval") { 00276 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue())); 00277 } 00278 if (nodeName == "InterfaceTransmissionDelay") { 00279 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue())); 00280 } 00281 if (nodeName == "RouterPriority") { 00282 intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue())); 00283 } 00284 if (nodeName == "HelloInterval") { 00285 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue())); 00286 } 00287 if (nodeName == "RouterDeadInterval") { 00288 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue())); 00289 } 00290 if (nodeName == "AuthenticationType") { 00291 std::string authenticationType = (*ifElemIt)->getNodeValue(); 00292 if (authenticationType == "SimplePasswordType") { 00293 intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType); 00294 } else if (authenticationType == "CrytographicType") { 00295 intf->SetAuthenticationType(AnsaOSPF::CrytographicType); 00296 } else { 00297 intf->SetAuthenticationType(AnsaOSPF::NullType); 00298 } 00299 } 00300 if (nodeName == "AuthenticationKey") { 00301 std::string key = (*ifElemIt)->getNodeValue(); 00302 AnsaOSPF::AuthenticationKeyType keyValue; 00303 memset(keyValue.bytes, 0, 8 * sizeof(char)); 00304 int keyLength = key.length(); 00305 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) { 00306 for (int i = keyLength; (i > 2); i -= 2) { 00307 keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]); 00308 } 00309 } 00310 intf->SetAuthenticationKey(keyValue); 00311 } 00312 if (nodeName == "PollInterval") { 00313 intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue())); 00314 } 00315 if ((interfaceType == "NBMAInterface") && (nodeName == "NBMANeighborList")) { 00316 cXMLElementList neighborList = (*ifElemIt)->getChildren(); 00317 for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) { 00318 std::string neighborNodeName = (*neighborIt)->getTagName(); 00319 if (neighborNodeName == "NBMANeighbor") { 00320 AnsaOSPF::Neighbor* neighbor = new AnsaOSPF::Neighbor; 00321 neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getChildrenByTagName("NetworkInterfaceAddress")[0]->getNodeValue())); 00322 neighbor->SetPriority(atoi((*neighborIt)->getChildrenByTagName("NeighborPriority")[0]->getNodeValue())); 00323 intf->AddNeighbor(neighbor); 00324 } 00325 } 00326 } 00327 if ((interfaceType == "PointToMultiPointInterface") && (nodeName == "PointToMultiPointNeighborList")) { 00328 cXMLElementList neighborList = (*ifElemIt)->getChildren(); 00329 for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) { 00330 std::string neighborNodeName = (*neighborIt)->getTagName(); 00331 if (neighborNodeName == "PointToMultiPointNeighbor") { 00332 AnsaOSPF::Neighbor* neighbor = new AnsaOSPF::Neighbor; 00333 neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getNodeValue())); 00334 intf->AddNeighbor(neighbor); 00335 } 00336 } 00337 } 00338 00339 } 00340 // add the interface to it's Area 00341 AnsaOSPF::Area* area = ospfRouter->GetArea(areaID); 00342 if (area != NULL) { 00343 area->AddInterface(intf); 00344 intf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp); // notification should come from the blackboard... 00345 } else { 00346 delete intf; 00347 error("Loading %s ifIndex[%d] in Area %d aborted", interfaceType.c_str(), ifIndex, areaID); 00348 } 00349 } 00350 00351 00356 void AnsaOSPFRouting::LoadExternalRoute(const cXMLElement& externalRouteConfig) 00357 { 00358 std::string ifName = externalRouteConfig.getAttribute("ifName"); 00359 int ifIndex = ResolveInterfaceName(ifName); 00360 OSPFASExternalLSAContents asExternalRoute; 00361 AnsaOSPF::RoutingTableEntry externalRoutingEntry; // only used here to keep the path cost calculation in one place 00362 AnsaOSPF::IPv4AddressRange networkAddress; 00363 00364 EV << " loading ExternalInterface " << ifName << " ifIndex[" << ifIndex << "]\n"; 00365 00366 cXMLElementList ifDetails = externalRouteConfig.getChildren(); 00367 for (cXMLElementList::iterator exElemIt = ifDetails.begin(); exElemIt != ifDetails.end(); exElemIt++) { 00368 std::string nodeName = (*exElemIt)->getTagName(); 00369 if (nodeName == "AdvertisedExternalNetwork") { 00370 networkAddress.address = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Address")[0]->getNodeValue()); 00371 networkAddress.mask = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Mask")[0]->getNodeValue()); 00372 asExternalRoute.setNetworkMask(ULongFromIPv4Address(networkAddress.mask)); 00373 } 00374 if (nodeName == "ExternalInterfaceOutputParameters") { 00375 std::string metricType = (*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputType")[0]->getNodeValue(); 00376 int routeCost = atoi((*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputCost")[0]->getNodeValue()); 00377 00378 asExternalRoute.setRouteCost(routeCost); 00379 if (metricType == "Type2") { 00380 asExternalRoute.setE_ExternalMetricType(true); 00381 externalRoutingEntry.SetType2Cost(routeCost); 00382 externalRoutingEntry.SetPathType(AnsaOSPF::RoutingTableEntry::Type2External); 00383 } else { 00384 asExternalRoute.setE_ExternalMetricType(false); 00385 externalRoutingEntry.SetCost(routeCost); 00386 externalRoutingEntry.SetPathType(AnsaOSPF::RoutingTableEntry::Type1External); 00387 } 00388 } 00389 if (nodeName == "ForwardingAddress") { 00390 asExternalRoute.setForwardingAddress(ULongFromAddressString((*exElemIt)->getNodeValue())); 00391 } 00392 if (nodeName == "ExternalRouteTag") { 00393 std::string externalRouteTag = (*exElemIt)->getNodeValue(); 00394 char externalRouteTagValue[4]; 00395 00396 memset(externalRouteTagValue, 0, 4 * sizeof(char)); 00397 int externalRouteTagLength = externalRouteTag.length(); 00398 if ((externalRouteTagLength > 4) && (externalRouteTagLength <= 10) && (externalRouteTagLength % 2 == 0) && (externalRouteTag[0] == '0') && (externalRouteTag[1] == 'x')) { 00399 for (int i = externalRouteTagLength; (i > 2); i -= 2) { 00400 externalRouteTagValue[(i - 2) / 2] = HexPairToByte(externalRouteTag[i - 1], externalRouteTag[i]); 00401 } 00402 } 00403 asExternalRoute.setExternalRouteTag((externalRouteTagValue[0] << 24) + (externalRouteTagValue[1] << 16) + (externalRouteTagValue[2] << 8) + externalRouteTagValue[3]); 00404 } 00405 } 00406 // add the external route to the OSPF datastructure 00407 ospfRouter->UpdateExternalRoute(networkAddress.address, asExternalRoute, ifIndex); 00408 } 00409 00410 00415 void AnsaOSPFRouting::LoadHostRoute(const cXMLElement& hostRouteConfig) 00416 { 00417 AnsaOSPF::HostRouteParameters hostParameters; 00418 AnsaOSPF::AreaID hostArea; 00419 00420 std::string ifName = hostRouteConfig.getAttribute("ifName"); 00421 hostParameters.ifIndex = ResolveInterfaceName(ifName); 00422 00423 EV << " loading HostInterface " << ifName << " ifIndex[" << static_cast<short> (hostParameters.ifIndex) << "]\n"; 00424 00425 cXMLElementList ifDetails = hostRouteConfig.getChildren(); 00426 for (cXMLElementList::iterator hostElemIt = ifDetails.begin(); hostElemIt != ifDetails.end(); hostElemIt++) { 00427 std::string nodeName = (*hostElemIt)->getTagName(); 00428 if (nodeName == "AreaID") { 00429 hostArea = ULongFromAddressString((*hostElemIt)->getNodeValue()); 00430 } 00431 if (nodeName == "AttachedHost") { 00432 hostParameters.address = IPv4AddressFromAddressString((*hostElemIt)->getNodeValue()); 00433 } 00434 if (nodeName == "LinkCost") { 00435 hostParameters.linkCost = atoi((*hostElemIt)->getNodeValue()); 00436 } 00437 } 00438 // add the host route to the OSPF datastructure. 00439 AnsaOSPF::Area* area = ospfRouter->GetArea(hostArea); 00440 if (area != NULL) { 00441 area->AddHostRoute(hostParameters); 00442 00443 } else { 00444 error("Loading HostInterface ifIndex[%d] in Area %d aborted", hostParameters.ifIndex, hostArea); 00445 } 00446 } 00447 00448 00453 void AnsaOSPFRouting::LoadVirtualLink(const cXMLElement& virtualLinkConfig) 00454 { 00455 AnsaOSPF::Interface* intf = new AnsaOSPF::Interface; 00456 std::string endPoint = virtualLinkConfig.getAttribute("endPointRouterID"); 00457 AnsaOSPF::Neighbor* neighbor = new AnsaOSPF::Neighbor; 00458 00459 EV << " loading VirtualLink to " << endPoint << "\n"; 00460 00461 intf->SetType(AnsaOSPF::Interface::Virtual); 00462 neighbor->SetNeighborID(ULongFromAddressString(endPoint.c_str())); 00463 intf->AddNeighbor(neighbor); 00464 00465 cXMLElementList ifDetails = virtualLinkConfig.getChildren(); 00466 for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) { 00467 std::string nodeName = (*ifElemIt)->getTagName(); 00468 if (nodeName == "TransitAreaID") { 00469 intf->SetTransitAreaID(ULongFromAddressString((*ifElemIt)->getNodeValue())); 00470 } 00471 if (nodeName == "RetransmissionInterval") { 00472 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue())); 00473 } 00474 if (nodeName == "InterfaceTransmissionDelay") { 00475 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue())); 00476 } 00477 if (nodeName == "HelloInterval") { 00478 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue())); 00479 } 00480 if (nodeName == "RouterDeadInterval") { 00481 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue())); 00482 } 00483 if (nodeName == "AuthenticationType") { 00484 std::string authenticationType = (*ifElemIt)->getNodeValue(); 00485 if (authenticationType == "SimplePasswordType") { 00486 intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType); 00487 } else if (authenticationType == "CrytographicType") { 00488 intf->SetAuthenticationType(AnsaOSPF::CrytographicType); 00489 } else { 00490 intf->SetAuthenticationType(AnsaOSPF::NullType); 00491 } 00492 } 00493 if (nodeName == "AuthenticationKey") { 00494 std::string key = (*ifElemIt)->getNodeValue(); 00495 AnsaOSPF::AuthenticationKeyType keyValue; 00496 memset(keyValue.bytes, 0, 8 * sizeof(char)); 00497 int keyLength = key.length(); 00498 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) { 00499 for (int i = keyLength; (i > 2); i -= 2) { 00500 keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]); 00501 } 00502 } 00503 intf->SetAuthenticationKey(keyValue); 00504 } 00505 } 00506 00507 // add the virtual link to the OSPF datastructure. 00508 AnsaOSPF::Area* transitArea = ospfRouter->GetArea(intf->GetAreaID()); 00509 AnsaOSPF::Area* backbone = ospfRouter->GetArea(AnsaOSPF::BackboneAreaID); 00510 00511 if ((backbone != NULL) && (transitArea != NULL) && (transitArea->GetExternalRoutingCapability())) { 00512 backbone->AddInterface(intf); 00513 } else { 00514 delete intf; 00515 error("Loading VirtualLink to %s through Area %d aborted", endPoint.c_str(), intf->GetAreaID()); 00516 } 00517 } 00518 00519 00526 bool AnsaOSPFRouting::LoadConfigFromXML(const char * filename) 00527 { 00528 cXMLElement* asConfig = ev.getXMLDocument(filename); 00529 if (asConfig == NULL) { 00530 error("Cannot read AS configuration from file: %s", filename); 00531 } 00532 00533 // load information on this router 00534 std::string routerXPath("Router[@id='"); 00535 IPAddress routerId(ospfRouter->GetRouterID()); 00536 routerXPath += routerId.str(); 00537 routerXPath += "']"; 00538 00539 cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str()); 00540 if (routerNode == NULL) { 00541 error("No configuration for Router ID: %s", routerId.str().c_str()); 00542 } 00543 else { 00544 EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n"; 00545 } 00546 00547 if (routerNode->getChildrenByTagName("RFC1583Compatible").size() > 0) { 00548 ospfRouter->SetRFC1583Compatibility(true); 00549 } 00550 00551 std::map<std::string, int> areaList; 00552 GetAreaListFromXML(*routerNode, areaList); 00553 00554 // load area information 00555 for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) { 00556 LoadAreaFromXML(*asConfig, areaIt->first); 00557 } 00558 // if the router is an area border router then it MUST be part of the backbone(area 0) 00559 if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) { 00560 LoadAreaFromXML(*asConfig, "0.0.0.0"); 00561 } 00562 00563 // load interface information 00564 cXMLElementList routerConfig = routerNode->getChildren(); 00565 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) { 00566 std::string nodeName = (*routerConfigIt)->getTagName(); 00567 if ((nodeName == "PointToPointInterface") || 00568 (nodeName == "BroadcastInterface") || 00569 (nodeName == "NBMAInterface") || 00570 (nodeName == "PointToMultiPointInterface")) 00571 { 00572 LoadInterfaceParameters(*(*routerConfigIt)); 00573 } 00574 if (nodeName == "ExternalInterface") { 00575 LoadExternalRoute(*(*routerConfigIt)); 00576 } 00577 if (nodeName == "HostInterface") { 00578 LoadHostRoute(*(*routerConfigIt)); 00579 } 00580 if (nodeName == "VirtualLink") { 00581 LoadVirtualLink(*(*routerConfigIt)); 00582 } 00583 } 00584 return true; 00585 } 00586 00592 void AnsaOSPFRouting::AnsaLoadInterface(AnsaOSPF::Area &area, AnsaOSPF::IPv4AddressRange &addressRange) 00593 { 00594 00595 cXMLElementList intConfig = IntNode->getChildren(); 00596 for (cXMLElementList::iterator intConfigIt = intConfig.begin(); intConfigIt != intConfig.end(); intConfigIt++) 00597 { 00598 std::string nodeName = (*intConfigIt)->getTagName(); 00599 if (nodeName == "Interface" && (*intConfigIt)->getAttribute("name")) 00600 { 00601 AnsaOSPF::IPv4Address ifAddress = IPv4AddressFromAddressString((*intConfigIt)->getFirstChildWithTag("IPAddress")->getNodeValue()); 00602 if((ifAddress != AnsaOSPF::NullIPv4Address) && ((ifAddress & addressRange.mask) == (addressRange.address & addressRange.mask))) 00603 { 00604 AnsaOSPF::IPv4AddressRange ifAddressRange; 00605 std::string ifName = (*intConfigIt)->getAttribute("name"); 00606 int ifIndex = ResolveInterfaceName(ifName); 00607 00608 std::map<int, AnsaOSPF::AreaID>::iterator ifIt = ifToAreaList.find(ifIndex); 00609 if (ifIt != ifToAreaList.end()) 00610 { 00611 if(ifIt->second == area.GetAreaID()) 00612 return; 00613 else 00614 error("OSPFRouting: Loading interface %s ifIndex[%d] aborted - Can not be in multiple areas!!!", ifName.c_str(), ifIndex); 00615 } 00616 00617 InterfaceEntry* ie = ift->getInterfaceById(ifIndex); 00618 00619 AnsaOSPF::Interface* intf = new AnsaOSPF::Interface; 00620 intf->SetIfIndex(ifIndex); 00621 intf->SetAreaID(area.GetAreaID()); 00622 00623 if(ie->isPointToPoint()) 00624 { 00625 intf->SetType(AnsaOSPF::Interface::PointToPoint); 00626 intf->SetRouterPriority(0); 00627 } else if(ie->isBroadcast()) 00628 { 00629 intf->SetType(AnsaOSPF::Interface::Broadcast); 00630 } 00631 00632 double datarate = ie->getDatarate(); 00633 if (datarate > 0.0) 00634 intf->SetOutputCost((int)(100000000.0/datarate)); 00635 00636 EV << " loading " << ifName << " ifIndex[" << ifIndex << "]\n"; 00637 00638 cXMLElementList ifDetails = (*intConfigIt)->getChildren(); 00639 for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) 00640 { 00641 std::string nodeName = (*ifElemIt)->getTagName(); 00642 if (nodeName == "Mask") { 00643 ifAddressRange.mask = IPv4AddressFromAddressString((*ifElemIt)->getNodeValue()); 00644 ifAddressRange.address = ifAddress & ifAddressRange.mask; 00645 } 00646 if (nodeName == "OspfNetworkType") { 00647 std::string interfaceType = (*ifElemIt)->getNodeValue(); 00648 if (interfaceType == "point-to-point") { 00649 intf->SetType(AnsaOSPF::Interface::PointToPoint); 00650 intf->SetRouterPriority(0); 00651 } else if (interfaceType == "broadcast") { 00652 intf->SetType(AnsaOSPF::Interface::Broadcast); 00653 } else if (interfaceType == "non-broadcast") { 00654 intf->SetType(AnsaOSPF::Interface::NBMA); 00655 } else if (interfaceType == "point-to-multipoint") { 00656 intf->SetType(AnsaOSPF::Interface::PointToMultiPoint); 00657 } else { 00658 delete intf; 00659 error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex); 00660 } 00661 } 00662 if (nodeName == "OspfCost") { 00663 intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue())); 00664 } 00665 if (nodeName == "OspfRetransmissionInterval") { 00666 intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue())); 00667 } 00668 if (nodeName == "OspfInterfaceTransmissionDelay") { 00669 intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue())); 00670 } 00671 if (nodeName == "OspfPriority") { 00672 intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue())); 00673 } 00674 if (nodeName == "OspfHelloInterval") { 00675 intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue())); 00676 } 00677 if (nodeName == "OspfDeadInterval") { 00678 intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue())); 00679 } 00680 if (nodeName == "OspfAuthenticationType") { 00681 std::string authenticationType = (*ifElemIt)->getNodeValue(); 00682 if (authenticationType == "ClearText") { 00683 intf->SetAuthenticationType(AnsaOSPF::SimplePasswordType); 00684 } else if (authenticationType == "MessageDigest") { 00685 intf->SetAuthenticationType(AnsaOSPF::CrytographicType); 00686 } else { 00687 intf->SetAuthenticationType(AnsaOSPF::NullType); 00688 } 00689 } 00690 if (nodeName == "OspfAuthenticationKey") { 00691 std::string key = (*ifElemIt)->getNodeValue(); 00692 AnsaOSPF::AuthenticationKeyType keyValue; 00693 memset(keyValue.bytes, 0, 8 * sizeof(char)); 00694 int keyLength = key.length(); 00695 if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) { 00696 for (int i = keyLength; (i > 2); i -= 2) { 00697 keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]); 00698 } 00699 } 00700 intf->SetAuthenticationKey(keyValue); 00701 } 00702 if (nodeName == "OspfPollInterval") { 00703 intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue())); 00704 } 00705 } 00706 00707 area.AddAddressRange(ifAddressRange, true); 00708 area.AddInterface(intf); 00709 ifToAreaList[ifIndex] = area.GetAreaID(); 00710 00711 IPv4InterfaceData::IPAddressVector mcg = ie->ipv4Data()->getMulticastGroups(); 00712 00713 mcg.push_back(IPAddress("224.0.0.5")); 00714 if(intf->GetType() == AnsaOSPF::Interface::Broadcast) 00715 mcg.push_back(IPAddress("224.0.0.6")); 00716 ie->ipv4Data()->setMulticastGroups(mcg); 00717 } 00718 } 00719 } 00720 } 00721 00727 void AnsaOSPFRouting::AnsaLoadArea(const cXMLElement& areaConfig) 00728 { 00729 std::string idString = areaConfig.getAttribute("id"); 00730 AnsaOSPF::AreaID areaID = ULongFromAddressString(idString.c_str()); 00731 00732 if (areaID == AnsaOSPF::BackboneAreaID && idString != "0.0.0.0") 00733 error("Wrong format of area ID: %s", idString.c_str()); 00734 else 00735 EV << " loading info for Area id = " << idString << "\n"; 00736 00737 AnsaOSPF::Area* area = new AnsaOSPF::Area(areaID); 00738 00739 00740 // load interfaces into area 00741 cXMLElementList networkConfig = areaConfig.getFirstChildWithTag("Networks")->getChildren(); 00742 for (cXMLElementList::iterator networkConfigIt = networkConfig.begin(); networkConfigIt != networkConfig.end(); networkConfigIt++) 00743 { 00744 std::string nodeName = (*networkConfigIt)->getTagName(); 00745 if (nodeName == "Network") 00746 { 00747 AnsaOSPF::IPv4AddressRange addressRange; 00748 addressRange.address = IPv4AddressFromAddressString((*networkConfigIt)->getFirstChildWithTag("IPAddress")->getNodeValue()); 00749 addressRange.mask = ~IPv4AddressFromAddressString((*networkConfigIt)->getFirstChildWithTag("Wildcard")->getNodeValue()); 00750 00751 AnsaLoadInterface(*area, addressRange); 00752 } 00753 } 00754 00755 if (areaConfig.getChildrenByTagName("Stub").size() > 0 && (areaID != AnsaOSPF::BackboneAreaID)) { // the backbone cannot be configured as a stub 00756 area->SetExternalRoutingCapability(false); 00757 cXMLElement* defaultCost = areaConfig.getFirstChildWithTag("DefaultCost"); 00758 if(defaultCost != NULL) 00759 area->SetStubDefaultCost(atoi(defaultCost->getNodeValue())); 00760 else 00761 area->SetStubDefaultCost(1); 00762 } 00763 00764 ospfRouter->AddArea(area); 00765 00766 /* 00767 cXMLElementList areaNetworks = areaConfig->getChildren(); 00768 for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) { 00769 std::string nodeName = (*arIt)->getTagName(); 00770 if (nodeName == "AddressRange") { 00771 AnsaOSPF::IPv4AddressRange addressRange; 00772 addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue()); 00773 addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue()); 00774 std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue(); 00775 if (status == "Advertise") { 00776 area->AddAddressRange(addressRange, true); 00777 } else { 00778 area->AddAddressRange(addressRange, false); 00779 } 00780 } 00781 if ((nodeName == "Stub") && (areaID != "0.0.0.0")) { // the backbone cannot be configured as a stub 00782 area->SetExternalRoutingCapability(false); 00783 area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue())); 00784 } 00785 } 00786 // Add the Area to the router 00787 ospfRouter->AddArea(area); 00788 */ 00789 } 00790 00791 00798 bool AnsaOSPFRouting::AnsaLoadConfigFromXML(const char * filename) 00799 { 00800 cXMLElement* asConfig = ev.getXMLDocument(filename); 00801 if (asConfig == NULL) { 00802 error("Cannot read OSPF configuration from file: %s", filename); 00803 } 00804 00805 // load information on this router 00806 std::string routerXPath("Router[@id='"); 00807 IPAddress routerId(ospfRouter->GetRouterID()); 00808 routerXPath += routerId.str(); 00809 routerXPath += "']"; 00810 00811 cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str()); 00812 if (routerNode == NULL) 00813 error("No configuration for Router ID: %s", routerId.str().c_str()); 00814 00815 cXMLElement* routingNode = routerNode->getFirstChildWithTag("Routing"); 00816 00817 if (routingNode != NULL){ 00818 IntNode = routerNode->getFirstChildWithTag("Interfaces"); 00819 OspfNode = routingNode->getFirstChildWithTag("Ospf"); 00820 } 00821 00822 if (routingNode == NULL || OspfNode == NULL || IntNode == NULL) { 00823 EV << "OSPFRouting: OSPF is not enabled on Router id = " << routerId.str() << "\n"; 00824 return true; 00825 } 00826 else { 00827 ospfEnabled = true; 00828 EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n"; 00829 } 00830 00831 if (OspfNode->getChildrenByTagName("RFC1583Compatible").size() > 0) { 00832 ospfRouter->SetRFC1583Compatibility(true); 00833 } 00834 00835 // load areas information 00836 cXMLElementList areasConfig = OspfNode->getFirstChildWithTag("Areas")->getChildren(); 00837 for (cXMLElementList::iterator areaConfigIt = areasConfig.begin(); areaConfigIt != areasConfig.end(); areaConfigIt++) 00838 { 00839 std::string nodeName = (*areaConfigIt)->getTagName(); 00840 if (nodeName == "Area" && (*areaConfigIt)->getAttribute("id")) 00841 AnsaLoadArea(*(*areaConfigIt)); 00842 } 00843 00844 // starts OSPF on interfaces 00845 for (std::map<int, AnsaOSPF::AreaID>::iterator ifMapIt = ifToAreaList.begin(); ifMapIt != ifToAreaList.end(); ifMapIt++) { 00846 ospfRouter->GetArea(ifMapIt->second)->GetInterface(ifMapIt->first)->ProcessEvent(AnsaOSPF::Interface::InterfaceUp);; 00847 } 00848 00849 00850 /* 00851 00852 std::map<std::string, int> areaList; 00853 GetAreaListFromXML(*routerNode, areaList); 00854 00855 // load area information 00856 for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) { 00857 LoadAreaFromXML(*asConfig, areaIt->first); 00858 } 00859 // if the router is an area border router then it MUST be part of the backbone(area 0) 00860 if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) { 00861 LoadAreaFromXML(*asConfig, "0.0.0.0"); 00862 } 00863 00864 // load interface information 00865 cXMLElementList routerConfig = routerNode->getChildren(); 00866 for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) { 00867 std::string nodeName = (*routerConfigIt)->getTagName(); 00868 if ((nodeName == "PointToPointInterface") || 00869 (nodeName == "BroadcastInterface") || 00870 (nodeName == "NBMAInterface") || 00871 (nodeName == "PointToMultiPointInterface")) 00872 { 00873 LoadInterfaceParameters(*(*routerConfigIt)); 00874 } 00875 if (nodeName == "ExternalInterface") { 00876 LoadExternalRoute(*(*routerConfigIt)); 00877 } 00878 if (nodeName == "HostInterface") { 00879 LoadHostRoute(*(*routerConfigIt)); 00880 } 00881 if (nodeName == "VirtualLink") { 00882 LoadVirtualLink(*(*routerConfigIt)); 00883 } 00884 } 00885 */ 00886 return true; 00887 }