| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.isis.controller.impl.lsdb; |
| |
| import org.onosproject.isis.controller.IsisInterface; |
| import org.onosproject.isis.controller.IsisLsdb; |
| import org.onosproject.isis.controller.IsisLsdbAge; |
| import org.onosproject.isis.controller.IsisLspBin; |
| import org.onosproject.isis.controller.IsisMessage; |
| import org.onosproject.isis.controller.IsisPduType; |
| import org.onosproject.isis.controller.LspWrapper; |
| import org.onosproject.isis.io.isispacket.pdu.LsPdu; |
| import org.onosproject.isis.io.util.IsisConstants; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| /** |
| * Representation of ISIS link state database. |
| */ |
| public class DefaultIsisLsdb implements IsisLsdb { |
| private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdb.class); |
| private Map<String, LspWrapper> isisL1Db = new ConcurrentHashMap<>(); |
| private Map<String, LspWrapper> isisL2Db = new ConcurrentHashMap<>(); |
| private IsisLsdbAge lsdbAge = null; |
| private int l1LspSeqNo = IsisConstants.STARTLSSEQUENCENUM; |
| private int l2LspSeqNo = IsisConstants.STARTLSSEQUENCENUM; |
| |
| /** |
| * Creates an instance of ISIS LSDB. |
| */ |
| public DefaultIsisLsdb() { |
| lsdbAge = new DefaultIsisLsdbAge(); |
| } |
| |
| /** |
| * Initializes the link state database. |
| */ |
| public void initializeDb() { |
| lsdbAge.startDbAging(); |
| } |
| |
| /** |
| * Returns the LSDB LSP key. |
| * |
| * @param systemId system ID |
| * @return key |
| */ |
| public String lspKey(String systemId) { |
| StringBuilder lspKey = new StringBuilder(); |
| lspKey.append(systemId); |
| lspKey.append(".00"); |
| lspKey.append("-"); |
| lspKey.append("00"); |
| |
| return lspKey.toString(); |
| } |
| |
| /** |
| * Returns the neighbor L1 database information. |
| * |
| * @return neighbor L1 database information |
| */ |
| public Map<String, LspWrapper> getL1Db() { |
| return isisL1Db; |
| } |
| |
| /** |
| * Returns the neighbor L2 database information. |
| * |
| * @return neighbor L2 database information |
| */ |
| public Map<String, LspWrapper> getL2Db() { |
| return isisL2Db; |
| } |
| |
| /** |
| * Returns the LSDB instance. |
| * |
| * @return LSDB instance |
| */ |
| public IsisLsdb isisLsdb() { |
| return this; |
| } |
| |
| /** |
| * Returns all LSPs (L1 and L2). |
| * |
| * @param excludeMaxAgeLsp exclude the max age LSPs |
| * @return List of LSPs |
| */ |
| public List<LspWrapper> allLspHeaders(boolean excludeMaxAgeLsp) { |
| List<LspWrapper> summaryList = new CopyOnWriteArrayList(); |
| addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL1Db); |
| addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL2Db); |
| |
| return summaryList; |
| } |
| |
| /** |
| * Adds the LSPs to summary list. |
| * |
| * @param summaryList summary list |
| * @param excludeMaxAgeLsp exclude max age LSP |
| * @param lspMap map of LSP |
| */ |
| private void addLspToHeaderList(List summaryList, boolean excludeMaxAgeLsp, Map lspMap) { |
| Iterator slotVals = lspMap.values().iterator(); |
| while (slotVals.hasNext()) { |
| LspWrapper wrapper = (LspWrapper) slotVals.next(); |
| if (excludeMaxAgeLsp) { |
| //if current age of lsa is max age or lsa present in Max Age bin |
| if (wrapper.remainingLifetime() != 0) { |
| addToList(wrapper, summaryList); |
| } |
| } else { |
| addToList(wrapper, summaryList); |
| } |
| } |
| } |
| |
| /** |
| * Adds the LSPWrapper to summary list. |
| * |
| * @param wrapper LSP wrapper instance |
| * @param summList LSP summary list |
| */ |
| private void addToList(LspWrapper wrapper, List summList) { |
| //set the current age |
| ((LsPdu) wrapper.lsPdu()).setRemainingLifeTime(wrapper.remainingLifetime()); |
| summList.add(wrapper); |
| } |
| |
| /** |
| * Finds the LSP from appropriate maps L1 or L2 based on type. |
| * |
| * @param pduType L1 or L2 LSP |
| * @param lspId LSP ID |
| * @return LSP wrapper object |
| */ |
| public LspWrapper findLsp(IsisPduType pduType, String lspId) { |
| LspWrapper lspWrapper = null; |
| |
| switch (pduType) { |
| case L1LSPDU: |
| lspWrapper = isisL1Db.get(lspId); |
| break; |
| case L2LSPDU: |
| lspWrapper = isisL2Db.get(lspId); |
| break; |
| default: |
| log.debug("Unknown LSP type..!!!"); |
| break; |
| } |
| |
| //set the current age |
| if (lspWrapper != null) { |
| //set the current age |
| ((DefaultLspWrapper) lspWrapper).lsPdu().setRemainingLifeTime(lspWrapper.remainingLifetime()); |
| } |
| |
| return lspWrapper; |
| } |
| |
| /** |
| * Installs a new self-originated LSP. |
| * |
| * @return true if successfully added |
| */ |
| public boolean addLsp(IsisMessage isisMessage, boolean isSelfOriginated, IsisInterface isisInterface) { |
| LsPdu lspdu = (LsPdu) isisMessage; |
| DefaultLspWrapper lspWrapper = new DefaultLspWrapper(); |
| lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime()); |
| lspWrapper.setRemainingLifetime(IsisConstants.LSPMAXAGE - lsdbAge.ageCounter()); |
| lspWrapper.setLspType(IsisPduType.get(lspdu.pduType())); |
| lspWrapper.setLsPdu(lspdu); |
| lspWrapper.setAgeCounterWhenReceived(lsdbAge.ageCounter()); |
| lspWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.ageCounterRollOver()); |
| lspWrapper.setSelfOriginated(isSelfOriginated); |
| lspWrapper.setIsisInterface(isisInterface); |
| lspWrapper.setLsdbAge(lsdbAge); |
| addLsp(lspWrapper, lspdu.lspId()); |
| |
| log.debug("Added LSp In LSDB: {}", lspWrapper); |
| |
| return true; |
| } |
| |
| /** |
| * Adds the LSP to L1 or L2 database. |
| * |
| * @param lspWrapper LSA wrapper instance |
| * @param key key |
| * @return True if added else false |
| */ |
| private boolean addLsp(LspWrapper lspWrapper, String key) { |
| //Remove the lsa from bin if exist. |
| removeLspFromBin(lspWrapper); |
| |
| switch (lspWrapper.lsPdu().isisPduType()) { |
| case L1LSPDU: |
| isisL1Db.put(key, lspWrapper); |
| break; |
| case L2LSPDU: |
| isisL2Db.put(key, lspWrapper); |
| break; |
| default: |
| log.debug("Unknown LSP type to add..!!!"); |
| break; |
| } |
| |
| //add it to bin |
| Integer binNumber = lsdbAge.age2Bin(IsisConstants.LSPMAXAGE - lspWrapper.remainingLifetime()); |
| IsisLspBin lspBin = lsdbAge.getLspBin(binNumber); |
| if (lspBin != null) { |
| //remove from existing |
| lspWrapper.setBinNumber(binNumber); |
| lspBin.addIsisLsp(key, lspWrapper); |
| lsdbAge.addLspBin(binNumber, lspBin); |
| log.debug("Added Type {} LSP to LSDB and LSABin[{}], Remaining life time of LSA {}", |
| lspWrapper.lsPdu().isisPduType(), |
| binNumber, lspWrapper.remainingLifetime()); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Removes LSP from Bin. |
| * |
| * @param lsaWrapper LSP wrapper instance |
| */ |
| public void removeLspFromBin(LspWrapper lsaWrapper) { |
| if (lsaWrapper != null) { |
| lsdbAge.removeLspFromBin(lsaWrapper); |
| } |
| } |
| |
| /** |
| * Returns new ,latest or old according to the type of ISIS message received. |
| * |
| * @param lsp1 LSP instance |
| * @param lsp2 LSP instance |
| * @return string status |
| */ |
| public String isNewerOrSameLsp(IsisMessage lsp1, IsisMessage lsp2) { |
| LsPdu receivedLsp = (LsPdu) lsp1; |
| LsPdu lspFromDb = (LsPdu) lsp2; |
| if (receivedLsp.sequenceNumber() > lspFromDb.sequenceNumber()) { |
| return "latest"; |
| } else if (receivedLsp.sequenceNumber() < lspFromDb.sequenceNumber()) { |
| return "old"; |
| } else if (receivedLsp.sequenceNumber() == lspFromDb.sequenceNumber()) { |
| return "same"; |
| } |
| |
| return ""; |
| } |
| |
| /** |
| * Returns the sequence number. |
| * |
| * @param lspType type of LSP |
| * @return sequence number |
| */ |
| public int lsSequenceNumber(IsisPduType lspType) { |
| switch (lspType) { |
| case L1LSPDU: |
| return l1LspSeqNo++; |
| case L2LSPDU: |
| return l2LspSeqNo++; |
| default: |
| return IsisConstants.STARTLSSEQUENCENUM; |
| } |
| } |
| |
| /** |
| * Deletes the given LSP. |
| * |
| * @param lspMessage LSP instance |
| */ |
| public void deleteLsp(IsisMessage lspMessage) { |
| LsPdu lsp = (LsPdu) lspMessage; |
| String lspKey = lsp.lspId(); |
| switch (lsp.isisPduType()) { |
| case L1LSPDU: |
| isisL1Db.remove(lspKey); |
| break; |
| case L2LSPDU: |
| isisL2Db.remove(lspKey); |
| break; |
| default: |
| log.debug("Unknown LSP type to remove..!!!"); |
| break; |
| } |
| } |
| } |