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
