ONOS-4086 to ONOS-4091, ONOS-4098 to ONOS-4100:ISIS controller implementation
Change-Id: I7be52805652fe762baf808515401d6b5042b2aa5
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdb.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdb.java
new file mode 100755
index 0000000..33a0a17
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdb.java
@@ -0,0 +1,315 @@
+/*
+ * 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java
new file mode 100755
index 0000000..2cf07ba
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java
@@ -0,0 +1,248 @@
+/*
+ * 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.IsisLsdbAge;
+import org.onosproject.isis.controller.IsisLspBin;
+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.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of ISIS link state database ageing process.
+ */
+public class DefaultIsisLsdbAge implements IsisLsdbAge {
+ private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdbAge.class);
+ protected static int ageCounter = 0;
+ private InternalAgeTimer dbAgeTimer;
+ private ScheduledExecutorService exServiceage;
+ private Integer maxBins = 1200;
+ private Map<Integer, IsisLspBin> ageBins = new ConcurrentHashMap<>(maxBins);
+ private int ageCounterRollOver = 0;
+ private IsisLspQueueConsumer queueConsumer = null;
+ private BlockingQueue<LspWrapper> lsaQueue = new ArrayBlockingQueue<>(1024);
+
+ /**
+ * Creates an instance of LSDB age.
+ */
+ public DefaultIsisLsdbAge() {
+ // create LSBin's in the HashMap.
+ for (int i = 0; i < maxBins; i++) {
+ IsisLspBin lspBin = new DefaultIsisLspBin(i);
+ ageBins.put(i, lspBin);
+ }
+ }
+
+ /**
+ * Returns age counter.
+ *
+ * @return age counter
+ */
+ public int ageCounter() {
+ return ageCounter;
+ }
+
+ /**
+ * Returns age counter roll over.
+ *
+ * @return age counter roll over
+ */
+ public int ageCounterRollOver() {
+
+ return ageCounterRollOver;
+ }
+
+ /**
+ * Adds LSP to LS bin for ageing.
+ *
+ * @param binNumber key to store in bin
+ * @param lspBin LSP bin instance
+ */
+ public void addLspBin(int binNumber, IsisLspBin lspBin) {
+ if (!ageBins.containsKey(binNumber)) {
+ ageBins.put(binNumber, lspBin);
+ }
+ }
+
+ /**
+ * Returns LSP from Bin.
+ *
+ * @param binKey key
+ * @return bin instance
+ */
+ public IsisLspBin getLspBin(int binKey) {
+
+ return ageBins.get(binKey);
+ }
+
+ /**
+ * Removes LSP from Bin.
+ *
+ * @param lspWrapper wrapper instance
+ */
+ public void removeLspFromBin(LspWrapper lspWrapper) {
+ if (ageBins.containsKey(lspWrapper.binNumber())) {
+ IsisLspBin lsaBin = ageBins.get(lspWrapper.binNumber());
+ lsaBin.removeIsisLsp(((LsPdu) lspWrapper.lsPdu()).lspId(), lspWrapper);
+ }
+ }
+
+ /**
+ * Returns the bin number.
+ *
+ * @param age Can be either age or ageCounter
+ * @return bin number.
+ */
+ public int age2Bin(int age) {
+ if (age <= ageCounter) {
+ return (ageCounter - age);
+ } else {
+ return ((IsisConstants.LSPMAXAGE - 1) + (ageCounter - age));
+ }
+ }
+
+ /**
+ * Starts the aging timer and queue consumer.
+ */
+ public void startDbAging() {
+ startDbAgeTimer();
+ queueConsumer = new IsisLspQueueConsumer(lsaQueue);
+ new Thread(queueConsumer).start();
+ }
+
+ /**
+ * Starts DB aging task.
+ */
+ private void startDbAgeTimer() {
+ dbAgeTimer = new InternalAgeTimer();
+ //from 1 sec
+ exServiceage = Executors.newSingleThreadScheduledExecutor();
+ exServiceage.scheduleAtFixedRate(dbAgeTimer, 1, 1, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Gets called every second as part of the aging process.
+ */
+ public void ageLsp() {
+ refreshLsa();
+ maxAgeLsa();
+
+ if (ageCounter == IsisConstants.LSPMAXAGE) {
+ ageCounter = 0;
+ ageCounterRollOver++;
+ } else {
+ ageCounter++;
+ }
+ }
+
+ /**
+ * If the LSP have completed the MaxAge - they are moved called stop aging.
+ */
+ public void maxAgeLsa() {
+ if (ageCounter == 0) {
+ return;
+ }
+ //Get from Age Bins
+ IsisLspBin lspBin = ageBins.get(ageCounter - 1);
+ if (lspBin == null) {
+ return;
+ }
+ Map lspBinMap = lspBin.listOfLsp();
+ for (Object key : lspBinMap.keySet()) {
+ LspWrapper lspWrapper = (LspWrapper) lspBinMap.get((String) key);
+ if (lspWrapper.currentAge() == IsisConstants.LSPMAXAGE) {
+ lspWrapper.setLspProcessing(IsisConstants.MAXAGELSP);
+ log.debug("Lsp picked for maxage removal. Age Counter: {}, AgeCounterRollover: {}, " +
+ "AgeCounterRollover WhenAddedToDb: {}, LSA Type: {}, LSA Key: {}",
+ ageCounter, ageCounterRollOver, lspWrapper.currentAge(),
+ lspWrapper.lsPdu().isisPduType(), key);
+ //add it to lspQueue for processing
+ try {
+ lsaQueue.put(lspWrapper);
+ //remove from bin
+ lspBin.removeIsisLsp((String) key, lspWrapper);
+ } catch (InterruptedException e) {
+ log.debug("Error::LSDBAge::maxAgeLsp::{}", e.getMessage());
+ }
+ }
+ }
+
+ }
+
+ /*
+ * If the LSP is in age bin of 900s- it's pushed into refresh list.
+ */
+ public void refreshLsa() {
+ int binNumber;
+ if (ageCounter < IsisConstants.LSPREFRESH) {
+ binNumber = ageCounter + IsisConstants.LSPREFRESH;
+ } else {
+ binNumber = ageCounter - IsisConstants.LSPREFRESH;
+ }
+ if (binNumber > IsisConstants.LSPMAXAGE) {
+ binNumber = binNumber - IsisConstants.LSPMAXAGE;
+ }
+ IsisLspBin lspBin = ageBins.get(binNumber);
+ if (lspBin == null) {
+ return;
+ }
+ Map lspBinMap = lspBin.listOfLsp();
+ for (Object key : lspBinMap.keySet()) {
+ LspWrapper lsp = (LspWrapper) lspBinMap.get((String) key);
+ try {
+ if (lsp.isSelfOriginated()) {
+ log.debug("Lsp picked for refreshLsp. binNumber: {}, LSA Type: {}, LSA Key: {}",
+ binNumber, lsp.lspType(), key);
+ lsp.setLspProcessing(IsisConstants.REFRESHLSP);
+ lsaQueue.put(lsp);
+ //remove from bin
+ lspBin.removeIsisLsp((String) key, lsp);
+ }
+ } catch (InterruptedException e) {
+ log.debug("Error::LSDBAge::refreshLsp::{}", e.getMessage());
+ }
+ }
+ }
+
+
+ /**
+ * Runnable task which runs every second and calls aging process.
+ */
+ private class InternalAgeTimer implements Runnable {
+
+ /**
+ * Creates an instance of age timer task.
+ */
+ InternalAgeTimer() {
+ log.debug("Starts::IsisLsdbAge::AgeTimer...!!! ");
+ }
+
+ @Override
+ public void run() {
+ ageLsp();
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java
new file mode 100755
index 0000000..2505c90
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java
@@ -0,0 +1,104 @@
+/*
+ * 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 com.google.common.base.MoreObjects;
+import org.onosproject.isis.controller.IsisLspBin;
+import org.onosproject.isis.controller.LspWrapper;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Representation of LSP bin, where an LSP is stored for Aging.
+ * A bin is identified by a bin number and can have one or more LSPs
+ * store in a particular bin location
+ */
+public class DefaultIsisLspBin implements IsisLspBin {
+ private int binNumber;
+ private Map<String, LspWrapper> listOfLsp = new ConcurrentHashMap<>();
+
+ /**
+ * Creates ISIS LSP bin instance.
+ *
+ * @param binNumber bin number
+ */
+ public DefaultIsisLspBin(int binNumber) {
+ this.binNumber = binNumber;
+ }
+
+ /**
+ * Adds the LSP to wrapper.
+ *
+ * @param lspKey key to add the LSP
+ * @param lspWrapper LSP wrapper instance
+ */
+ public void addIsisLsp(String lspKey, LspWrapper lspWrapper) {
+ if (!listOfLsp.containsKey(lspKey)) {
+ listOfLsp.put(lspKey, lspWrapper);
+ lspWrapper.setBinNumber(this.binNumber);
+ }
+ }
+
+ /**
+ * Returns the LSP wrapper.
+ *
+ * @param lspKey LSP key
+ * @return LSP wrapper
+ */
+ public LspWrapper isisLsp(String lspKey) {
+ return listOfLsp.get(lspKey);
+ }
+
+ /**
+ * Removes ISIS LSP from database.
+ *
+ * @param lspKey LSP key
+ * @param lspWrapper LSP wrapper instance
+ */
+ public void removeIsisLsp(String lspKey, LspWrapper lspWrapper) {
+ if (listOfLsp.containsKey(lspKey)) {
+ listOfLsp.remove(lspKey);
+ }
+ }
+
+ /**
+ * Returns all LSP wrappers.
+ *
+ * @return all LSP wrappers
+ */
+ public Map<String, LspWrapper> listOfLsp() {
+ return listOfLsp;
+ }
+
+ /**
+ * Returns the bin number.
+ *
+ * @return the bin number
+ */
+ public int binNumber() {
+ return binNumber;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("binNumber", binNumber)
+ .add("listOfLsp", listOfLsp)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java
new file mode 100755
index 0000000..b89e88f
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java
@@ -0,0 +1,267 @@
+/*
+ * 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.IsisLsdbAge;
+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;
+
+/**
+ * Representation of LSP wrapper where the LSPs are stored with metadata.
+ */
+public class DefaultLspWrapper implements LspWrapper {
+ private int binNumber = -1;
+ private boolean selfOriginated = false;
+ private IsisPduType lspType;
+ private int lspAgeReceived;
+ private int ageCounterWhenReceived;
+ private LsPdu lsPdu;
+ private IsisLsdbAge lsdbAge;
+ private int ageCounterRollOverWhenAdded;
+ private int remainingLifetime;
+ private IsisInterface isisInterface;
+ private String lspProcessing;
+
+ /**
+ * Returns "refreshLsp" or "maxageLsp" based on LSP to process.
+ *
+ * @return LSP processing string
+ */
+ public String lspProcessing() {
+ return lspProcessing;
+ }
+
+ /**
+ * Sets LSP processing "refreshLsp" or "maxageLsp" based on LSP to process.
+ *
+ * @param lspProcessing "refreshLsp" or "maxageLsp" based on LSP to process
+ */
+ public void setLspProcessing(String lspProcessing) {
+ this.lspProcessing = lspProcessing;
+ }
+
+ /**
+ * Returns LSP age received.
+ *
+ * @return LSP age received
+ */
+ public int lspAgeReceived() {
+ return lspAgeReceived;
+ }
+
+ /**
+ * Sets LSP age received.
+ *
+ * @param lspAgeReceived LSP age received.
+ */
+ public void setLspAgeReceived(int lspAgeReceived) {
+ this.lspAgeReceived = lspAgeReceived;
+ }
+
+ /**
+ * Returns ISIS interface instance.
+ *
+ * @return ISIS interface instance
+ */
+ public IsisInterface isisInterface() {
+ return isisInterface;
+ }
+
+ /**
+ * Sets ISIS interface.
+ *
+ * @param isisInterface ISIS interface instance
+ */
+ public void setIsisInterface(IsisInterface isisInterface) {
+ this.isisInterface = isisInterface;
+ }
+
+ /**
+ * Returns age counter when received.
+ *
+ * @return age counter when received
+ */
+ public int ageCounterWhenReceived() {
+
+ return ageCounterWhenReceived;
+ }
+
+ /**
+ * Sets age counter when received.
+ *
+ * @param ageCounterWhenReceived age counter when received
+ */
+ public void setAgeCounterWhenReceived(int ageCounterWhenReceived) {
+ this.ageCounterWhenReceived = ageCounterWhenReceived;
+ }
+
+ /**
+ * Returns age counter roll over.
+ *
+ * @return age counter roll over
+ */
+ public int ageCounterRollOverWhenAdded() {
+ return ageCounterRollOverWhenAdded;
+ }
+
+ /**
+ * Sets age counter roll over when added.
+ *
+ * @param ageCounterRollOverWhenAdded age counter roll over when added
+ */
+ public void setAgeCounterRollOverWhenAdded(int ageCounterRollOverWhenAdded) {
+ this.ageCounterRollOverWhenAdded = ageCounterRollOverWhenAdded;
+ }
+
+ /**
+ * Returns bin number.
+ *
+ * @return bin number
+ */
+ public int binNumber() {
+ return binNumber;
+ }
+
+ /**
+ * Sets bin number.
+ *
+ * @param binNumber bin number
+ */
+ public void setBinNumber(int binNumber) {
+ this.binNumber = binNumber;
+ }
+
+ /**
+ * Returns true if self originated.
+ *
+ * @return true if self originated.
+ */
+ public boolean isSelfOriginated() {
+ return selfOriginated;
+ }
+
+ /**
+ * Sets true if self originated.
+ *
+ * @param selfOriginated true if self originated else false
+ */
+ public void setSelfOriginated(boolean selfOriginated) {
+ this.selfOriginated = selfOriginated;
+ }
+
+ /**
+ * Returns ISIS PDU type.
+ *
+ * @return ISIS PDU type
+ */
+ public IsisPduType lspType() {
+ return lspType;
+ }
+
+ /**
+ * Sets ISIS PDU type.
+ *
+ * @param lspType ISIS PDU type
+ */
+ public void setLspType(IsisPduType lspType) {
+ this.lspType = lspType;
+ }
+
+ /**
+ * Returns LSPDU which the wrapper contains.
+ *
+ * @return LSPDU which the wrapper contains
+ */
+ public LsPdu lsPdu() {
+ return lsPdu;
+ }
+
+ /**
+ * Sets LSPDU which the wrapper contains.
+ *
+ * @param lsPdu LSPDU which the wrapper contains
+ */
+ public void setLsPdu(LsPdu lsPdu) {
+ this.lsPdu = lsPdu;
+ }
+
+ /**
+ * Returns ISIS LSDB age.
+ *
+ * @return ISIS LSDB age
+ */
+ public IsisLsdbAge lsdbAge() {
+ return lsdbAge;
+ }
+
+ /**
+ * Sets LSDB age.
+ *
+ * @param lsdbAge LSDB age
+ */
+ public void setLsdbAge(IsisLsdbAge lsdbAge) {
+ this.lsdbAge = lsdbAge;
+ }
+
+ /**
+ * Returns the current LSP Age.
+ *
+ * @return LSP age
+ */
+ public int currentAge() {
+
+ int currentAge = 0;
+ //ls age received
+ if (lsdbAge.ageCounter() >= ageCounterWhenReceived) {
+ currentAge = lspAgeReceived + (lsdbAge.ageCounter() - ageCounterWhenReceived);
+ } else {
+ currentAge = lspAgeReceived + ((IsisConstants.LSPMAXAGE + lsdbAge.ageCounter())
+ - ageCounterWhenReceived);
+ }
+
+ if (currentAge >= IsisConstants.LSPMAXAGE) {
+ return IsisConstants.LSPMAXAGE;
+ } else if ((currentAge == lspAgeReceived) && ageCounterRollOverWhenAdded
+ != lsdbAge.ageCounterRollOver()) {
+ return IsisConstants.LSPMAXAGE;
+ }
+
+ return currentAge;
+ }
+
+ /**
+ * Returns remaining time.
+ *
+ * @return remaining time
+ */
+ public int remainingLifetime() {
+ //Calculate the remaining lifetime
+ remainingLifetime = IsisConstants.LSPMAXAGE - lsdbAge.ageCounter();
+ return remainingLifetime;
+ }
+
+ /**
+ * Sets remaining life time.
+ *
+ * @param remainingLifetime LSPs remaining life time
+ */
+ public void setRemainingLifetime(int remainingLifetime) {
+ this.remainingLifetime = remainingLifetime;
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java
new file mode 100755
index 0000000..9007093
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java
@@ -0,0 +1,128 @@
+/*
+ * 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.jboss.netty.channel.Channel;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.controller.impl.DefaultIsisInterface;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.onosproject.isis.io.util.IsisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * Representation of LSP queue consumer.
+ */
+public class IsisLspQueueConsumer implements Runnable {
+ private static final Logger log = LoggerFactory.getLogger(IsisLspQueueConsumer.class);
+ private BlockingQueue queue = null;
+
+ /**
+ * Creates an instance of LSP queue consumer.
+ *
+ * @param queue queue instance
+ */
+ public IsisLspQueueConsumer(BlockingQueue queue) {
+ this.queue = queue;
+ }
+
+ /**
+ * Gets the LSP wrapper instance from queue and process it.
+ */
+ @Override
+ public void run() {
+ log.debug("LSPQueueConsumer:run...!!!");
+ try {
+ while (true) {
+ if (!queue.isEmpty()) {
+ LspWrapper wrapper = (LspWrapper) queue.take();
+ String lspProcessing = wrapper.lspProcessing();
+ switch (lspProcessing) {
+ case IsisConstants.REFRESHLSP:
+ log.debug("LSPQueueConsumer: Message - " + IsisConstants.REFRESHLSP +
+ " consumed.");
+ processRefreshLsp(wrapper);
+ break;
+ case IsisConstants.MAXAGELSP:
+ log.debug("LSPQueueConsumer: Message - " + IsisConstants.MAXAGELSP +
+ " consumed.");
+ processMaxAgeLsa(wrapper);
+ break;
+ default:
+ log.debug("Unknown command to process the LSP in queue ...!!!");
+ break;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ log.debug("Error::LSPQueueConsumer::{}", e.getMessage());
+ }
+ }
+
+ /**
+ * Process refresh LSP.
+ *
+ * @param wrapper LSP wrapper instance
+ */
+ private void processRefreshLsp(LspWrapper wrapper) throws Exception {
+ if (wrapper.isSelfOriginated()) { //self originated
+ DefaultIsisInterface isisInterface = (DefaultIsisInterface) wrapper.isisInterface();
+ Channel channel = isisInterface.channel();
+ if (channel != null && channel.isConnected()) {
+ LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
+ lsPdu.setSequenceNumber(isisInterface.isisLsdb().lsSequenceNumber(
+ IsisPduType.get(lsPdu.pduType())));
+ lsPdu.setRemainingLifeTime(IsisConstants.LSPMAXAGE);
+ byte[] lspBytes = lsPdu.asBytes();
+ lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
+ IsisConstants.LENGTHPOSITION + 1,
+ IsisConstants.RESERVEDPOSITION);
+ lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
+ IsisConstants.CHECKSUMPOSITION + 1);
+ //write to the channel
+ channel.write(IsisUtil.framePacket(lspBytes, isisInterface.interfaceIndex()));
+
+ log.debug("LSPQueueConsumer: processRefreshLsp - Flooded SelfOriginated LSP {}",
+ wrapper.lsPdu());
+ }
+
+ }
+ }
+
+ /**
+ * Process max age LSP.
+ *
+ * @param wrapper LSP wrapper instance
+ */
+ private void processMaxAgeLsa(LspWrapper wrapper) {
+ //set the destination
+ DefaultIsisInterface isisInterface = (DefaultIsisInterface) wrapper.isisInterface();
+ if (isisInterface != null) {
+ //delete from db
+ LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
+ IsisLsdb isisDb = isisInterface.isisLsdb();
+ isisDb.deleteLsp(lsPdu);
+ log.debug("LSPQueueConsumer: processMaxAgeLsp - Removed-Max Age LSP {}",
+ wrapper.lsPdu());
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java
new file mode 100755
index 0000000..cbab4b4
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of the ISIS controller LSDB and related functionality.
+ */
+package org.onosproject.isis.controller.impl.lsdb;
\ No newline at end of file