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 }