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>