|
INET Framework for OMNeT++/OMNEST
|
#include <AnsaOSPFRouter.h>
Public Member Functions | |
| Router (RouterID id, cSimpleModule *containingModule) | |
| virtual | ~Router (void) |
| void | SetRouterID (RouterID id) |
| RouterID | GetRouterID (void) const |
| void | SetRFC1583Compatibility (bool compatibility) |
| bool | GetRFC1583Compatibility (void) const |
| unsigned long | GetAreaCount (void) const |
| MessageHandler * | GetMessageHandler (void) |
| unsigned long | GetASExternalLSACount (void) const |
| ASExternalLSA * | GetASExternalLSA (unsigned long i) |
| const ASExternalLSA * | GetASExternalLSA (unsigned long i) const |
| bool | GetASBoundaryRouter (void) const |
| unsigned long | GetRoutingTableEntryCount (void) const |
| RoutingTableEntry * | GetRoutingTableEntry (unsigned long i) |
| const RoutingTableEntry * | GetRoutingTableEntry (unsigned long i) const |
| void | AddRoutingTableEntry (RoutingTableEntry *entry) |
| void | AddWatches (void) |
| void | AddArea (Area *area) |
| Area * | GetArea (AreaID areaID) |
| Area * | GetArea (IPv4Address address) |
| Interface * | GetNonVirtualInterface (unsigned char ifIndex) |
| bool | InstallLSA (OSPFLSA *lsa, AreaID areaID=BackboneAreaID) |
| OSPFLSA * | FindLSA (LSAType lsaType, LSAKeyType lsaKey, AreaID areaID) |
| void | AgeDatabase (void) |
| bool | HasAnyNeighborInStates (int states) const |
| void | RemoveFromAllRetransmissionLists (LSAKeyType lsaKey) |
| bool | IsOnAnyRetransmissionList (LSAKeyType lsaKey) const |
| bool | FloodLSA (OSPFLSA *lsa, AreaID areaID=BackboneAreaID, Interface *intf=NULL, Neighbor *neighbor=NULL) |
| bool | IsLocalAddress (IPv4Address address) const |
| bool | HasAddressRange (IPv4AddressRange addressRange) const |
| bool | IsDestinationUnreachable (OSPFLSA *lsa) const |
| RoutingTableEntry * | Lookup (IPAddress destination, std::vector< RoutingTableEntry * > *table=NULL) const |
| void | RebuildRoutingTable (void) |
| IPv4AddressRange | GetContainingAddressRange (IPv4AddressRange addressRange, bool *advertise=NULL) const |
| void | UpdateExternalRoute (IPv4Address networkAddress, const OSPFASExternalLSAContents &externalRouteContents, int ifIndex) |
| void | RemoveExternalRoute (IPv4Address networkAddress) |
| RoutingTableEntry * | GetPreferredEntry (const OSPFLSA &lsa, bool skipSelfOriginated, std::vector< RoutingTableEntry * > *fromRoutingTable=NULL) |
Public Attributes | |
| Stat | stat |
Private Member Functions | |
| bool | InstallASExternalLSA (OSPFASExternalLSA *lsa) |
| ASExternalLSA * | FindASExternalLSA (LSAKeyType lsaKey) |
| const ASExternalLSA * | FindASExternalLSA (LSAKeyType lsaKey) const |
| ASExternalLSA * | OriginateASExternalLSA (ASExternalLSA *lsa) |
| LinkStateID | GetUniqueLinkStateID (IPv4AddressRange destination, Metric destinationCost, AnsaOSPF::ASExternalLSA *&lsaToReoriginate, bool externalMetricIsType2=false) const |
| void | CalculateASExternalRoutes (std::vector< RoutingTableEntry * > &newRoutingTable) |
| void | NotifyAboutRoutingTableChanges (std::vector< RoutingTableEntry * > &oldRoutingTable) |
| bool | HasRouteToASBoundaryRouter (const std::vector< RoutingTableEntry * > &inRoutingTable, AnsaOSPF::RouterID routerID) const |
| std::vector< RoutingTableEntry * > | GetRoutesToASBoundaryRouter (const std::vector< RoutingTableEntry * > &fromRoutingTable, AnsaOSPF::RouterID routerID) const |
| void | PruneASBoundaryRouterEntries (std::vector< RoutingTableEntry * > &asbrEntries) const |
| RoutingTableEntry * | SelectLeastCostRoutingEntry (std::vector< RoutingTableEntry * > &entries) const |
Private Attributes | |
| RouterID | routerID |
| The router ID assigned by the IP layer. | |
| std::map< AreaID, Area * > | areasByID |
| A map of the contained areas with the AreaID as key. | |
| std::vector< Area * > | areas |
| A list of the contained areas. | |
| std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > | asExternalLSAsByID |
| A map of the ASExternalLSAs advertised by this router. | |
| std::vector< ASExternalLSA * > | asExternalLSAs |
| A list of the ASExternalLSAs advertised by this router. | |
| std::map< IPv4Address, OSPFASExternalLSAContents, IPv4Address_Less > | externalRoutes |
| A map of the external route advertised by this router. | |
| OSPFTimer * | ageTimer |
| Database age timer - fires every second. | |
| std::vector< RoutingTableEntry * > | routingTable |
| The OSPF routing table - contains more information than the one in the IP layer. | |
| MessageHandler * | messageHandler |
| The message dispatcher class. | |
| bool | rfc1583Compatibility |
| Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not. | |
Represents the full OSPF datastructure as laid out in RFC2328.
Definition at line 22 of file AnsaOSPFRouter.h.
| AnsaOSPF::Router::Router | ( | AnsaOSPF::RouterID | id, |
| cSimpleModule * | containingModule | ||
| ) |
Constructor. Initializes internal variables, adds a MessageHandler and starts the Database Age timer.
Definition at line 8 of file AnsaOSPFRouter.cc.
:
routerID(id),
rfc1583Compatibility(false)
{
messageHandler = new AnsaOSPF::MessageHandler(this, containingModule);
ageTimer = new OSPFTimer;
ageTimer->setTimerKind(DatabaseAgeTimer);
ageTimer->setContextPointer(this);
ageTimer->setName("AnsaOSPF::Router::DatabaseAgeTimer");
messageHandler->StartTimer(ageTimer, 1.0);
}
| AnsaOSPF::Router::~Router | ( | void | ) | [virtual] |
Destructor. Clears all LSA lists and kills the Database Age timer.
Definition at line 26 of file AnsaOSPFRouter.cc.
{
long areaCount = areas.size();
for (long i = 0; i < areaCount; i++) {
delete areas[i];
}
long lsaCount = asExternalLSAs.size();
for (long j = 0; j < lsaCount; j++) {
delete asExternalLSAs[j];
}
long routeCount = routingTable.size();
for (long k = 0; k < routeCount; k++) {
delete routingTable[k];
}
messageHandler->ClearTimer(ageTimer);
delete ageTimer;
delete messageHandler;
}
| void AnsaOSPF::Router::AddArea | ( | AnsaOSPF::Area * | area | ) |
Adds a new Area to the Area list.
| area | [in] The Area to add. |
Definition at line 61 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPFRouting::AnsaLoadArea(), and AnsaOSPFRouting::LoadAreaFromXML().
| void AnsaOSPF::Router::AddRoutingTableEntry | ( | RoutingTableEntry * | entry | ) | [inline] |
Definition at line 55 of file AnsaOSPFRouter.h.
{ routingTable.push_back(entry); }
| void AnsaOSPF::Router::AddWatches | ( | void | ) |
Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs.
Definition at line 49 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPFRouting::initialize().
{
WATCH(routerID);
WATCH_PTRVECTOR(areas);
WATCH_PTRVECTOR(asExternalLSAs);
}
| void AnsaOSPF::Router::AgeDatabase | ( | void | ) |
Ages the LSAs in the Router's database. This method is called on every firing of the DatabaseAgeTimer(every second).
Definition at line 345 of file AnsaOSPFRouter.cc.
{
long lsaCount = asExternalLSAs.size();
bool rebuildRoutingTable = false;
for (long i = 0; i < lsaCount; i++) {
unsigned short lsAge = asExternalLSAs[i]->getHeader().getLsAge();
bool selfOriginated = (asExternalLSAs[i]->getHeader().getAdvertisingRouter().getInt() == routerID);
bool unreachable = IsDestinationUnreachable(asExternalLSAs[i]);
AnsaOSPF::ASExternalLSA* lsa = asExternalLSAs[i];
if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
lsa->getHeader().setLsAge(lsAge + 1);
if ((lsAge + 1) % CHECK_AGE == 0) {
if (!lsa->ValidateLSChecksum()) {
EV << "Invalid LS checksum. Memory error detected!\n";
}
}
lsa->IncrementInstallTime();
}
if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
if (unreachable) {
lsa->getHeader().setLsAge(MAX_AGE);
FloodLSA(lsa, AnsaOSPF::BackboneAreaID);
lsa->IncrementInstallTime();
} else {
long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
lsa->getHeader().setLsAge(MAX_AGE);
FloodLSA(lsa, AnsaOSPF::BackboneAreaID);
lsa->IncrementInstallTime();
} else {
AnsaOSPF::ASExternalLSA* newLSA = OriginateASExternalLSA(lsa);
newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum
rebuildRoutingTable |= lsa->Update(newLSA);
delete newLSA;
FloodLSA(lsa, AnsaOSPF::BackboneAreaID);
}
}
}
if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
lsa->getHeader().setLsAge(MAX_AGE);
FloodLSA(lsa, AnsaOSPF::BackboneAreaID);
lsa->IncrementInstallTime();
}
if (lsAge == MAX_AGE) {
AnsaOSPF::LSAKeyType lsaKey;
lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
if (!IsOnAnyRetransmissionList(lsaKey) &&
!HasAnyNeighborInStates(AnsaOSPF::Neighbor::ExchangeState | AnsaOSPF::Neighbor::LoadingState))
{
if (!selfOriginated || unreachable) {
asExternalLSAsByID.erase(lsaKey);
delete lsa;
asExternalLSAs[i] = NULL;
rebuildRoutingTable = true;
} else {
if (lsa->GetPurgeable()) {
asExternalLSAsByID.erase(lsaKey);
delete lsa;
asExternalLSAs[i] = NULL;
rebuildRoutingTable = true;
} else {
AnsaOSPF::ASExternalLSA* newLSA = OriginateASExternalLSA(lsa);
long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum
rebuildRoutingTable |= lsa->Update(newLSA);
delete newLSA;
FloodLSA(lsa, AnsaOSPF::BackboneAreaID);
}
}
}
}
}
std::vector<ASExternalLSA*>::iterator it = asExternalLSAs.begin();
while (it != asExternalLSAs.end()) {
if ((*it) == NULL) {
it = asExternalLSAs.erase(it);
} else {
it++;
}
}
long areaCount = areas.size();
for (long j = 0; j < areaCount; j++) {
areas[j]->AgeDatabase();
}
messageHandler->StartTimer(ageTimer, 1.0);
if (rebuildRoutingTable) {
RebuildRoutingTable();
}
}
| void AnsaOSPF::Router::CalculateASExternalRoutes | ( | std::vector< RoutingTableEntry * > & | newRoutingTable | ) | [private] |
| AnsaOSPF::ASExternalLSA * AnsaOSPF::Router::FindASExternalLSA | ( | AnsaOSPF::LSAKeyType | lsaKey | ) | [private] |
Find the AS External LSA identified by the input lsaKey in the database.
| lsaKey | [in] Look for the AS External LSA which is identified by this key. |
Definition at line 313 of file AnsaOSPFRouter.cc.
{
std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::ASExternalLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
if (lsaIt != asExternalLSAsByID.end()) {
return lsaIt->second;
} else {
return NULL;
}
}
| const AnsaOSPF::ASExternalLSA * AnsaOSPF::Router::FindASExternalLSA | ( | AnsaOSPF::LSAKeyType | lsaKey | ) | const [private] |
Find the AS External LSA identified by the input lsaKey in the database.
| lsaKey | [in] Look for the AS External LSA which is identified by this key. |
Definition at line 329 of file AnsaOSPFRouter.cc.
{
std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::ASExternalLSA*, AnsaOSPF::LSAKeyType_Less>::const_iterator lsaIt = asExternalLSAsByID.find(lsaKey);
if (lsaIt != asExternalLSAsByID.end()) {
return lsaIt->second;
} else {
return NULL;
}
}
| OSPFLSA * AnsaOSPF::Router::FindLSA | ( | LSAType | lsaType, |
| AnsaOSPF::LSAKeyType | lsaKey, | ||
| AnsaOSPF::AreaID | areaID | ||
| ) |
Find the LSA identified by the input lsaKey in the database.
| lsaType | [in] Look for an LSA of this type. |
| lsaKey | [in] Look for the LSA which is identified by this key. |
| areaID | [in] In case of Router, Network and Summary LSAs, look in the Area's database identified by this parameter. |
Definition at line 267 of file AnsaOSPFRouter.cc.
{
switch (lsaType) {
case RouterLSAType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
return areaIt->second->FindRouterLSA(lsaKey.linkStateID);
}
}
break;
case NetworkLSAType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
return areaIt->second->FindNetworkLSA(lsaKey.linkStateID);
}
}
break;
case SummaryLSA_NetworksType:
case SummaryLSA_ASBoundaryRoutersType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
return areaIt->second->FindSummaryLSA(lsaKey);
}
}
break;
case ASExternalLSAType:
{
return FindASExternalLSA(lsaKey);
}
break;
default:
ASSERT(false);
break;
}
return NULL;
}
| bool AnsaOSPF::Router::FloodLSA | ( | OSPFLSA * | lsa, |
| AnsaOSPF::AreaID | areaID = BackboneAreaID, |
||
| AnsaOSPF::Interface * | intf = NULL, |
||
| AnsaOSPF::Neighbor * | neighbor = NULL |
||
| ) |
Floods out the input lsa on a set of Interfaces.
| lsa | [in] The LSA to be flooded out. |
| areaID | [in] If the lsa is a Router, Network or Summary LSA, then flood it only in this Area. |
| intf | [in] The Interface this LSA arrived on. |
| neighbor | [in] The Nieghbor this LSA arrived from. |
Definition at line 507 of file AnsaOSPFRouter.cc.
{
bool floodedBackOut = false;
if (lsa != NULL) {
if (lsa->getHeader().getLsType() == ASExternalLSAType) {
long areaCount = areas.size();
for (long i = 0; i < areaCount; i++) {
if (areas[i]->GetExternalRoutingCapability()) {
if (areas[i]->FloodLSA(lsa, intf, neighbor)) {
floodedBackOut = true;
}
}
}
} else {
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
floodedBackOut = areaIt->second->FloodLSA(lsa, intf, neighbor);
}
}
}
return floodedBackOut;
}
| AnsaOSPF::Area * AnsaOSPF::Router::GetArea | ( | AnsaOSPF::AreaID | areaID | ) |
Returns the pointer to the Area identified by the input areaID, if it's on the Area list, NULL otherwise.
| areaID | [in] The Area identifier. |
Definition at line 75 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPFRouting::AnsaLoadConfigFromXML(), AnsaOSPFRouting::LoadHostRoute(), AnsaOSPFRouting::LoadInterfaceParameters(), and AnsaOSPFRouting::LoadVirtualLink().
| AnsaOSPF::Area * AnsaOSPF::Router::GetArea | ( | AnsaOSPF::IPv4Address | address | ) |
| unsigned long AnsaOSPF::Router::GetAreaCount | ( | void | ) | const [inline] |
Definition at line 43 of file AnsaOSPFRouter.h.
{ return areas.size(); }
| bool AnsaOSPF::Router::GetASBoundaryRouter | ( | void | ) | const [inline] |
Definition at line 50 of file AnsaOSPFRouter.h.
{ return (externalRoutes.size() > 0); }
| ASExternalLSA* AnsaOSPF::Router::GetASExternalLSA | ( | unsigned long | i | ) | [inline] |
Definition at line 48 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPF::Neighbor::CreateDatabaseSummary().
{ return asExternalLSAs[i]; }
| const ASExternalLSA* AnsaOSPF::Router::GetASExternalLSA | ( | unsigned long | i | ) | const [inline] |
Definition at line 49 of file AnsaOSPFRouter.h.
{ return asExternalLSAs[i]; }
| unsigned long AnsaOSPF::Router::GetASExternalLSACount | ( | void | ) | const [inline] |
Definition at line 47 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPF::Neighbor::CreateDatabaseSummary().
{ return asExternalLSAs.size(); }
| AnsaOSPF::IPv4AddressRange AnsaOSPF::Router::GetContainingAddressRange | ( | AnsaOSPF::IPv4AddressRange | addressRange, |
| bool * | advertise = NULL |
||
| ) | const |
Scans through the router's areas' preconfigured address ranges and returns the one containing the input addressRange.
| addressRange | [in] The address range to look for. |
| advertise | [out] Whether the advertise flag is set in the returned preconfigured address range. |
Definition at line 1215 of file AnsaOSPFRouter.cc.
{
unsigned long areaCount = areas.size();
for (unsigned long i = 0; i < areaCount; i++) {
AnsaOSPF::IPv4AddressRange containingAddressRange = areas[i]->GetContainingAddressRange(addressRange, advertise);
if (containingAddressRange != AnsaOSPF::NullIPv4AddressRange) {
return containingAddressRange;
}
}
if (advertise != NULL) {
*advertise = false;
}
return AnsaOSPF::NullIPv4AddressRange;
}
| MessageHandler* AnsaOSPF::Router::GetMessageHandler | ( | void | ) | [inline] |
Definition at line 45 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPFRouting::handleMessage(), AnsaOSPF::NeighborStateAttempt::ProcessEvent(), AnsaOSPF::NeighborStateTwoWay::ProcessEvent(), AnsaOSPF::NeighborStateLoading::ProcessEvent(), AnsaOSPF::NeighborStateInit::ProcessEvent(), AnsaOSPF::NeighborStateFull::ProcessEvent(), AnsaOSPF::NeighborStateExchangeStart::ProcessEvent(), AnsaOSPF::NeighborStateExchange::ProcessEvent(), AnsaOSPF::NeighborStateDown::ProcessEvent(), AnsaOSPF::InterfaceStateDown::ProcessEvent(), AnsaOSPF::InterfaceStateWaiting::ProcessEvent(), AnsaOSPF::InterfaceStatePointToPoint::ProcessEvent(), AnsaOSPF::InterfaceStateNotDesignatedRouter::ProcessEvent(), AnsaOSPF::InterfaceStateBackup::ProcessEvent(), and AnsaOSPF::InterfaceStateDesignatedRouter::ProcessEvent().
{ return messageHandler; }
| AnsaOSPF::Interface * AnsaOSPF::Router::GetNonVirtualInterface | ( | unsigned char | ifIndex | ) |
Returns the pointer of the physical Interface identified by the input interface index, NULL if the Router doesn't have such an interface.
| ifIndex | [in] The interface index to look for. |
Definition at line 109 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPFRouting::receiveChangeNotification().
| RoutingTableEntry* AnsaOSPF::Router::GetPreferredEntry | ( | const OSPFLSA & | lsa, |
| bool | skipSelfOriginated, | ||
| std::vector< RoutingTableEntry * > * | fromRoutingTable = NULL |
||
| ) |
| bool AnsaOSPF::Router::GetRFC1583Compatibility | ( | void | ) | const [inline] |
Definition at line 42 of file AnsaOSPFRouter.h.
{ return rfc1583Compatibility; }
| RouterID AnsaOSPF::Router::GetRouterID | ( | void | ) | const [inline] |
Definition at line 40 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPFRouting::AnsaLoadConfigFromXML(), AnsaOSPF::InterfaceState::CalculateDesignatedRouter(), AnsaOSPF::InterfaceState::ChangeState(), AnsaOSPF::NeighborState::ChangeState(), and AnsaOSPFRouting::LoadConfigFromXML().
{ return routerID; }
| std::vector<RoutingTableEntry*> AnsaOSPF::Router::GetRoutesToASBoundaryRouter | ( | const std::vector< RoutingTableEntry * > & | fromRoutingTable, |
| AnsaOSPF::RouterID | routerID | ||
| ) | const [private] |
| RoutingTableEntry* AnsaOSPF::Router::GetRoutingTableEntry | ( | unsigned long | i | ) | [inline] |
Definition at line 53 of file AnsaOSPFRouter.h.
{ return routingTable[i]; }
| const RoutingTableEntry* AnsaOSPF::Router::GetRoutingTableEntry | ( | unsigned long | i | ) | const [inline] |
Definition at line 54 of file AnsaOSPFRouter.h.
{ return routingTable[i]; }
| unsigned long AnsaOSPF::Router::GetRoutingTableEntryCount | ( | void | ) | const [inline] |
Definition at line 52 of file AnsaOSPFRouter.h.
{ return routingTable.size(); }
| AnsaOSPF::LinkStateID AnsaOSPF::Router::GetUniqueLinkStateID | ( | AnsaOSPF::IPv4AddressRange | destination, |
| AnsaOSPF::Metric | destinationCost, | ||
| AnsaOSPF::ASExternalLSA *& | lsaToReoriginate, | ||
| bool | externalMetricIsType2 = false |
||
| ) | const [private] |
Generates a unique LinkStateID for a given destination. This may require the reorigination of an LSA already in the database(with a different LinkStateID).
| destination | [in] The destination for which a unique LinkStateID is required. |
| destinationCost | [in] The path cost to the destination. |
| lsaToReoriginate | [out] The LSA to reoriginate(which was already in the database, and had to be changed). |
| externalMetricIsType2 | [in] True if the destinationCost is given as a Type2 external metric. |
Definition at line 1246 of file AnsaOSPFRouter.cc.
{
if (lsaToReoriginate != NULL) {
delete lsaToReoriginate;
lsaToReoriginate = NULL;
}
AnsaOSPF::LSAKeyType lsaKey;
lsaKey.linkStateID = ULongFromIPv4Address(destination.address);
lsaKey.advertisingRouter = routerID;
const AnsaOSPF::ASExternalLSA* foundLSA = FindASExternalLSA(lsaKey);
if (foundLSA == NULL) {
return lsaKey.linkStateID;
} else {
AnsaOSPF::IPv4Address existingMask = IPv4AddressFromULong(foundLSA->getContents().getNetworkMask().getInt());
if (destination.mask >= existingMask) {
return (lsaKey.linkStateID | (~(ULongFromIPv4Address(destination.mask))));
} else {
AnsaOSPF::ASExternalLSA* asExternalLSA = new AnsaOSPF::ASExternalLSA(*foundLSA);
long sequenceNumber = asExternalLSA->getHeader().getLsSequenceNumber();
asExternalLSA->getHeader().setLsAge(0);
asExternalLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
asExternalLSA->getContents().setNetworkMask(ULongFromIPv4Address(destination.mask));
asExternalLSA->getContents().setE_ExternalMetricType(externalMetricIsType2);
asExternalLSA->getContents().setRouteCost(destinationCost);
asExternalLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum
lsaToReoriginate = asExternalLSA;
return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask))));
}
}
}
| bool AnsaOSPF::Router::HasAddressRange | ( | AnsaOSPF::IPv4AddressRange | addressRange | ) | const |
| bool AnsaOSPF::Router::HasAnyNeighborInStates | ( | int | states | ) | const |
Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input states, false otherwise.
| states | [in] A bitfield combination of NeighborStateType values. |
Definition at line 455 of file AnsaOSPFRouter.cc.
| bool AnsaOSPF::Router::HasRouteToASBoundaryRouter | ( | const std::vector< RoutingTableEntry * > & | inRoutingTable, |
| AnsaOSPF::RouterID | routerID | ||
| ) | const [private] |
| bool AnsaOSPF::Router::InstallASExternalLSA | ( | OSPFASExternalLSA * | lsa | ) | [private] |
Installs a new AS External LSA into the Router's database. It tries to install keep one of multiple functionally equivalent AS External LSAs in the database. (See the comment in the method implementation.)
| lsa | [in] The LSA to install. It will be copied into the database. |
From RFC2328 Section 12.4.4.1.: "If two routers, both reachable from one another, originate functionally equivalent AS-External-LSAs(i.e., same destination, cost and non-zero forwarding address), then the LSA originated by the router having the highest OSPF Router ID is used. The router having the lower OSPF Router ID can then flush its LSA." The problem is: how do we tell whether two routers are reachable from one another based on a Link State Update packet? 0. We can assume that if this LSA reached this router, then this router is reachable from the other router. But what about the other direction? 1. The update packet is most likely not sent by the router originating the functionally equivalent AS-External-LSA, so we cannot use the IP packet source address. 2. The AS-External-LSA contains only the Router ID of the advertising router, so we can only look up "router" type routing entries in the routing table(these contain the Router ID as their Destination ID). However these entries are only inserted into the routing table for intra-area routers...
Definition at line 182 of file AnsaOSPFRouter.cc.
{
// TODO: how to solve this problem?
AnsaOSPF::RouterID advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
bool reachable = false;
unsigned int routeCount = routingTable.size();
for (unsigned int i = 0; i < routeCount; i++) {
if ((((routingTable[i]->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
((routingTable[i]->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
(routingTable[i]->GetDestinationID().getInt() == advertisingRouter))
{
reachable = true;
break;
}
}
bool ownLSAFloodedOut = false;
AnsaOSPF::LSAKeyType lsaKey;
lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
lsaKey.advertisingRouter = routerID;
std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::ASExternalLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
if ((lsaIt != asExternalLSAsByID.end()) &&
reachable &&
(lsaIt->second->getContents().getE_ExternalMetricType() == lsa->getContents().getE_ExternalMetricType()) &&
(lsaIt->second->getContents().getRouteCost() == lsa->getContents().getRouteCost()) &&
(lsa->getContents().getForwardingAddress().getInt() != 0) && // forwarding address != 0.0.0.0
(lsaIt->second->getContents().getForwardingAddress() == lsa->getContents().getForwardingAddress()))
{
if (routerID > advertisingRouter) {
return false;
} else {
lsaIt->second->getHeader().setLsAge(MAX_AGE);
FloodLSA(lsaIt->second, AnsaOSPF::BackboneAreaID);
lsaIt->second->IncrementInstallTime();
ownLSAFloodedOut = true;
}
}
lsaKey.advertisingRouter = advertisingRouter;
lsaIt = asExternalLSAsByID.find(lsaKey);
if (lsaIt != asExternalLSAsByID.end()) {
unsigned long areaCount = areas.size();
for (unsigned long i = 0; i < areaCount; i++) {
areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
}
return ((lsaIt->second->Update(lsa)) | ownLSAFloodedOut);
} else {
AnsaOSPF::ASExternalLSA* lsaCopy = new AnsaOSPF::ASExternalLSA(*lsa);
asExternalLSAsByID[lsaKey] = lsaCopy;
asExternalLSAs.push_back(lsaCopy);
return true;
}
}
| bool AnsaOSPF::Router::InstallLSA | ( | OSPFLSA * | lsa, |
| AnsaOSPF::AreaID | areaID = BackboneAreaID |
||
| ) |
Installs a new LSA into the Router database. Checks the input LSA's type and installs it into either the selected Area's database, or if it's an AS External LSA then into the Router's common asExternalLSAs list.
| lsa | [in] The LSA to install. It will be copied into the database. |
| areaID | [in] Identifies the input Router, Network and Summary LSA's Area. |
Definition at line 130 of file AnsaOSPFRouter.cc.
{
switch (lsa->getHeader().getLsType()) {
case RouterLSAType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
OSPFRouterLSA* ospfRouterLSA = check_and_cast<OSPFRouterLSA*> (lsa);
return areaIt->second->InstallRouterLSA(ospfRouterLSA);
}
}
break;
case NetworkLSAType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
OSPFNetworkLSA* ospfNetworkLSA = check_and_cast<OSPFNetworkLSA*> (lsa);
return areaIt->second->InstallNetworkLSA(ospfNetworkLSA);
}
}
break;
case SummaryLSA_NetworksType:
case SummaryLSA_ASBoundaryRoutersType:
{
std::map<AnsaOSPF::AreaID, AnsaOSPF::Area*>::iterator areaIt = areasByID.find(areaID);
if (areaIt != areasByID.end()) {
OSPFSummaryLSA* ospfSummaryLSA = check_and_cast<OSPFSummaryLSA*> (lsa);
return areaIt->second->InstallSummaryLSA(ospfSummaryLSA);
}
}
break;
case ASExternalLSAType:
{
OSPFASExternalLSA* ospfASExternalLSA = check_and_cast<OSPFASExternalLSA*> (lsa);
return InstallASExternalLSA(ospfASExternalLSA);
}
break;
default:
ASSERT(false);
break;
}
return false;
}
| bool AnsaOSPF::Router::IsDestinationUnreachable | ( | OSPFLSA * | lsa | ) | const |
Returns true if the destination described by the input lsa is in the routing table, false otherwise.
| lsa | [in] The LSA which describes the destination to look for. |
Definition at line 593 of file AnsaOSPFRouter.cc.
{
IPAddress destination = lsa->getHeader().getLinkStateID();
OSPFRouterLSA* routerLSA = dynamic_cast<OSPFRouterLSA*> (lsa);
OSPFNetworkLSA* networkLSA = dynamic_cast<OSPFNetworkLSA*> (lsa);
OSPFSummaryLSA* summaryLSA = dynamic_cast<OSPFSummaryLSA*> (lsa);
OSPFASExternalLSA* asExternalLSA = dynamic_cast<OSPFASExternalLSA*> (lsa);
// TODO: verify
if (routerLSA != NULL) {
AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (routerLSA);
if (routerLSA->getHeader().getLinkStateID() == routerID) { // this is spfTreeRoot
return false;
}
// get the interface address pointing backwards on the shortest path tree
unsigned int linkCount = routerLSA->getLinksArraySize();
AnsaOSPF::RouterLSA* toRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (routingInfo->GetParent());
if (toRouterLSA != NULL) {
bool destinationFound = false;
bool unnumberedPointToPointLink = false;
IPAddress firstNumberedIfAddress;
for (unsigned int i = 0; i < linkCount; i++) {
Link& link = routerLSA->getLinks(i);
if (link.getType() == PointToPointLink) {
if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
if ((link.getLinkData() & 0xFF000000) == 0) {
unnumberedPointToPointLink = true;
if (!firstNumberedIfAddress.isUnspecified()) {
break;
}
} else {
destination = link.getLinkData();
destinationFound = true;
break;
}
} else {
if (((link.getLinkData() & 0xFF000000) != 0) &&
firstNumberedIfAddress.isUnspecified())
{
firstNumberedIfAddress = link.getLinkData();
}
}
} else if (link.getType() == TransitLink) {
if (firstNumberedIfAddress.isUnspecified()) {
firstNumberedIfAddress = link.getLinkData();
}
} else if (link.getType() == VirtualLink) {
if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
destination = link.getLinkData();
destinationFound = true;
break;
} else {
if (firstNumberedIfAddress.isUnspecified()) {
firstNumberedIfAddress = link.getLinkData();
}
}
}
// There's no way to get an interface address for the router from a StubLink
}
if (unnumberedPointToPointLink) {
if (!firstNumberedIfAddress.isUnspecified()) {
destination = firstNumberedIfAddress;
} else {
return true;
}
}
if (!destinationFound) {
return true;
}
} else {
AnsaOSPF::NetworkLSA* toNetworkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (routingInfo->GetParent());
if (toNetworkLSA != NULL) {
// get the interface address pointing backwards on the shortest path tree
bool destinationFound = false;
for (unsigned int i = 0; i < linkCount; i++) {
Link& link = routerLSA->getLinks(i);
if ((link.getType() == TransitLink) &&
(link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()))
{
destination = link.getLinkData();
destinationFound = true;
break;
}
}
if (!destinationFound) {
return true;
}
} else {
return true;
}
}
}
if (networkLSA != NULL) {
destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask().getInt();
}
if ((summaryLSA != NULL) && (summaryLSA->getHeader().getLsType() == SummaryLSA_NetworksType)) {
destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask().getInt();
}
if (asExternalLSA != NULL) {
destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask().getInt();
}
if (Lookup(destination) == NULL) {
return true;
} else {
return false;
}
}
| bool AnsaOSPF::Router::IsLocalAddress | ( | AnsaOSPF::IPv4Address | address | ) | const |
| bool AnsaOSPF::Router::IsOnAnyRetransmissionList | ( | AnsaOSPF::LSAKeyType | lsaKey | ) | const |
Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the input lsaKey, false otherwise.
| lsaKey | [in] Identifies the LSAs to look for on the retransmission lists. |
Definition at line 486 of file AnsaOSPFRouter.cc.
| RoutingTableEntry* AnsaOSPF::Router::Lookup | ( | IPAddress | destination, |
| std::vector< RoutingTableEntry * > * | table = NULL |
||
| ) | const |
| void AnsaOSPF::Router::NotifyAboutRoutingTableChanges | ( | std::vector< RoutingTableEntry * > & | oldRoutingTable | ) | [private] |
| AnsaOSPF::ASExternalLSA * AnsaOSPF::Router::OriginateASExternalLSA | ( | AnsaOSPF::ASExternalLSA * | lsa | ) | [private] |
Originates a new AS External LSA based on the input lsa.
| lsa | [in] The LSA whose contents should be copied into the newly originated LSA. |
Definition at line 572 of file AnsaOSPFRouter.cc.
{
AnsaOSPF::ASExternalLSA* asExternalLSA = new AnsaOSPF::ASExternalLSA(*lsa);
OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
OSPFOptions lsaOptions;
lsaHeader.setLsAge(0);
memset(&lsaOptions, 0, sizeof(OSPFOptions));
lsaOptions.E_ExternalRoutingCapability = true;
lsaHeader.setLsOptions(lsaOptions);
lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
asExternalLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated);
return asExternalLSA;
}
| void AnsaOSPF::Router::PruneASBoundaryRouterEntries | ( | std::vector< RoutingTableEntry * > & | asbrEntries | ) | const [private] |
| void AnsaOSPF::Router::RebuildRoutingTable | ( | void | ) |
Rebuilds the routing table from scratch(based on the LSA database).
Definition at line 804 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPF::InterfaceState::ChangeState(), and AnsaOSPF::NeighborState::ChangeState().
{
unsigned long areaCount = areas.size();
bool hasTransitAreas = false;
std::vector<AnsaOSPF::RoutingTableEntry*> newTable;
unsigned long i;
EV << "Rebuilding routing table:\n";
for (i = 0; i < areaCount; i++) {
areas[i]->CalculateShortestPathTree(newTable);
if (areas[i]->GetTransitCapability()) {
hasTransitAreas = true;
}
}
if (areaCount > 1) {
AnsaOSPF::Area* backbone = GetArea(AnsaOSPF::BackboneAreaID);
if (backbone != NULL) {
backbone->CalculateInterAreaRoutes(newTable);
}
} else {
if (areaCount == 1) {
areas[0]->CalculateInterAreaRoutes(newTable);
}
}
if (hasTransitAreas) {
for (i = 0; i < areaCount; i++) {
if (areas[i]->GetTransitCapability()) {
areas[i]->ReCheckSummaryLSAs(newTable);
}
}
}
CalculateASExternalRoutes(newTable);
// backup the routing table
unsigned long routeCount = routingTable.size();
std::vector<AnsaOSPF::RoutingTableEntry*> oldTable;
oldTable.assign(routingTable.begin(), routingTable.end());
routingTable.clear();
routingTable.assign(newTable.begin(), newTable.end());
RoutingTableAccess routingTableAccess;
std::vector<const IPRoute*> eraseEntries;
IRoutingTable* simRoutingTable = routingTableAccess.get();
unsigned long routingEntryNumber = simRoutingTable->getNumRoutes();
// remove entries from the IP routing table inserted by the OSPF module
for (i = 0; i < routingEntryNumber; i++) {
const IPRoute *entry = simRoutingTable->getRoute(i);
const AnsaOSPF::RoutingTableEntry* ospfEntry = dynamic_cast<const AnsaOSPF::RoutingTableEntry*>(entry);
if (ospfEntry != NULL) {
eraseEntries.push_back(entry);
}
}
unsigned int eraseCount = eraseEntries.size();
for (i = 0; i < eraseCount; i++) {
simRoutingTable->deleteRoute(eraseEntries[i]);
}
// add the new routing entries
routeCount = routingTable.size();
for (i = 0; i < routeCount; i++) {
if (routingTable[i]->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) {
simRoutingTable->addRoute(new AnsaOSPF::RoutingTableEntry(*(routingTable[i])));
}
}
NotifyAboutRoutingTableChanges(oldTable);
routeCount = oldTable.size();
for (i = 0; i < routeCount; i++) {
delete(oldTable[i]);
}
EV << "Routing table was rebuilt.\n"
<< "Results:\n";
routeCount = routingTable.size();
for (i = 0; i < routeCount; i++) {
EV << *routingTable[i]
<< "\n";
}
}
| void AnsaOSPF::Router::RemoveExternalRoute | ( | AnsaOSPF::IPv4Address | networkAddress | ) |
Removes an AS External Route from the database.
| networkAddress | [in] The network address of the external route which needs to be removed. |
Definition at line 1581 of file AnsaOSPFRouter.cc.
{
AnsaOSPF::LSAKeyType lsaKey;
lsaKey.linkStateID = ULongFromIPv4Address(networkAddress);
lsaKey.advertisingRouter = routerID;
std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::ASExternalLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
if (lsaIt != asExternalLSAsByID.end()) {
lsaIt->second->getHeader().setLsAge(MAX_AGE);
lsaIt->second->SetPurgeable();
FloodLSA(lsaIt->second, AnsaOSPF::BackboneAreaID);
}
std::map<AnsaOSPF::IPv4Address, OSPFASExternalLSAContents, AnsaOSPF::IPv4Address_Less>::iterator externalIt = externalRoutes.find(networkAddress);
if (externalIt != externalRoutes.end()) {
externalRoutes.erase(externalIt);
}
}
Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey.
| lsaKey | [in] Identifies the LSAs to remove from the retransmission lists. |
Definition at line 472 of file AnsaOSPFRouter.cc.
| RoutingTableEntry* AnsaOSPF::Router::SelectLeastCostRoutingEntry | ( | std::vector< RoutingTableEntry * > & | entries | ) | const [private] |
| void AnsaOSPF::Router::SetRFC1583Compatibility | ( | bool | compatibility | ) | [inline] |
Definition at line 41 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPFRouting::AnsaLoadConfigFromXML(), and AnsaOSPFRouting::LoadConfigFromXML().
{ rfc1583Compatibility = compatibility; }
| void AnsaOSPF::Router::SetRouterID | ( | RouterID | id | ) | [inline] |
Definition at line 39 of file AnsaOSPFRouter.h.
{ routerID = id; }
| void AnsaOSPF::Router::UpdateExternalRoute | ( | AnsaOSPF::IPv4Address | networkAddress, |
| const OSPFASExternalLSAContents & | externalRouteContents, | ||
| int | ifIndex | ||
| ) |
Stores information on an AS External Route in externalRoutes and intalls(or updates) a new ASExternalLSA into the database.
| networkAddress | [in] The external route's network address. |
| externalRouteContents | [in] Route configuration data for the external route. |
| ifIndex | [in] |
Definition at line 1519 of file AnsaOSPFRouter.cc.
Referenced by AnsaOSPFRouting::LoadExternalRoute().
{
AnsaOSPF::ASExternalLSA* asExternalLSA = new AnsaOSPF::ASExternalLSA;
OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
OSPFOptions lsaOptions;
//AnsaOSPF::LSAKeyType lsaKey;
IRoutingTable* simRoutingTable = RoutingTableAccess().get();
unsigned long routingEntryNumber = simRoutingTable->getNumRoutes();
bool inRoutingTable = false;
// add the external route to the routing table if it was not added by another module
for (unsigned long i = 0; i < routingEntryNumber; i++) {
const IPRoute *entry = simRoutingTable->getRoute(i);
if ((entry->getHost().getInt() & entry->getNetmask().getInt()) ==
(ULongFromIPv4Address(networkAddress) & externalRouteContents.getNetworkMask().getInt()))
{
inRoutingTable = true;
}
}
if (!inRoutingTable) {
IPRoute* entry = new IPRoute;
entry->setHost(ULongFromIPv4Address(networkAddress));
entry->setNetmask(externalRouteContents.getNetworkMask());
entry->setInterface(InterfaceTableAccess().get()->getInterfaceById(ifIndex));
entry->setType(IPRoute::REMOTE);
entry->setSource(IPRoute::MANUAL);
entry->setMetric(externalRouteContents.getRouteCost());
simRoutingTable->addRoute(entry); // IRoutingTable deletes entry pointer
}
lsaHeader.setLsAge(0);
memset(&lsaOptions, 0, sizeof(OSPFOptions));
lsaOptions.E_ExternalRoutingCapability = true;
lsaHeader.setLsOptions(lsaOptions);
lsaHeader.setLsType(ASExternalLSAType);
lsaHeader.setLinkStateID(ULongFromIPv4Address(networkAddress)); // TODO: get unique LinkStateID
lsaHeader.setAdvertisingRouter(routerID);
lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
asExternalLSA->setContents(externalRouteContents);
lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum
asExternalLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated);
externalRoutes[networkAddress] = externalRouteContents;
bool rebuild = InstallASExternalLSA(asExternalLSA);
FloodLSA(asExternalLSA, AnsaOSPF::BackboneAreaID);
delete asExternalLSA;
if (rebuild) {
RebuildRoutingTable();
}
}
OSPFTimer* AnsaOSPF::Router::ageTimer [private] |
Database age timer - fires every second.
Definition at line 30 of file AnsaOSPFRouter.h.
Referenced by Router().
std::vector<Area*> AnsaOSPF::Router::areas [private] |
A list of the contained areas.
Definition at line 26 of file AnsaOSPFRouter.h.
Referenced by GetAreaCount().
std::map<AreaID, Area*> AnsaOSPF::Router::areasByID [private] |
A map of the contained areas with the AreaID as key.
Definition at line 25 of file AnsaOSPFRouter.h.
std::vector<ASExternalLSA*> AnsaOSPF::Router::asExternalLSAs [private] |
A list of the ASExternalLSAs advertised by this router.
Definition at line 28 of file AnsaOSPFRouter.h.
Referenced by GetASExternalLSA(), and GetASExternalLSACount().
std::map<LSAKeyType, ASExternalLSA*, LSAKeyType_Less> AnsaOSPF::Router::asExternalLSAsByID [private] |
A map of the ASExternalLSAs advertised by this router.
Definition at line 27 of file AnsaOSPFRouter.h.
std::map<IPv4Address, OSPFASExternalLSAContents, IPv4Address_Less> AnsaOSPF::Router::externalRoutes [private] |
A map of the external route advertised by this router.
Definition at line 29 of file AnsaOSPFRouter.h.
Referenced by GetASBoundaryRouter().
MessageHandler* AnsaOSPF::Router::messageHandler [private] |
The message dispatcher class.
Definition at line 32 of file AnsaOSPFRouter.h.
Referenced by GetMessageHandler(), and Router().
bool AnsaOSPF::Router::rfc1583Compatibility [private] |
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not.
Definition at line 33 of file AnsaOSPFRouter.h.
Referenced by GetRFC1583Compatibility(), and SetRFC1583Compatibility().
RouterID AnsaOSPF::Router::routerID [private] |
The router ID assigned by the IP layer.
Definition at line 24 of file AnsaOSPFRouter.h.
Referenced by GetRouterID(), and SetRouterID().
std::vector<RoutingTableEntry*> AnsaOSPF::Router::routingTable [private] |
The OSPF routing table - contains more information than the one in the IP layer.
Definition at line 31 of file AnsaOSPFRouter.h.
Referenced by AddRoutingTableEntry(), GetRoutingTableEntry(), and GetRoutingTableEntryCount().
Definition at line 81 of file AnsaOSPFRouter.h.
Referenced by AnsaOSPFRouting::finish().