OSPFNeighborState.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Andras Babos and Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include "OSPFNeighborState.h"
00019 #include "OSPFInterface.h"
00020 #include "OSPFArea.h"
00021 #include "OSPFRouter.h"
00022 
00023 void OSPF::NeighborState::ChangeState(OSPF::Neighbor* neighbor, OSPF::NeighborState* newState, OSPF::NeighborState* currentState)
00024 {
00025 
00026     OSPF::Neighbor::NeighborStateType   oldState            = currentState->GetState();
00027     OSPF::Neighbor::NeighborStateType   nextState           = newState->GetState();
00028     bool                                rebuildRoutingTable = false;
00029 
00030     neighbor->ChangeState(newState, currentState);
00031 
00032     if ((oldState == OSPF::Neighbor::FullState) || (nextState == OSPF::Neighbor::FullState)) {
00033         OSPF::RouterID   routerID  = neighbor->GetInterface()->GetArea()->GetRouter()->GetRouterID();
00034         OSPF::RouterLSA* routerLSA = neighbor->GetInterface()->GetArea()->FindRouterLSA(routerID);
00035 
00036         if (routerLSA != NULL) {
00037             long sequenceNumber = routerLSA->getHeader().getLsSequenceNumber();
00038             if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00039                 routerLSA->getHeader().setLsAge(MAX_AGE);
00040                 neighbor->GetInterface()->GetArea()->FloodLSA(routerLSA);
00041                 routerLSA->IncrementInstallTime();
00042             } else {
00043                 OSPF::RouterLSA* newLSA = neighbor->GetInterface()->GetArea()->OriginateRouterLSA();
00044 
00045                 newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
00046                 newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
00047                 rebuildRoutingTable |= routerLSA->Update(newLSA);
00048                 delete newLSA;
00049 
00050                 neighbor->GetInterface()->GetArea()->FloodLSA(routerLSA);
00051             }
00052         }
00053 
00054         if (neighbor->GetInterface()->GetState() == OSPF::Interface::DesignatedRouterState) {
00055             OSPF::NetworkLSA* networkLSA = neighbor->GetInterface()->GetArea()->FindNetworkLSA(ULongFromIPv4Address(neighbor->GetInterface()->GetAddressRange().address));
00056 
00057             if (networkLSA != NULL) {
00058                 long sequenceNumber = networkLSA->getHeader().getLsSequenceNumber();
00059                 if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00060                     networkLSA->getHeader().setLsAge(MAX_AGE);
00061                     neighbor->GetInterface()->GetArea()->FloodLSA(networkLSA);
00062                     networkLSA->IncrementInstallTime();
00063                 } else {
00064                     OSPF::NetworkLSA* newLSA = neighbor->GetInterface()->GetArea()->OriginateNetworkLSA(neighbor->GetInterface());
00065 
00066                     if (newLSA != NULL) {
00067                         newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
00068                         newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
00069                         rebuildRoutingTable |= networkLSA->Update(newLSA);
00070                         delete newLSA;
00071                     } else {    // no neighbors on the network -> old NetworkLSA must be flushed
00072                         networkLSA->getHeader().setLsAge(MAX_AGE);
00073                         networkLSA->IncrementInstallTime();
00074                     }
00075 
00076                     neighbor->GetInterface()->GetArea()->FloodLSA(networkLSA);
00077                 }
00078             }
00079         }
00080     }
00081 
00082     if (rebuildRoutingTable) {
00083         neighbor->GetInterface()->GetArea()->GetRouter()->RebuildRoutingTable();
00084     }
00085 }