#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 | |
| IInterfaceTable * | ift |
| Provides access to the interface table. | |
| IRoutingTable * | rt |
| Provides access to the IP routing table. | |
| OSPF::Router * | ospfRouter |
| Root object of the OSPF datastructure. | |
OMNeT++ module class acting as a facade for the OSPF datastructure. Handles the configuration loading and forwards the OMNeT++ messages(OSPF packets).
Definition at line 32 of file OSPFRouting.h.
| OSPFRouting::OSPFRouting | ( | ) |
Definition at line 37 of file OSPFRouting.cc.
{
ospfRouter = NULL;
}
| OSPFRouting::~OSPFRouting | ( | void | ) | [virtual] |
Destructor. Deletes the whole OSPF datastructure.
Definition at line 46 of file OSPFRouting.cc.
{
delete ospfRouter;
}
| void OSPFRouting::GetAreaListFromXML | ( | const cXMLElement & | routerNode, | |
| std::map< std::string, int > & | areaList | |||
| ) | const [private] |
Loads a list of OSPF Areas connected to this router from the config XML.
| routerNode | [in] XML node describing this router. | |
| areaList | [out] A hash of OSPF Areas connected to this router. The hash key is the Area ID. |
Definition at line 109 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
cXMLElementList routerConfig = routerNode.getChildren();
for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
std::string nodeName = (*routerConfigIt)->getTagName();
if ((nodeName == "PointToPointInterface") ||
(nodeName == "BroadcastInterface") ||
(nodeName == "NBMAInterface") ||
(nodeName == "PointToMultiPointInterface"))
{
std::string areaId = (*routerConfigIt)->getChildrenByTagName("AreaID")[0]->getNodeValue();
if (areaList.find(areaId) == areaList.end()) {
areaList[areaId] = 1;
}
}
}
}
| void OSPFRouting::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Forwards OSPF messages to the message handler object of the OSPF datastructure.
| msg | [in] The OSPF message. |
Definition at line 85 of file OSPFRouting.cc.
{
// if (simulation.getEventNumber() == 90591) {
// __asm int 3;
// }
ospfRouter->GetMessageHandler()->MessageReceived(msg);
}
| void OSPFRouting::initialize | ( | int | stage | ) | [protected, virtual] |
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.
| stage | [in] The initialization stage. |
Definition at line 59 of file OSPFRouting.cc.
{
// we have to wait for stage 2 until interfaces get registered(stage 0)
// and routerId gets assigned(stage 3)
if (stage == 4)
{
rt = RoutingTableAccess().get();
ift = InterfaceTableAccess().get();
// Get routerId
ospfRouter = new OSPF::Router(rt->getRouterId().getInt(), this);
// read the OSPF AS configuration
const char *fileName = par("ospfConfigFile");
if (fileName == NULL || (!strcmp(fileName, "")) || !LoadConfigFromXML(fileName))
error("Error reading AS configuration from file %s", fileName);
ospfRouter->AddWatches();
}
}
| void OSPFRouting::LoadAreaFromXML | ( | const cXMLElement & | asConfig, | |
| const std::string & | areaID | |||
| ) | [private] |
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.
| asConfig | [in] XML node describing the configuration of the whole Autonomous System. | |
| areaID | [in] The Area to be added to the OSPF datastructure. |
Definition at line 134 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
std::string areaXPath("Area[@id='");
areaXPath += areaID;
areaXPath += "']";
cXMLElement* areaConfig = asConfig.getElementByPath(areaXPath.c_str());
if (areaConfig == NULL) {
error("No configuration for Area ID: %s", areaID.c_str());
}
else {
EV << " loading info for Area id = " << areaID << "\n";
}
OSPF::Area* area = new OSPF::Area(ULongFromAddressString(areaID.c_str()));
cXMLElementList areaDetails = areaConfig->getChildren();
for (cXMLElementList::iterator arIt = areaDetails.begin(); arIt != areaDetails.end(); arIt++) {
std::string nodeName = (*arIt)->getTagName();
if (nodeName == "AddressRange") {
OSPF::IPv4AddressRange addressRange;
addressRange.address = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Address")[0]->getNodeValue());
addressRange.mask = IPv4AddressFromAddressString((*arIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
std::string status = (*arIt)->getChildrenByTagName("Status")[0]->getNodeValue();
if (status == "Advertise") {
area->AddAddressRange(addressRange, true);
} else {
area->AddAddressRange(addressRange, false);
}
}
if ((nodeName == "Stub") && (areaID != "0.0.0.0")) { // the backbone cannot be configured as a stub
area->SetExternalRoutingCapability(false);
area->SetStubDefaultCost(atoi((*arIt)->getChildrenByTagName("DefaultCost")[0]->getNodeValue()));
}
}
// Add the Area to the router
ospfRouter->AddArea(area);
}
| bool OSPFRouting::LoadConfigFromXML | ( | const char * | filename | ) | [private] |
Loads the configuration of the OSPF datastructure from the config XML.
| filename | [in] The path of the XML config file. |
| an | getError() otherwise. |
Definition at line 464 of file OSPFRouting.cc.
Referenced by initialize().
{
cXMLElement* asConfig = ev.getXMLDocument(filename);
if (asConfig == NULL) {
error("Cannot read AS configuration from file: %s", filename);
}
// load information on this router
std::string routerXPath("Router[@id='");
IPAddress routerId(ospfRouter->GetRouterID());
routerXPath += routerId.str();
routerXPath += "']";
cXMLElement* routerNode = asConfig->getElementByPath(routerXPath.c_str());
if (routerNode == NULL) {
error("No configuration for Router ID: %s", routerId.str().c_str());
}
else {
EV << "OSPFRouting: Loading info for Router id = " << routerId.str() << "\n";
}
if (routerNode->getChildrenByTagName("RFC1583Compatible").size() > 0) {
ospfRouter->SetRFC1583Compatibility(true);
}
std::map<std::string, int> areaList;
GetAreaListFromXML(*routerNode, areaList);
// load area information
for (std::map<std::string, int>::iterator areaIt = areaList.begin(); areaIt != areaList.end(); areaIt++) {
LoadAreaFromXML(*asConfig, areaIt->first);
}
// if the router is an area border router then it MUST be part of the backbone(area 0)
if ((areaList.size() > 1) && (areaList.find("0.0.0.0") == areaList.end())) {
LoadAreaFromXML(*asConfig, "0.0.0.0");
}
// load interface information
cXMLElementList routerConfig = routerNode->getChildren();
for (cXMLElementList::iterator routerConfigIt = routerConfig.begin(); routerConfigIt != routerConfig.end(); routerConfigIt++) {
std::string nodeName = (*routerConfigIt)->getTagName();
if ((nodeName == "PointToPointInterface") ||
(nodeName == "BroadcastInterface") ||
(nodeName == "NBMAInterface") ||
(nodeName == "PointToMultiPointInterface"))
{
LoadInterfaceParameters(*(*routerConfigIt));
}
if (nodeName == "ExternalInterface") {
LoadExternalRoute(*(*routerConfigIt));
}
if (nodeName == "HostInterface") {
LoadHostRoute(*(*routerConfigIt));
}
if (nodeName == "VirtualLink") {
LoadVirtualLink(*(*routerConfigIt));
}
}
return true;
}
| void OSPFRouting::LoadExternalRoute | ( | const cXMLElement & | externalRouteConfig | ) | [private] |
Loads the configuration information of a route outside of the Autonomous System(external route).
| externalRouteConfig | [in] XML node describing the parameters of an external route. |
Definition at line 294 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
std::string ifName = externalRouteConfig.getAttribute("ifName");
int ifIndex = ResolveInterfaceName(ifName);
OSPFASExternalLSAContents asExternalRoute;
OSPF::RoutingTableEntry externalRoutingEntry; // only used here to keep the path cost calculation in one place
OSPF::IPv4AddressRange networkAddress;
EV << " loading ExternalInterface " << ifName << " ifIndex[" << ifIndex << "]\n";
cXMLElementList ifDetails = externalRouteConfig.getChildren();
for (cXMLElementList::iterator exElemIt = ifDetails.begin(); exElemIt != ifDetails.end(); exElemIt++) {
std::string nodeName = (*exElemIt)->getTagName();
if (nodeName == "AdvertisedExternalNetwork") {
networkAddress.address = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Address")[0]->getNodeValue());
networkAddress.mask = IPv4AddressFromAddressString((*exElemIt)->getChildrenByTagName("Mask")[0]->getNodeValue());
asExternalRoute.setNetworkMask(ULongFromIPv4Address(networkAddress.mask));
}
if (nodeName == "ExternalInterfaceOutputParameters") {
std::string metricType = (*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputType")[0]->getNodeValue();
int routeCost = atoi((*exElemIt)->getChildrenByTagName("ExternalInterfaceOutputCost")[0]->getNodeValue());
asExternalRoute.setRouteCost(routeCost);
if (metricType == "Type2") {
asExternalRoute.setE_ExternalMetricType(true);
externalRoutingEntry.SetType2Cost(routeCost);
externalRoutingEntry.SetPathType(OSPF::RoutingTableEntry::Type2External);
} else {
asExternalRoute.setE_ExternalMetricType(false);
externalRoutingEntry.SetCost(routeCost);
externalRoutingEntry.SetPathType(OSPF::RoutingTableEntry::Type1External);
}
}
if (nodeName == "ForwardingAddress") {
asExternalRoute.setForwardingAddress(ULongFromAddressString((*exElemIt)->getNodeValue()));
}
if (nodeName == "ExternalRouteTag") {
std::string externalRouteTag = (*exElemIt)->getNodeValue();
char externalRouteTagValue[4];
memset(externalRouteTagValue, 0, 4 * sizeof(char));
int externalRouteTagLength = externalRouteTag.length();
if ((externalRouteTagLength > 4) && (externalRouteTagLength <= 10) && (externalRouteTagLength % 2 == 0) && (externalRouteTag[0] == '0') && (externalRouteTag[1] == 'x')) {
for (int i = externalRouteTagLength; (i > 2); i -= 2) {
externalRouteTagValue[(i - 2) / 2] = HexPairToByte(externalRouteTag[i - 1], externalRouteTag[i]);
}
}
asExternalRoute.setExternalRouteTag((externalRouteTagValue[0] << 24) + (externalRouteTagValue[1] << 16) + (externalRouteTagValue[2] << 8) + externalRouteTagValue[3]);
}
}
// add the external route to the OSPF datastructure
ospfRouter->UpdateExternalRoute(networkAddress.address, asExternalRoute, ifIndex);
}
| void OSPFRouting::LoadHostRoute | ( | const cXMLElement & | hostRouteConfig | ) | [private] |
Loads the configuration of a host getRoute(a host directly connected to the router).
| hostRouteConfig | [in] XML node describing the parameters of a host route. |
Definition at line 353 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
OSPF::HostRouteParameters hostParameters;
OSPF::AreaID hostArea;
std::string ifName = hostRouteConfig.getAttribute("ifName");
hostParameters.ifIndex = ResolveInterfaceName(ifName);
EV << " loading HostInterface " << ifName << " ifIndex[" << static_cast<short> (hostParameters.ifIndex) << "]\n";
cXMLElementList ifDetails = hostRouteConfig.getChildren();
for (cXMLElementList::iterator hostElemIt = ifDetails.begin(); hostElemIt != ifDetails.end(); hostElemIt++) {
std::string nodeName = (*hostElemIt)->getTagName();
if (nodeName == "AreaID") {
hostArea = ULongFromAddressString((*hostElemIt)->getNodeValue());
}
if (nodeName == "AttachedHost") {
hostParameters.address = IPv4AddressFromAddressString((*hostElemIt)->getNodeValue());
}
if (nodeName == "LinkCost") {
hostParameters.linkCost = atoi((*hostElemIt)->getNodeValue());
}
}
// add the host route to the OSPF datastructure.
OSPF::Area* area = ospfRouter->GetArea(hostArea);
if (area != NULL) {
area->AddHostRoute(hostParameters);
} else {
error("Loading HostInterface ifIndex[%d] in Area %d aborted", hostParameters.ifIndex, hostArea);
}
}
| void OSPFRouting::LoadInterfaceParameters | ( | const cXMLElement & | ifConfig | ) | [private] |
Loads OSPF configuration information for a router interface. Handles PointToPoint, Broadcast, NBMA and PointToMultiPoint interfaces.
| ifConfig | [in] XML node describing the configuration of an OSPF interface. |
Definition at line 178 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
OSPF::Interface* intf = new OSPF::Interface;
std::string ifName = ifConfig.getAttribute("ifName");
int ifIndex = ResolveInterfaceName(ifName);
std::string interfaceType = ifConfig.getTagName();
EV << " loading " << interfaceType << " " << ifName << " ifIndex[" << ifIndex << "]\n";
intf->SetIfIndex(ifIndex);
if (interfaceType == "PointToPointInterface") {
intf->SetType(OSPF::Interface::PointToPoint);
} else if (interfaceType == "BroadcastInterface") {
intf->SetType(OSPF::Interface::Broadcast);
} else if (interfaceType == "NBMAInterface") {
intf->SetType(OSPF::Interface::NBMA);
} else if (interfaceType == "PointToMultiPointInterface") {
intf->SetType(OSPF::Interface::PointToMultiPoint);
} else {
delete intf;
error("Loading %s ifIndex[%d] aborted", interfaceType.c_str(), ifIndex);
}
OSPF::AreaID areaID = 0;
cXMLElementList ifDetails = ifConfig.getChildren();
for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
std::string nodeName = (*ifElemIt)->getTagName();
if (nodeName == "AreaID") {
areaID = ULongFromAddressString((*ifElemIt)->getNodeValue());
intf->SetAreaID(areaID);
}
if (nodeName == "InterfaceOutputCost") {
intf->SetOutputCost(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "RetransmissionInterval") {
intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "InterfaceTransmissionDelay") {
intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "RouterPriority") {
intf->SetRouterPriority(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "HelloInterval") {
intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "RouterDeadInterval") {
intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "AuthenticationType") {
std::string authenticationType = (*ifElemIt)->getNodeValue();
if (authenticationType == "SimplePasswordType") {
intf->SetAuthenticationType(OSPF::SimplePasswordType);
} else if (authenticationType == "CrytographicType") {
intf->SetAuthenticationType(OSPF::CrytographicType);
} else {
intf->SetAuthenticationType(OSPF::NullType);
}
}
if (nodeName == "AuthenticationKey") {
std::string key = (*ifElemIt)->getNodeValue();
OSPF::AuthenticationKeyType keyValue;
memset(keyValue.bytes, 0, 8 * sizeof(char));
int keyLength = key.length();
if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
for (int i = keyLength; (i > 2); i -= 2) {
keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
}
}
intf->SetAuthenticationKey(keyValue);
}
if (nodeName == "PollInterval") {
intf->SetPollInterval(atoi((*ifElemIt)->getNodeValue()));
}
if ((interfaceType == "NBMAInterface") && (nodeName == "NBMANeighborList")) {
cXMLElementList neighborList = (*ifElemIt)->getChildren();
for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
std::string neighborNodeName = (*neighborIt)->getTagName();
if (neighborNodeName == "NBMANeighbor") {
OSPF::Neighbor* neighbor = new OSPF::Neighbor;
neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getChildrenByTagName("NetworkInterfaceAddress")[0]->getNodeValue()));
neighbor->SetPriority(atoi((*neighborIt)->getChildrenByTagName("NeighborPriority")[0]->getNodeValue()));
intf->AddNeighbor(neighbor);
}
}
}
if ((interfaceType == "PointToMultiPointInterface") && (nodeName == "PointToMultiPointNeighborList")) {
cXMLElementList neighborList = (*ifElemIt)->getChildren();
for (cXMLElementList::iterator neighborIt = neighborList.begin(); neighborIt != neighborList.end(); neighborIt++) {
std::string neighborNodeName = (*neighborIt)->getTagName();
if (neighborNodeName == "PointToMultiPointNeighbor") {
OSPF::Neighbor* neighbor = new OSPF::Neighbor;
neighbor->SetAddress(IPv4AddressFromAddressString((*neighborIt)->getNodeValue()));
intf->AddNeighbor(neighbor);
}
}
}
}
// add the interface to it's Area
OSPF::Area* area = ospfRouter->GetArea(areaID);
if (area != NULL) {
area->AddInterface(intf);
intf->ProcessEvent(OSPF::Interface::InterfaceUp); // notification should come from the blackboard...
} else {
delete intf;
error("Loading %s ifIndex[%d] in Area %d aborted", interfaceType.c_str(), ifIndex, areaID);
}
}
| void OSPFRouting::LoadVirtualLink | ( | const cXMLElement & | virtualLinkConfig | ) | [private] |
Loads the configuration of an OSPf virtual link(virtual connection between two backbone routers).
| virtualLinkConfig | [in] XML node describing the parameters of a virtual link. |
Definition at line 391 of file OSPFRouting.cc.
Referenced by LoadConfigFromXML().
{
OSPF::Interface* intf = new OSPF::Interface;
std::string endPoint = virtualLinkConfig.getAttribute("endPointRouterID");
OSPF::Neighbor* neighbor = new OSPF::Neighbor;
EV << " loading VirtualLink to " << endPoint << "\n";
intf->SetType(OSPF::Interface::Virtual);
neighbor->SetNeighborID(ULongFromAddressString(endPoint.c_str()));
intf->AddNeighbor(neighbor);
cXMLElementList ifDetails = virtualLinkConfig.getChildren();
for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ifElemIt++) {
std::string nodeName = (*ifElemIt)->getTagName();
if (nodeName == "TransitAreaID") {
intf->SetTransitAreaID(ULongFromAddressString((*ifElemIt)->getNodeValue()));
}
if (nodeName == "RetransmissionInterval") {
intf->SetRetransmissionInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "InterfaceTransmissionDelay") {
intf->SetTransmissionDelay(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "HelloInterval") {
intf->SetHelloInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "RouterDeadInterval") {
intf->SetRouterDeadInterval(atoi((*ifElemIt)->getNodeValue()));
}
if (nodeName == "AuthenticationType") {
std::string authenticationType = (*ifElemIt)->getNodeValue();
if (authenticationType == "SimplePasswordType") {
intf->SetAuthenticationType(OSPF::SimplePasswordType);
} else if (authenticationType == "CrytographicType") {
intf->SetAuthenticationType(OSPF::CrytographicType);
} else {
intf->SetAuthenticationType(OSPF::NullType);
}
}
if (nodeName == "AuthenticationKey") {
std::string key = (*ifElemIt)->getNodeValue();
OSPF::AuthenticationKeyType keyValue;
memset(keyValue.bytes, 0, 8 * sizeof(char));
int keyLength = key.length();
if ((keyLength > 4) && (keyLength <= 18) && (keyLength % 2 == 0) && (key[0] == '0') && (key[1] == 'x')) {
for (int i = keyLength; (i > 2); i -= 2) {
keyValue.bytes[(i - 2) / 2] = HexPairToByte(key[i - 1], key[i]);
}
}
intf->SetAuthenticationKey(keyValue);
}
}
// add the virtual link to the OSPF datastructure.
OSPF::Area* transitArea = ospfRouter->GetArea(intf->GetAreaID());
OSPF::Area* backbone = ospfRouter->GetArea(OSPF::BackboneAreaID);
if ((backbone != NULL) && (transitArea != NULL) && (transitArea->GetExternalRoutingCapability())) {
backbone->AddInterface(intf);
} else {
delete intf;
error("Loading VirtualLink to %s through Area %d aborted", endPoint.c_str(), intf->GetAreaID());
}
}
| virtual int OSPFRouting::numInitStages | ( | ) | const [inline, protected, virtual] |
Definition at line 54 of file OSPFRouting.h.
{return 5;}
| int OSPFRouting::ResolveInterfaceName | ( | const std::string & | name | ) | const [private] |
Looks up the interface name in IInterfaceTable, and returns interfaceId a.k.a ifIndex.
Definition at line 96 of file OSPFRouting.cc.
Referenced by LoadExternalRoute(), LoadHostRoute(), and LoadInterfaceParameters().
{
InterfaceEntry* ie = ift->getInterfaceByName(name.c_str());
if (!ie)
opp_error("error reading XML config: IInterfaceTable contains no interface named '%s'", name.c_str());
return ie->getInterfaceId();
}
IInterfaceTable* OSPFRouting::ift [private] |
Provides access to the interface table.
Definition at line 35 of file OSPFRouting.h.
Referenced by initialize(), and ResolveInterfaceName().
OSPF::Router* OSPFRouting::ospfRouter [private] |
Root object of the OSPF datastructure.
Definition at line 37 of file OSPFRouting.h.
Referenced by handleMessage(), initialize(), LoadAreaFromXML(), LoadConfigFromXML(), LoadExternalRoute(), LoadHostRoute(), LoadInterfaceParameters(), LoadVirtualLink(), OSPFRouting(), and ~OSPFRouting().
IRoutingTable* OSPFRouting::rt [private] |
Provides access to the IP routing table.
Definition at line 36 of file OSPFRouting.h.
Referenced by initialize().
1.7.1