#include <OSPFInterfaceState.h>
Public Member Functions | |
| virtual | ~InterfaceState () |
| virtual void | ProcessEvent (Interface *intf, Interface::InterfaceEventType event)=0 |
| virtual Interface::InterfaceStateType | GetState (void) const =0 |
Protected Member Functions | |
| void | ChangeState (Interface *intf, InterfaceState *newState, InterfaceState *currentState) |
| void | CalculateDesignatedRouter (Interface *intf) |
Definition at line 25 of file OSPFInterfaceState.h.
| virtual OSPF::InterfaceState::~InterfaceState | ( | ) | [inline, virtual] |
Definition at line 31 of file OSPFInterfaceState.h.
{}
| void OSPF::InterfaceState::CalculateDesignatedRouter | ( | OSPF::Interface * | intf | ) | [protected] |
Definition at line 114 of file OSPFInterfaceState.cc.
Referenced by OSPF::InterfaceStateWaiting::ProcessEvent(), OSPF::InterfaceStateNotDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateDesignatedRouter::ProcessEvent(), and OSPF::InterfaceStateBackup::ProcessEvent().
{
OSPF::RouterID routerID = intf->parentArea->GetRouter()->GetRouterID();
OSPF::DesignatedRouterID currentDesignatedRouter = intf->designatedRouter;
OSPF::DesignatedRouterID currentBackupRouter = intf->backupDesignatedRouter;
unsigned int neighborCount = intf->neighboringRouters.size();
unsigned char repeatCount = 0;
unsigned int i;
OSPF::DesignatedRouterID declaredBackup;
unsigned char declaredBackupPriority;
OSPF::RouterID declaredBackupID;
bool backupDeclared;
OSPF::DesignatedRouterID declaredDesignatedRouter;
unsigned char declaredDesignatedRouterPriority;
OSPF::RouterID declaredDesignatedRouterID;
bool designatedRouterDeclared;
do {
// calculating backup designated router
declaredBackup = OSPF::NullDesignatedRouterID;
declaredBackupPriority = 0;
declaredBackupID = OSPF::NullRouterID;
backupDeclared = false;
OSPF::DesignatedRouterID highestRouter = OSPF::NullDesignatedRouterID;
unsigned char highestPriority = 0;
OSPF::RouterID highestID = OSPF::NullRouterID;
for (i = 0; i < neighborCount; i++) {
OSPF::Neighbor* neighbor = intf->neighboringRouters[i];
unsigned char neighborPriority = neighbor->GetPriority();
if (neighbor->GetState() < OSPF::Neighbor::TwoWayState) {
continue;
}
if (neighborPriority == 0) {
continue;
}
OSPF::RouterID neighborID = neighbor->GetNeighborID();
OSPF::DesignatedRouterID neighborsDesignatedRouter = neighbor->GetDesignatedRouter();
OSPF::DesignatedRouterID neighborsBackupDesignatedRouter = neighbor->GetBackupDesignatedRouter();
if (neighborsDesignatedRouter.routerID != neighborID) {
if (neighborsBackupDesignatedRouter.routerID == neighborID) {
if ((neighborPriority > declaredBackupPriority) ||
((neighborPriority == declaredBackupPriority) &&
(neighborID > declaredBackupID)))
{
declaredBackup = neighborsBackupDesignatedRouter;
declaredBackupPriority = neighborPriority;
declaredBackupID = neighborID;
backupDeclared = true;
}
}
if (!backupDeclared) {
if ((neighborPriority > highestPriority) ||
((neighborPriority == highestPriority) &&
(neighborID > highestID)))
{
highestRouter.routerID = neighborID;
highestRouter.ipInterfaceAddress = neighbor->GetAddress();
highestPriority = neighborPriority;
highestID = neighborID;
}
}
}
}
// also include the router itself in the calculations
if (intf->routerPriority > 0) {
if (currentDesignatedRouter.routerID != routerID) {
if (currentBackupRouter.routerID == routerID) {
if ((intf->routerPriority > declaredBackupPriority) ||
((intf->routerPriority == declaredBackupPriority) &&
(routerID > declaredBackupID)))
{
declaredBackup.routerID = routerID;
declaredBackup.ipInterfaceAddress = intf->interfaceAddressRange.address;
declaredBackupPriority = intf->routerPriority;
declaredBackupID = routerID;
backupDeclared = true;
}
}
if (!backupDeclared) {
if ((intf->routerPriority > highestPriority) ||
((intf->routerPriority == highestPriority) &&
(routerID > highestID)))
{
declaredBackup.routerID = routerID;
declaredBackup.ipInterfaceAddress = intf->interfaceAddressRange.address;
declaredBackupPriority = intf->routerPriority;
declaredBackupID = routerID;
backupDeclared = true;
} else {
declaredBackup = highestRouter;
declaredBackupPriority = highestPriority;
declaredBackupID = highestID;
backupDeclared = true;
}
}
}
}
// calculating backup designated router
declaredDesignatedRouter = OSPF::NullDesignatedRouterID;
declaredDesignatedRouterPriority = 0;
declaredDesignatedRouterID = OSPF::NullRouterID;
designatedRouterDeclared = false;
for (i = 0; i < neighborCount; i++) {
OSPF::Neighbor* neighbor = intf->neighboringRouters[i];
unsigned char neighborPriority = neighbor->GetPriority();
if (neighbor->GetState() < OSPF::Neighbor::TwoWayState) {
continue;
}
if (neighborPriority == 0) {
continue;
}
OSPF::RouterID neighborID = neighbor->GetNeighborID();
OSPF::DesignatedRouterID neighborsDesignatedRouter = neighbor->GetDesignatedRouter();
OSPF::DesignatedRouterID neighborsBackupDesignatedRouter = neighbor->GetBackupDesignatedRouter();
if (neighborsDesignatedRouter.routerID == neighborID) {
if ((neighborPriority > declaredDesignatedRouterPriority) ||
((neighborPriority == declaredDesignatedRouterPriority) &&
(neighborID > declaredDesignatedRouterID)))
{
declaredDesignatedRouter = neighborsDesignatedRouter;
declaredDesignatedRouterPriority = neighborPriority;
declaredDesignatedRouterID = neighborID;
designatedRouterDeclared = true;
}
}
}
// also include the router itself in the calculations
if (intf->routerPriority > 0) {
if (currentDesignatedRouter.routerID == routerID) {
if ((intf->routerPriority > declaredDesignatedRouterPriority) ||
((intf->routerPriority == declaredDesignatedRouterPriority) &&
(routerID > declaredDesignatedRouterID)))
{
declaredDesignatedRouter.routerID = routerID;
declaredDesignatedRouter.ipInterfaceAddress = intf->interfaceAddressRange.address;
declaredDesignatedRouterPriority = intf->routerPriority;
declaredDesignatedRouterID = routerID;
designatedRouterDeclared = true;
}
}
}
if (!designatedRouterDeclared) {
declaredDesignatedRouter = declaredBackup;
declaredDesignatedRouterPriority = declaredBackupPriority;
declaredDesignatedRouterID = declaredBackupID;
designatedRouterDeclared = true;
}
// if the router is any kind of DR or is no longer one of them, then repeat
//FIXME suggest parentheses around && within ||
if (
(
(declaredDesignatedRouter.routerID != OSPF::NullRouterID) &&
(
(currentDesignatedRouter.routerID == routerID) &&
(declaredDesignatedRouter.routerID != routerID)
) ||
(
(currentDesignatedRouter.routerID != routerID) &&
(declaredDesignatedRouter.routerID == routerID)
)
) ||
(
(declaredBackup.routerID != OSPF::NullRouterID) &&
(
(currentBackupRouter.routerID == routerID) &&
(declaredBackup.routerID != routerID)
) ||
(
(currentBackupRouter.routerID != routerID) &&
(declaredBackup.routerID == routerID)
)
)
)
{
currentDesignatedRouter = declaredDesignatedRouter;
currentBackupRouter = declaredBackup;
repeatCount++;
} else {
repeatCount += 2;
}
} while (repeatCount < 2);
OSPF::RouterID routersOldDesignatedRouterID = intf->designatedRouter.routerID;
OSPF::RouterID routersOldBackupID = intf->backupDesignatedRouter.routerID;
intf->designatedRouter = declaredDesignatedRouter;
intf->backupDesignatedRouter = declaredBackup;
bool wasBackupDesignatedRouter = (routersOldBackupID == routerID);
bool wasDesignatedRouter = (routersOldDesignatedRouterID == routerID);
bool wasOther = (intf->GetState() == OSPF::Interface::NotDesignatedRouterState);
bool wasWaiting = (!wasBackupDesignatedRouter && !wasDesignatedRouter && !wasOther);
bool isBackupDesignatedRouter = (declaredBackup.routerID == routerID);
bool isDesignatedRouter = (declaredDesignatedRouter.routerID == routerID);
bool isOther = (!isBackupDesignatedRouter && !isDesignatedRouter);
if (wasBackupDesignatedRouter) {
if (isDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateDesignatedRouter, this);
}
if (isOther) {
ChangeState(intf, new OSPF::InterfaceStateNotDesignatedRouter, this);
}
}
if (wasDesignatedRouter) {
if (isBackupDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateBackup, this);
}
if (isOther) {
ChangeState(intf, new OSPF::InterfaceStateNotDesignatedRouter, this);
}
}
if (wasOther) {
if (isDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateDesignatedRouter, this);
}
if (isBackupDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateBackup, this);
}
}
if (wasWaiting) {
if (isDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateDesignatedRouter, this);
}
if (isBackupDesignatedRouter) {
ChangeState(intf, new OSPF::InterfaceStateBackup, this);
}
if (isOther) {
ChangeState(intf, new OSPF::InterfaceStateNotDesignatedRouter, this);
}
}
for (i = 0; i < neighborCount; i++) {
if ((intf->interfaceType == OSPF::Interface::NBMA) &&
((!wasBackupDesignatedRouter && isBackupDesignatedRouter) ||
(!wasDesignatedRouter && isDesignatedRouter)))
{
if (intf->neighboringRouters[i]->GetPriority() == 0) {
intf->neighboringRouters[i]->ProcessEvent(OSPF::Neighbor::Start);
}
}
if ((declaredDesignatedRouter.routerID != routersOldDesignatedRouterID) ||
(declaredBackup.routerID != routersOldBackupID))
{
if (intf->neighboringRouters[i]->GetState() >= OSPF::Neighbor::TwoWayState) {
intf->neighboringRouters[i]->ProcessEvent(OSPF::Neighbor::IsAdjacencyOK);
}
}
}
}
| void OSPF::InterfaceState::ChangeState | ( | OSPF::Interface * | intf, | |
| OSPF::InterfaceState * | newState, | |||
| OSPF::InterfaceState * | currentState | |||
| ) | [protected] |
Definition at line 27 of file OSPFInterfaceState.cc.
Referenced by CalculateDesignatedRouter(), OSPF::InterfaceStateWaiting::ProcessEvent(), OSPF::InterfaceStatePointToPoint::ProcessEvent(), OSPF::InterfaceStateNotDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateLoopback::ProcessEvent(), OSPF::InterfaceStateDown::ProcessEvent(), OSPF::InterfaceStateDesignatedRouter::ProcessEvent(), and OSPF::InterfaceStateBackup::ProcessEvent().
{
OSPF::Interface::InterfaceStateType oldState = currentState->GetState();
OSPF::Interface::InterfaceStateType nextState = newState->GetState();
OSPF::Interface::OSPFInterfaceType intfType = intf->GetType();
bool rebuildRoutingTable = false;
intf->ChangeState(newState, currentState);
if ((oldState == OSPF::Interface::DownState) ||
(nextState == OSPF::Interface::DownState) ||
(oldState == OSPF::Interface::LoopbackState) ||
(nextState == OSPF::Interface::LoopbackState) ||
(oldState == OSPF::Interface::DesignatedRouterState) ||
(nextState == OSPF::Interface::DesignatedRouterState) ||
((intfType == OSPF::Interface::PointToPoint) &&
((oldState == OSPF::Interface::PointToPointState) ||
(nextState == OSPF::Interface::PointToPointState))) ||
(((intfType == OSPF::Interface::Broadcast) ||
(intfType == OSPF::Interface::NBMA)) &&
((oldState == OSPF::Interface::WaitingState) ||
(nextState == OSPF::Interface::WaitingState))))
{
OSPF::RouterLSA* routerLSA = intf->GetArea()->FindRouterLSA(intf->GetArea()->GetRouter()->GetRouterID());
if (routerLSA != NULL) {
long sequenceNumber = routerLSA->getHeader().getLsSequenceNumber();
if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
routerLSA->getHeader().setLsAge(MAX_AGE);
intf->GetArea()->FloodLSA(routerLSA);
routerLSA->IncrementInstallTime();
} else {
OSPF::RouterLSA* newLSA = intf->GetArea()->OriginateRouterLSA();
newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum
rebuildRoutingTable |= routerLSA->Update(newLSA);
delete newLSA;
intf->GetArea()->FloodLSA(routerLSA);
}
} else { // (lsa == NULL) -> This must be the first time any interface is up...
OSPF::RouterLSA* newLSA = intf->GetArea()->OriginateRouterLSA();
rebuildRoutingTable |= intf->GetArea()->InstallRouterLSA(newLSA);
routerLSA = intf->GetArea()->FindRouterLSA(intf->GetArea()->GetRouter()->GetRouterID());
intf->GetArea()->SetSPFTreeRoot(routerLSA);
intf->GetArea()->FloodLSA(newLSA);
delete newLSA;
}
}
if (nextState == OSPF::Interface::DesignatedRouterState) {
OSPF::NetworkLSA* newLSA = intf->GetArea()->OriginateNetworkLSA(intf);
if (newLSA != NULL) {
rebuildRoutingTable |= intf->GetArea()->InstallNetworkLSA(newLSA);
intf->GetArea()->FloodLSA(newLSA);
delete newLSA;
} else { // no neighbors on the network -> old NetworkLSA must be flushed
OSPF::NetworkLSA* oldLSA = intf->GetArea()->FindNetworkLSA(ULongFromIPv4Address(intf->GetAddressRange().address));
if (oldLSA != NULL) {
oldLSA->getHeader().setLsAge(MAX_AGE);
intf->GetArea()->FloodLSA(oldLSA);
oldLSA->IncrementInstallTime();
}
}
}
if (oldState == OSPF::Interface::DesignatedRouterState) {
OSPF::NetworkLSA* networkLSA = intf->GetArea()->FindNetworkLSA(ULongFromIPv4Address(intf->GetAddressRange().address));
if (networkLSA != NULL) {
networkLSA->getHeader().setLsAge(MAX_AGE);
intf->GetArea()->FloodLSA(networkLSA);
networkLSA->IncrementInstallTime();
}
}
if (rebuildRoutingTable) {
intf->GetArea()->GetRouter()->RebuildRoutingTable();
}
}
| virtual Interface::InterfaceStateType OSPF::InterfaceState::GetState | ( | void | ) | const [pure virtual] |
Implemented in OSPF::InterfaceStateBackup, OSPF::InterfaceStateDesignatedRouter, OSPF::InterfaceStateDown, OSPF::InterfaceStateLoopback, OSPF::InterfaceStateNotDesignatedRouter, OSPF::InterfaceStatePointToPoint, and OSPF::InterfaceStateWaiting.
Referenced by ChangeState(), and OSPF::Interface::GetState().
| virtual void OSPF::InterfaceState::ProcessEvent | ( | Interface * | intf, | |
| Interface::InterfaceEventType | event | |||
| ) | [pure virtual] |
1.7.1