blob: 33a0a17497ac2505196c40db1c0292a10027b1b3 [file] [log] [blame]
/*
* 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;
}
}
}