ONOS-4086 to ONOS-4091, ONOS-4098 to ONOS-4100:ISIS controller implementation
Change-Id: I7be52805652fe762baf808515401d6b5042b2aa5
diff --git a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisController.java b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisController.java
index 7d5b111..fc10019 100644
--- a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisController.java
+++ b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisController.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.isis.controller;
+import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.isis.controller.topology.IsisRouterListener;
import java.util.List;
@@ -41,18 +42,9 @@
/**
* Updates configuration of processes.
*
- * @param processes process instance to update
+ * @param processesNode json node represents process
*/
- void updateConfig(List<IsisProcess> processes);
-
- /**
- * Deletes configuration parameters.
- *
- * @param processes list of process instance
- * @param attribute string key which deletes the particular node or element
- * from the controller
- */
- void deleteConfig(List<IsisProcess> processes, String attribute);
+ void updateConfig(JsonNode processesNode);
/**
* Gets the all configured processes.
diff --git a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisInterface.java b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisInterface.java
index 0b97c7d..3ac7122 100644
--- a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisInterface.java
+++ b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisInterface.java
@@ -230,6 +230,13 @@
void setPriority(int priority);
/**
+ * Returns hello interval.
+ *
+ * @return hello interval
+ */
+ public int helloInterval();
+
+ /**
* Sets hello interval.
*
* @param helloInterval hello interval
@@ -301,4 +308,11 @@
* @param circuitId circuit ID
*/
void setCircuitId(String circuitId);
+
+ /**
+ * Removes neighbor from the interface neighbor map.
+ *
+ * @param isisNeighbor ISIS neighbor instance
+ */
+ void removeNeighbor(IsisNeighbor isisNeighbor);
}
diff --git a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisNeighbor.java b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisNeighbor.java
index 22b0cca..eedf11c 100644
--- a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisNeighbor.java
+++ b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisNeighbor.java
@@ -98,4 +98,14 @@
* @param holdingTime Holding time of neighbor
*/
void setHoldingTime(int holdingTime);
+
+ /**
+ * Starts the inactivity timer for this neighbor.
+ */
+ void startInactivityTimeCheck();
+
+ /**
+ * Stops the inactivity timer.
+ */
+ void stopInactivityTimeCheck();
}
diff --git a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisProcess.java b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisProcess.java
index a5d1ae6..ec6dcc1 100644
--- a/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisProcess.java
+++ b/protocols/isis/api/src/main/java/org/onosproject/isis/controller/IsisProcess.java
@@ -23,6 +23,13 @@
public interface IsisProcess {
/**
+ * Returns process ID.
+ *
+ * @return process ID
+ */
+ public String processId();
+
+ /**
* Sets process ID.
*
* @param processId process ID
diff --git a/protocols/isis/ctl/pom.xml b/protocols/isis/ctl/pom.xml
new file mode 100644
index 0000000..886b65e
--- /dev/null
+++ b/protocols/isis/ctl/pom.xml
@@ -0,0 +1,63 @@
+<!--
+ ~ Copyright 2016 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.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-isis</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-isis-ctl</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>ONOS ISIS controller subsystem API</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-isis-isisio</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+
+</project>
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/Controller.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/Controller.java
new file mode 100755
index 0000000..c12c520
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/Controller.java
@@ -0,0 +1,241 @@
+/*
+ * 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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisNetworkType;
+import org.onosproject.isis.controller.IsisProcess;
+import org.onosproject.isis.controller.IsisRouterType;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executors;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Representation of an ISIS controller.
+ */
+public class Controller {
+ protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
+ private static final Logger log = LoggerFactory.getLogger(Controller.class);
+ private final int peerWorkerThreads = 16;
+ private List<IsisProcess> processes = null;
+ private IsisChannelHandler isisChannelHandler;
+ private NioClientSocketChannelFactory peerExecFactory;
+ private ClientBootstrap peerBootstrap = null;
+ private TpPort isisPort = TpPort.tpPort(IsisConstants.SPORT);
+
+ /**
+ * Deactivates ISIS controller.
+ */
+ public void isisDeactivate() {
+ peerExecFactory.shutdown();
+ }
+
+ /**
+ * Updates the processes configuration.
+ *
+ * @param jsonNode json node instance
+ * @throws Exception might throws parse exception
+ */
+ public void updateConfig(JsonNode jsonNode) throws Exception {
+ log.debug("Controller::UpdateConfig called");
+ byte[] configPacket = new byte[IsisConstants.CONFIG_LENGTH];
+ byte numberOfInterface = 0; // number of interfaces to configure
+
+ configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
+ List<IsisProcess> isisProcesses = getConfig(jsonNode);
+
+ for (IsisProcess isisProcess : isisProcesses) {
+ log.debug("IsisProcessDetails : " + isisProcess);
+ for (IsisInterface isisInterface : isisProcess.isisInterfaceList()) {
+ DefaultIsisInterface isisInterfaceImpl = (DefaultIsisInterface) isisInterface;
+ log.debug("IsisInterfaceDetails : " + isisInterface);
+ numberOfInterface++;
+ configPacket[2 * numberOfInterface] = (byte) isisInterfaceImpl.interfaceIndex();
+ if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
+ isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
+ configPacket[(2 * numberOfInterface) + 1] = (byte) 0;
+ } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
+ isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L2.value()) {
+ configPacket[(2 * numberOfInterface) + 1] = (byte) 1;
+ } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
+ configPacket[(2 * numberOfInterface) + 1] = (byte) 2;
+ } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
+ isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1L2.value()) {
+ configPacket[(2 * numberOfInterface) + 1] = (byte) 3;
+ }
+ }
+ }
+ configPacket[1] = numberOfInterface;
+ //First time configuration
+ if (processes == null) {
+ processes = isisProcesses;
+ //Initialize connection by creating a channel handler instance and sent the config packet);
+ initConnection();
+ //Initializing the interface map in channel handler
+ isisChannelHandler.initializeInterfaceMap();
+ } else {
+ isisChannelHandler.updateInterfaceMap(isisProcesses);
+ }
+ //Send the config packet
+ isisChannelHandler.sentConfigPacket(configPacket);
+ }
+
+ /**
+ * Initializes the netty client channel connection.
+ */
+ private void initConnection() {
+ if (peerBootstrap != null) {
+ return;
+ }
+ peerBootstrap = createPeerBootStrap();
+
+ peerBootstrap.setOption("reuseAddress", true);
+ peerBootstrap.setOption("tcpNoDelay", true);
+ peerBootstrap.setOption("keepAlive", true);
+ peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("receiveBufferSizePredictorFactory",
+ new FixedReceiveBufferSizePredictorFactory(
+ Controller.BUFFER_SIZE));
+ peerBootstrap.setOption("receiveBufferSizePredictor",
+ new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
+ peerBootstrap.setOption("child.keepAlive", true);
+ peerBootstrap.setOption("child.tcpNoDelay", true);
+ peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
+ peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
+ new FixedReceiveBufferSizePredictorFactory(
+ Controller.BUFFER_SIZE));
+ peerBootstrap.setOption("child.reuseAddress", true);
+
+ isisChannelHandler = new IsisChannelHandler(this, processes);
+ ChannelPipelineFactory pfact = new IsisPipelineFactory(isisChannelHandler);
+ peerBootstrap.setPipelineFactory(pfact);
+ ChannelFuture connection = peerBootstrap.connect(new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt()));
+ }
+
+ /**
+ * Creates peer boot strap.
+ *
+ * @return client bootstrap instance
+ */
+ private ClientBootstrap createPeerBootStrap() {
+
+ if (peerWorkerThreads == 0) {
+ peerExecFactory = new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
+ return new ClientBootstrap(peerExecFactory);
+ } else {
+ peerExecFactory = new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
+ Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
+ peerWorkerThreads);
+ return new ClientBootstrap(peerExecFactory);
+ }
+ }
+
+ /**
+ * Gets all configured processes.
+ *
+ * @return all configured processes
+ */
+ public List<IsisProcess> getAllConfiguredProcesses() {
+ return processes;
+ }
+
+ /**
+ * Gets the list of processes configured.
+ *
+ * @param json posted json
+ * @return list of processes configured
+ */
+ private List<IsisProcess> getConfig(JsonNode json) throws Exception {
+
+ List<IsisProcess> isisProcessesList = new ArrayList<>();
+ JsonNode jsonNodes = json;
+
+ if (jsonNodes == null) {
+ return isisProcessesList;
+ }
+ jsonNodes.forEach(jsonNode -> {
+ List<IsisInterface> interfaceList = new ArrayList<>();
+ for (JsonNode jsonNode1 : jsonNode.path(IsisConstants.INTERFACE)) {
+ IsisInterface isisInterface = new DefaultIsisInterface();
+ isisInterface.setInterfaceIndex(jsonNode1.path(IsisConstants.INTERFACEINDEX).asInt());
+ isisInterface.setInterfaceIpAddress(Ip4Address.valueOf(jsonNode1
+ .path(IsisConstants.INTERFACEIP)
+ .asText()));
+ try {
+ isisInterface.setNetworkMask(InetAddress.getByName((jsonNode1
+ .path(IsisConstants.NETWORKMASK).asText())).getAddress());
+ } catch (UnknownHostException e) {
+ log.debug("Error:: Parsing network mask");
+ }
+ isisInterface.setInterfaceMacAddress(MacAddress.valueOf(jsonNode1
+ .path(IsisConstants.MACADDRESS)
+ .asText()));
+ isisInterface.setIntermediateSystemName(jsonNode1
+ .path(IsisConstants.INTERMEDIATESYSTEMNAME)
+ .asText());
+ isisInterface.setSystemId(jsonNode1.path(IsisConstants.SYSTEMID).asText());
+ isisInterface.setReservedPacketCircuitType(jsonNode1
+ .path(IsisConstants.RESERVEDPACKETCIRCUITTYPE)
+ .asInt());
+ if (isisInterface.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
+ isisInterface.setL1LanId(jsonNode1.path(IsisConstants.LANID).asText());
+ }
+ isisInterface.setIdLength(jsonNode1.path(IsisConstants.IDLENGTH).asInt());
+ isisInterface.setMaxAreaAddresses(jsonNode1.path(IsisConstants.MAXAREAADDRESSES).asInt());
+ isisInterface.setNetworkType(IsisNetworkType.get(jsonNode1
+ .path(IsisConstants.NETWORKTYPE)
+ .asInt()));
+ isisInterface.setAreaAddress(jsonNode1.path(IsisConstants.AREAADDRESS).asText());
+ isisInterface.setAreaLength(jsonNode1.path(IsisConstants.AREALENGTH).asInt());
+ isisInterface.setLspId(jsonNode1.path(IsisConstants.LSPID).asText());
+ isisInterface.setCircuitId(jsonNode1.path(IsisConstants.CIRCUITID).asText());
+ isisInterface.setHoldingTime(jsonNode1.path(IsisConstants.HOLDINGTIME).asInt());
+ isisInterface.setPriority(jsonNode1.path(IsisConstants.PRIORITY).asInt());
+ isisInterface.setHelloInterval(jsonNode1.path(IsisConstants.HELLOINTERVAL).asInt());
+ interfaceList.add(isisInterface);
+ }
+ IsisProcess process = new DefaultIsisProcess();
+ process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
+ process.setIsisInterfaceList(interfaceList);
+ isisProcessesList.add(process);
+ });
+
+ return isisProcessesList;
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisController.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisController.java
new file mode 100755
index 0000000..0929db4
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisController.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.isis.controller.IsisController;
+import org.onosproject.isis.controller.IsisProcess;
+import org.onosproject.isis.controller.topology.IsisRouterListener;
+import org.onosproject.net.driver.DriverService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * Represents ISIS controller implementation.
+ */
+@Component(immediate = true)
+@Service
+public class DefaultIsisController implements IsisController {
+
+ protected static final Logger log = LoggerFactory.getLogger(DefaultIsisController.class);
+ private final Controller controller = new Controller();
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+
+ @Activate
+ public void activate() {
+ log.debug("ISISControllerImpl activate");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ controller.isisDeactivate();
+ log.debug("ISISControllerImpl deActivate");
+ }
+
+ @Override
+ public List<IsisProcess> allConfiguredProcesses() {
+ List<IsisProcess> processes = controller.getAllConfiguredProcesses();
+ return processes;
+ }
+
+ @Override
+ public void updateConfig(JsonNode jsonNode) {
+ log.debug("updateConfig::IsisList::processes::{}", jsonNode);
+ try {
+ controller.updateConfig(jsonNode);
+ } catch (Exception e) {
+ log.debug("Error::updateConfig::{}", e.getMessage());
+ }
+ }
+
+ @Override
+ public void addRouterListener(IsisRouterListener isisRouterListener) {
+ log.debug("IsisControllerImpl::addRouterListener...");
+ }
+
+ @Override
+ public void removeRouterListener(IsisRouterListener isisRouterListener) {
+ log.debug("IsisControllerImpl::removeRouterListener...");
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisInterface.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisInterface.java
new file mode 100755
index 0000000..bbeb4dd
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisInterface.java
@@ -0,0 +1,1086 @@
+/*
+ * 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;
+
+import org.jboss.netty.channel.Channel;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisInterfaceState;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisMessage;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisNetworkType;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.IsisRouterType;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.io.isispacket.IsisHeader;
+import org.onosproject.isis.io.isispacket.pdu.Csnp;
+import org.onosproject.isis.io.isispacket.pdu.HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.Psnp;
+import org.onosproject.isis.io.isispacket.tlv.AdjacencyStateTlv;
+import org.onosproject.isis.io.isispacket.tlv.IsisTlv;
+import org.onosproject.isis.io.isispacket.tlv.LspEntriesTlv;
+import org.onosproject.isis.io.isispacket.tlv.LspEntry;
+import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
+import org.onosproject.isis.io.isispacket.tlv.TlvType;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.onosproject.isis.io.util.IsisUtil;
+import org.onosproject.isis.io.util.LspGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of an ISIS interface.
+ */
+public class DefaultIsisInterface implements IsisInterface {
+ private static final Logger log = LoggerFactory.getLogger(DefaultIsisInterface.class);
+ boolean flagValue = false;
+ private int interfaceIndex;
+ private Ip4Address interfaceIpAddress;
+ private byte[] networkMask;
+ private MacAddress interfaceMacAddress;
+ private String intermediateSystemName;
+ private String systemId;
+ private String l1LanId;
+ private String l2LanId;
+ private int idLength;
+ private int maxAreaAddresses;
+ private int reservedPacketCircuitType;
+ private IsisNetworkType networkType;
+ private String areaAddress;
+ private int areaLength;
+ private String lspId;
+ private int holdingTime;
+ private int priority;
+ private String circuitId;
+ private int helloInterval;
+ private Map<MacAddress, IsisNeighbor> neighborList = new ConcurrentHashMap<>();
+ private IsisHelloPduSender isisHelloPduSender = null;
+ private ScheduledExecutorService exServiceHello = null;
+ private IsisInterfaceState interfaceState = IsisInterfaceState.DOWN;
+ private IsisLsdb isisLsdb = null;
+ private List<Ip4Address> allConfiguredInterfaceIps = null;
+ private Channel channel;
+
+ /**
+ * Returns ISIS LSDB instance.
+ *
+ * @return ISIS LSDB instance
+ */
+ public IsisLsdb isisLsdb() {
+ return isisLsdb;
+ }
+
+ /**
+ * Sets all configured interface IPs.
+ *
+ * @param allConfiguredInterfaces all configured interface IPs
+ */
+ public void setAllConfiguredInterfaceIps(List<Ip4Address> allConfiguredInterfaces) {
+ allConfiguredInterfaceIps = allConfiguredInterfaces;
+ }
+
+ /**
+ * Removes neighbor from the interface neighbor map.
+ *
+ * @param isisNeighbor ISIS neighbor instance
+ */
+ public void removeNeighbor(IsisNeighbor isisNeighbor) {
+ neighborList.remove(isisNeighbor.neighborMacAddress());
+ }
+
+ /**
+ * Returns the ISIS neighbor instance if exists.
+ *
+ * @param isisNeighborMac mac address of the neighbor router
+ * @return ISIS neighbor instance if exists else null
+ */
+ public IsisNeighbor lookup(MacAddress isisNeighborMac) {
+ return neighborList.get(isisNeighborMac);
+ }
+
+ /**
+ * Returns the neighbors list.
+ *
+ * @return neighbors list
+ */
+ public Set<MacAddress> neighbors() {
+ return neighborList.keySet();
+ }
+
+ /**
+ * Returns channel instance.
+ *
+ * @return channel instance
+ */
+ public Channel channel() {
+ return channel;
+ }
+
+ /**
+ * Returns interface index.
+ *
+ * @return interface index
+ */
+ public int interfaceIndex() {
+ return interfaceIndex;
+ }
+
+ /**
+ * Set interface index.
+ *
+ * @param interfaceIndex interface index
+ */
+ public void setInterfaceIndex(int interfaceIndex) {
+ this.interfaceIndex = interfaceIndex;
+ }
+
+ /**
+ * Returns the interface IP address.
+ *
+ * @return interface IP address
+ */
+ public Ip4Address interfaceIpAddress() {
+ return interfaceIpAddress;
+ }
+
+ /**
+ * Sets the interface IP address.
+ *
+ * @param interfaceIpAddress interfaceIpAddress interface IP address
+ */
+ public void setInterfaceIpAddress(Ip4Address interfaceIpAddress) {
+ this.interfaceIpAddress = interfaceIpAddress;
+ }
+
+ /**
+ * Returns the network mask.
+ *
+ * @return network mask
+ */
+ public byte[] networkMask() {
+ return networkMask;
+ }
+
+ /**
+ * Sets the network mask.
+ *
+ * @param networkMask network mask
+ */
+ public void setNetworkMask(byte[] networkMask) {
+ this.networkMask = networkMask;
+ }
+
+ /**
+ * Returns the interface mac address.
+ *
+ * @return interface mac address
+ */
+ public MacAddress getInterfaceMacAddress() {
+ return interfaceMacAddress;
+ }
+
+ /**
+ * Sets the interface mac address.
+ *
+ * @param interfaceMacAddress interface mac address
+ */
+ public void setInterfaceMacAddress(MacAddress interfaceMacAddress) {
+ this.interfaceMacAddress = interfaceMacAddress;
+ }
+
+ /**
+ * Returns intermediate system name.
+ *
+ * @return intermediate system name
+ */
+ public String intermediateSystemName() {
+ return intermediateSystemName;
+ }
+
+ /**
+ * Sets intermediate system name.
+ *
+ * @param intermediateSystemName intermediate system name
+ */
+ public void setIntermediateSystemName(String intermediateSystemName) {
+ this.intermediateSystemName = intermediateSystemName;
+ }
+
+ /**
+ * Returns system ID.
+ *
+ * @return system ID
+ */
+ public String systemId() {
+ return systemId;
+ }
+
+ /**
+ * Sets system ID.
+ *
+ * @param systemId system ID
+ */
+ public void setSystemId(String systemId) {
+ this.systemId = systemId;
+ }
+
+ /**
+ * Returns LAN ID.
+ *
+ * @return LAN ID
+ */
+ public String l1LanId() {
+ return l1LanId;
+ }
+
+ /**
+ * Sets LAN ID.
+ *
+ * @param l1LanId LAN ID
+ */
+ public void setL1LanId(String l1LanId) {
+ this.l1LanId = l1LanId;
+ }
+
+ /**
+ * Returns LAN ID.
+ *
+ * @return LAN ID
+ */
+ public String l2LanId() {
+ return l2LanId;
+ }
+
+ /**
+ * Sets LAN ID.
+ *
+ * @param l2LanId LAN ID
+ */
+ public void setL2LanId(String l2LanId) {
+ this.l2LanId = l2LanId;
+ }
+
+ /**
+ * Returns ID length.
+ *
+ * @return ID length
+ */
+ public int getIdLength() {
+
+ return ((idLength == 0) ? 6 : idLength);
+ }
+
+ /**
+ * Sets ID length.
+ *
+ * @param idLength ID length
+ */
+ public void setIdLength(int idLength) {
+ this.idLength = idLength;
+ }
+
+ /**
+ * Returns max area addresses.
+ *
+ * @return max area addresses
+ */
+ public int getMaxAreaAddresses() {
+
+ return maxAreaAddresses;
+ }
+
+ /**
+ * Sets area max addresses.
+ *
+ * @param maxAreaAddresses max area addresses
+ */
+ public void setMaxAreaAddresses(int maxAreaAddresses) {
+ this.maxAreaAddresses = maxAreaAddresses;
+ }
+
+ /**
+ * Returns reserved packet circuit type.
+ *
+ * @return reserved packet circuit type
+ */
+ public int reservedPacketCircuitType() {
+ return reservedPacketCircuitType;
+ }
+
+ /**
+ * Sets reserved packet circuit type.
+ *
+ * @param reservedPacketCircuitType reserved packet circuit type
+ */
+ public void setReservedPacketCircuitType(int reservedPacketCircuitType) {
+ this.reservedPacketCircuitType = reservedPacketCircuitType;
+ }
+
+ /**
+ * Returns point to point.
+ *
+ * @return point to point
+ */
+ public IsisNetworkType networkType() {
+ return networkType;
+ }
+
+ /**
+ * Sets point to point or broadcast.
+ *
+ * @param networkType point to point or broadcast
+ */
+ public void setNetworkType(IsisNetworkType networkType) {
+ this.networkType = networkType;
+ }
+
+ /**
+ * Returns area address.
+ *
+ * @return area address
+ */
+ public String areaAddress() {
+ return areaAddress;
+ }
+
+ /**
+ * Sets area address.
+ *
+ * @param areaAddress area address
+ */
+ public void setAreaAddress(String areaAddress) {
+ this.areaAddress = areaAddress;
+ }
+
+ /**
+ * Returns area length.
+ *
+ * @return area length
+ */
+ public int getAreaLength() {
+ return areaLength;
+ }
+
+ /**
+ * Sets area length.
+ *
+ * @param areaLength area length
+ */
+ public void setAreaLength(int areaLength) {
+ this.areaLength = areaLength;
+ }
+
+ /**
+ * Returns LSP ID.
+ *
+ * @return LSP ID
+ */
+ public String getLspId() {
+ return lspId;
+ }
+
+ /**
+ * Sets LSP ID.
+ *
+ * @param lspId link state packet ID
+ */
+ public void setLspId(String lspId) {
+ this.lspId = lspId;
+ }
+
+ /**
+ * Returns holding time.
+ *
+ * @return holding time
+ */
+ public int holdingTime() {
+ return holdingTime;
+ }
+
+ /**
+ * Sets holding time.
+ *
+ * @param holdingTime holding time
+ */
+ public void setHoldingTime(int holdingTime) {
+ this.holdingTime = holdingTime;
+ }
+
+ /**
+ * Returns priority.
+ *
+ * @return priority
+ */
+ public int priority() {
+ return priority;
+ }
+
+ /**
+ * Sets priority.
+ *
+ * @param priority priority
+ */
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ /**
+ * Returns hello interval.
+ *
+ * @return hello interval
+ */
+ public int helloInterval() {
+ return helloInterval;
+ }
+
+ /**
+ * Sets hello interval.
+ *
+ * @param helloInterval hello interval
+ */
+ public void setHelloInterval(int helloInterval) {
+ this.helloInterval = helloInterval;
+ }
+
+ /**
+ * Returns the interface state.
+ *
+ * @return interface state
+ */
+ public IsisInterfaceState interfaceState() {
+ return interfaceState;
+ }
+
+ /**
+ * Sets the interface state.
+ *
+ * @param interfaceState the interface state
+ */
+ public void setInterfaceState(IsisInterfaceState interfaceState) {
+ this.interfaceState = interfaceState;
+ }
+
+ /**
+ * Returns the circuit ID.
+ *
+ * @return circuit ID
+ */
+ public String circuitId() {
+ return circuitId;
+ }
+
+ /**
+ * Sets the circuit ID.
+ *
+ * @param circuitId circuit ID
+ */
+ public void setCircuitId(String circuitId) {
+ this.circuitId = circuitId;
+ }
+
+ /**
+ * Processes received ISIS message.
+ * When an ISIS message received it is handed over to this method.
+ * Based on the type of the ISIS message received it will be handed over
+ * to corresponding message handler methods.
+ *
+ * @param isisMessage received ISIS message
+ * @param isisLsdb ISIS LSDB instance
+ */
+ public void processIsisMessage(IsisMessage isisMessage, IsisLsdb isisLsdb, Channel channel) {
+ log.debug("IsisInterfaceImpl::processIsisMessage...!!!");
+ if (channel == null) {
+ this.channel = channel;
+ }
+ if (this.isisLsdb == null) {
+ this.isisLsdb = isisLsdb;
+ }
+
+ switch (isisMessage.isisPduType()) {
+ case L1HELLOPDU:
+ case L2HELLOPDU:
+ processL1L2HelloPduMessage(isisMessage, channel);
+ break;
+ case P2PHELLOPDU:
+ processP2pHelloPduMessage(isisMessage, channel);
+ break;
+ case L1LSPDU:
+ case L2LSPDU:
+ processLsPduMessage(isisMessage, channel);
+ break;
+ case L1CSNP:
+ case L2CSNP:
+ processCsnPduMessage(isisMessage, channel);
+ break;
+ case L1PSNP:
+ case L2PSNP:
+ log.debug("Received a PSNP packet...!!!");
+ break;
+ default:
+ log.debug("Unknown packet to process...!!!");
+ break;
+ }
+ }
+
+ /**
+ * Validates the received message.
+ *
+ * @param helloPdu ISIS message instance
+ * @return true if valid ISIS message else false
+ */
+ public boolean validateHelloMessage(HelloPdu helloPdu) {
+ boolean isValid = false;
+
+ //Local InterfaceAddress TLV and compare with the IP Interface address and check if they are in same subnet
+ List<Ip4Address> interfaceIpAddresses = helloPdu.interfaceIpAddresses();
+ Ip4Address neighborIp = (helloPdu.interfaceIpAddresses() != null) ?
+ interfaceIpAddresses.get(0) : Ip4Address.valueOf("0.0.0.0");
+ if (!IsisUtil.sameNetwork(interfaceIpAddress, neighborIp, networkMask)) {
+ return false;
+ }
+
+ //Verify if it's in same area, Areas which the router belongs to
+ List<String> areas = helloPdu.areaAddress();
+ for (String area : areas) {
+ if (areaAddress.equals(area)) {
+ isValid = true;
+ }
+ }
+
+ return isValid;
+ }
+
+ /**
+ * Checks neighbor presents in the list or not.
+ *
+ * @param neighborMac neighbor MAc address
+ * @return true if neighbor exist else false
+ */
+ private boolean isNeighborInList(MacAddress neighborMac) {
+ return neighborList.containsKey(neighborMac);
+ }
+
+ /**
+ * Adds neighbor in the list.
+ *
+ * @param neighbor neighbor MAC address
+ * @return true if neighbor exist else false
+ */
+ private void addNeighbouringRouter(IsisNeighbor neighbor) {
+ neighborList.put(neighbor.neighborMacAddress(), neighbor);
+ }
+
+ /**
+ * Returns neighbor presents in the list.
+ *
+ * @param neighborMac neighbor MAc address
+ * @return neighbor instance
+ */
+ private IsisNeighbor neighbouringRouter(MacAddress neighborMac) {
+ return neighborList.get(neighborMac);
+ }
+
+ /**
+ * Processes the L1 or L2 hello message.
+ *
+ * @param isisMessage hello message instance
+ * @param channel channel instance
+ */
+ public void processL1L2HelloPduMessage(IsisMessage isisMessage, Channel channel) {
+ log.debug("Enters processL1L2HelloPduMessage ...!!!");
+ log.debug("IsisInterfaceImpl::processHelloMessage...!!!");
+
+ L1L2HelloPdu helloPacket = (L1L2HelloPdu) isisMessage;
+ log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} ISISInterfaceState {} ",
+ networkType, interfaceState);
+
+ //If L1 Hello, validate the area, network and max address
+ if (IsisPduType.get(helloPacket.pduType()) == IsisPduType.L1HELLOPDU &&
+ !validateHelloMessage(helloPacket)) {
+ return;
+ }
+
+ //Get the neighbor
+ IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
+ //Neighbor is not in list
+ if (!isNeighborInList(isisMessage.sourceMac())) {
+ neighbor = new DefaultIsisNeighbor(helloPacket, this);
+ addNeighbouringRouter(neighbor);
+ }
+
+ neighbor.stopInactivityTimeCheck();
+ neighbor.startInactivityTimeCheck();
+
+ //Assign the DIS
+ String lanId = helloPacket.lanId();
+
+ if (IsisPduType.L1HELLOPDU == helloPacket.isisPduType()) {
+ buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
+ l1LanId = lanId;
+ neighbor.setL1LanId(lanId);
+ //if a change in lanid
+ } else if (IsisPduType.L2HELLOPDU == helloPacket.isisPduType()) {
+ buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
+ l2LanId = lanId;
+ neighbor.setL2LanId(lanId);
+ }
+
+ //Check in neighbors list our MAC address present
+ List<MacAddress> neighbors = helloPacket.neighborList();
+ for (MacAddress macAddress : neighbors) {
+ if (interfaceMacAddress.equals(macAddress)) {
+ neighbor.setNeighborState(IsisInterfaceState.UP);
+ //Build Self LSP add in LSDB and sent it.
+ buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Builds and store and send self generated LSP.
+ *
+ * @param channel netty channel instance
+ */
+ private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel) {
+ //Check our LSP is present in DB. else create a self LSP and store it and sent it
+ String lspKey = isisLsdb.lspKey(systemId);
+ LspWrapper wrapper = null;
+ if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
+ wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
+ if (wrapper == null) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ }
+ } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
+ wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
+ if (wrapper == null) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ }
+ } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
+ wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
+ if (wrapper == null) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ }
+
+ wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
+ if (wrapper == null) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ }
+ }
+ }
+
+ /**
+ * Builds and update in DB and send self generated LSP.
+ *
+ * @param previousLanId previous DIS ID
+ * @param latestLanId latest DIS ID
+ * @param channel netty channel instance
+ */
+ private void buildUpdateAndSendSelfGeneratedLspIfDisChange(String previousLanId,
+ String latestLanId, Channel channel) {
+ //If DIS change then build and sent LSP
+ if (previousLanId != null && !previousLanId.equals(IsisConstants.DEFAULTLANID) &&
+ !previousLanId.equals(latestLanId)) {
+ //Create a self LSP and Update it in DB and sent it
+ String lspKey = isisLsdb.lspKey(systemId);
+ if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ } else if (reservedPacketCircuitType == IsisRouterType.L1L2.value()) {
+ //L1 LSPDU
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L1LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ //L1 LSPDU
+ lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
+ isisLsdb.addLsp(lsp, true, this);
+ sendLsp(lsp, channel);
+ }
+ }
+
+ }
+
+ /**
+ * Sends LS PDU message to channel.
+ *
+ * @param lsp LS PDU message instance
+ * @param channel channel instance
+ */
+ private void sendLsp(LsPdu lsp, Channel channel) {
+ byte[] lspBytes = lsp.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, interfaceIndex));
+ }
+
+ /**
+ * Processes P2P hello message.
+ *
+ * @param isisMessage hello message instance
+ * @param channel channel instance
+ */
+ public void processP2pHelloPduMessage(IsisMessage isisMessage, Channel channel) {
+ log.debug("Enters processP2pHelloPduMessage ...!!!");
+ P2PHelloPdu helloPacket = (P2PHelloPdu) isisMessage;
+
+ log.debug("IsisInterfaceImpl::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
+ networkType, interfaceState);
+
+ //validate the area, network and max address
+ if (!validateHelloMessage(helloPacket)) {
+ return;
+ }
+
+ IsisNeighbor neighbor = null;
+ List<IsisTlv> tlvs = ((P2PHelloPdu) isisMessage).tlvs();
+ AdjacencyStateTlv stateTlv = null;
+ for (IsisTlv tlv : tlvs) {
+ if (tlv instanceof AdjacencyStateTlv) {
+ stateTlv = (AdjacencyStateTlv) tlv;
+ break;
+ }
+ }
+
+ if (stateTlv == null) {
+ neighbor = neighbouringRouter(isisMessage.sourceMac());
+ if (neighbor == null) {
+ neighbor = new DefaultIsisNeighbor(helloPacket, this);
+ addNeighbouringRouter(neighbor);
+ }
+ neighbor.setNeighborState(IsisInterfaceState.DOWN);
+ buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
+ } else if (stateTlv.adjacencyType() == IsisInterfaceState.DOWN.value()) {
+ neighbor = neighbouringRouter(isisMessage.sourceMac());
+ if (neighbor == null) {
+ neighbor = new DefaultIsisNeighbor(helloPacket, this);
+ addNeighbouringRouter(neighbor);
+ }
+ neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
+ } else if (stateTlv.adjacencyType() == IsisInterfaceState.INITIAL.value()) {
+ //Neighbor already present in the list
+ neighbor = neighbouringRouter(isisMessage.sourceMac());
+ neighbor.setNeighborState(IsisInterfaceState.INITIAL);
+ neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
+ //interfaceState = IsisInterfaceState.UP;
+ } else if (stateTlv.adjacencyType() == IsisInterfaceState.UP.value()) {
+ //Build Self LSP add in LSDB and sent it.
+ neighbor = neighbouringRouter(isisMessage.sourceMac());
+ neighbor.setNeighborState(IsisInterfaceState.UP);
+ neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
+ buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
+ }
+
+ neighbor.stopInactivityTimeCheck();
+ neighbor.startInactivityTimeCheck();
+ }
+
+ /**
+ * Processes LS PDU message.
+ *
+ * @param isisMessage LS pdu message instance
+ * @param channel channel instance
+ */
+ public void processLsPduMessage(IsisMessage isisMessage, Channel channel) {
+ log.debug("Enters processLsPduMessage ...!!!");
+ LsPdu lsPdu = (LsPdu) isisMessage;
+ LspWrapper wrapper = isisLsdb.findLsp(lsPdu.isisPduType(), lsPdu.lspId());
+ if (wrapper == null || isisLsdb.isNewerOrSameLsp(lsPdu, wrapper.lsPdu()).equalsIgnoreCase("latest")) {
+ //not exist in the database or latest, then add it in database
+ isisLsdb.addLsp(lsPdu, false, this);
+ }
+
+ //If network type is P2P, acknowledge with a PSNP
+ if (networkType() == IsisNetworkType.P2P) {
+ IsisPduType psnpType = null;
+ if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L1LSPDU) {
+ psnpType = IsisPduType.L1PSNP;
+ } else if (IsisPduType.get(lsPdu.pduType()) == IsisPduType.L2LSPDU) {
+ psnpType = IsisPduType.L2PSNP;
+ }
+ IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
+ Psnp psnp = new Psnp(isisHeader);
+ psnp.setSourceId(lspKeyP2P(this.systemId));
+ TlvHeader tlvHeader = new TlvHeader();
+ tlvHeader.setTlvType(TlvType.LSPENTRY.value());
+ tlvHeader.setTlvLength(0);
+ LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
+ LspEntry lspEntry = new LspEntry();
+ lspEntry.setLspChecksum(lsPdu.checkSum());
+ lspEntry.setLspId(lsPdu.lspId());
+ lspEntry.setLspSequenceNumber(lsPdu.sequenceNumber());
+ lspEntry.setRemainingTime(lsPdu.remainingLifeTime());
+ lspEntriesTlv.addLspEntry(lspEntry);
+ psnp.addTlv(lspEntriesTlv);
+
+ //write it to channel buffer.
+ byte[] psnpBytes = psnp.asBytes();
+ psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
+ IsisConstants.LENGTHPOSITION + 1,
+ IsisConstants.RESERVEDPOSITION);
+ flagValue = false;
+ //write to the channel
+ channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+ }
+ }
+
+ /**
+ * Processes CSN PDU message.
+ *
+ * @param isisMessage CSN PDU message instance
+ * @param channel channel instance
+ */
+ public void processCsnPduMessage(IsisMessage isisMessage, Channel channel) {
+ log.debug("Enters processCsnPduMessage ...!!!");
+ if (reservedPacketCircuitType == IsisRouterType.L1.value()) {
+ processOnL1CsnPdu(isisMessage, channel);
+ } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
+ processOnL2CsnPdu(isisMessage, channel);
+ }
+ }
+
+ /**
+ * Process the isisMessage which belongs to L1 CSN PDU.
+ * checks the database for this LsPdu if it exists further check for sequence number
+ * sequence number is greater will send PsnPdu.
+ *
+ * @param isisMessage CSN PDU message instance
+ * @param channel netty channel instance
+ */
+ private void processOnL1CsnPdu(IsisMessage isisMessage, Channel channel) {
+ Csnp csnPacket = (Csnp) isisMessage;
+ List<LspEntry> lspEntryRequestList = new ArrayList<>();
+ boolean selfOriginatedFound = false;
+ if (IsisPduType.L1CSNP.equals(csnPacket.isisPduType())) {
+ List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
+ Iterator iterator = isisTlvs.iterator();
+ while (iterator.hasNext()) {
+ IsisTlv isisTlv = (IsisTlv) iterator.next();
+ if (isisTlv instanceof LspEntriesTlv) {
+ LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
+ List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
+ Iterator lspEntryListIterator = lspEntryList.iterator();
+ while (lspEntryListIterator.hasNext()) {
+ LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
+ String lspKey = lspEntry.lspId();
+ LspWrapper lspWrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
+ if (lspWrapper != null) {
+ LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
+ if (lspWrapper.isSelfOriginated()) {
+ selfOriginatedFound = true;
+ if (lspEntry.lspSequenceNumber() > lsPdu.sequenceNumber()) {
+ sendLsPduMessage(lspEntry.lspSequenceNumber(), csnPacket.isisPduType(), channel);
+ }
+ } else {
+ if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
+ lspEntryRequestList.add(lspEntry);
+ flagValue = true;
+ }
+ }
+ } else {
+ lspEntryRequestList.add(lspEntry);
+ flagValue = true;
+ }
+ }
+ }
+ }
+ if (flagValue) {
+ sendPsnPduMessage(lspEntryRequestList, csnPacket.isisPduType(), channel);
+ }
+
+ if (!selfOriginatedFound) {
+ String lspKey = isisLsdb.lspKey(systemId);
+ LspWrapper wrapper = isisLsdb.findLsp(IsisPduType.L1LSPDU, lspKey);
+ sendLsp((LsPdu) wrapper.lsPdu(), channel);
+ }
+ }
+ }
+
+ /**
+ * Process the isisMessage which belongs to L2 CSNP.
+ * checks the database for this LsPdu if it exists further check for sequence number
+ * sequence number is greater will send PsnPdu.
+ *
+ * @param isisMessage received CSNP message
+ * @param channel netty channel instance
+ */
+ private void processOnL2CsnPdu(IsisMessage isisMessage, Channel channel) {
+ Csnp csnPacket = (Csnp) isisMessage;
+ List<LspEntry> lspEntryRequestList = new ArrayList<>();
+ boolean selfOriginatedFound = false;
+ if (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) {
+ List<IsisTlv> isisTlvs = csnPacket.getAllTlv();
+ Iterator iterator = isisTlvs.iterator();
+ while (iterator.hasNext()) {
+ IsisTlv isisTlv = (IsisTlv) iterator.next();
+ if (isisTlv instanceof LspEntriesTlv) {
+ LspEntriesTlv lspEntriesTlv = (LspEntriesTlv) isisTlv;
+ List<LspEntry> lspEntryList = lspEntriesTlv.lspEntry();
+ Iterator lspEntryListIterator = lspEntryList.iterator();
+ while (lspEntryListIterator.hasNext()) {
+ LspEntry lspEntry = (LspEntry) lspEntryListIterator.next();
+ String lspKey = lspEntry.lspId();
+ LspWrapper lspWrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
+ if (lspWrapper != null) {
+ LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
+ if (lspWrapper.isSelfOriginated()) {
+ selfOriginatedFound = true;
+ if (lspEntry.lspSequenceNumber() > lsPdu.sequenceNumber()) {
+ sendLsPduMessage(lspEntry.lspSequenceNumber(), csnPacket.isisPduType(), channel);
+ }
+ } else {
+ if (lsPdu.sequenceNumber() < lspEntry.lspSequenceNumber()) {
+ lspEntryRequestList.add(lspEntry);
+ flagValue = true;
+ }
+ }
+ } else {
+ lspEntryRequestList.add(lspEntry);
+ flagValue = true;
+ }
+ }
+ }
+ }
+ if (flagValue) {
+ sendPsnPduMessage(lspEntryRequestList, csnPacket.isisPduType(), channel);
+ lspEntryRequestList.clear();
+ }
+
+ if (!selfOriginatedFound) {
+ String lspKey = isisLsdb.lspKey(systemId);
+ LspWrapper wrapper = isisLsdb.findLsp(IsisPduType.L2LSPDU, lspKey);
+ sendLsp((LsPdu) wrapper.lsPdu(), channel);
+ }
+ }
+ }
+
+ /**
+ * Sends the partial sequence number PDU.
+ *
+ * @param lspEntryRequestList list of lsp entry request
+ * @param isisPduType intermediate system PDU type
+ * @param channel netty channel instance
+ */
+ private void sendPsnPduMessage(List<LspEntry> lspEntryRequestList, IsisPduType isisPduType, Channel channel) {
+ IsisPduType psnpType = null;
+ if (isisPduType == IsisPduType.L1CSNP) {
+ psnpType = IsisPduType.L1PSNP;
+ } else if (reservedPacketCircuitType == IsisRouterType.L2.value()) {
+ psnpType = IsisPduType.L2PSNP;
+ }
+ IsisHeader isisHeader = new LspGenerator().getHeader(psnpType);
+ Psnp psnp = new Psnp(isisHeader);
+ psnp.setSourceId(lspKeyP2P(this.systemId));
+ TlvHeader tlvHeader = new TlvHeader();
+ tlvHeader.setTlvType(TlvType.LSPENTRY.value());
+ tlvHeader.setTlvLength(0);
+ LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
+ for (LspEntry lspEntry : lspEntryRequestList) {
+ lspEntriesTlv.addLspEntry(lspEntry);
+ }
+ psnp.addTlv(lspEntriesTlv);
+ //write it to channel buffer.
+ byte[] psnpBytes = psnp.asBytes();
+ psnpBytes = IsisUtil.addLengthAndMarkItInReserved(psnpBytes, IsisConstants.LENGTHPOSITION,
+ IsisConstants.LENGTHPOSITION + 1,
+ IsisConstants.RESERVEDPOSITION);
+ flagValue = false;
+ //write to the channel
+ channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+ }
+
+ /**
+ * Gets the LSP key.
+ *
+ * @param systemId system ID
+ * @return key
+ */
+ public String lspKeyP2P(String systemId) {
+ StringBuilder lspKey = new StringBuilder();
+ lspKey.append(systemId);
+ lspKey.append(".00");
+ return lspKey.toString();
+ }
+
+ /**
+ * Sends the link state PDU with latest self generated lsp entry.
+ *
+ * @param sequenceNumber sequence number of the self generated lsp
+ * @param isisPduType intermediate system type
+ * @param channel netty channel instance
+ */
+ private void sendLsPduMessage(int sequenceNumber, IsisPduType isisPduType, Channel channel) {
+ String lspKey = isisLsdb.lspKey(systemId);
+ LsPdu lsp = new LspGenerator().getLsp(this, lspKey, isisPduType, allConfiguredInterfaceIps);
+ lsp.setSequenceNumber(sequenceNumber);
+ byte[] lspBytes = lsp.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, interfaceIndex));
+ }
+
+
+ /**
+ * Starts the hello timer which sends hello packet every configured seconds.
+ *
+ * @param channel netty channel instance
+ */
+ public void startHelloSender(Channel channel) {
+ log.debug("IsisInterfaceImpl::startHelloSender");
+
+ isisHelloPduSender = new IsisHelloPduSender(channel, this);
+ exServiceHello = Executors.newSingleThreadScheduledExecutor();
+ final ScheduledFuture<?> helloHandle =
+ exServiceHello.scheduleAtFixedRate(isisHelloPduSender, 0,
+ helloInterval, TimeUnit.SECONDS);
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java
new file mode 100755
index 0000000..3180c5d
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java
@@ -0,0 +1,350 @@
+/*
+ * 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;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisInterfaceState;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.IsisRouterType;
+import org.onosproject.isis.io.isispacket.pdu.HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of an ISIS neighbor.
+ * The first thing an ISIS router must do is find its neighbors and form adjacency.
+ * Each neighbor that the router finds will be represented by this class.
+ */
+public class DefaultIsisNeighbor implements IsisNeighbor {
+ private static final Logger log = LoggerFactory.getLogger(DefaultIsisNeighbor.class);
+ private String neighborAreaId;
+ private String neighborSystemId;
+ private Ip4Address interfaceIp;
+ private MacAddress neighborMacAddress;
+ private int holdingTime;
+ private IsisRouterType routerType;
+ private String l1LanId;
+ private String l2LanId;
+ private byte localCircuitId;
+ private int localExtendedCircuitId;
+ private IsisInterfaceState neighborState = IsisInterfaceState.INITIAL;
+ private InternalInactivityTimeCheck inActivityTimeCheckTask;
+ private ScheduledExecutorService exServiceInActivity;
+ private boolean inActivityTimerScheduled = false;
+ private IsisInterface isisInterface;
+
+ /**
+ * Creates an instance of ISIS neighbor.
+ *
+ * @param helloMessage hello message instance
+ * @param isisInterface ISIS interface instance
+ */
+ public DefaultIsisNeighbor(HelloPdu helloMessage, IsisInterface isisInterface) {
+ this.neighborMacAddress = helloMessage.sourceMac();
+ List<String> areaAddresses = helloMessage.areaAddress();
+ this.neighborAreaId = (areaAddresses != null) ? areaAddresses.get(0) : "";
+ this.neighborSystemId = helloMessage.sourceId();
+ List<Ip4Address> interfaceIpAddresses = helloMessage.interfaceIpAddresses();
+ this.interfaceIp = (helloMessage.interfaceIpAddresses() != null) ?
+ interfaceIpAddresses.get(0) : IsisConstants.DEFAULTIP;
+ this.holdingTime = helloMessage.holdingTime();
+ this.routerType = IsisRouterType.get(helloMessage.circuitType());
+ if (helloMessage instanceof L1L2HelloPdu) {
+ if (IsisPduType.L1HELLOPDU == helloMessage.isisPduType()) {
+ l1LanId = ((L1L2HelloPdu) helloMessage).lanId();
+ } else if (IsisPduType.L2HELLOPDU == helloMessage.isisPduType()) {
+ l2LanId = ((L1L2HelloPdu) helloMessage).lanId();
+ }
+ } else if (helloMessage instanceof P2PHelloPdu) {
+ this.localCircuitId = ((P2PHelloPdu) helloMessage).localCircuitId();
+ }
+ this.isisInterface = isisInterface;
+ }
+
+ /**
+ * Returns local extended circuit ID.
+ *
+ * @return local extended circuit ID
+ */
+ public int localExtendedCircuitId() {
+ return localExtendedCircuitId;
+ }
+
+ /**
+ * Sets local extended circuit ID.
+ *
+ * @param localExtendedCircuitId neighbor extended circuit ID
+ */
+ public void setLocalExtendedCircuitId(int localExtendedCircuitId) {
+ this.localExtendedCircuitId = localExtendedCircuitId;
+ }
+
+ /**
+ * Returns neighbor area ID.
+ *
+ * @return neighbor area ID
+ */
+ public String neighborAreaId() {
+ return neighborAreaId;
+ }
+
+ /**
+ * Sets neighbor area ID.
+ *
+ * @param neighborAreaId neighbor area ID
+ */
+ public void setNeighborAreaId(String neighborAreaId) {
+ this.neighborAreaId = neighborAreaId;
+ }
+
+ /**
+ * Returns neighbor system ID.
+ *
+ * @return neighbor system ID
+ */
+ public String neighborSystemId() {
+ return neighborSystemId;
+ }
+
+ /**
+ * Sets neighbor system ID.
+ *
+ * @param neighborSystemId neighbor system ID
+ */
+ public void setNeighborSystemId(String neighborSystemId) {
+ this.neighborSystemId = neighborSystemId;
+ }
+
+ /**
+ * Returns interface IP.
+ *
+ * @return interface IP
+ */
+ public Ip4Address interfaceIp() {
+ return interfaceIp;
+ }
+
+ /**
+ * Sets interface IP.
+ *
+ * @param interfaceIp IP
+ */
+ public void setInterfaceIp(Ip4Address interfaceIp) {
+ this.interfaceIp = interfaceIp;
+ }
+
+ /**
+ * Returns neighbor mac address.
+ *
+ * @return neighborMacAddress neighbor mac address
+ */
+ public MacAddress neighborMacAddress() {
+ return neighborMacAddress;
+ }
+
+ /**
+ * Sets neighbor mac address.
+ *
+ * @param neighborMacAddress mac address
+ */
+ public void setNeighborMacAddress(MacAddress neighborMacAddress) {
+ this.neighborMacAddress = neighborMacAddress;
+ }
+
+ /**
+ * Returns holding time.
+ *
+ * @return holding time
+ */
+ public int holdingTime() {
+ return holdingTime;
+ }
+
+ /**
+ * Sets holding time.
+ *
+ * @param holdingTime holding time
+ */
+ public void setHoldingTime(int holdingTime) {
+ this.holdingTime = holdingTime;
+ }
+
+ /**
+ * Returns router type.
+ *
+ * @return router type
+ */
+ public IsisRouterType routerType() {
+ return routerType;
+ }
+
+ /**
+ * Sets router type.
+ *
+ * @param routerType router type
+ */
+ public void setRouterType(IsisRouterType routerType) {
+ this.routerType = routerType;
+ }
+
+ /**
+ * Returns L1 lan ID.
+ *
+ * @return L1 lan ID
+ */
+ public String l1LanId() {
+ return l1LanId;
+ }
+
+ /**
+ * Sets L1 lan ID.
+ *
+ * @param l1LanId L1 lan ID
+ */
+ public void setL1LanId(String l1LanId) {
+ this.l1LanId = l1LanId;
+ }
+
+ /**
+ * Returns L2 lan ID.
+ *
+ * @return L2 lan ID
+ */
+ public String l2LanId() {
+ return l2LanId;
+ }
+
+ /**
+ * Sets L2 lan ID.
+ *
+ * @param l2LanId L2 lan ID
+ */
+ public void setL2LanId(String l2LanId) {
+ this.l1LanId = l1LanId;
+ }
+
+ /**
+ * Gets the neighbor interface state.
+ *
+ * @return neighbor interface state
+ */
+ public IsisInterfaceState interfaceState() {
+ return neighborState;
+ }
+
+ /**
+ * Sets the neighbor interface state.
+ *
+ * @param neighborState the neighbor interface state
+ */
+ public void setNeighborState(IsisInterfaceState neighborState) {
+ this.neighborState = neighborState;
+ }
+
+ /**
+ * Returns local circuit ID.
+ *
+ * @return local circuit ID
+ */
+ public byte localCircuitId() {
+ return localCircuitId;
+ }
+
+ /**
+ * Sets local circuit ID.
+ *
+ * @param localCircuitId local circuit ID
+ */
+ public void setLocalCircuitId(byte localCircuitId) {
+ this.localCircuitId = localCircuitId;
+ }
+
+ /**
+ * Returns neighbor state.
+ *
+ * @return neighbor state
+ */
+ public IsisInterfaceState neighborState() {
+ return neighborState;
+ }
+
+ /**
+ * Starts the inactivity timer.
+ */
+ public void startInactivityTimeCheck() {
+ if (!inActivityTimerScheduled) {
+ log.debug("IsisNeighbor::startInactivityTimeCheck");
+ inActivityTimeCheckTask = new InternalInactivityTimeCheck();
+ exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
+ exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, holdingTime,
+ holdingTime, TimeUnit.SECONDS);
+ inActivityTimerScheduled = true;
+ }
+ }
+
+ /**
+ * Stops the inactivity timer.
+ */
+ public void stopInactivityTimeCheck() {
+ if (inActivityTimerScheduled) {
+ log.debug("IsisNeighbor::stopInactivityTimeCheck ");
+ exServiceInActivity.shutdown();
+ inActivityTimerScheduled = false;
+ }
+ }
+
+ /**
+ * Called when neighbor is down.
+ */
+ public void neighborDown() {
+ log.debug("Neighbor Down {} and NeighborSystemId {}", neighborMacAddress,
+ neighborSystemId);
+ stopInactivityTimeCheck();
+ isisInterface.setL1LanId(IsisConstants.DEFAULTLANID);
+ isisInterface.setL2LanId(IsisConstants.DEFAULTLANID);
+
+ neighborState = IsisInterfaceState.DOWN;
+ isisInterface.removeNeighbor(this);
+ }
+
+ /**
+ * Represents a Task which will do an inactivity time check.
+ */
+ private class InternalInactivityTimeCheck implements Runnable {
+ /**
+ * Creates an instance.
+ */
+ InternalInactivityTimeCheck() {
+ }
+
+ @Override
+ public void run() {
+ log.debug("Neighbor Not Heard till the past router dead interval .");
+ neighborDown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisProcess.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisProcess.java
new file mode 100755
index 0000000..cc8bfd4
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisProcess.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisProcess;
+
+import java.util.List;
+
+/**
+ * Represents of an ISIS process.
+ */
+public class DefaultIsisProcess implements IsisProcess {
+ private String processId;
+ private List<IsisInterface> isisInterfaceList;
+
+ /**
+ * Gets process ID.
+ *
+ * @return process ID
+ */
+ public String processId() {
+ return processId;
+ }
+
+ /**
+ * Sets process ID.
+ *
+ * @param processId process ID
+ */
+ public void setProcessId(String processId) {
+ this.processId = processId;
+ }
+
+ /**
+ * Gets list of ISIS interface details.
+ *
+ * @return list of ISIS interface details
+ */
+ public List<IsisInterface> isisInterfaceList() {
+ return isisInterfaceList;
+ }
+
+ /**
+ * Sets list of ISIS interface details.
+ *
+ * @param isisInterfaceList list of ISIS interface details
+ */
+ public void setIsisInterfaceList(List<IsisInterface> isisInterfaceList) {
+ this.isisInterfaceList = isisInterfaceList;
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java
new file mode 100755
index 0000000..064176d
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisChannelHandler.java
@@ -0,0 +1,251 @@
+/*
+ * 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;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
+import org.jboss.netty.handler.timeout.ReadTimeoutException;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisMessage;
+import org.onosproject.isis.controller.IsisProcess;
+import org.onosproject.isis.controller.impl.lsdb.DefaultIsisLsdb;
+import org.onosproject.isis.exceptions.IsisParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Channel handler deals with the ISIS channel connection.
+ * Also it dispatches messages to the appropriate handlers for processing.
+ */
+public class IsisChannelHandler extends IdleStateAwareChannelHandler {
+
+ private static final Logger log = LoggerFactory.getLogger(IsisChannelHandler.class);
+ private static Map<Integer, Object> isisDb = null;
+ private Channel channel;
+ private Controller controller;
+ private List<IsisProcess> processes = null;
+ private List<ScheduledExecutorService> executorList = new ArrayList<>();
+ private byte[] configPacket = null;
+ private Map<Integer, IsisInterface> isisInterfaceMap = new ConcurrentHashMap<>();
+ private IsisLsdb isisLsdb = new DefaultIsisLsdb();
+ private List<Ip4Address> interfaceIps = new ArrayList<>();
+
+ /**
+ * Creates an instance of ISIS channel handler.
+ *
+ * @param controller controller instance
+ * @param processes list of configured processes
+ */
+ public IsisChannelHandler(Controller controller, List<IsisProcess> processes) {
+ this.controller = controller;
+ this.processes = processes;
+ }
+
+ /**
+ * Initializes the interface map with interface details.
+ */
+ public void initializeInterfaceMap() {
+ for (IsisProcess process : processes) {
+ for (IsisInterface isisInterface : process.isisInterfaceList()) {
+ isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+ interfaceIps.add(isisInterface.interfaceIpAddress());
+ }
+ }
+ //Initializes the interface with all interface ip details - for ls pdu generation
+ initializeInterfaceIpList();
+ }
+
+ /**
+ * Updates the interface map with interface details.
+ *
+ * @param isisProcesses updated process instances
+ */
+ public void updateInterfaceMap(List<IsisProcess> isisProcesses) {
+ for (IsisProcess isisUpdatedProcess : isisProcesses) {
+ for (IsisInterface isisUpdatedInterface : isisUpdatedProcess.isisInterfaceList()) {
+ IsisInterface isisInterface = isisInterfaceMap.get(isisUpdatedInterface.interfaceIndex());
+ if (isisInterface == null) {
+ isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+ interfaceIps.add(isisInterface.interfaceIpAddress());
+ } else {
+ isisInterface.setReservedPacketCircuitType(isisUpdatedInterface.reservedPacketCircuitType());
+ isisInterface.setNetworkType(isisUpdatedInterface.networkType());
+ isisInterface.setHoldingTime(isisUpdatedInterface.holdingTime());
+ isisInterface.setHelloInterval(isisUpdatedInterface.helloInterval());
+ isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
+ }
+ }
+ }
+ }
+
+ /**
+ * Initializes the interface with all interface ip details.
+ */
+ public void initializeInterfaceIpList() {
+ for (IsisProcess process : processes) {
+ for (IsisInterface isisInterface : process.isisInterfaceList()) {
+ ((DefaultIsisInterface) isisInterface).setAllConfiguredInterfaceIps(interfaceIps);
+ }
+ }
+ }
+
+ /**
+ * Initialize channel, start hello sender and initialize LSDB.
+ */
+ private void initialize() {
+ log.debug("IsisChannelHandler initialize..!!!");
+ if (configPacket != null) {
+ log.debug("IsisChannelHandler initialize -> sentConfig packet of length ::"
+ + configPacket.length);
+ sentConfigPacket(configPacket);
+ }
+ //start the hello timer
+ startHelloSender();
+ //Initialize Database
+ isisLsdb.initializeDb();
+ }
+
+ @Override
+ public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) throws Exception {
+ log.info("ISIS channelConnected from {}", evt.getChannel().getRemoteAddress());
+ this.channel = evt.getChannel();
+ initialize();
+ }
+
+ @Override
+ public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
+ log.debug("IsisChannelHandler::channelDisconnected...!!!");
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+ log.info("[exceptionCaught]: " + e.toString());
+ if (e.getCause() instanceof ReadTimeoutException) {
+ log.error("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
+ return;
+ } else if (e.getCause() instanceof ClosedChannelException) {
+ log.debug("Channel for ISIS {} already closed", e.getChannel().getRemoteAddress());
+ } else if (e.getCause() instanceof IOException) {
+ log.error("Disconnecting ISIS {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
+ e.getCause().getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("StackTrace for previous Exception: {}", e.getCause());
+ }
+ } else if (e.getCause() instanceof IsisParseException) {
+ IsisParseException errMsg = (IsisParseException) e.getCause();
+ byte errorCode = errMsg.errorCode();
+ byte errorSubCode = errMsg.errorSubCode();
+ log.error("Error while parsing message from ISIS {}, ErrorCode {}",
+ e.getChannel().getRemoteAddress(), errorCode);
+ } else if (e.getCause() instanceof RejectedExecutionException) {
+ log.warn("Could not process message: queue full");
+ } else {
+ log.error("Error while processing message from ISIS {}",
+ e.getChannel().getRemoteAddress());
+ }
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+ log.debug("IsisChannelHandler::messageReceived...!!!");
+ Object message = e.getMessage();
+ if (message instanceof List) {
+ List<IsisMessage> isisMessageList = (List<IsisMessage>) message;
+ log.debug("IsisChannelHandler::List of IsisMessages Size {}", isisMessageList.size());
+ if (isisMessageList != null) {
+ for (IsisMessage isisMessage : isisMessageList) {
+ processIsisMessage(isisMessage, ctx);
+ }
+ } else {
+ log.debug("IsisChannelHandler::IsisMessages Null List...!!");
+ }
+ }
+ if (message instanceof IsisMessage) {
+ IsisMessage isisMessage = (IsisMessage) message;
+ log.debug("IsisChannelHandler::IsisMessages received...!!");
+ processIsisMessage(isisMessage, ctx);
+ }
+ }
+
+ /**
+ * When an ISIS message received it is handed over to this method.
+ * Based on the type of the ISIS message received it will be handed over
+ * to corresponding message handler methods.
+ *
+ * @param isisMessage received ISIS message
+ * @param ctx channel handler context instance.
+ * @throws Exception might throws exception
+ */
+ public void processIsisMessage(IsisMessage isisMessage, ChannelHandlerContext ctx) throws Exception {
+ log.debug("IsisChannelHandler::processIsisMessage...!!!");
+ int interfaceIndex = isisMessage.interfaceIndex();
+ IsisInterface isisInterface = isisInterfaceMap.get(interfaceIndex);
+ isisInterface.processIsisMessage(isisMessage, isisLsdb, channel);
+ }
+
+ /**
+ * Starts the hello timer which sends hello packet every configured seconds.
+ */
+ public void startHelloSender() {
+ log.debug("IsisController::startHelloSender");
+ Set<Integer> interfaceIndexes = isisInterfaceMap.keySet();
+ for (Integer interfaceIndex : interfaceIndexes) {
+ IsisInterface isisInterface = isisInterfaceMap.get(interfaceIndex);
+ isisInterface.startHelloSender(channel);
+ }
+ }
+
+ /**
+ * Stops the hello timer.
+ */
+ public void stopHelloSender() {
+ log.debug("ISISChannelHandler::stopHelloTimer ");
+ for (ScheduledExecutorService exServiceHello : executorList) {
+ exServiceHello.shutdown();
+ }
+ }
+
+ /**
+ * Sends the interface configuration packet to server.
+ *
+ * @param configPacket interface configuration
+ */
+ public void sentConfigPacket(byte[] configPacket) {
+ if (channel != null) {
+ channel.write(configPacket);
+ log.debug("IsisChannelHandler sentConfigPacket packet sent..!!!");
+ } else {
+ log.debug("IsisChannelHandler sentConfigPacket channel not connected - re try..!!!");
+ this.configPacket = configPacket;
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisHelloPduSender.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisHelloPduSender.java
new file mode 100755
index 0000000..87338f5
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisHelloPduSender.java
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.channel.Channel;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisNetworkType;
+import org.onosproject.isis.controller.IsisRouterType;
+import org.onosproject.isis.io.util.IsisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Representation of an ISIS hello pdu sender task.
+ */
+public class IsisHelloPduSender implements Runnable {
+ private static final Logger log = LoggerFactory.getLogger(IsisHelloPduSender.class);
+ private Channel channel = null;
+ private IsisInterface isisInterface = null;
+
+ /**
+ * Creates an instance of Hello PDU Sender task.
+ *
+ * @param channel netty channel instance
+ * @param isisInterface ISIS interface instance
+ */
+ public IsisHelloPduSender(Channel channel, IsisInterface isisInterface) {
+ this.channel = channel;
+ this.isisInterface = isisInterface;
+ }
+
+ @Override
+ public void run() {
+ if (channel != null) {
+ try {
+ byte[] helloPdu = null;
+ byte[] interfaceIndex = {(byte) isisInterface.interfaceIndex()};
+
+ if (isisInterface.networkType() == IsisNetworkType.P2P) {
+ helloPdu = IsisUtil.getP2pHelloPdu(isisInterface, true);
+ helloPdu = Bytes.concat(helloPdu, interfaceIndex);
+ channel.write(helloPdu);
+ } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST) {
+ switch (IsisRouterType.get(isisInterface.reservedPacketCircuitType())) {
+ case L1:
+ helloPdu = IsisUtil.getL1HelloPdu(isisInterface, true);
+ helloPdu = Bytes.concat(helloPdu, interfaceIndex);
+ channel.write(helloPdu);
+ break;
+ case L2:
+ helloPdu = IsisUtil.getL2HelloPdu(isisInterface, true);
+ helloPdu = Bytes.concat(helloPdu, interfaceIndex);
+ channel.write(helloPdu);
+ break;
+ case L1L2:
+ helloPdu = IsisUtil.getL1HelloPdu(isisInterface, true);
+ helloPdu = Bytes.concat(helloPdu, interfaceIndex);
+ channel.write(helloPdu);
+
+ helloPdu = IsisUtil.getL2HelloPdu(isisInterface, true);
+ helloPdu = Bytes.concat(helloPdu, interfaceIndex);
+ channel.write(helloPdu);
+ break;
+ default:
+ log.debug("IsisHelloPduSender::Unknown circuit type...!!!");
+ break;
+ }
+ }
+ } catch (Exception e) {
+ log.debug("Exception @IsisHelloPduSender:: {}", e.getMessage());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageDecoder.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageDecoder.java
new file mode 100755
index 0000000..f2cbf19
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageDecoder.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisMessage;
+import org.onosproject.isis.io.isispacket.IsisMessageReader;
+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.LinkedList;
+import java.util.List;
+
+/**
+ * Decodes an ISIS message from a Channel, for use in a netty pipeline.
+ */
+public class IsisMessageDecoder extends FrameDecoder {
+
+ private static final Logger log = LoggerFactory.getLogger(IsisMessageDecoder.class);
+
+ @Override
+ protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
+ log.debug("IsisMessageDecoder::Message received <:> length {}", buffer.readableBytes());
+ if (!channel.isConnected()) {
+ log.info("Channel is not connected.");
+ return null;
+ }
+
+ IsisMessageReader messageReader = new IsisMessageReader();
+ List<IsisMessage> isisMessageList = new LinkedList<>();
+ int dataLength = buffer.readableBytes();
+ while (buffer.readableBytes() >= IsisConstants.MINIMUM_FRAME_LEN) {
+ ChannelBuffer payload = buffer.readBytes(IsisConstants.MINIMUM_FRAME_LEN);
+ ChannelBuffer ethernetHeader = payload.readBytes(IsisUtil.ETHER_HEADER_LEN);
+ //Read the Source MAC address from ethernet header at the 6th position
+ MacAddress sourceMac = getSourceMac(ethernetHeader);
+ //Strip 17 byte ethernet header and get the ISIS data buffer
+ ChannelBuffer isisDataBuffer = payload.readBytes(payload.readableBytes());
+ int readableBytes = isisDataBuffer.readableBytes();
+ IsisMessage message = messageReader.readFromBuffer(isisDataBuffer);
+ //Last 7 bytes is metadata. ie. interface MAC address and interface index.
+ if (message != null) {
+ if (isisDataBuffer.readableBytes() >= IsisConstants.METADATA_LEN) {
+ //Sets the source MAC
+ message.setSourceMac(sourceMac);
+ isisDataBuffer.readerIndex(readableBytes - IsisConstants.METADATA_LEN);
+ log.debug("IsisMessageDecoder::Reading metadata <:> length {}", isisDataBuffer.readableBytes());
+ byte[] macBytes = new byte[IsisUtil.SIX_BYTES];
+ isisDataBuffer.readBytes(macBytes, 0, IsisUtil.SIX_BYTES);
+ MacAddress macAddress = MacAddress.valueOf(macBytes);
+ int interfaceIndex = isisDataBuffer.readByte();
+ message.setInterfaceMac(macAddress);
+ message.setInterfaceIndex(interfaceIndex);
+ }
+ isisMessageList.add(message);
+ }
+ }
+
+ return isisMessageList;
+ }
+
+ /**
+ * Gets the source MAC address from the ethernet header.
+ *
+ * @param ethHeader ethernet header bytes
+ * @return MAC address of the source router
+ */
+ private MacAddress getSourceMac(ChannelBuffer ethHeader) {
+ //Source MAC is at position 6 to 11 (6 bytes)
+ ethHeader.skipBytes(IsisUtil.SIX_BYTES);
+ MacAddress sourceMac = MacAddress.valueOf(ethHeader.readBytes(IsisUtil.SIX_BYTES).array());
+
+ return sourceMac;
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageEncoder.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageEncoder.java
new file mode 100755
index 0000000..af46712
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisMessageEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encodes an ISIS message for output into a ChannelBuffer, for use in a netty pipeline.
+ */
+public class IsisMessageEncoder extends OneToOneEncoder {
+ private static final Logger log = LoggerFactory.getLogger(IsisMessageEncoder.class);
+
+ @Override
+ protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
+
+ byte[] byteMsg = (byte[]) msg;
+ log.debug("Encoding isisMessage of length {}", byteMsg.length);
+ ChannelBuffer channelBuffer = ChannelBuffers.buffer(byteMsg.length);
+ channelBuffer.writeBytes(byteMsg);
+
+ return channelBuffer;
+ }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisPipelineFactory.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisPipelineFactory.java
new file mode 100755
index 0000000..227bb2f
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/IsisPipelineFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+
+/**
+ * Creates a ChannelPipeline for a client-side ISIS channel.
+ */
+public class IsisPipelineFactory implements ChannelPipelineFactory {
+ private IsisChannelHandler isisChannelHandler;
+
+ /**
+ * Creates an instance of ISIS channel pipeline factory.
+ *
+ * @param isisChannelHandler ISIS channel handler instance
+ */
+ public IsisPipelineFactory(IsisChannelHandler isisChannelHandler) {
+ this.isisChannelHandler = isisChannelHandler;
+ }
+
+ @Override
+ public ChannelPipeline getPipeline() throws Exception {
+ ChannelPipeline pipeline = Channels.pipeline();
+ pipeline.addLast("encoder", new IsisMessageDecoder());
+ pipeline.addLast("decoder", new IsisMessageEncoder());
+ pipeline.addLast("handler", isisChannelHandler);
+
+ return pipeline;
+ }
+}
\ No newline at end of file
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
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/package-info.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/package-info.java
new file mode 100755
index 0000000..99f39be
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/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.
+ */
+package org.onosproject.isis.controller.impl;
\ No newline at end of file
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/pdu/LsPdu.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/pdu/LsPdu.java
index 11de4f4..f6bd85c 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/pdu/LsPdu.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/pdu/LsPdu.java
@@ -280,7 +280,7 @@
* Returns the packet data unit length of link state packet.
* Entire length of this PDU, in octets
*
- * @return pduLength packte date unit length
+ * @return pduLength packet data unit length
*/
public int pduLength() {
return pduLength;
@@ -290,7 +290,7 @@
* Sets the packet data unit length for link state packet.
* Entire Length of this PDU, in octets
*
- * @param pduLength packte data length
+ * @param pduLength packet data length
*/
public void setPduLength(int pduLength) {
this.pduLength = pduLength;
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IpExtendedReachabilityTlv.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IpExtendedReachabilityTlv.java
index 14962d8..f1549e4 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IpExtendedReachabilityTlv.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IpExtendedReachabilityTlv.java
@@ -220,10 +220,9 @@
byte[] bytes = null;
byte[] tlvHeader = tlvHeaderAsByteArray();
byte[] tlvBody = tlvBodyAsBytes();
- //systemID + pseudo number+length of subtlv=11l
- tlvBody[10] = (byte) (tlvBody.length - 11);
tlvHeader[1] = (byte) tlvBody.length;
bytes = Bytes.concat(tlvHeader, tlvBody);
+
return bytes;
}
@@ -246,8 +245,8 @@
} else {
controlInfo = controlInfo + "0";
}
- String prefixlength = IsisUtil.toEightBitBinary(Integer.toBinaryString(this.prefixLength()));
- controlInfo = controlInfo + prefixlength.substring(2, prefixlength.length());
+ String prefixLength = IsisUtil.toEightBitBinary(Integer.toBinaryString(this.prefixLength()));
+ controlInfo = controlInfo + prefixLength.substring(2, prefixLength.length());
bodyLst.add(Byte.parseByte(controlInfo, 2));
if (this.isSubTlvPresence()) {
bodyLst.add(this.subTlvLength());
@@ -255,6 +254,8 @@
bodyLst.addAll(SubTlvToBytes.tlvToBytes(trafficEngineeringSubTlv));
}
}
+ bodyLst.addAll(Bytes.asList(IsisUtil.prefixToBytes(this.prefix())));
+
return Bytes.toArray(bodyLst);
}
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IsExtendedReachability.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IsExtendedReachability.java
new file mode 100644
index 0000000..c6cd9f0
--- /dev/null
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/IsExtendedReachability.java
@@ -0,0 +1,151 @@
+/*
+ * 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.io.isispacket.tlv;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.isis.io.isispacket.tlv.subtlv.SubTlvFinder;
+import org.onosproject.isis.io.isispacket.tlv.subtlv.SubTlvToBytes;
+import org.onosproject.isis.io.isispacket.tlv.subtlv.SubTlvType;
+import org.onosproject.isis.io.isispacket.tlv.subtlv.TrafficEngineeringSubTlv;
+import org.onosproject.isis.io.util.IsisUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of IS extended reachability TLV.
+ */
+public class IsExtendedReachability extends TlvHeader implements IsisTlv {
+
+ private String neighborId;
+ private int metric;
+ private List<TrafficEngineeringSubTlv> trafEnginSubTlv = new ArrayList<>();
+
+ /**
+ * Creates an instance of IP external reachability TLV.
+ *
+ * @param tlvHeader TLV header
+ */
+ public IsExtendedReachability(TlvHeader tlvHeader) {
+ this.setTlvType(tlvHeader.tlvType());
+ this.setTlvLength(tlvHeader.tlvLength());
+ }
+
+ /**
+ * Returns neighbor ID.
+ *
+ * @return neighbor ID
+ */
+ public String neighborId() {
+ return neighborId;
+ }
+
+ /**
+ * Sets neighbor ID.
+ *
+ * @param neighborId neighbor ID
+ */
+ public void setNeighborId(String neighborId) {
+ this.neighborId = neighborId;
+ }
+
+ /**
+ * Returns metric.
+ *
+ * @return metric
+ */
+ public int metric() {
+ return metric;
+ }
+
+ /**
+ * Sets metric.
+ *
+ * @param metric metric
+ */
+ public void setMetric(int metric) {
+ this.metric = metric;
+ }
+
+ /**
+ * Adds the traffic engineering sub TLV to IS extended reachability TLV.
+ *
+ * @param trafEnginSubTlv traffic engineering sub TLV
+ */
+ public void addSubTlv(TrafficEngineeringSubTlv trafEnginSubTlv) {
+ this.trafEnginSubTlv.add(trafEnginSubTlv);
+ }
+
+ @Override
+ public void readFrom(ChannelBuffer channelBuffer) {
+ byte[] tempByteArray = new byte[IsisUtil.ID_SIX_BYTES];
+ channelBuffer.readBytes(tempByteArray, 0, IsisUtil.ID_SIX_BYTES);
+ this.setNeighborId(IsisUtil.systemId(tempByteArray));
+ this.setMetric(channelBuffer.readUnsignedMedium());
+ while (channelBuffer.readableBytes() > 0) {
+ TlvHeader tlvHeader = new TlvHeader();
+ tlvHeader.setTlvType(channelBuffer.readByte());
+ tlvHeader.setTlvLength(channelBuffer.readByte());
+ SubTlvType tlvValue = SubTlvType.get(tlvHeader.tlvType());
+ if (tlvValue != null) {
+ this.addSubTlv(SubTlvFinder.findSubTlv(tlvHeader,
+ channelBuffer.readBytes(tlvHeader.tlvLength())));
+ } else {
+ channelBuffer.readBytes(tlvHeader.tlvLength());
+ }
+ }
+ }
+
+ @Override
+ public byte[] asBytes() {
+ byte[] bytes = null;
+ byte[] tlvHeader = tlvHeaderAsByteArray();
+ byte[] tlvBody = tlvBodyAsBytes();
+ tlvHeader[1] = (byte) tlvBody.length;
+ bytes = Bytes.concat(tlvHeader, tlvBody);
+ return bytes;
+ }
+
+ /**
+ * Returns TLV body of IS extended reachability TLV.
+ *
+ * @return byteArray TLV body of IS extended reachability TLV.
+ */
+ private byte[] tlvBodyAsBytes() {
+ List<Byte> byteList = new ArrayList<>();
+ byteList.addAll(IsisUtil.sourceAndLanIdToBytes(this.neighborId()));
+ byteList.addAll(Bytes.asList(IsisUtil.convertToThreeBytes(this.metric())));
+ if (this.trafEnginSubTlv.size() > 0) {
+ for (TrafficEngineeringSubTlv trafficEngineeringSubTlv : this.trafEnginSubTlv) {
+ byteList.addAll(SubTlvToBytes.tlvToBytes(trafficEngineeringSubTlv));
+ }
+ }
+ return Bytes.toArray(byteList);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("neighborId", neighborId)
+ .add("metric", metric)
+ .add("trafEnginSubTlv", trafEnginSubTlv)
+ .toString();
+ }
+
+}
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/MetricOfInternalReachability.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/MetricOfInternalReachability.java
index 179b3e6..4ad4871 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/MetricOfInternalReachability.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/MetricOfInternalReachability.java
@@ -358,10 +358,7 @@
} else {
this.setErrorMetricSupported(false);
}
- List<Byte> byteList = new ArrayList<>();
- while (channelBuffer.readableBytes() > 0) {
- byteList.add(channelBuffer.readByte());
- }
+
byte[] tempByteArray = new byte[IsisUtil.FOUR_BYTES];
channelBuffer.readBytes(tempByteArray, 0, IsisUtil.FOUR_BYTES);
this.setIpAddress(Ip4Address.valueOf(tempByteArray));
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvFinder.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvFinder.java
index d6bb909..5e31c17 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvFinder.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvFinder.java
@@ -42,7 +42,10 @@
//TODO
break;
case EXTENDEDISREACHABILITY:
- //TODO
+ IsExtendedReachability isExtendedReachability =
+ new IsExtendedReachability(tlvHeader);
+ isExtendedReachability.readFrom(channelBuffer);
+ isisTlv = isExtendedReachability;
break;
case HOSTNAME:
HostNameTlv hostNameTlv = new HostNameTlv(tlvHeader);
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvsToBytes.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvsToBytes.java
index e3eba57..7978385 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvsToBytes.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/isispacket/tlv/TlvsToBytes.java
@@ -82,6 +82,10 @@
LspEntriesTlv lspEntriesTlv
= (LspEntriesTlv) isisTlv;
tlvBytes.addAll(Bytes.asList(lspEntriesTlv.asBytes()));
+ } else if (isisTlv instanceof IsExtendedReachability) {
+ IsExtendedReachability isExtendedReachability
+ = (IsExtendedReachability) isisTlv;
+ tlvBytes.addAll(Bytes.asList(isExtendedReachability.asBytes()));
} else {
log.debug("TlvsToBytes::UNKNOWN TLV TYPE ::TlvsToBytes ");
}
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java
deleted file mode 100644
index 9b37cbd..0000000
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.io.util;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-/**
- * Representation of ISIS config.
- */
-public enum IsisConfig {
- INSTANCE;
- private JsonNode jsonNodes = null;
-
- /**
- * Returns the config value.
- *
- * @return jsonNodes json node
- */
- public JsonNode config() {
- return jsonNodes;
- }
-
- /**
- * Sets the config value for jsonNode.
- *
- * @param jsonNodes json node
- */
- public void setConfig(JsonNode jsonNodes) {
- this.jsonNodes = jsonNodes;
- }
-}
\ No newline at end of file
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
index fe84218..cf5871a 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
@@ -16,21 +16,25 @@
package org.onosproject.isis.io.util;
+import org.onlab.packet.Ip4Address;
+
/**
* Representation of ISIS Constants.
*/
public final class IsisConstants {
- public static final char PDU_LENGTH = 1497; // mtu (1500) - (3) LLC
+ public static final char PDU_LENGTH = 1497;
+ public static final char CONFIG_LENGTH = 1498;
public static final int MINIMUM_FRAME_LEN = 1521;
public static final int METADATA_LEN = 7;
public static final String SHOST = "127.0.0.1";
+ public static final Ip4Address DEFAULTIP = Ip4Address.valueOf("0.0.0.0");
public static final int SPORT = 3000;
public static final byte L2 = 1;
public static final int IRPDISCRIMINATOR = 131;
public static final int ISISVERSION = 1;
public static final int RESERVED = 0;
public static final int MAXAREAADDRESS = 0;
- public static final int IDLENGTH = 0;
+ public static final int SYSTEMIDLENGTH = 0;
public static final int PROTOCOLSUPPORTED = 204;
public static final int LOCALCIRCUITIDFORP2P = 130;
public static final int P2PHELLOHEADERLENGTH = 20;
@@ -48,6 +52,27 @@
public static final int CHECKSUMPOSITION = 24;
public static final String REFRESHLSP = "refreshLsp";
public static final String MAXAGELSP = "maxAgeLsp";
+ public static final String DEFAULTLANID = "0000.0000.0000.00";
+ public static final String PROCESSESID = "processId";
+ public static final String INTERFACE = "interface";
+ public static final String INTERFACEIP = "interfaceIp";
+ public static final String NETWORKMASK = "networkMask";
+ public static final String INTERFACEINDEX = "interfaceIndex";
+ public static final String INTERMEDIATESYSTEMNAME = "intermediateSystemName";
+ public static final String SYSTEMID = "systemId";
+ public static final String LANID = "lanId";
+ public static final String IDLENGTH = "idLength";
+ public static final String MAXAREAADDRESSES = "maxAreaAddresses";
+ public static final String RESERVEDPACKETCIRCUITTYPE = "reservedPacketCircuitType";
+ public static final String CIRCUITID = "circuitId";
+ public static final String NETWORKTYPE = "networkType";
+ public static final String AREAADDRESS = "areaAddress";
+ public static final String AREALENGTH = "areaLength";
+ public static final String LSPID = "lspId";
+ public static final String HOLDINGTIME = "holdingTime";
+ public static final String HELLOINTERVAL = "helloInterval";
+ public static final String PRIORITY = "priority";
+ public static final String MACADDRESS = "macAddress";
/**
* Non parameterized constructor.
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
index 44ad9e0..c21a93b 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
@@ -391,7 +391,7 @@
isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
isisHeader.setPduHeaderLength((byte) IsisConstants.P2PHELLOHEADERLENGTH);
isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
- isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+ isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
isisHeader.setIsisPduType(IsisPduType.P2PHELLOPDU.value());
isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
//isisHeader.setReserved((byte) IsisConstants.RESERVED);
@@ -484,7 +484,7 @@
isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
isisHeader.setPduHeaderLength((byte) IsisConstants.HELLOHEADERLENGTH);
isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
- isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+ isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
if (isisPduType == IsisPduType.L1HELLOPDU) {
isisHeader.setIsisPduType(IsisPduType.L1HELLOPDU.value());
lanId = isisInterface.l1LanId();
@@ -693,4 +693,19 @@
}
return prefix;
}
+
+ /**
+ * Converts the prefix to bytes.
+ *
+ * @param prefix prefix
+ * @return prefix to bytes
+ */
+ public static byte[] prefixToBytes(String prefix) {
+ List<Byte> byteList = new ArrayList<>();
+ StringTokenizer tokenizer = new StringTokenizer(prefix, ".");
+ while (tokenizer.hasMoreTokens()) {
+ byteList.add((byte) Integer.parseInt(tokenizer.nextToken()));
+ }
+ return Bytes.toArray(byteList);
+ }
}
\ No newline at end of file
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
index 1dfb1a4..c6ae962 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
@@ -26,6 +26,7 @@
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
import org.onosproject.isis.io.isispacket.tlv.HostNameTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpExtendedReachabilityTlv;
import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
import org.onosproject.isis.io.isispacket.tlv.IpInternalReachabilityTlv;
import org.onosproject.isis.io.isispacket.tlv.IsReachabilityTlv;
@@ -115,7 +116,7 @@
} else if (isisInterface.networkType() == IsisNetworkType.P2P) {
MacAddress neighborMac = isisInterface.neighbors().iterator().next();
IsisNeighbor neighbor = isisInterface.lookup(neighborMac);
- metricsOfReachability.setNeighborId(neighbor.neighborSystemId());
+ metricsOfReachability.setNeighborId(neighbor.neighborSystemId() + ".00");
}
isReachabilityTlv.addMeticsOfReachability(metricsOfReachability);
@@ -137,10 +138,25 @@
metricOfIntRea.setErrorMetric((byte) 0);
metricOfIntRea.setErrorMetricSupported(false);
metricOfIntRea.setExpenseIsInternal(true);
- metricOfIntRea.setIpAddress(isisInterface.interfaceIpAddress());
+ Ip4Address ip4Address = isisInterface.interfaceIpAddress();
+ byte[] ipAddress = ip4Address.toOctets();
+ ipAddress[ipAddress.length - 1] = 0;
+ metricOfIntRea.setIpAddress(Ip4Address.valueOf(ipAddress));
metricOfIntRea.setSubnetAddres(Ip4Address.valueOf(isisInterface.networkMask()));
ipInterReacTlv.addInternalReachabilityMetric(metricOfIntRea);
lsp.addTlv(ipInterReacTlv);
+
+ tlvHeader.setTlvType(TlvType.IPEXTENDEDREACHABILITY.value());
+ tlvHeader.setTlvLength(0);
+ IpExtendedReachabilityTlv extendedTlv = new IpExtendedReachabilityTlv(tlvHeader);
+ extendedTlv.setDown(false);
+ extendedTlv.setMetric(10);
+ extendedTlv.setPrefix("192.168.7");
+ extendedTlv.setPrefixLength(24);
+ extendedTlv.setSubTlvLength((byte) 0);
+ extendedTlv.setSubTlvPresence(false);
+ lsp.addTlv(extendedTlv);
+
return lsp;
}
@@ -149,7 +165,7 @@
isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
isisHeader.setPduHeaderLength((byte) IsisUtil.getPduHeaderLength(pduType.value()));
isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
- isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+ isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
isisHeader.setIsisPduType(pduType.value());
isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
isisHeader.setReserved((byte) IsisConstants.RESERVED);
diff --git a/protocols/isis/pom.xml b/protocols/isis/pom.xml
index 90d9ded..bf6ac7a 100644
--- a/protocols/isis/pom.xml
+++ b/protocols/isis/pom.xml
@@ -34,6 +34,7 @@
<modules>
<module>api</module>
<module>isisio</module>
+ <module>ctl</module>
</modules>
</project>