ONOS-4505: Bug Fixes

Change-Id: Ia030aa3aff9e2ad34a5e27fbe4ba088dda65bfa7
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
old mode 100755
new mode 100644
index c12c520..f16aeb4
--- 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
@@ -19,6 +19,7 @@
 import org.jboss.netty.bootstrap.ClientBootstrap;
 import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
 import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
 import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
@@ -35,10 +36,14 @@
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import static org.onlab.util.Tools.groupedThreads;
 
@@ -48,12 +53,17 @@
 public class Controller {
     protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
     private static final Logger log = LoggerFactory.getLogger(Controller.class);
+    private static final int RETRY_INTERVAL = 4;
     private final int peerWorkerThreads = 16;
+    byte[] configPacket = null;
     private List<IsisProcess> processes = null;
     private IsisChannelHandler isisChannelHandler;
     private NioClientSocketChannelFactory peerExecFactory;
     private ClientBootstrap peerBootstrap = null;
     private TpPort isisPort = TpPort.tpPort(IsisConstants.SPORT);
+    private ScheduledExecutorService connectExecutor = null;
+    private int connectRetryCounter = 0;
+    private int connectRetryTime;
 
     /**
      * Deactivates ISIS controller.
@@ -70,12 +80,11 @@
      */
     public void updateConfig(JsonNode jsonNode) throws Exception {
         log.debug("Controller::UpdateConfig called");
-        byte[] configPacket = new byte[IsisConstants.CONFIG_LENGTH];
+        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()) {
@@ -100,16 +109,19 @@
         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();
+            if (isisProcesses.size() > 0) {
+                processes = isisProcesses;
+                connectPeer();
+                //Initializing the interface map in channel handler
+                if (isisChannelHandler != null) {
+                    isisChannelHandler.initializeInterfaceMap();
+                }
+            }
         } else {
             isisChannelHandler.updateInterfaceMap(isisProcesses);
+            //Send the config packet
+            isisChannelHandler.sentConfigPacket(configPacket);
         }
-        //Send the config packet
-        isisChannelHandler.sentConfigPacket(configPacket);
     }
 
     /**
@@ -182,10 +194,8 @@
      * @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;
         }
@@ -193,49 +203,335 @@
             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");
+                String index = jsonNode1.path(IsisConstants.INTERFACEINDEX).asText();
+                if (isPrimitive(index)) {
+                    int input = Integer.parseInt(index);
+                    if (input < 1 || input > 255) {
+                        log.debug("Wrong interface index: {}", index);
+                        continue;
+                    }
+                    isisInterface.setInterfaceIndex(Integer.parseInt(index));
+                } else {
+                    log.debug("Wrong interface index {}", index);
+                    continue;
                 }
-                isisInterface.setInterfaceMacAddress(MacAddress.valueOf(jsonNode1
-                                                                                .path(IsisConstants.MACADDRESS)
-                                                                                .asText()));
+                Ip4Address ipAddress = getInterfaceIp(isisInterface.interfaceIndex());
+                if (ipAddress != null && !ipAddress.equals(IsisConstants.DEFAULTIP)) {
+                    isisInterface.setInterfaceIpAddress(ipAddress);
+                } else {
+                    log.debug("Wrong interface index {}. No matching interface in system.", index);
+                    continue;
+                }
+                MacAddress macAddress = getInterfaceMac(isisInterface.interfaceIndex());
+                if (macAddress != null) {
+                    isisInterface.setInterfaceMacAddress(macAddress);
+                } else {
+                    log.debug("Wrong interface index {}. No matching interface in system.", index);
+                    continue;
+                }
+                String mask = getInterfaceMask(isisInterface.interfaceIndex());
+                if (mask != null) {
+                    try {
+                        isisInterface.setNetworkMask(InetAddress.getByName(mask).getAddress());
+                    } catch (UnknownHostException e) {
+                        log.debug("Wrong interface index {}. Error while getting network mask.", index);
+                    }
+                } else {
+                    log.debug("Wrong interface index {}. Error while getting network mask.", index);
+                    continue;
+                }
                 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());
+                String systemId = jsonNode1.path(IsisConstants.SYSTEMID).asText();
+                if (isValidSystemId(systemId)) {
+                    isisInterface.setSystemId(systemId);
+                } else {
+                    log.debug("Wrong systemId: {} for interface index {}.", systemId, index);
+                    continue;
                 }
-                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());
+                String circuitType = jsonNode1.path(IsisConstants.RESERVEDPACKETCIRCUITTYPE).asText();
+                if (isPrimitive(circuitType)) {
+                    int input = Integer.parseInt(circuitType);
+                    if (input < 1 || input > 3) {
+                        log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
+                        continue;
+                    }
+                    isisInterface.setReservedPacketCircuitType(input);
+                } else {
+                    log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
+                    continue;
+                }
+                String networkType = jsonNode1.path(IsisConstants.NETWORKTYPE).asText();
+                if (isPrimitive(networkType)) {
+                    int input = Integer.parseInt(networkType);
+                    if (input < 1 || input > 2) {
+                        log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
+                        continue;
+                    }
+                    isisInterface.setNetworkType(IsisNetworkType.get(input));
+                } else {
+                    log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
+                    continue;
+                }
+                String areaAddress = jsonNode1.path(IsisConstants.AREAADDRESS).asText();
+                if (isPrimitive(areaAddress)) {
+                    if (areaAddress.length() > 7) {
+                        log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
+                        continue;
+                    }
+                    isisInterface.setAreaAddress(areaAddress);
+                } else {
+                    log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
+                    continue;
+                }
+                String circuitId = jsonNode1.path(IsisConstants.CIRCUITID).asText();
+                if (isPrimitive(circuitId)) {
+                    int input = Integer.parseInt(circuitId);
+                    if (input < 1) {
+                        log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
+                        continue;
+                    }
+                    isisInterface.setCircuitId(circuitId);
+                } else {
+                    log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
+                    continue;
+                }
+                String holdingTime = jsonNode1.path(IsisConstants.HOLDINGTIME).asText();
+                if (isPrimitive(holdingTime)) {
+                    int input = Integer.parseInt(holdingTime);
+                    if (input < 1 || input > 255) {
+                        log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
+                        continue;
+                    }
+                    isisInterface.setHoldingTime(input);
+                } else {
+                    log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
+                    continue;
+                }
+                String helloInterval = jsonNode1.path(IsisConstants.HELLOINTERVAL).asText();
+                if (isPrimitive(helloInterval)) {
+                    int interval = Integer.parseInt(helloInterval);
+                    if (interval > 0 && interval <= 255) {
+                        isisInterface.setHelloInterval(interval);
+                    } else {
+                        log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
+                        continue;
+                    }
+                } else {
+                    log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
+                    continue;
+                }
                 interfaceList.add(isisInterface);
             }
-            IsisProcess process = new DefaultIsisProcess();
-            process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
-            process.setIsisInterfaceList(interfaceList);
-            isisProcessesList.add(process);
+            if (interfaceList.size() > 0) {
+                IsisProcess process = new DefaultIsisProcess();
+                process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
+                process.setIsisInterfaceList(interfaceList);
+                isisProcessesList.add(process);
+            }
         });
 
         return isisProcessesList;
     }
+
+    /**
+     * Returns interface MAC by index.
+     *
+     * @param interfaceIndex interface index
+     * @return interface IP by index
+     */
+    private MacAddress getInterfaceMac(int interfaceIndex) {
+        MacAddress macAddress = null;
+        try {
+            NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
+            macAddress = MacAddress.valueOf(networkInterface.getHardwareAddress());
+        } catch (Exception e) {
+            log.debug("Error while getting Interface IP by index");
+            return macAddress;
+        }
+
+        return macAddress;
+    }
+
+    /**
+     * Returns interface IP by index.
+     *
+     * @param interfaceIndex interface index
+     * @return interface IP by index
+     */
+    private Ip4Address getInterfaceIp(int interfaceIndex) {
+        Ip4Address ipAddress = null;
+        try {
+            NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
+            Enumeration ipAddresses = networkInterface.getInetAddresses();
+            while (ipAddresses.hasMoreElements()) {
+                InetAddress address = (InetAddress) ipAddresses.nextElement();
+                if (!address.isLinkLocalAddress()) {
+                    ipAddress = Ip4Address.valueOf(address.getAddress());
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            log.debug("Error while getting Interface IP by index");
+            return IsisConstants.DEFAULTIP;
+        }
+        return ipAddress;
+    }
+
+    /**
+     * Returns interface MAC by index.
+     *
+     * @param interfaceIndex interface index
+     * @return interface IP by index
+     */
+    private String getInterfaceMask(int interfaceIndex) {
+        String subnetMask = null;
+        try {
+            Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
+            NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
+                    InetAddress.getByName(ipAddress.toString()));
+            Enumeration ipAddresses = networkInterface.getInetAddresses();
+            int index = 0;
+            while (ipAddresses.hasMoreElements()) {
+                InetAddress address = (InetAddress) ipAddresses.nextElement();
+                if (!address.isLinkLocalAddress()) {
+                    break;
+                }
+                index++;
+            }
+            int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
+            int shft = 0xffffffff << (32 - prfLen);
+            int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
+            int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
+            int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
+            int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
+            subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
+        } catch (Exception e) {
+            log.debug("Error while getting Interface network mask by index");
+            return subnetMask;
+        }
+        return subnetMask;
+    }
+
+    /**
+     * Checks if primitive or not.
+     *
+     * @param value input value
+     * @return true if number else false
+     */
+    private boolean isPrimitive(String value) {
+        boolean status = true;
+        value = value.trim();
+        if (value.length() < 1) {
+            return false;
+        }
+        for (int i = 0; i < value.length(); i++) {
+            char c = value.charAt(i);
+            if (!Character.isDigit(c)) {
+                status = false;
+                break;
+            }
+        }
+
+        return status;
+    }
+
+    /**
+     * Checks if system id is valid or not.
+     *
+     * @param value input value
+     * @return true if valid else false
+     */
+    private boolean isValidSystemId(String value) {
+        value = value.trim();
+        boolean status = true;
+        if (value.length() != 14) {
+            return false;
+        }
+        for (int i = 0; i < value.length(); i++) {
+            char c = value.charAt(i);
+            if (!Character.isDigit(c)) {
+                if (!((i == 4 || i == 9) && c == '.')) {
+                    status = false;
+                    break;
+                }
+            }
+        }
+
+        return status;
+    }
+
+    /**
+     * Disconnects the executor.
+     */
+    public void disconnectExecutor() {
+        if (connectExecutor != null) {
+            connectExecutor.shutdown();
+            connectExecutor = null;
+        }
+    }
+
+    /**
+     * Connects to peer.
+     */
+    public void connectPeer() {
+        scheduleConnectionRetry(this.connectRetryTime);
+    }
+
+    /**
+     * Retry connection with exponential back-off mechanism.
+     *
+     * @param retryDelay retry delay
+     */
+    private void scheduleConnectionRetry(long retryDelay) {
+        if (this.connectExecutor == null) {
+            this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
+        }
+        this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
+    }
+
+    /**
+     * Implements ISIS connection and manages connection to peer with back-off mechanism in case of failure.
+     */
+    class ConnectionRetry implements Runnable {
+        @Override
+        public void run() {
+            log.debug("Connect to peer {}", IsisConstants.SHOST);
+            initConnection();
+            InetSocketAddress connectToSocket = new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt());
+            try {
+                peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
+                    @Override
+                    public void operationComplete(ChannelFuture future) throws Exception {
+                        if (!future.isSuccess()) {
+                            connectRetryCounter++;
+                            log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
+                                      IsisConstants.SHOST);
+                            /*
+                             * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
+                             * mins.
+                             */
+                            if (connectRetryTime < RETRY_INTERVAL) {
+                                connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
+                            }
+                            scheduleConnectionRetry(connectRetryTime);
+                        } else {
+                            connectRetryCounter++;
+                            log.info("Connected to remote host {}, Connect Counter {}", IsisConstants.SHOST,
+                                     connectRetryCounter);
+                            disconnectExecutor();
+                            isisChannelHandler.initializeInterfaceMap();
+                            //Send the config packet
+                            isisChannelHandler.sentConfigPacket(configPacket);
+                            return;
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                log.info("Connect peer exception : " + e.toString());
+                disconnectExecutor();
+            }
+        }
+    }
 }
\ 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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644
index bbeb4dd..134a48b
--- 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
@@ -69,15 +69,14 @@
     private MacAddress interfaceMacAddress;
     private String intermediateSystemName;
     private String systemId;
-    private String l1LanId;
-    private String l2LanId;
+    private String l1LanId = IsisConstants.DEFAULTLANID;
+    private String l2LanId = IsisConstants.DEFAULTLANID;
     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;
@@ -114,10 +113,25 @@
      * @param isisNeighbor ISIS neighbor instance
      */
     public void removeNeighbor(IsisNeighbor isisNeighbor) {
+        log.debug("Neighbor removed - {}", isisNeighbor.neighborMacAddress());
+        isisNeighbor.stopHoldingTimeCheck();
+        isisNeighbor.stopInactivityTimeCheck();
         neighborList.remove(isisNeighbor.neighborMacAddress());
     }
 
     /**
+     * Removes all the neighbors.
+     */
+    public void removeNeighbors() {
+        Set<MacAddress> neighbors = neighbors();
+        for (MacAddress mac : neighbors) {
+            removeNeighbor(lookup(mac));
+            log.debug("Neighbor removed - {}", mac);
+        }
+        neighborList.clear();
+    }
+
+    /**
      * Returns the ISIS neighbor instance if exists.
      *
      * @param isisNeighborMac mac address of the neighbor router
@@ -400,24 +414,6 @@
     }
 
     /**
-     * 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
@@ -518,9 +514,21 @@
      */
     public void processIsisMessage(IsisMessage isisMessage, IsisLsdb isisLsdb, Channel channel) {
         log.debug("IsisInterfaceImpl::processIsisMessage...!!!");
-        if (channel == null) {
-            this.channel = channel;
+        this.channel = channel;
+
+        if (isisMessage.sourceMac().equals(interfaceMacAddress)) {
+            log.debug("Received our own message {}...!!!", isisMessage.isisPduType());
+            return;
         }
+
+        if (isisMessage.isisPduType() == IsisPduType.P2PHELLOPDU && networkType.equals(IsisNetworkType.BROADCAST)) {
+            return;
+        } else if ((isisMessage.isisPduType() == IsisPduType.L1HELLOPDU ||
+                isisMessage.isisPduType() == IsisPduType.L2HELLOPDU)
+                && networkType.equals(IsisNetworkType.P2P)) {
+            return;
+        }
+
         if (this.isisLsdb == null) {
             this.isisLsdb = isisLsdb;
         }
@@ -543,7 +551,7 @@
                 break;
             case L1PSNP:
             case L2PSNP:
-                log.debug("Received a PSNP packet...!!!");
+                processPsnPduMessage(isisMessage, channel);
                 break;
             default:
                 log.debug("Unknown packet to process...!!!");
@@ -560,6 +568,13 @@
     public boolean validateHelloMessage(HelloPdu helloPdu) {
         boolean isValid = false;
 
+        if ((helloPdu.circuitType() == IsisRouterType.L1.value() &&
+                reservedPacketCircuitType == IsisRouterType.L2.value()) ||
+                (helloPdu.circuitType() == IsisRouterType.L2.value() &&
+                        reservedPacketCircuitType == IsisRouterType.L1.value())) {
+            return 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) ?
@@ -569,11 +584,16 @@
         }
 
         //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;
+        if (helloPdu.circuitType() == IsisRouterType.L1.value()) {
+            List<String> areas = helloPdu.areaAddress();
+            for (String area : areas) {
+                if (areaAddress.equals(area)) {
+                    isValid = true;
+                }
             }
+        } else if (helloPdu.circuitType() == IsisRouterType.L2.value() ||
+                helloPdu.circuitType() == IsisRouterType.L1L2.value()) {
+            isValid = true;
         }
 
         return isValid;
@@ -585,6 +605,7 @@
      * @param neighborMac neighbor MAc address
      * @return true if neighbor exist else false
      */
+
     private boolean isNeighborInList(MacAddress neighborMac) {
         return neighborList.containsKey(neighborMac);
     }
@@ -623,9 +644,8 @@
         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)) {
+        //If validate the area, network and max address
+        if (!validateHelloMessage(helloPacket)) {
             return;
         }
 
@@ -637,6 +657,7 @@
             addNeighbouringRouter(neighbor);
         }
 
+        neighbor.setHoldingTime(helloPacket.holdingTime());
         neighbor.stopInactivityTimeCheck();
         neighbor.startInactivityTimeCheck();
 
@@ -644,24 +665,29 @@
         String lanId = helloPacket.lanId();
 
         if (IsisPduType.L1HELLOPDU == helloPacket.isisPduType()) {
-            buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
+            buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel,
+                                                          IsisRouterType.get(helloPacket.circuitType()));
             l1LanId = lanId;
             neighbor.setL1LanId(lanId);
             //if a change in lanid
         } else if (IsisPduType.L2HELLOPDU == helloPacket.isisPduType()) {
-            buildUpdateAndSendSelfGeneratedLspIfDisChange(l1LanId, lanId, channel);
+            buildUpdateAndSendSelfGeneratedLspIfDisChange(l2LanId, lanId, channel,
+                                                          IsisRouterType.get(helloPacket.circuitType()));
             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;
+        if (neighbors != null) {
+            for (MacAddress macAddress : neighbors) {
+                if (interfaceMacAddress.equals(macAddress)) {
+                    neighbor.setNeighborState(IsisInterfaceState.UP);
+                    //Build Self LSP add in LSDB and sent it.
+                    buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel,
+                                                                    IsisRouterType.get(helloPacket.circuitType()));
+                    break;
+                }
             }
         }
     }
@@ -671,7 +697,8 @@
      *
      * @param channel netty channel instance
      */
-    private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel) {
+    private void buildStoreAndSendSelfGeneratedLspIfNotExistInDb(Channel channel, IsisRouterType neighborRouterType) {
+        this.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;
@@ -690,18 +717,25 @@
                 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);
+            if ((neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2)) {
+
+                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);
+            if ((neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
+                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);
+                }
             }
         }
     }
@@ -714,29 +748,35 @@
      * @param channel       netty channel instance
      */
     private void buildUpdateAndSendSelfGeneratedLspIfDisChange(String previousLanId,
-                                                               String latestLanId, Channel channel) {
+                                                               String latestLanId, Channel channel,
+                                                               IsisRouterType neighborRouterType) {
+        this.channel = channel;
         //If DIS change then build and sent LSP
-        if (previousLanId != null && !previousLanId.equals(IsisConstants.DEFAULTLANID) &&
-                !previousLanId.equals(latestLanId)) {
+        if (!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()) {
+            } else if (reservedPacketCircuitType == IsisRouterType.L2.value() &&
+                    (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2)) {
                 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);
+                if (neighborRouterType == IsisRouterType.L1 || neighborRouterType == IsisRouterType.L1L2) {
+                    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);
+                if (neighborRouterType == IsisRouterType.L2 || neighborRouterType == IsisRouterType.L1L2) {
+                    LsPdu lsp = new LspGenerator().getLsp(this, lspKey, IsisPduType.L2LSPDU, allConfiguredInterfaceIps);
+                    isisLsdb.addLsp(lsp, true, this);
+                    sendLsp(lsp, channel);
+                }
             }
         }
 
@@ -756,7 +796,9 @@
         lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
                                         IsisConstants.CHECKSUMPOSITION + 1);
         //write to the channel
-        channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
+        if (channel != null && channel.isConnected() && channel.isOpen()) {
+            channel.write(IsisUtil.framePacket(lspBytes, interfaceIndex));
+        }
     }
 
     /**
@@ -794,7 +836,7 @@
                 addNeighbouringRouter(neighbor);
             }
             neighbor.setNeighborState(IsisInterfaceState.DOWN);
-            buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
+            buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
         } else if (stateTlv.adjacencyType() == IsisInterfaceState.DOWN.value()) {
             neighbor = neighbouringRouter(isisMessage.sourceMac());
             if (neighbor == null) {
@@ -805,6 +847,10 @@
         } else if (stateTlv.adjacencyType() == IsisInterfaceState.INITIAL.value()) {
             //Neighbor already present in the list
             neighbor = neighbouringRouter(isisMessage.sourceMac());
+            if (neighbor == null) {
+                neighbor = new DefaultIsisNeighbor(helloPacket, this);
+                addNeighbouringRouter(neighbor);
+            }
             neighbor.setNeighborState(IsisInterfaceState.INITIAL);
             neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
             //interfaceState = IsisInterfaceState.UP;
@@ -813,9 +859,10 @@
             neighbor = neighbouringRouter(isisMessage.sourceMac());
             neighbor.setNeighborState(IsisInterfaceState.UP);
             neighbor.setLocalExtendedCircuitId(stateTlv.localCircuitId());
-            buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel);
+            buildStoreAndSendSelfGeneratedLspIfNotExistInDb(channel, IsisRouterType.get(helloPacket.circuitType()));
         }
 
+        neighbor.setHoldingTime(helloPacket.holdingTime());
         neighbor.stopInactivityTimeCheck();
         neighbor.startInactivityTimeCheck();
     }
@@ -828,11 +875,36 @@
      */
     public void processLsPduMessage(IsisMessage isisMessage, Channel channel) {
         log.debug("Enters processLsPduMessage ...!!!");
+        IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
+        if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
+            return;
+        }
+
         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 (wrapper != null) {               // verify if the LSA - is your own LSA - get system ID and compare LSP
+                String lspKey = isisLsdb.lspKey(systemId);
+                if (lsPdu.lspId().equals(lspKey)) {
+                    lsPdu.setSequenceNumber(lsPdu.sequenceNumber() + 1);
+                    if (lsPdu.pduType() == IsisPduType.L1LSPDU.value()) {
+                        // setting the ls sequence number
+                        isisLsdb.setL1LspSeqNo(lsPdu.sequenceNumber());
+                    } else if (lsPdu.pduType() == IsisPduType.L2LSPDU.value()) {
+                        // setting the ls sequence number
+                        isisLsdb.setL2LspSeqNo(lsPdu.sequenceNumber());
+                    }
+                    isisLsdb.addLsp(lsPdu, true, this);
+                    sendLsp(lsPdu, channel);
+                } else {
+                    isisLsdb.addLsp(lsPdu, false, this);
+                }
+
+
+            } else {
+                //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
@@ -865,7 +937,48 @@
                                                               IsisConstants.RESERVEDPOSITION);
             flagValue = false;
             //write to the channel
-            channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+            if (channel != null && channel.isConnected() && channel.isOpen()) {
+                channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+            }
+        }
+    }
+
+    /**
+     * Processes PSN PDU message.
+     * Checks for self originated LSP entries in PSNP message and sends the missing LSP.
+     *
+     * @param isisMessage PSN PDU message instance
+     * @param channel     channel instance
+     */
+    public void processPsnPduMessage(IsisMessage isisMessage, Channel channel) {
+        log.debug("Enters processPsnPduMessage ...!!!");
+        //If adjacency not formed don't process.
+        IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
+        if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
+            return;
+        }
+
+        Psnp psnPacket = (Psnp) isisMessage;
+        List<IsisTlv> isisTlvs = psnPacket.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(psnPacket.isisPduType(), lspKey);
+                    if (lspWrapper != null) {
+                        if (lspWrapper.isSelfOriginated()) {
+                            //Sent the LSP
+                            sendLsp((LsPdu) lspWrapper.lsPdu(), channel);
+                        }
+                    }
+                }
+            }
         }
     }
 
@@ -877,123 +990,60 @@
      */
     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);
+        IsisNeighbor neighbor = neighbouringRouter(isisMessage.sourceMac());
+        if (networkType == IsisNetworkType.BROADCAST && neighbor == null) {
+            return;
         }
-    }
 
-    /**
-     * 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;
+        IsisPduType psnPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
+                IsisPduType.L2PSNP : IsisPduType.L1PSNP;
+        IsisPduType lsPduType = (IsisPduType.L2CSNP.equals(csnPacket.isisPduType())) ?
+                IsisPduType.L2LSPDU : IsisPduType.L1LSPDU;
+
         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;
-                                }
+        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(lsPduType, lspKey);
+                    if (lspWrapper != null) {
+                        LsPdu lsPdu = (LsPdu) lspWrapper.lsPdu();
+                        if (lspWrapper.isSelfOriginated()) {
+                            selfOriginatedFound = true;
+                            if (lspEntry.lspSequenceNumber() < lsPdu.sequenceNumber()) {
+                                sendLsp(lsPdu, channel);
                             }
                         } else {
-                            lspEntryRequestList.add(lspEntry);
-                            flagValue = true;
+                            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);
-            }
         }
-    }
+        if (flagValue) {
+            sendPsnPduMessage(lspEntryRequestList, psnPduType, channel);
+            lspEntryRequestList.clear();
+        }
 
-    /**
-     * 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);
+        if (!selfOriginatedFound) {
+            String lspKey = isisLsdb.lspKey(systemId);
+            LspWrapper wrapper = isisLsdb.findLsp(lsPduType, lspKey);
+            if (wrapper != null) {
                 sendLsp((LsPdu) wrapper.lsPdu(), channel);
             }
         }
@@ -1007,13 +1057,7 @@
      * @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);
+        IsisHeader isisHeader = new LspGenerator().getHeader(isisPduType);
         Psnp psnp = new Psnp(isisHeader);
         psnp.setSourceId(lspKeyP2P(this.systemId));
         TlvHeader tlvHeader = new TlvHeader();
@@ -1021,6 +1065,9 @@
         tlvHeader.setTlvLength(0);
         LspEntriesTlv lspEntriesTlv = new LspEntriesTlv(tlvHeader);
         for (LspEntry lspEntry : lspEntryRequestList) {
+            lspEntry.setLspChecksum(0);
+            lspEntry.setLspSequenceNumber(0);
+            lspEntry.setRemainingTime(0);
             lspEntriesTlv.addLspEntry(lspEntry);
         }
         psnp.addTlv(lspEntriesTlv);
@@ -1031,7 +1078,9 @@
                                                           IsisConstants.RESERVEDPOSITION);
         flagValue = false;
         //write to the channel
-        channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+        if (channel != null && channel.isConnected() && channel.isOpen()) {
+            channel.write(IsisUtil.framePacket(psnpBytes, interfaceIndex));
+        }
     }
 
     /**
@@ -1048,28 +1097,6 @@
     }
 
     /**
-     * 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
@@ -1083,4 +1110,12 @@
                 exServiceHello.scheduleAtFixedRate(isisHelloPduSender, 0,
                                                    helloInterval, TimeUnit.SECONDS);
     }
+
+    /**
+     * Stops the hello timer which sends hello packet every configured seconds.
+     */
+    public void stopHelloSender() {
+        log.debug("IsisInterfaceImpl::stopHelloSender");
+        exServiceHello.shutdown();
+    }
 }
\ 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
old mode 100755
new mode 100644
index 7fac0cb..3e05a37
--- 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
@@ -88,6 +88,7 @@
         }
         this.isisInterface = isisInterface;
         startHoldingTimeCheck();
+        log.debug("Neighbor added - {}", neighborMacAddress);
     }
 
     /**
@@ -387,6 +388,10 @@
         @Override
         public void run() {
             holdingTime--;
+            if (holdingTime <= 0) {
+                log.debug("Calling neighbor down. Holding time is 0.");
+                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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644
index 064176d..86c6853
--- 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
@@ -94,13 +94,35 @@
             for (IsisInterface isisUpdatedInterface : isisUpdatedProcess.isisInterfaceList()) {
                 IsisInterface isisInterface = isisInterfaceMap.get(isisUpdatedInterface.interfaceIndex());
                 if (isisInterface == null) {
-                    isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
-                    interfaceIps.add(isisInterface.interfaceIpAddress());
+                    isisInterfaceMap.put(isisUpdatedInterface.interfaceIndex(), isisUpdatedInterface);
+                    interfaceIps.add(isisUpdatedInterface.interfaceIpAddress());
                 } else {
-                    isisInterface.setReservedPacketCircuitType(isisUpdatedInterface.reservedPacketCircuitType());
-                    isisInterface.setNetworkType(isisUpdatedInterface.networkType());
-                    isisInterface.setHoldingTime(isisUpdatedInterface.holdingTime());
-                    isisInterface.setHelloInterval(isisUpdatedInterface.helloInterval());
+                    if (isisInterface.intermediateSystemName() != isisUpdatedInterface.intermediateSystemName()) {
+                        isisInterface.setIntermediateSystemName(isisUpdatedInterface.intermediateSystemName());
+                    }
+                    if (isisInterface.reservedPacketCircuitType() != isisUpdatedInterface.reservedPacketCircuitType()) {
+                        isisInterface.setReservedPacketCircuitType(isisUpdatedInterface.reservedPacketCircuitType());
+                        isisInterface.removeNeighbors();
+                    }
+                    if (isisInterface.circuitId() != isisUpdatedInterface.circuitId()) {
+                        isisInterface.setCircuitId(isisUpdatedInterface.circuitId());
+                    }
+                    if (isisInterface.networkType() != isisUpdatedInterface.networkType()) {
+                        isisInterface.setNetworkType(isisUpdatedInterface.networkType());
+                        isisInterface.removeNeighbors();
+                    }
+                    if (isisInterface.areaAddress() != isisUpdatedInterface.areaAddress()) {
+                        isisInterface.setAreaAddress(isisUpdatedInterface.areaAddress());
+                    }
+                    if (isisInterface.holdingTime() != isisUpdatedInterface.holdingTime()) {
+                        isisInterface.setHoldingTime(isisUpdatedInterface.holdingTime());
+                    }
+                    if (isisInterface.helloInterval() != isisUpdatedInterface.helloInterval()) {
+                        isisInterface.setHelloInterval(isisUpdatedInterface.helloInterval());
+                        isisInterface.stopHelloSender();
+                        isisInterface.startHelloSender(channel);
+                    }
+
                     isisInterfaceMap.put(isisInterface.interfaceIndex(), isisInterface);
                 }
             }
@@ -144,6 +166,9 @@
     @Override
     public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
         log.debug("IsisChannelHandler::channelDisconnected...!!!");
+        if (controller != null) {
+            controller.connectPeer();
+        }
     }
 
     @Override
@@ -169,8 +194,9 @@
         } 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());
+            log.error("Error while processing message from ISIS {}, {}",
+                      e.getChannel().getRemoteAddress(), e.getCause().getMessage());
+            e.getCause().printStackTrace();
         }
     }
 
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
old mode 100755
new mode 100644
index 87338f5..e798b3e
--- 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
@@ -45,7 +45,7 @@
 
     @Override
     public void run() {
-        if (channel != null) {
+        if (channel != null && channel.isConnected() && channel.isOpen()) {
             try {
                 byte[] helloPdu = null;
                 byte[] interfaceIndex = {(byte) isisInterface.interfaceIndex()};
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
old mode 100755
new mode 100644
index f2cbf19..b75bc3f
--- 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
@@ -44,7 +44,6 @@
             log.info("Channel is not connected.");
             return null;
         }
-
         IsisMessageReader messageReader = new IsisMessageReader();
         List<IsisMessage> isisMessageList = new LinkedList<>();
         int dataLength = buffer.readableBytes();
@@ -74,8 +73,7 @@
                 isisMessageList.add(message);
             }
         }
-
-        return isisMessageList;
+        return (isisMessageList.size() > 0) ? isisMessageList : null;
     }
 
     /**
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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644
index 8a58269..3c66bf8
--- 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
@@ -45,7 +45,6 @@
     private IsisLsdbAge lsdbAge = null;
 
 
-
     private int l1LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
     private int l2LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
 
@@ -80,6 +79,7 @@
     public void setL2LspSeqNo(int l2LspSeqNo) {
         this.l2LspSeqNo = l2LspSeqNo;
     }
+
     /**
      * Returns the LSDB LSP key.
      *
@@ -96,6 +96,7 @@
         return lspKey.toString();
     }
 
+
     /**
      * Returns the neighbor L1 database information.
      *
@@ -218,7 +219,12 @@
             byte[] checkSum = {lspBytes[IsisConstants.CHECKSUMPOSITION], lspBytes[IsisConstants.CHECKSUMPOSITION + 1]};
             lspdu.setCheckSum(ChannelBuffers.copiedBuffer(checkSum).readUnsignedShort());
         }
-        DefaultLspWrapper lspWrapper = new DefaultLspWrapper();
+
+        DefaultLspWrapper lspWrapper = (DefaultLspWrapper) findLsp(lspdu.isisPduType(), lspdu.lspId());
+        if (lspWrapper == null) {
+            lspWrapper = new DefaultLspWrapper();
+        }
+
         lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime());
         lspWrapper.setLspType(IsisPduType.get(lspdu.pduType()));
         lspWrapper.setLsPdu(lspdu);
@@ -228,8 +234,8 @@
         lspWrapper.setIsisInterface(isisInterface);
         lspWrapper.setLsdbAge(lsdbAge);
         addLsp(lspWrapper, lspdu.lspId());
-        log.debug("Added LSp In LSDB: {}", lspWrapper);
 
+        log.debug("Added LSp In LSDB: {}", lspWrapper);
         return true;
     }
 
@@ -270,7 +276,6 @@
                       lspWrapper.lsPdu().isisPduType(),
                       binNumber, lspWrapper.remainingLifetime());
         }
-
         return false;
     }
 
@@ -344,4 +349,4 @@
                 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
old mode 100755
new mode 100644
index 2cf07ba..5a48798
--- 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
@@ -36,10 +36,10 @@
  */
 public class DefaultIsisLsdbAge implements IsisLsdbAge {
     private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdbAge.class);
-    protected static int ageCounter = 0;
+    protected int ageCounter = 0;
     private InternalAgeTimer dbAgeTimer;
     private ScheduledExecutorService exServiceage;
-    private Integer maxBins = 1200;
+    private Integer maxBins = IsisConstants.LSPMAXAGE;
     private Map<Integer, IsisLspBin> ageBins = new ConcurrentHashMap<>(maxBins);
     private int ageCounterRollOver = 0;
     private IsisLspQueueConsumer queueConsumer = null;
@@ -202,7 +202,7 @@
         } else {
             binNumber = ageCounter - IsisConstants.LSPREFRESH;
         }
-        if (binNumber > IsisConstants.LSPMAXAGE) {
+        if (binNumber >= IsisConstants.LSPMAXAGE) {
             binNumber = binNumber - IsisConstants.LSPMAXAGE;
         }
         IsisLspBin lspBin = ageBins.get(binNumber);
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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644
index b89e88f..b9b3306
--- 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
@@ -21,11 +21,14 @@
 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;
 
 /**
  * Representation of LSP wrapper where the LSPs are stored with metadata.
  */
 public class DefaultLspWrapper implements LspWrapper {
+    private static final Logger log = LoggerFactory.getLogger(DefaultLspWrapper.class);
     private int binNumber = -1;
     private boolean selfOriginated = false;
     private IsisPduType lspType;
@@ -229,7 +232,15 @@
         int currentAge = 0;
         //ls age received
         if (lsdbAge.ageCounter() >= ageCounterWhenReceived) {
+            if (!selfOriginated) {
+                if (ageCounterRollOverWhenAdded == lsdbAge.ageCounterRollOver()) {
             currentAge = lspAgeReceived + (lsdbAge.ageCounter() - ageCounterWhenReceived);
+                } else {
+                    return IsisConstants.LSPMAXAGE;
+                }
+            } else {
+                currentAge = lspAgeReceived + (lsdbAge.ageCounter() - ageCounterWhenReceived);
+            }
         } else {
             currentAge = lspAgeReceived + ((IsisConstants.LSPMAXAGE + lsdbAge.ageCounter())
                     - ageCounterWhenReceived);
@@ -245,6 +256,8 @@
         return currentAge;
     }
 
+
+
     /**
      * Returns remaining time.
      *
@@ -252,7 +265,7 @@
      */
     public int remainingLifetime() {
         //Calculate the remaining lifetime
-        remainingLifetime = IsisConstants.LSPMAXAGE - lsdbAge.ageCounter();
+        remainingLifetime = IsisConstants.LSPMAXAGE - currentAge();
         return remainingLifetime;
     }
 
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
old mode 100755
new mode 100644
index 9007093..b5eca27
--- 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
@@ -100,7 +100,9 @@
                                                 IsisConstants.CHECKSUMPOSITION + 1);
                 //write to the channel
                 channel.write(IsisUtil.framePacket(lspBytes, isisInterface.interfaceIndex()));
-
+                // Updating the database with resetting remaining life time to default.
+                IsisLsdb isisDb = isisInterface.isisLsdb();
+                isisDb.addLsp(lsPdu, true, isisInterface);
                 log.debug("LSPQueueConsumer: processRefreshLsp - Flooded SelfOriginated LSP {}",
                           wrapper.lsPdu());
             }
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
old mode 100755
new mode 100644
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
old mode 100755
new mode 100644