diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
index f4c70c0..9a7bd47 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
@@ -21,7 +21,6 @@
 import org.onlab.packet.Ip4Address;
 import org.onosproject.ospf.controller.LsaWrapper;
 import org.onosproject.ospf.controller.OspfArea;
-import org.onosproject.ospf.controller.OspfAreaAddressRange;
 import org.onosproject.ospf.controller.OspfInterface;
 import org.onosproject.ospf.controller.OspfLsa;
 import org.onosproject.ospf.controller.OspfLsaType;
@@ -54,28 +53,14 @@
 public class OspfAreaImpl implements OspfArea {
     private static final Logger log = LoggerFactory.getLogger(OspfAreaImpl.class);
     /**
-     * Address ranges in order to aggregate routing information at area.
-     * boundaries. Each address range is specified by an [address,mask] pair and
-     * a status indication of either Advertise or DoNotAdvertise
-     */
-    private List<OspfAreaAddressRange> addressRanges;
-    /**
-     * This parameter indicates whether the area can carry data traffic that.
-     * neither originates nor terminates in the area itself.
-     */
-    private boolean transitCapability;
-    /**
      * Whether AS-external-LSAs will be flooded into/throughout the area.
      */
     private boolean externalRoutingCapability;
-    /**
-     * Indicates the cost of the default summary-LSA.
-     */
-    private int stubCost;
+
     /**
      * Represents a list of all router's interfaces associated with this area.
      */
-    private List<OspfInterface> interfacesLst;
+    private List<OspfInterface> ospfInterfaceList;
     /**
      * The LS Database for this area. It includes router-LSAs, network-LSAs and.
      * summary-LSAs. AS-external-LSAs are hold in the OSPF class itself.
@@ -116,18 +101,15 @@
         OspfAreaImpl that = (OspfAreaImpl) o;
         return Objects.equal(areaId, that.areaId) &&
                 Objects.equal(routerId, that.routerId) &&
-                Objects.equal(addressRanges.size(), that.addressRanges.size()) &&
-                Objects.equal(transitCapability, that.transitCapability) &&
                 Objects.equal(externalRoutingCapability, that.externalRoutingCapability) &&
-                Objects.equal(stubCost, that.stubCost) &&
-                Objects.equal(interfacesLst.size(), that.interfacesLst.size()) &&
+                Objects.equal(ospfInterfaceList.size(), that.ospfInterfaceList.size()) &&
                 Objects.equal(database, that.database);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(areaId, routerId, addressRanges, transitCapability, externalRoutingCapability,
-                                stubCost, interfacesLst, database);
+        return Objects.hashCode(areaId, routerId, externalRoutingCapability,
+                                ospfInterfaceList, database);
     }
 
     /**
@@ -234,7 +216,7 @@
         networkLsa.setNetworkMask(mask);
         //Adding our own router.
         networkLsa.addAttachedRouter(routerId());
-        Iterator iter = interfacesLst.iterator();
+        Iterator iter = ospfInterfaceList.iterator();
         OspfInterfaceImpl ospfInterface = null;
         while (iter.hasNext()) {
             ospfInterface = (OspfInterfaceImpl) iter.next();
@@ -310,7 +292,7 @@
      */
     private void buildLinkForRouterLsa(RouterLsa routerLsa, OspfInterface ospfInterface) {
         OspfInterfaceImpl nextInterface;
-        Iterator interfaces = interfacesLst.iterator();
+        Iterator interfaces = ospfInterfaceList.iterator();
         while (interfaces.hasNext()) {
             nextInterface = (OspfInterfaceImpl) interfaces.next();
             if (nextInterface.state() == OspfInterfaceState.DOWN) {
@@ -418,44 +400,6 @@
     }
 
     /**
-     * Gets address range.
-     *
-     * @return list of area address ranges
-     */
-    public List<OspfAreaAddressRange> addressRanges() {
-        return addressRanges;
-    }
-
-    /**
-     * Sets the area address ranges.
-     *
-     * @param addressRanges list of area address range
-     */
-    @JsonProperty("addressRange")
-    public void setAddressRanges(List<OspfAreaAddressRange> addressRanges) {
-        this.addressRanges = addressRanges;
-    }
-
-    /**
-     * Gets is transit capable or not.
-     *
-     * @return true if transit capable, else false
-     */
-    public boolean isTransitCapability() {
-        return transitCapability;
-    }
-
-    /**
-     * Sets transit capability.
-     *
-     * @param transitCapability true if transit capable, else false
-     */
-    @JsonProperty("transitCapability")
-    public void setTransitCapability(boolean transitCapability) {
-        this.transitCapability = transitCapability;
-    }
-
-    /**
      * Gets external routing capability.
      *
      * @return true if external routing capable, else false
@@ -475,41 +419,22 @@
     }
 
     /**
-     * Gets the stub cost.
-     *
-     * @return stub cost
-     */
-    public int stubCost() {
-        return stubCost;
-    }
-
-    /**
-     * Sets the stub cost.
-     *
-     * @param stubCost stub cost
-     */
-    @JsonProperty("stubCost")
-    public void setStubCost(int stubCost) {
-        this.stubCost = stubCost;
-    }
-
-    /**
      * Gets the list of interfaces in this area.
      *
      * @return list of interfaces
      */
-    public List<OspfInterface> getInterfacesLst() {
-        return interfacesLst;
+    public List<OspfInterface> ospfInterfaceList() {
+        return ospfInterfaceList;
     }
 
     /**
      * Sets the list of interfaces attached to the area.
      *
-     * @param interfacesLst list of OspfInterface instances
+     * @param ospfInterfaceList list of OspfInterface instances
      */
     @JsonProperty("interface")
-    public void setInterfacesLst(List<OspfInterface> interfacesLst) {
-        this.interfacesLst = interfacesLst;
+    public void setOspfInterfaceList(List<OspfInterface> ospfInterfaceList) {
+        this.ospfInterfaceList = ospfInterfaceList;
     }
 
     /**
@@ -522,7 +447,7 @@
     public boolean noNeighborInLsaExchangeProcess() {
         OspfInterfaceImpl nextInterface;
         OspfNeighborState nextNeighborState;
-        Iterator interfaces = interfacesLst.iterator();
+        Iterator interfaces = ospfInterfaceList.iterator();
         while (interfaces.hasNext()) {
             nextInterface = (OspfInterfaceImpl) interfaces.next();
             Iterator neighbors = nextInterface.listOfNeighbors().values().iterator();
@@ -659,19 +584,14 @@
         return MoreObjects.toStringHelper(getClass())
                 .omitNullValues()
                 .add("areaID", areaId)
-                .add("stubCost", stubCost)
-                .add("addressRanges", addressRanges)
-                .add("interfacesLst", interfacesLst)
-                .add("transitCapability", transitCapability)
+                .add("ospfInterfaceList", ospfInterfaceList)
                 .add("externalRoutingCapability", externalRoutingCapability)
                 .toString();
     }
 
     /**
      * Checks all Neighbors belonging to this Area whether they are in state lesser than the EXCHANGE.
-     * <p>
      * Creates list of such neighbors
-     * <p>
      * Returns list of neighbors who satisfy the conditions
      *
      * @param ospfInterface OSPF interface instance
@@ -716,7 +636,7 @@
     public void addToOtherNeighborLsaTxList(LsaHeader recLsa) {
         //Add the received LSA in other neighbors retransmission list.
         log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList");
-        List<OspfInterface> ospfInterfaces = getInterfacesLst();
+        List<OspfInterface> ospfInterfaces = ospfInterfaceList();
         for (OspfInterface ospfInterfaceFromArea : ospfInterfaces) {
             Map neighbors = ospfInterfaceFromArea.listOfNeighbors();
             for (Object neighborIP : neighbors.keySet()) {
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfInterfaceImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfInterfaceImpl.java
index 19f8ef5..b10cf33 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfInterfaceImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfInterfaceImpl.java
@@ -18,47 +18,93 @@
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
 import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.OspfArea;
 import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLinkTed;
+import org.onosproject.ospf.controller.OspfLsa;
+import org.onosproject.ospf.controller.OspfMessage;
 import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.OspfPacketType;
+import org.onosproject.ospf.controller.OspfRouter;
+import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
+import org.onosproject.ospf.controller.impl.Controller;
+import org.onosproject.ospf.controller.impl.OspfNbrImpl;
+import org.onosproject.ospf.controller.impl.TopologyForDeviceAndLinkImpl;
+import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
+import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
+import org.onosproject.ospf.controller.util.OspfEligibleRouter;
+import org.onosproject.ospf.controller.util.OspfInterfaceType;
 import org.onosproject.ospf.protocol.lsa.LsaHeader;
 import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
+import org.onosproject.ospf.protocol.ospfpacket.OspfMessageWriter;
+import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
+import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.HelloPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
+import org.onosproject.ospf.protocol.util.ChecksumCalculator;
 import org.onosproject.ospf.protocol.util.OspfInterfaceState;
 import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
+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 OSPF interface.
  */
 public class OspfInterfaceImpl implements OspfInterface {
     private static final Logger log = LoggerFactory.getLogger(OspfInterfaceImpl.class);
+    private int interfaceIndex;
     private Ip4Address ipAddress;
     private Ip4Address ipNetworkMask;
-    private int areaId;
+    private Channel channel = null;
     private int helloIntervalTime;
     private int routerDeadIntervalTime;
-    private int transmitDelay;
     private int routerPriority;
-    private int systemInterfaceType;
     private int interfaceType;
-    private int interfaceCost;
-    private String authType;
-    private String authKey;
-    private int pollInterval;
     private int mtu;
     private int reTransmitInterval;
     private Ip4Address dr;
     private Ip4Address bdr;
     private OspfInterfaceState state;
     private List<LsaHeader> linkStateHeaders = new ArrayList<>();
-    private HashMap<String, OspfNbr> listOfNeighbors = new HashMap<>();
-    private HashMap<String, LsaHeader> listOfNeighborMap = new HashMap<>();
+    private Map<String, OspfNbr> listOfNeighbors = new ConcurrentHashMap<>();
+    private Map<String, LsaHeader> listOfNeighborMap = new ConcurrentHashMap<>();
+    private long delay = 0;
+    private InternalHelloTimer helloTimerTask;
+    private InternalWaitTimer waitTimerTask;
+    private InternalDelayedAckTimer delayedAckTimerTask;
+    private ScheduledExecutorService exServiceHello;
+    private ScheduledExecutorService exServiceWait;
+    private ScheduledExecutorService exServiceDelayedAck;
+    private boolean isDelayedAckTimerScheduled = false;
+    private int delayedAckTimerInterval = 2500;
+    private int interfaceTypeOldValue = 0;
+    private TopologyForDeviceAndLink topologyForDeviceAndLink = new TopologyForDeviceAndLinkImpl();
+    private OspfArea ospfArea;
+    private Controller controller;
+
 
     /**
      * Gets the interface state.
@@ -79,6 +125,51 @@
     }
 
     /**
+     * Sets the netty channel.
+     *
+     * @param channel channel
+     */
+    public void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    /**
+     * Returns OSPF area instance.
+     *
+     * @return OSPF area instance
+     */
+    public OspfArea ospfArea() {
+        return ospfArea;
+    }
+
+    /**
+     * Sets OSPF controller instance.
+     *
+     * @param controller OSPF controller instance
+     */
+    public void setController(Controller controller) {
+        this.controller = controller;
+    }
+
+    /**
+     * Sets OSPF area instance.
+     *
+     * @param ospfArea OSPF area instance
+     */
+    public void setOspfArea(OspfArea ospfArea) {
+        this.ospfArea = ospfArea;
+    }
+
+    /**
+     * Gets interface state.
+     *
+     * @return interface state
+     */
+    public String interfaceState() {
+        return state.interfaceState();
+    }
+
+    /**
      * Gets link state headers.
      *
      * @return get the list of lsa headers
@@ -130,9 +221,36 @@
         return listOfNeighbors.get(neighborId);
     }
 
+    /**
+     * Removes all the neighbors.
+     */
+    public void removeNeighbors() {
+        Set<String> neighbors = listOfNeighbors.keySet();
+        for (String neighborId : neighbors) {
+            removeNeighbor(listOfNeighbors.get(neighborId));
+            log.debug("Neighbor removed - {}", neighborId);
+        }
+        listOfNeighbors.clear();
+    }
 
     /**
-     * Adds LSAHeader to map.
+     * Removes neighbor from the interface neighbor map.
+     *
+     * @param ospfNeighbor OSPF neighbor instance
+     */
+    public void removeNeighbor(OspfNbr ospfNeighbor) {
+        log.debug("Neighbor removed - {}", ospfNeighbor.neighborId());
+        ospfNeighbor.stopInactivityTimeCheck();
+        ospfNeighbor.stopFloodingTimer();
+        ospfNeighbor.stopRxMtDdTimer();
+        ospfNeighbor.stopRxMtLsrTimer();
+
+        listOfNeighbors.remove(ospfNeighbor.neighborId());
+    }
+
+
+    /**
+     * Adds LSA header to map.
      *
      * @param lsaHeader LSA header instance
      */
@@ -175,7 +293,7 @@
      *
      * @return listOfNeighbors as key value pair
      */
-    public HashMap<String, OspfNbr> listOfNeighbors() {
+    public Map<String, OspfNbr> listOfNeighbors() {
         return listOfNeighbors;
     }
 
@@ -189,6 +307,24 @@
     }
 
     /**
+     * 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;
+    }
+
+    /**
      * Gets the IP address.
      *
      * @return IP address
@@ -225,25 +361,6 @@
     }
 
     /**
-     * Gets the area id this interface belongs.
-     *
-     * @return area id this interface belongs
-     */
-    public int areaId() {
-        return areaId;
-    }
-
-
-    /**
-     * Sets the area id this interface belongs.
-     *
-     * @param areaId the area id this interface belongs
-     */
-    public void setAreaId(int areaId) {
-        this.areaId = areaId;
-    }
-
-    /**
      * Gets hello interval time.
      *
      * @return hello interval time
@@ -298,78 +415,6 @@
     }
 
     /**
-     * Gets interface cost.
-     *
-     * @return interface cost
-     */
-    public int interfaceCost() {
-        return interfaceCost;
-    }
-
-    /**
-     * Sets interface cost.
-     *
-     * @param interfaceCost interface cost
-     */
-    public void setInterfaceCost(int interfaceCost) {
-        this.interfaceCost = interfaceCost;
-    }
-
-    /**
-     * Gets authentication type.
-     *
-     * @return authType represents authentication type
-     */
-    public String authType() {
-        return authType;
-    }
-
-    /**
-     * Sets authentication type.
-     *
-     * @param authType authType represents authentication type
-     */
-    public void setAuthType(String authType) {
-        this.authType = authType;
-    }
-
-    /**
-     * Gets authentication key.
-     *
-     * @return authKey represents authentication key
-     */
-    public String authKey() {
-        return authKey;
-    }
-
-    /**
-     * Sets authentication key.
-     *
-     * @param authKey represents authentication key
-     */
-    public void setAuthKey(String authKey) {
-        this.authKey = authKey;
-    }
-
-    /**
-     * Gets poll interval.
-     *
-     * @return pollInterval an integer represents poll interval
-     */
-    public int pollInterval() {
-        return pollInterval;
-    }
-
-    /**
-     * Sets poll interval.
-     *
-     * @param pollInterval an integer represents poll interval
-     */
-    public void setPollInterval(int pollInterval) {
-        this.pollInterval = pollInterval;
-    }
-
-    /**
      * Gets max transfer unit.
      *
      * @return mtu an integer represents max transfer unit
@@ -442,23 +487,1070 @@
     }
 
     /**
-     * Get transmission delay.
+     * Represents an interface is up and connected.
      *
-     * @return transmission delay
+     * @throws Exception might throws exception
      */
-    public int transmitDelay() {
-        return transmitDelay;
+    public void interfaceUp() throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::interfaceUp...!!!");
+        if (interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
+            setState(OspfInterfaceState.POINT2POINT);
+            interfaceTypeOldValue = interfaceType();
+            log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} ",
+                      interfaceType(), state());
+        } else if (interfaceType() == OspfInterfaceType.BROADCAST.value()) {
+            //if router priority is 0, move the state to DROther
+            interfaceTypeOldValue = interfaceType();
+            if (routerPriority() == 0) {
+                setState(OspfInterfaceState.DROTHER);
+            } else {
+                log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} RouterPriority {}",
+                          interfaceType(),
+                          state(), routerPriority());
+                setState(OspfInterfaceState.WAITING);
+                //start wait timer - like inactivity timer with router deadInterval
+                startWaitTimer();
+            }
+        }
+        // Start hello timer with interval from config - convert seconds to milliseconds
+        startHelloTimer();
+        ospfArea.refreshArea(this);
+    }
+
+
+    /**
+     * Gets called when a BDR was detected before the wait timer expired.
+     *
+     * @param ch channel instance
+     * @throws Exception might throws exception
+     */
+    public void backupSeen(Channel ch) throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::backupSeen ");
+        if (state() == OspfInterfaceState.WAITING) {
+            electRouter(ch);
+        }
     }
 
     /**
-     * Sets transmission delay.
+     * Gets called when no hello message received for particular period.
      *
-     * @param transmitDelay transmission delay
+     * @param ch channel instance
+     * @throws Exception might throws exception
      */
-    public void setTransmitDelay(int transmitDelay) {
-        this.transmitDelay = transmitDelay;
+    public void waitTimer(Channel ch) throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::waitTimer ");
+        //According to RFC-2328 section 9.4
+        if (state() == OspfInterfaceState.WAITING) {
+            electRouter(ch);
+        }
     }
 
+    /**
+     * Initiates DR election process.
+     *
+     * @param ch netty channel instance
+     * @throws Exception might throws exception
+     */
+    public void callDrElection(Channel ch) throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::callDrElection ");
+        //call when timer expired
+        //no hello message received for particular interval
+        //section 9.4
+        electRouter(ch);
+        interfaceTypeOldValue = interfaceType();
+    }
+
+    /**
+     * Neighbor change event is triggered when the router priority gets changed.
+     *
+     * @throws Exception might throws exception
+     */
+    public void neighborChange() throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::neighborChange ");
+        if (state() == OspfInterfaceState.DR || state() == OspfInterfaceState.BDR ||
+                state() == OspfInterfaceState.DROTHER) {
+            electRouter(channel);
+        }
+    }
+
+    /**
+     * Gets called when an interface is down.
+     * All interface variables are reset, and interface timers disabled.
+     * Also all neighbor connections associated with the interface are destroyed.
+     */
+    public void interfaceDown() {
+        log.debug("OSPFInterfaceChannelHandler::interfaceDown ");
+        stopHelloTimer();
+        listOfNeighbors().clear();
+        setState(OspfInterfaceState.DOWN);
+    }
+
+    /**
+     * When an OSPF message received it is handed over to this method.
+     * Based on the type of the OSPF message received it will be handed over
+     * to corresponding message handler methods.
+     *
+     * @param ospfMessage received OSPF message
+     * @param ctx         channel handler context instance.
+     * @throws Exception might throws exception
+     */
+    public void processOspfMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("OspfChannelHandler::processOspfMessage...!!!");
+
+        if (!validateMessage(ospfMessage)) {
+            return;
+        }
+
+        switch (ospfMessage.ospfMessageType().value()) {
+            case OspfParameters.HELLO:
+                processHelloMessage(ospfMessage, ctx);
+                break;
+            case OspfParameters.DD:
+                processDdMessage(ospfMessage, ctx);
+                break;
+            case OspfParameters.LSREQUEST:
+                processLsRequestMessage(ospfMessage, ctx);
+                break;
+            case OspfParameters.LSUPDATE:
+                processLsUpdateMessage(ospfMessage, ctx);
+                break;
+            case OspfParameters.LSACK:
+                processLsAckMessage(ospfMessage, ctx);
+                break;
+            default:
+                log.debug("Unknown packet to process...!!!");
+                break;
+        }
+    }
+
+    /**
+     * Validates the OSPF message received.
+     *
+     * @param ospfMessage OSPF message.
+     * @return true if it is a valid else false.
+     * @throws Exception might throws exception
+     */
+    private boolean validateMessage(OspfMessage ospfMessage) throws Exception {
+        boolean isValid = true;
+        OspfPacketHeader header = (OspfPacketHeader) ospfMessage;
+
+        //added the check to eliminate self origin packets also two interfaces on same router.
+        if (!header.sourceIp().equals(ipAddress()) && !header.routerId().equals(
+                ospfArea.routerId())) {
+            //Verify the checksum
+            ChecksumCalculator checksum = new ChecksumCalculator();
+            if (!checksum.isValidOspfCheckSum(ospfMessage, OspfUtil.OSPFPACKET_CHECKSUM_POS1,
+                                              OspfUtil.OSPFPACKET_CHECKSUM_POS2)) {
+                log.debug("Checksum mismatch. Received packet type {} ", ospfMessage.ospfMessageType());
+                return false;
+            }
+            if (((OspfPacketHeader) ospfMessage).ospfVersion() != OspfUtil.OSPF_VERSION_2) {
+                log.debug("Received osfpMessage Version should match with Interface Version ");
+                return false;
+            }
+            if (!((OspfPacketHeader) ospfMessage).areaId().equals(ospfArea.areaId())) {
+                log.debug("Received ospf packets are from different area than our Area ID. " +
+                                  "Received Area ID {}, Our AreaId {} ",
+                          ((OspfPacketHeader) ospfMessage).areaId(), ospfArea.areaId());
+                return false;
+            }
+
+            //According to RFC-2328 (8.2)
+            /**
+             * ABR should receive packets from backbone 0.0.0.0 as we are not acting as ABR
+             * we are rejecting the packet.
+             */
+            if (((OspfPacketHeader) ospfMessage).areaId().equals(Ip4Address.valueOf("0.0.0.0"))) {
+                log.debug("ABR should receive packets from backbone 0.0.0.0 as we are not acting as " +
+                                  "ABR we are rejecting the ospf packet");
+                return false;
+            }
+            if (interfaceType() == OspfInterfaceType.BROADCAST.value() &&
+                    !OspfUtil.sameNetwork(((OspfPacketHeader) ospfMessage).sourceIp(),
+                                          ipAddress(), ipNetworkMask())) {
+                log.debug("Received packets from different subnets. Discarding...!!!");
+                return false;
+            }
+        } else {
+            isValid = false;
+        }
+
+        return isValid;
+    }
+
+    /**
+     * Processes Hello message.
+     *
+     * @param ospfMessage OSPF message instance.
+     * @param ctx         context instance.
+     * @throws Exception might throws exception
+     */
+    void processHelloMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        Channel channel = ctx.getChannel();
+        log.debug("OspfChannelHandler::processHelloMessage...!!!");
+        HelloPacket helloPacket = (HelloPacket) ospfMessage;
+
+        // processing of hello packet as per RFC 2328 section 10.5
+        log.debug("OspfChannelHandler::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
+                  interfaceType(), state());
+
+        if (interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
+            if (!helloPacket.networkMask().equals(ipNetworkMask())) {
+                log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received does not " +
+                                  "match the same network mask as the configure Interface");
+                return;
+            }
+        }
+        if (helloPacket.helloInterval() != helloIntervalTime()) {
+            log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
+                              "hello interval as configured Interface");
+            return;
+        }
+        if (helloPacket.routerDeadInterval() != routerDeadIntervalTime()) {
+            log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
+                              "Router Dead interval as configured Interface");
+            return;
+        }
+
+        if (interfaceType == OspfInterfaceType.POINT_TO_POINT.value() &&
+                !helloPacket.dr().equals(OspfUtil.DEFAULTIP)) {
+            log.debug("OspfChannelHandler::processHelloMessage:: Neighbor in broadcast network");
+            return;
+        }
+
+        if (interfaceType == OspfInterfaceType.POINT_TO_POINT.value()) {
+            // to verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
+            OspfNbr nbr;
+            if (!isNeighborInList(helloPacket.routerId().toString())) {
+                nbr = new OspfNbrImpl(ospfArea, this, helloPacket.sourceIp(),
+                                      helloPacket.routerId(), helloPacket.options(), topologyForDeviceAndLink);
+                addNeighbouringRouter(nbr);
+            } else {
+                nbr = neighbouringRouter(helloPacket.routerId().toString());
+                nbr.setRouterPriority(helloPacket.routerPriority());
+            }
+            if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
+                ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
+            } else {
+                ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
+            }
+        } else if (interfaceType == OspfInterfaceType.BROADCAST.value()) {
+
+            if (state() == OspfInterfaceState.WAITING) {
+                if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0"))) &&
+                        (!helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))) {
+                    stopWaitTimer();
+                    setDr(helloPacket.dr());
+                    setBdr(helloPacket.bdr());
+                    if (helloPacket.dr().equals(ipAddress())) {
+                        setState(OspfInterfaceState.DR);
+                        //refresh router Lsa
+                        ospfArea.refreshArea(this);
+                    } else if (helloPacket.bdr().equals(ipAddress())) {
+                        setState(OspfInterfaceState.BDR);
+                        //refresh router Lsa
+                        ospfArea.refreshArea(this);
+                    } else {
+                        setState(OspfInterfaceState.DROTHER);
+                        ospfArea.refreshArea(this);
+                    }
+
+                } else if (!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
+                        !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
+                    setDr(helloPacket.dr());
+                    setBdr(helloPacket.bdr());
+                }
+                Ip4Address sourceIp = helloPacket.sourceIp();
+                OspfNbr nbr;
+                if (!isNeighborInList(helloPacket.routerId().toString())) {
+                    nbr = new OspfNbrImpl(ospfArea, this, sourceIp, helloPacket.routerId(),
+                                          helloPacket.options(), topologyForDeviceAndLink);
+                    nbr.setNeighborId(helloPacket.routerId());
+                    nbr.setNeighborBdr(helloPacket.bdr());
+                    nbr.setNeighborDr(helloPacket.dr());
+                    nbr.setRouterPriority(helloPacket.routerPriority());
+                    addNeighbouringRouter(nbr);
+                } else {
+                    nbr = neighbouringRouter(helloPacket.routerId().toString());
+                    nbr.setRouterPriority(helloPacket.routerPriority());
+                }
+                if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
+                    ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
+                } else {
+                    ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
+                }
+
+                if (helloPacket.dr().equals(sourceIp)) {
+                    if (helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
+                        // call backup seen
+                        stopWaitTimer();
+                        backupSeen(ctx.getChannel());
+                    }
+                }
+
+                if (helloPacket.bdr().equals(sourceIp)) {
+                    // call backup seen
+                    stopWaitTimer();
+                    backupSeen(ctx.getChannel());
+                }
+            } else {
+
+                if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
+                        !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))
+                        && routerPriority() == 0) {
+                    setDr(helloPacket.dr());
+                    setBdr(helloPacket.bdr());
+                }
+                //To verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
+                Ip4Address sourceIp = helloPacket.sourceIp();
+                OspfNbr nbr;
+                if (!isNeighborInList(helloPacket.routerId().toString())) {
+                    nbr = new OspfNbrImpl(ospfArea, this, sourceIp, helloPacket.routerId(),
+                                          helloPacket.options(), topologyForDeviceAndLink);
+                    nbr.setNeighborId(helloPacket.routerId());
+                    nbr.setNeighborBdr(helloPacket.bdr());
+                    nbr.setNeighborDr(helloPacket.dr());
+                    nbr.setRouterPriority(helloPacket.routerPriority());
+                    addNeighbouringRouter(nbr);
+                    ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
+                } else {
+                    log.debug("OspfChannelHandler::NeighborInList::helloPacket.bdr(): {}, " +
+                                      "helloPacket.dr(): {}", helloPacket.bdr(), helloPacket.dr());
+                    nbr = neighbouringRouter(helloPacket.routerId().toString());
+                    nbr.setRouterPriority(helloPacket.routerPriority());
+                    if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
+                        ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
+                    } else {
+                        ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
+                    }
+                    if (nbr.routerPriority() != helloPacket.routerPriority()) {
+                        nbr.setNeighborBdr(helloPacket.bdr());
+                        nbr.setNeighborDr(helloPacket.dr());
+                        neighborChange();
+                    }
+
+
+                    if (nbr.neighborIpAddr().equals(helloPacket.dr()) &&
+                            !(nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
+                        nbr.setNeighborBdr(helloPacket.bdr());
+                        nbr.setNeighborDr(helloPacket.dr());
+                        neighborChange();
+                    }
+
+                    if (!(nbr.neighborIpAddr().equals(helloPacket.dr())) &&
+                            (nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
+                        nbr.setNeighborBdr(helloPacket.bdr());
+                        nbr.setNeighborDr(helloPacket.dr());
+                        neighborChange();
+                    }
+
+                    if (nbr.neighborIpAddr().equals(helloPacket.bdr()) &&
+                            !(nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
+                        nbr.setNeighborBdr(helloPacket.bdr());
+                        nbr.setNeighborDr(helloPacket.dr());
+                        neighborChange();
+                    }
+
+                    if (!(nbr.neighborIpAddr().equals(helloPacket.bdr())) &&
+                            (nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
+                        nbr.setNeighborBdr(helloPacket.bdr());
+                        nbr.setNeighborDr(helloPacket.dr());
+                        neighborChange();
+                    }
+
+                    nbr.setNeighborBdr(helloPacket.bdr());
+                    nbr.setNeighborDr(helloPacket.dr());
+                }
+            }
+        }
+    }
+
+    /**
+     * process the DD message which received.
+     *
+     * @param ospfMessage OSPF message instance.
+     * @param ctx         channel handler context instance
+     * @throws Exception might throws exception
+     */
+    void processDdMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("OspfChannelHandler::processDdMessage...!!!");
+        Channel channel = ctx.getChannel();
+        DdPacket ddPacket = (DdPacket) ospfMessage;
+        log.debug("Got DD packet from {}", ddPacket.sourceIp());
+        //check it is present in listOfNeighbors
+        Ip4Address neighbourId = ddPacket.routerId();
+        OspfNbr nbr = neighbouringRouter(neighbourId.toString());
+
+        if (nbr != null) {
+            log.debug("OspfChannelHandler::processDdMessage:: OSPFNeighborState {}", nbr.getState());
+            // set options for the NBR
+            nbr.setIsOpaqueCapable(ddPacket.isOpaqueCapable());
+            if (ddPacket.imtu() > mtu()) {
+                log.debug("the MTU size is greater than the interface MTU");
+                return;
+            }
+            if (nbr.getState() == OspfNeighborState.DOWN) {
+                return;
+            }
+            if (nbr.getState() == OspfNeighborState.ATTEMPT) {
+                return;
+            }
+            if (nbr.getState() == OspfNeighborState.TWOWAY) {
+                nbr.adjOk(channel);
+                return;
+            }
+            //if init is the state call twoWayReceived
+            if (nbr.getState() == OspfNeighborState.INIT) {
+                ((OspfNbrImpl) nbr).twoWayReceived(ddPacket, ctx.getChannel());
+            } else if (nbr.getState() == OspfNeighborState.EXSTART) {
+                //get I,M,MS Bits
+                int initialize = ddPacket.isInitialize();
+                int more = ddPacket.isMore();
+                int masterOrSlave = ddPacket.isMaster();
+                int options = ddPacket.options();
+                nbr.setOptions(options);
+
+                if (initialize == OspfUtil.INITIALIZE_SET && more == OspfUtil.MORE_SET &&
+                        masterOrSlave == OspfUtil.IS_MASTER) {
+                    if (ddPacket.getLsaHeaderList().isEmpty()) {
+                        if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) >
+                                OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
+                            nbr.setIsMaster(OspfUtil.IS_MASTER);
+                            ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
+                            nbr.setDdSeqNum(ddPacket.sequenceNo());
+                            nbr.setOptions(ddPacket.options());
+                            ((OspfNbrImpl) nbr).negotiationDone(ddPacket, true, ddPacket.getLsaHeaderList(),
+                                                                ctx.getChannel());
+                        }
+                    }
+                }
+                if (initialize == OspfUtil.INITIALIZE_NOTSET && masterOrSlave == OspfUtil.NOT_MASTER) {
+                    if (nbr.ddSeqNum() == ddPacket.sequenceNo()) {
+                        if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) <
+                                OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
+                            ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
+                            nbr.setOptions(ddPacket.options());
+                            nbr.setDdSeqNum(nbr.ddSeqNum() + 1);
+                            ((OspfNbrImpl) nbr).negotiationDone(ddPacket, false, ddPacket.getLsaHeaderList(),
+                                                                ctx.getChannel());
+                        }
+                    }
+                }
+
+            } else if (nbr.getState() == OspfNeighborState.EXCHANGE) {
+                //get I,M,MS Bits
+                log.debug("Neighbor state:: EXCHANGE");
+                boolean isDuplicateDDPacket = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
+                int initialize = ddPacket.isInitialize();
+                int more = ddPacket.isMore();
+                int masterOrSlave = ddPacket.isMaster();
+                int options = ddPacket.options();
+
+                if (!isDuplicateDDPacket) {
+                    //if dd packet is not duplicate  then continue
+                    if (nbr.isMaster() != masterOrSlave) {
+                        DdPacket newResPacket =
+                                (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Master/Slave Inconsistency");
+                        newResPacket.setDestinationIp(ddPacket.sourceIp());
+                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
+                        byte[] messageToWrite = getMessage(newResPacket);
+                        ctx.getChannel().write(messageToWrite);
+                    } else if (initialize == 1) {
+                        DdPacket newResPacket =
+                                (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
+                        newResPacket.setDestinationIp(ddPacket.sourceIp());
+                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
+                        byte[] messageToWrite = getMessage(newResPacket);
+                        ctx.getChannel().write(messageToWrite);
+                    } else {
+
+                        if (masterOrSlave == OspfUtil.NOT_MASTER) {
+                            if (ddPacket.sequenceNo() == nbr.ddSeqNum()) {
+                                //Process the DD Packet
+                                ((OspfNbrImpl) nbr).processDdPacket(false, ddPacket, ctx.getChannel());
+                                log.debug("Received DD Packet");
+                            } else {
+                                DdPacket newResPacket =
+                                        (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Sequence Number Mismatch");
+                                newResPacket.setDestinationIp(ddPacket.sourceIp());
+                                log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
+                                byte[] messageToWrite = getMessage(newResPacket);
+                                ctx.getChannel().write(messageToWrite);
+                            }
+                        } else {
+                            //we are the slave
+                            if (ddPacket.sequenceNo() == (nbr.ddSeqNum() + 1)) {
+                                ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
+                                ((OspfNbrImpl) nbr).processDdPacket(true, ddPacket, ctx.getChannel());
+                                log.debug("Process DD Packet");
+                            } else {
+                                DdPacket newResPacket =
+                                        (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("options inconsistency");
+                                newResPacket.setDestinationIp(ddPacket.sourceIp());
+                                log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
+                                byte[] messageToWrite = getMessage(newResPacket);
+                                ctx.getChannel().write(messageToWrite);
+                            }
+                        }
+                    }
+                } else {
+                    if (masterOrSlave == OspfUtil.NOT_MASTER) {
+                        return;
+                    } else {
+                        DdPacket newResPacket = ((OspfNbrImpl) nbr).lastSentDdPacket();
+                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
+                        byte[] messageToWrite = getMessage(newResPacket);
+                        ctx.getChannel().write(messageToWrite);
+                    }
+                }
+            } else if (nbr.getState() == OspfNeighborState.LOADING || nbr.getState() == OspfNeighborState.FULL) {
+                //In case if we are slave then we have to send the last received DD Packet
+                int options = ddPacket.options();
+                if (nbr.options() != options) {
+                    OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
+                    newResPacket.setDestinationIp(ddPacket.sourceIp());
+                    byte[] messageToWrite = getMessage(newResPacket);
+                    ctx.getChannel().write(messageToWrite);
+                } else if (ddPacket.isInitialize() == OspfUtil.INITIALIZE_SET) {
+                    OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
+                    newResPacket.setDestinationIp(ddPacket.sourceIp());
+                    byte[] messageToWrite = getMessage(newResPacket);
+                    ctx.getChannel().write(messageToWrite);
+                }
+                boolean isDuplicate = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
+                //we are master
+                if (nbr.isMaster() != OspfUtil.IS_MASTER) {
+                    // check if the packet is duplicate, duplicates should be discarded by the master
+                    if (isDuplicate) {
+                        log.debug("received a duplicate DD packet");
+                    }
+                } else {
+                    //The slave must respond to duplicates by repeating the last Database Description packet
+                    //that it had sent.
+                    if (isDuplicate) {
+                        ddPacket.setDestinationIp(ddPacket.sourceIp());
+                        byte[] messageToWrite = getMessage(((OspfNbrImpl) nbr).lastSentDdPacket());
+                        ctx.getChannel().write(messageToWrite);
+                        log.debug("Sending back the duplicate packet ");
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Process the Ls Request message.
+     *
+     * @param ospfMessage OSPF message instance.
+     * @param ctx         channel handler context instance.
+     * @throws Exception might throws exception
+     */
+    void processLsRequestMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("OspfChannelHandler::processLsRequestMessage...!!!");
+        Channel channel = ctx.getChannel();
+        LsRequest lsrPacket = (LsRequest) ospfMessage;
+        OspfNbr nbr = neighbouringRouter(lsrPacket.routerId().toString());
+
+        if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING ||
+                nbr.getState() == OspfNeighborState.FULL) {
+
+            LsRequest reqMsg = (LsRequest) ospfMessage;
+            if (reqMsg.getLinkStateRequests().isEmpty()) {
+                log.debug("Received Link State Request Vector is Empty ");
+                return;
+            } else {
+                //Send the LsUpdate back
+                ListIterator<LsRequestPacket> listItr = reqMsg.getLinkStateRequests().listIterator();
+                while (listItr.hasNext()) {
+                    LsUpdate lsupdate = new LsUpdate();
+                    lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
+                    lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
+                    lsupdate.setRouterId(ospfArea.routerId());
+                    lsupdate.setAreaId(ospfArea.areaId());
+                    lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
+                    lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                    lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                    lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
+
+                    //limit to mtu
+                    int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
+                    int maxSize = mtu() -
+                            OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
+                    int noLsa = 0;
+                    while (listItr.hasNext()) {
+                        LsRequestPacket lsRequest = (LsRequestPacket) listItr.next();
+                        // to verify length of the LSA
+                        LsaWrapper wrapper = ospfArea.getLsa(lsRequest.lsType(), lsRequest.linkStateId(),
+                                                             lsRequest.ownRouterId());
+                        OspfLsa ospflsa = wrapper.ospfLsa();
+                        if ((currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen()) >= maxSize) {
+                            listItr.previous();
+                            break;
+                        }
+                        if (ospflsa != null) {
+                            lsupdate.addLsa(ospflsa);
+                            noLsa++;
+
+                            currentLength = currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen();
+                        } else {
+                            nbr.badLSReq(channel);
+                        }
+                    }
+                    lsupdate.setNumberOfLsa(noLsa);
+                    //set the destination
+                    if (state() == OspfInterfaceState.DR ||
+                            state() == OspfInterfaceState.BDR ||
+                            state() == OspfInterfaceState.POINT2POINT) {
+                        lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+                    } else if (state() == OspfInterfaceState.DROTHER) {
+                        lsupdate.setDestinationIp(OspfUtil.ALL_DROUTERS);
+                    }
+                    byte[] messageToWrite = getMessage(lsupdate);
+                    ctx.getChannel().write(messageToWrite);
+                }
+            }
+        }
+    }
+
+    /**
+     * Process the ls update message.
+     *
+     * @param ospfMessage OSPF message instance.
+     * @param ctx         channel handler context instance.
+     * @throws Exception might throws exception
+     */
+    void processLsUpdateMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("OspfChannelHandler::processLsUpdateMessage");
+        LsUpdate lsUpdate = (LsUpdate) ospfMessage;
+        String neighbourId = lsUpdate.routerId().toString();
+        //LSUpdate packet has been associated with a particular neighbor.
+        //Neighbor should not be in lesser state than Exchange.
+        if (isNeighborInList(neighbourId)) {
+            OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(neighbourId);
+            if (nbr.getState() == OspfNeighborState.EXCHANGE ||
+                    nbr.getState() == OspfNeighborState.LOADING) {
+                nbr.processLsUpdate(lsUpdate, ctx.getChannel());
+            } else if (nbr.getState() == OspfNeighborState.FULL) {
+                if (lsUpdate.noLsa() != 0) {
+                    List<OspfLsa> list = lsUpdate.getLsaList();
+                    Iterator itr = list.iterator();
+                    while (itr.hasNext()) {
+                        LsaHeader lsa = (LsaHeader) itr.next();
+                        nbr.processReceivedLsa(lsa, true, ctx.getChannel(), lsUpdate.sourceIp());
+                    }
+                } else {
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Process the ls acknowledge message.
+     *
+     * @param ospfMessage OSPF message instance.
+     * @param ctx         channel handler context instance.
+     * @throws Exception might throws exception
+     */
+    void processLsAckMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+        log.debug("OspfChannelHandler::processLsAckMessage");
+        LsAcknowledge lsAckPacket = (LsAcknowledge) ospfMessage;
+        //check it is present in listOfNeighbors
+        OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(lsAckPacket.routerId().toString());
+        if (nbr != null) {
+            if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
+                // discard the packet.
+                return;
+            } else {
+                // process ls acknowledgements
+                Iterator itr = lsAckPacket.getLinkStateHeaders().iterator();
+                while (itr.hasNext()) {
+                    LsaHeader lsRequest = (LsaHeader) itr.next();
+
+                    OspfLsa ospfLsa =
+                            (OspfLsa) nbr.getPendingReTxList().get(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
+                    if (lsRequest != null && ospfLsa != null) {
+                        String isSame = ((OspfLsdbImpl) ospfArea.database()).isNewerOrSameLsa(
+                                lsRequest, (LsaHeader) ospfLsa);
+                        if (isSame.equals("same")) {
+                            nbr.getPendingReTxList().remove(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Compares two Dd Packets to check whether its duplicate or not.
+     *
+     * @param receivedDPacket received DD packet from network.
+     * @param lastDdPacket    Last DdPacket which we sent.
+     * @return true if it is a duplicate packet else false.
+     */
+    public boolean compareDdPackets(DdPacket receivedDPacket, DdPacket lastDdPacket) {
+        if (receivedDPacket.isInitialize() == lastDdPacket.isInitialize()) {
+            if (receivedDPacket.isMaster() == lastDdPacket.isMaster()) {
+                if (receivedDPacket.isMore() == lastDdPacket.isMore()) {
+                    if (receivedDPacket.options() == lastDdPacket.options()) {
+                        if (receivedDPacket.sequenceNo() == lastDdPacket.sequenceNo()) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Starts the hello timer which sends hello packet every configured seconds.
+     */
+    public void startHelloTimer() {
+        log.debug("OSPFInterfaceChannelHandler::startHelloTimer");
+        exServiceHello = Executors.newSingleThreadScheduledExecutor();
+        helloTimerTask = new InternalHelloTimer();
+        final ScheduledFuture<?> helloHandle =
+                exServiceHello.scheduleAtFixedRate(helloTimerTask, delay, helloIntervalTime, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Stops the hello timer.
+     */
+    public void stopHelloTimer() {
+        log.debug("OSPFInterfaceChannelHandler::stopHelloTimer ");
+        exServiceHello.shutdown();
+    }
+
+    /**
+     * Starts the wait timer.
+     */
+    public void startWaitTimer() {
+        log.debug("OSPFNbr::startWaitTimer");
+        exServiceWait = Executors.newSingleThreadScheduledExecutor();
+        waitTimerTask = new InternalWaitTimer();
+        final ScheduledFuture<?> waitTimerHandle =
+                exServiceWait.schedule(waitTimerTask, routerDeadIntervalTime(), TimeUnit.SECONDS);
+    }
+
+    /**
+     * Stops the wait timer.
+     */
+    public void stopWaitTimer() {
+        log.debug("OSPFNbr::stopWaitTimer ");
+        exServiceWait.shutdown();
+    }
+
+    /**
+     * Starts the timer which waits for configured seconds and sends Delayed Ack Packet.
+     */
+    public void startDelayedAckTimer() {
+        if (!isDelayedAckTimerScheduled) {
+            log.debug("Started DelayedAckTimer...!!!");
+            exServiceDelayedAck = Executors.newSingleThreadScheduledExecutor();
+            delayedAckTimerTask = new InternalDelayedAckTimer();
+            final ScheduledFuture<?> delayAckHandle =
+                    exServiceDelayedAck.scheduleAtFixedRate(delayedAckTimerTask, delayedAckTimerInterval,
+                                                            delayedAckTimerInterval, TimeUnit.MILLISECONDS);
+            isDelayedAckTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops the delayed acknowledge timer.
+     */
+    public void stopDelayedAckTimer() {
+        if (isDelayedAckTimerScheduled) {
+            log.debug("Stopped DelayedAckTimer...!!!");
+            isDelayedAckTimerScheduled = false;
+            exServiceDelayedAck.shutdown();
+        }
+    }
+
+    /**
+     * Performs DR election.
+     *
+     * @param ch Netty Channel instance.
+     * @throws Exception might throws exception
+     */
+    public void electRouter(Channel ch) throws Exception {
+
+        Ip4Address currentDr = dr();
+        Ip4Address currentBdr = bdr();
+        OspfInterfaceState oldState = state();
+        OspfInterfaceState newState;
+
+        log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
+                  currentDr, currentBdr);
+        List<OspfEligibleRouter> eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
+
+        log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
+        OspfEligibleRouter electedBdr = electBdr(eligibleRouters);
+        OspfEligibleRouter electedDr = electDr(eligibleRouters, electedBdr);
+
+        setBdr(electedBdr.getIpAddress());
+        setDr(electedDr.getIpAddress());
+
+        if (electedBdr.getIpAddress().equals(ipAddress()) &&
+                !electedBdr.getIpAddress().equals(currentBdr)) {
+            setState(OspfInterfaceState.BDR);
+        }
+
+        if (electedDr.getIpAddress().equals(ipAddress()) &&
+                !electedDr.getIpAddress().equals(currentDr)) {
+            setState(OspfInterfaceState.DR);
+        }
+
+        if (state() != oldState &&
+                !(state() == OspfInterfaceState.DROTHER &&
+                        oldState.value() < OspfInterfaceState.DROTHER.value())) {
+            log.debug("Recalculating as the State is changed ");
+            log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
+                      currentDr, currentBdr);
+            eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
+
+            log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
+            electedBdr = electBdr(eligibleRouters);
+            electedDr = electDr(eligibleRouters, electedBdr);
+
+            setBdr(electedBdr.getIpAddress());
+            setDr(electedDr.getIpAddress());
+        }
+
+        if (electedBdr.getIpAddress().equals(ipAddress()) &&
+                !electedBdr.getIpAddress().equals(currentBdr)) {
+            setState(OspfInterfaceState.BDR);
+            ospfArea.refreshArea(this);
+        }
+
+        if (electedDr.getIpAddress().equals(ipAddress()) &&
+                !electedDr.getIpAddress().equals(currentDr)) {
+            setState(OspfInterfaceState.DR);
+            //Refresh Router Lsa & Network Lsa
+            ospfArea.refreshArea(this);
+        }
+
+        if (currentDr != electedDr.getIpAddress() || currentBdr != electedBdr.getIpAddress()) {
+            Set<String> negibhorIdList;
+            negibhorIdList = listOfNeighbors().keySet();
+            for (String routerid : negibhorIdList) {
+                OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(routerid);
+                if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue()) {
+                    nbr.adjOk(ch);
+                }
+            }
+        }
+
+        log.debug("OSPFInterfaceChannelHandler::electRouter -> ElectedDR: {}, ElectedBDR: {}",
+                  electedDr.getIpAddress(), electedBdr.getIpAddress());
+    }
+
+
+    /**
+     * BDR Election process. Find the list of eligible router to participate in the process.
+     *
+     * @param electedDr router elected as DR.
+     * @return list of eligible routers
+     */
+    public List<OspfEligibleRouter> calculateListOfEligibleRouters(OspfEligibleRouter electedDr) {
+        log.debug("OSPFNbr::calculateListOfEligibleRouters ");
+        Set<String> neighborIdList;
+        List<OspfEligibleRouter> eligibleRouters = new ArrayList<>();
+
+        neighborIdList = listOfNeighbors().keySet();
+        for (String routerId : neighborIdList) {
+            OspfNbrImpl nbr = (OspfNbrImpl) neighbouringRouter(routerId);
+            if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue() &&
+                    nbr.routerPriority() > 0) {
+                OspfEligibleRouter router = new OspfEligibleRouter();
+                router.setIpAddress(nbr.neighborIpAddr());
+                router.setRouterId(nbr.neighborId());
+                router.setRouterPriority(nbr.routerPriority());
+                if (nbr.neighborDr().equals(nbr.neighborIpAddr()) ||
+                        electedDr.getIpAddress().equals(nbr.neighborIpAddr())) {
+                    router.setIsDr(true);
+                } else if (nbr.neighborBdr().equals(nbr.neighborIpAddr())) {
+                    router.setIsBdr(true);
+                }
+                eligibleRouters.add(router);
+            }
+        }
+        // interface does not have states like two and all
+        if (routerPriority() > 0) {
+            OspfEligibleRouter router = new OspfEligibleRouter();
+            router.setIpAddress(ipAddress());
+            router.setRouterId(ospfArea.routerId());
+            router.setRouterPriority(routerPriority());
+            if (dr().equals(ipAddress()) ||
+                    electedDr.getIpAddress().equals(ipAddress())) {
+                router.setIsDr(true);
+            } else if (bdr().equals(ipAddress()) &&
+                    !dr().equals(ipAddress())) {
+                router.setIsBdr(true);
+            }
+
+            eligibleRouters.add(router);
+        }
+
+        return eligibleRouters;
+    }
+
+    /**
+     * Based on router priority assigns BDR.
+     *
+     * @param eligibleRouters list of routers to participate in bdr election.
+     * @return OSPF Eligible router instance.
+     */
+    public OspfEligibleRouter electBdr(List<OspfEligibleRouter> eligibleRouters) {
+        log.debug("OSPFInterfaceChannelHandler::electBdr -> eligibleRouters: {}", eligibleRouters);
+        List<OspfEligibleRouter> declaredAsBdr = new ArrayList<>();
+        List<OspfEligibleRouter> notDrAndBdr = new ArrayList<>();
+        for (OspfEligibleRouter router : eligibleRouters) {
+            if (router.isBdr()) {
+                declaredAsBdr.add(router);
+            }
+            if (!router.isBdr() && !router.isDr()) {
+                notDrAndBdr.add(router);
+            }
+        }
+
+        OspfEligibleRouter electedBdr = new OspfEligibleRouter();
+        if (!declaredAsBdr.isEmpty()) {
+            if (declaredAsBdr.size() == 1) {
+                electedBdr = declaredAsBdr.get(0);
+            } else if (declaredAsBdr.size() > 1) {
+                electedBdr = selectRouterBasedOnPriority(declaredAsBdr);
+            }
+        } else {
+            if (notDrAndBdr.size() == 1) {
+                electedBdr = notDrAndBdr.get(0);
+            } else if (notDrAndBdr.size() > 1) {
+                electedBdr = selectRouterBasedOnPriority(notDrAndBdr);
+            }
+        }
+
+        electedBdr.setIsBdr(true);
+        electedBdr.setIsDr(false);
+
+        return electedBdr;
+    }
+
+    /**
+     * DR Election process.
+     *
+     * @param eligibleRouters list of eligible routers.
+     * @param electedBdr      Elected Bdr, OSPF eligible router instance.
+     * @return OSPF eligible router instance.
+     */
+    public OspfEligibleRouter electDr(List<OspfEligibleRouter> eligibleRouters,
+                                      OspfEligibleRouter electedBdr) {
+
+        List<OspfEligibleRouter> declaredAsDr = new ArrayList<>();
+        for (OspfEligibleRouter router : eligibleRouters) {
+            if (router.isDr()) {
+                declaredAsDr.add(router);
+            }
+        }
+
+        OspfEligibleRouter electedDr = new OspfEligibleRouter();
+        if (!declaredAsDr.isEmpty()) {
+            if (declaredAsDr.size() == 1) {
+                electedDr = declaredAsDr.get(0);
+            } else if (eligibleRouters.size() > 1) {
+                electedDr = selectRouterBasedOnPriority(declaredAsDr);
+            }
+        } else {
+            electedDr = electedBdr;
+            electedDr.setIsDr(true);
+            electedDr.setIsBdr(false);
+        }
+
+        return electedDr;
+    }
+
+    /**
+     * DR election process.
+     *
+     * @param routersList list of eligible routers.
+     * @return OSPF eligible router instance.
+     */
+    public OspfEligibleRouter selectRouterBasedOnPriority(List<OspfEligibleRouter> routersList) {
+
+        OspfEligibleRouter initialRouter = routersList.get(0);
+
+        for (int i = 1; i < routersList.size(); i++) {
+            OspfEligibleRouter router = routersList.get(i);
+            if (router.getRouterPriority() > initialRouter.getRouterPriority()) {
+                initialRouter = router;
+            } else if (router.getRouterPriority() == initialRouter.getRouterPriority()) {
+                try {
+                    if (OspfUtil.ipAddressToLong(router.getIpAddress().toString()) >
+                            OspfUtil.ipAddressToLong(initialRouter.getIpAddress().toString())) {
+                        initialRouter = router;
+                    }
+                } catch (Exception e) {
+                    log.debug("OSPFInterfaceChannelHandler::selectRouterBasedOnPriority ->" +
+                                      " eligibleRouters: {}", initialRouter);
+                }
+            }
+        }
+
+        return initialRouter;
+    }
+
+    /**
+     * Adds device information.
+     *
+     * @param ospfRouter OSPF router instance
+     */
+    public void addDeviceInformation(OspfRouter ospfRouter) {
+        controller.addDeviceDetails(ospfRouter);
+    }
+
+    /**
+     * removes device information.
+     *
+     * @param ospfRouter OSPF neighbor instance
+     */
+    public void removeDeviceInformation(OspfRouter ospfRouter) {
+        controller.removeDeviceDetails(ospfRouter);
+    }
+
+    /**
+     * Adds link information.
+     *
+     * @param ospfRouter  OSPF router instance
+     * @param ospfLinkTed list link ted instances
+     */
+    public void addLinkInformation(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
+        controller.addLinkDetails(ospfRouter, ospfLinkTed);
+    }
+
+    /**
+     * Removes link information.
+     *
+     * @param ospfRouter  OSPF router instance
+     * @param ospfLinkTed OSPF link TED instance
+     */
+    public void removeLinkInformation(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
+        controller.removeLinkDetails(ospfRouter, ospfLinkTed);
+    }
+
+    /**
+     * Gets message as bytes.
+     *
+     * @param ospfMessage OSPF message
+     * @return OSPF message
+     */
+    private byte[] getMessage(OspfMessage ospfMessage) {
+        OspfMessageWriter messageWriter = new OspfMessageWriter();
+        if (state().equals(OspfInterfaceState.POINT2POINT)) {
+            ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+        }
+        return (messageWriter.getMessage(ospfMessage, interfaceIndex, state.value()));
+    }
+
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -468,32 +1560,24 @@
             return false;
         }
         OspfInterfaceImpl that = (OspfInterfaceImpl) o;
-        return Objects.equal(areaId, that.areaId) &&
-                Objects.equal(helloIntervalTime, that.helloIntervalTime) &&
+        return Objects.equal(helloIntervalTime, that.helloIntervalTime) &&
                 Objects.equal(routerDeadIntervalTime, that.routerDeadIntervalTime) &&
-                Objects.equal(transmitDelay, that.transmitDelay) &&
                 Objects.equal(routerPriority, that.routerPriority) &&
-                Objects.equal(systemInterfaceType, that.systemInterfaceType) &&
                 Objects.equal(interfaceType, that.interfaceType) &&
-                Objects.equal(interfaceCost, that.interfaceCost) &&
-                Objects.equal(pollInterval, that.pollInterval) &&
                 Objects.equal(mtu, that.mtu) &&
                 Objects.equal(reTransmitInterval, that.reTransmitInterval) &&
                 Objects.equal(ipAddress, that.ipAddress) &&
                 Objects.equal(ipNetworkMask, that.ipNetworkMask) &&
                 Objects.equal(listOfNeighbors, that.listOfNeighbors) &&
-                Objects.equal(authType, that.authType) &&
-                Objects.equal(authKey, that.authKey) &&
                 Objects.equal(dr, that.dr) &&
                 Objects.equal(bdr, that.bdr);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(ipAddress, ipNetworkMask, areaId, helloIntervalTime,
-                                routerDeadIntervalTime, transmitDelay, routerPriority, listOfNeighbors,
-                                systemInterfaceType, interfaceType, interfaceCost, authType, authKey,
-                                pollInterval, mtu, reTransmitInterval, dr, bdr);
+        return Objects.hashCode(ipAddress, ipNetworkMask, helloIntervalTime,
+                                routerDeadIntervalTime, routerPriority, listOfNeighbors,
+                                interfaceType, mtu, reTransmitInterval, dr, bdr);
     }
 
     @Override
@@ -502,19 +1586,187 @@
                 .omitNullValues()
                 .add("ipAddress", ipAddress)
                 .add("routerPriority", routerPriority)
-                .add("areaID", areaId)
                 .add("helloIntervalTime", helloIntervalTime)
                 .add("routerDeadIntervalTime", routerDeadIntervalTime)
                 .add("interfaceType", interfaceType)
-                .add("interfaceCost", interfaceCost)
-                .add("authType", authType)
-                .add("authKey", authKey)
-                .add("pollInterval", pollInterval)
                 .add("mtu", mtu)
                 .add("reTransmitInterval", reTransmitInterval)
                 .add("dr", dr)
                 .add("bdr", bdr)
-                .add("transmitDelay", transmitDelay)
                 .toString();
     }
+
+    /**
+     * Represents a Hello task which sent a hello message every configured time interval.
+     */
+    private class InternalHelloTimer implements Runnable {
+
+        /**
+         * Creates an instance of Hello Timer.
+         */
+        InternalHelloTimer() {
+        }
+
+        @Override
+        public void run() {
+            if (channel != null && channel.isOpen() && channel.isConnected()) {
+                if (interfaceType() == OspfInterfaceType.BROADCAST.value()) {
+                    if (interfaceTypeOldValue != interfaceType()) {
+                        try {
+                            callDrElection(channel);
+                        } catch (Exception e) {
+                            log.debug("Error while calling interfaceUp {}", e.getMessage());
+                        }
+                    }
+                } else {
+                    if (interfaceTypeOldValue != interfaceType()) {
+                        interfaceTypeOldValue = interfaceType();
+                    }
+                }
+                HelloPacket hellopacket = new HelloPacket();
+                //Headers
+                hellopacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                hellopacket.setOspftype(OspfPacketType.HELLO.value());
+                hellopacket.setOspfPacLength(0); //will be modified while encoding
+                hellopacket.setRouterId(ospfArea.routerId());
+                hellopacket.setAreaId(ospfArea.areaId());
+                hellopacket.setChecksum(0); //will be modified while encoding
+                hellopacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                hellopacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                //Body
+                hellopacket.setNetworkMask(ipNetworkMask());
+                hellopacket.setOptions(ospfArea.options());
+                hellopacket.setHelloInterval(helloIntervalTime());
+                hellopacket.setRouterPriority(routerPriority());
+                hellopacket.setRouterDeadInterval(routerDeadIntervalTime());
+                hellopacket.setDr(dr());
+                hellopacket.setBdr(bdr());
+
+                Map<String, OspfNbr> listOfNeighbors = listOfNeighbors();
+                Set<String> keys = listOfNeighbors.keySet();
+                Iterator itr = keys.iterator();
+                while (itr.hasNext()) {
+                    String nbrKey = (String) itr.next();
+                    OspfNbrImpl nbr = (OspfNbrImpl) listOfNeighbors.get(nbrKey);
+                    if (nbr.getState() != OspfNeighborState.DOWN) {
+                        hellopacket.addNeighbor(Ip4Address.valueOf(nbrKey));
+                    }
+                }
+                // build a hello Packet
+                if (channel == null || !channel.isOpen() || !channel.isConnected()) {
+                    log.debug("Hello Packet not sent !!.. Channel Issue...");
+                    return;
+                }
+
+                hellopacket.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+                byte[] messageToWrite = getMessage(hellopacket);
+                ChannelFuture future = channel.write(messageToWrite);
+                if (future.isSuccess()) {
+                    log.debug("Hello Packet successfully sent !!");
+                } else {
+                    future.awaitUninterruptibly();
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Represents a Wait Timer task which waits the interface state to become WAITING.
+     * It initiates DR election process.
+     */
+    private class InternalWaitTimer implements Runnable {
+        Channel ch;
+
+        /**
+         * Creates an instance of Wait Timer.
+         */
+        InternalWaitTimer() {
+            this.ch = channel;
+        }
+
+        @Override
+        public void run() {
+            log.debug("Wait timer expires...");
+            if (ch != null && ch.isConnected()) {
+                try {
+                    waitTimer(ch);
+                } catch (Exception e) {
+                    log.debug("Exception at wait timer ...!!!");
+                }
+            }
+        }
+    }
+
+    /**
+     * Represents a task which sent a LS Acknowledge from the link state headers list.
+     */
+    private class InternalDelayedAckTimer implements Runnable {
+        Channel ch;
+
+        /**
+         * Creates an instance of Delayed acknowledge timer.
+         */
+        InternalDelayedAckTimer() {
+            this.ch = channel;
+        }
+
+        @Override
+        public void run() {
+            if (!linkStateHeaders().isEmpty()) {
+                isDelayedAckTimerScheduled = true;
+                if (ch != null && ch.isConnected()) {
+
+                    List<LsaHeader> listOfLsaHeadersAcknowledged = new ArrayList<>();
+                    List<LsaHeader> listOfLsaHeaders = linkStateHeaders();
+                    log.debug("Delayed Ack, Number of Lsa's to Ack {}", listOfLsaHeaders.size());
+                    Iterator itr = listOfLsaHeaders.iterator();
+                    while (itr.hasNext()) {
+                        LsAcknowledge ackContent = new LsAcknowledge();
+                        //Setting OSPF Header
+                        ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
+                        ackContent.setOspftype(OspfPacketType.LSAACK.value());
+                        ackContent.setRouterId(ospfArea.routerId());
+                        ackContent.setAreaId(ospfArea.areaId());
+                        ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
+                        ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                        ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
+                        ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
+                        //limit to mtu
+                        int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
+                        int maxSize = mtu() -
+                                OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
+                        while (itr.hasNext()) {
+                            if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) >= maxSize) {
+                                break;
+                            }
+                            LsaHeader lsaHeader = (LsaHeader) itr.next();
+                            ackContent.addLinkStateHeader(lsaHeader);
+                            currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
+                            listOfLsaHeadersAcknowledged.add(lsaHeader);
+                            log.debug("Delayed Ack, Added Lsa's to Ack {}", lsaHeader);
+                        }
+
+                        log.debug("Delayed Ack, Number of Lsa's in LsAck packet {}",
+                                  ackContent.getLinkStateHeaders().size());
+
+                        //set the destination
+                        if (state() == OspfInterfaceState.DR || state() == OspfInterfaceState.BDR
+                                || state() == OspfInterfaceState.POINT2POINT) {
+                            ackContent.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+                        } else if (state() == OspfInterfaceState.DROTHER) {
+                            ackContent.setDestinationIp(OspfUtil.ALL_DROUTERS);
+                        }
+                        byte[] messageToWrite = getMessage(ackContent);
+                        ch.write(messageToWrite);
+
+                        for (LsaHeader lsa : listOfLsaHeadersAcknowledged) {
+                            linkStateHeaders().remove(lsa);
+                            removeLsaFromNeighborMap(((OspfAreaImpl) ospfArea).getLsaKey(lsa));
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
index 3f8f967..cf24080 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/Controller.java
@@ -15,13 +15,15 @@
  */
 package org.onosproject.ospf.controller.impl;
 
-import org.jboss.netty.bootstrap.ServerBootstrap;
+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.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.TpPort;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.ospf.controller.OspfAgent;
 import org.onosproject.ospf.controller.OspfArea;
@@ -29,42 +31,137 @@
 import org.onosproject.ospf.controller.OspfLinkTed;
 import org.onosproject.ospf.controller.OspfProcess;
 import org.onosproject.ospf.controller.OspfRouter;
+import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import static org.onlab.util.Tools.groupedThreads;
 
 /**
- * Representation of the main controller class. Handles all setup and network listeners.
+ * Representation of an OSPF controller.
  */
 public class Controller {
-
-    protected static final Logger log = LoggerFactory.getLogger(Controller.class);
     protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
-    private static final String PROCESS = "process";
-    private static final String AREA = "area";
-    private static final String INTERFACE = "interface";
-
-    protected int ospfPort = 7000;
-    protected int workerThreads = 16;
+    private static final Logger log = LoggerFactory.getLogger(Controller.class);
+    private static final int RETRY_INTERVAL = 4;
+    private final int peerWorkerThreads = 16;
     protected long systemStartTime;
+    byte[] configPacket = null;
+    private List<OspfProcess> processes = null;
+    private OspfInterfaceChannelHandler ospfChannelHandler;
+    private NioClientSocketChannelFactory peerExecFactory;
+    private ClientBootstrap peerBootstrap = null;
+    private TpPort isisPort = TpPort.tpPort(OspfUtil.SPORT);
+    private ScheduledExecutorService connectExecutor = null;
+    private int connectRetryCounter = 0;
+    private int connectRetryTime;
     private DriverService driverService;
     private OspfAgent agent;
-    private List<ChannelGroup> cgList = new ArrayList();
-    private List<NioServerSocketChannelFactory> execFactoryLst = new ArrayList<>();
-    private List<OspfProcess> processes;
+
+    /**
+     * Deactivates OSPF controller.
+     */
+    public void isisDeactivate() {
+        peerExecFactory.shutdown();
+    }
+
+    /**
+     * Updates the processes configuration.
+     *
+     * @param ospfProcesses list of OSPF process instances
+     * @throws Exception might throws parse exception
+     */
+    public void updateConfig(List<OspfProcess> ospfProcesses) throws Exception {
+        log.debug("Controller::UpdateConfig called");
+        configPacket = new byte[OspfUtil.CONFIG_LENGTH];
+        byte numberOfInterface = 0; // number of interfaces to configure
+        configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
+        for (OspfProcess ospfProcess : ospfProcesses) {
+            log.debug("OspfProcessDetails : " + ospfProcess);
+            for (OspfArea ospfArea : ospfProcess.areas()) {
+                for (OspfInterface ospfInterface : ospfArea.ospfInterfaceList()) {
+                    log.debug("OspfInterfaceDetails : " + ospfInterface);
+                    numberOfInterface++;
+                    configPacket[2 * numberOfInterface] = (byte) ospfInterface.interfaceIndex();
+                    configPacket[(2 * numberOfInterface) + 1] = (byte) 4;
+                }
+            }
+        }
+        configPacket[1] = numberOfInterface;
+        //First time configuration
+        if (processes == null) {
+            if (ospfProcesses.size() > 0) {
+                processes = ospfProcesses;
+                connectPeer();
+            }
+        } else {
+            ospfChannelHandler.updateInterfaceMap(ospfProcesses);
+            //Send the config packet
+            ospfChannelHandler.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, 4096, 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);
+
+        ospfChannelHandler = new OspfInterfaceChannelHandler(this, processes);
+        ChannelPipelineFactory pfact = new OspfPipelineFactory(ospfChannelHandler);
+        peerBootstrap.setPipelineFactory(pfact);
+    }
+
+    /**
+     * 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.
@@ -106,36 +203,14 @@
     /**
      * Removes link details.
      *
-     * @param ospfRouter OSPF router instance
+     * @param ospfRouter  OSPF router instance
+     * @param ospfLinkTed OSPF link ted instance
      */
-    public void removeLinkDetails(OspfRouter ospfRouter) {
-        agent.deleteLink(ospfRouter);
+    public void removeLinkDetails(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
+        agent.deleteLink(ospfRouter, ospfLinkTed);
     }
 
     /**
-     * Creates a server bootstrap.
-     *
-     * @return ServerBootstrap bootstrap instance
-     */
-    private ServerBootstrap createServerBootStrap() {
-
-        Executor bossPool = Executors.newCachedThreadPool();
-        Executor workerPool = Executors.newCachedThreadPool();
-        NioServerSocketChannelFactory executerFactory;
-
-        if (workerThreads == 0) {
-            executerFactory = new NioServerSocketChannelFactory(bossPool, workerPool);
-            execFactoryLst.add(executerFactory);
-        } else {
-            executerFactory = new NioServerSocketChannelFactory(bossPool, workerPool, workerThreads);
-            execFactoryLst.add(executerFactory);
-        }
-
-        return new ServerBootstrap(executerFactory);
-    }
-
-
-    /**
      * Initializes internal data structures.
      */
     public void init() {
@@ -149,7 +224,7 @@
      * @param driverService driver service instance
      */
     public void start(OspfAgent ag, DriverService driverService) {
-        log.info("Starting OSPF Controller...!!!");
+        log.info("Starting OSPF controller...!!!");
         this.agent = ag;
         this.driverService = driverService;
         this.init();
@@ -159,615 +234,143 @@
      * Stops the Controller.
      */
     public void stop() {
-        log.info("Stopping OSPF Controller...!!!");
-
-        for (ChannelGroup cg : cgList) {
-            cg.close();
-        }
-
-        for (NioServerSocketChannelFactory execFactory : execFactoryLst) {
-            execFactory.shutdown();
-        }
-
+        log.info("Stopping OSPF controller...!!!");
+        isisDeactivate();
         processes.clear();
     }
 
     /**
-     * Deletes configured interface from the area.
+     * Returns interface IP by index.
      *
-     * @param processId         process id
-     * @param areaId            area id
-     * @param interfaceToDelete interface to delete
-     * @return true if operation success else false
+     * @param interfaceIndex interface index
+     * @return interface IP by index
      */
-    public boolean deleteInterfaceFromArea(String processId, String areaId, String interfaceToDelete) {
-        Iterator<OspfProcess> processItr = processes.iterator();
-
-        while (processItr.hasNext()) {
-            OspfProcess process = processItr.next();
-            if (processId.equalsIgnoreCase(process.processId())) {
-                Iterator<OspfArea> areaItr = process.areas().iterator();
-                while (areaItr.hasNext()) {
-                    OspfArea area = areaItr.next();
-                    Iterator<OspfInterface> ospfIntrItr = area.getInterfacesLst().iterator();
-                    if (area.areaId().toString().equalsIgnoreCase(areaId)) {
-                        while (ospfIntrItr.hasNext()) {
-                            OspfInterface ospfIntr = ospfIntrItr.next();
-                            if (interfaceToDelete.equalsIgnoreCase(ospfIntr.ipAddress().toString())) {
-                                ospfIntrItr.remove();
-                                log.debug("Interface With Id {} is removed from Area {}",
-                                          ospfIntr.ipAddress(), ospfIntr.areaId());
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /*
-    * Checks area with area id exists in process.
-    *
-    * @param processId process id
-    * @param areaId area id
-    * @return true if exist else false
-    */
-    public boolean checkArea(String processId, String areaId) {
-        for (OspfProcess process : processes) {
-            if (processId.equalsIgnoreCase(process.processId())) {
-                for (OspfArea area : process.areas()) {
-                    if (area.areaId().toString().equalsIgnoreCase(areaId)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /*
-    * Checks process with process id exists or not.
-    *
-    * @param processId process id
-    * @return true if exist else false
-    */
-    public boolean checkProcess(String processId) {
-        log.debug("CheckProcess,Process Id ={} processes={}", processId, processes);
-        for (OspfProcess process : processes) {
-            if (processId.equalsIgnoreCase(process.processId())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /*
-    * Checks interface exists in given area.
-    *
-    * @param processId process id
-    * @param areaId area id
-    * @param ipAddress interface
-    * @return true if exist else false
-    */
-    public boolean checkInterface(String processId, String areaId, String interfaceIp) {
-        for (OspfProcess process : processes) {
-            if (processId.equalsIgnoreCase(process.processId())) {
-                for (OspfArea area : process.areas()) {
-                    if (area.areaId().toString().equalsIgnoreCase(areaId)) {
-                        for (OspfInterface ospfInterface : area.getInterfacesLst()) {
-                            if (ospfInterface.ipAddress().toString().equalsIgnoreCase(interfaceIp)) {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Create processes first time when no process exist.
-     * Create server bootstraps for all the interfaces in the processes.
-     *
-     * @param ospfProcesses list of OSPF processes to create
-     */
-    private void createProcessWhenNoProcessesExists(List<OspfProcess> ospfProcesses) {
-        Set<String> interfaceIpList = new HashSet<>();
-        Set<String> areaIdList = new HashSet<>();
-        if (processes != null) {
-            if (processes.size() == 0) {
-
-                processes.addAll(ospfProcesses);
-                for (OspfProcess process : ospfProcesses) {
-                    for (OspfArea area : process.areas()) {
-                        areaIdList.add(area.areaId().toString());
-                        for (OspfInterface intrfc : area.getInterfacesLst()) {
-                            interfaceIpList.add(intrfc.ipAddress().toString());
-                        }
-                    }
-                }
-                createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-            }
-        } else {
-            processes = new ArrayList<>();
-            processes.addAll(ospfProcesses);
-
-            for (OspfProcess process : ospfProcesses) {
-                for (OspfArea area : process.areas()) {
-                    areaIdList.add(area.areaId().toString());
-                    for (OspfInterface intrfc : area.getInterfacesLst()) {
-                        interfaceIpList.add(intrfc.ipAddress().toString());
-                    }
-                }
-            }
-            createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-        }
-    }
-
-    /**
-     * Creates processes when already process exist.
-     * It can be modifying existing process or adding a new process.
-     *
-     * @param ospfProcesses list of processes
-     */
-    private void createProcessWhenProcessesExists(List<OspfProcess> ospfProcesses) {
-        if (ospfProcesses != null) {
-            for (OspfProcess process : ospfProcesses) {
-                if (!checkProcess(process.processId())) {
-                    createNewProcess(process.processId(), process);
-                } else {
-                    List<OspfArea> areas = process.areas();
-                    for (OspfArea area : areas) {
-                        if (!checkArea(process.processId(), area.areaId().toString())) {
-                            createAreaInProcess(process.processId(),
-                                                area.areaId().toString(), area);
-                        } else {
-                            updateAreaInProcess(process.processId(), area.areaId().toString(), area);
-                            for (OspfInterface interfc : area.getInterfacesLst()) {
-                                if (!checkInterface(process.processId(),
-                                                    area.areaId().toString(), interfc.ipAddress().toString())) {
-                                    createInterfaceInAreaInProcess(process.processId(),
-                                                                   area.areaId().toString(), interfc);
-                                } else {
-                                    updateInterfaceParameters(process.processId(),
-                                                              area.areaId().toString(),
-                                                              interfc.ipAddress().toString(), interfc);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Updates the area information in already started OSPF processes.
-     *
-     * @param processId     process id
-     * @param areaId        area id
-     * @param areaFrmConfig area to update
-     */
-    public void updateAreaInProcess(String processId, String areaId, OspfArea areaFrmConfig) {
-        if (processes != null) {
-            Iterator<OspfProcess> processItr = processes.iterator();
-            while (processItr.hasNext()) {
-                OspfProcess process = processItr.next();
-                if (processId.equalsIgnoreCase(process.processId())) {
-                    Iterator<OspfArea> area = process.areas().iterator();
-                    while (area.hasNext()) {
-                        OspfArea ospfArea = area.next();
-                        if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
-                            ospfArea.setAddressRanges(areaFrmConfig.addressRanges());
-                            ospfArea.setRouterId(areaFrmConfig.routerId());
-                            ospfArea.setTransitCapability(areaFrmConfig.isTransitCapability());
-                            ospfArea.setExternalRoutingCapability(areaFrmConfig.isExternalRoutingCapability());
-                            ospfArea.setStubCost(areaFrmConfig.stubCost());
-                            ospfArea.setOptions(areaFrmConfig.options());
-                            ospfArea.setIsOpaqueEnabled(areaFrmConfig.isOpaqueEnabled());
-                            log.debug("updateAreaInProcess::Process Id::{}::Ospf Area with Id::{}::is " +
-                                              "updated", processId, areaId);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Updates the processes configuration.
-     *
-     * @param ospfProcesses list of OSPF processes
-     */
-    public void updateConfig(List<OspfProcess> ospfProcesses) {
-        log.info("Controller::UpdateConfig called");
-        if (processes != null) {
-            if (processes.size() == 0) {
-                createProcessWhenNoProcessesExists(ospfProcesses);
-            } else {
-                createProcessWhenProcessesExists(ospfProcesses);
-            }
-        } else {
-            createProcessWhenNoProcessesExists(ospfProcesses);
-        }
-    }
-
-    /**
-     * Deletes configuration.
-     *
-     * @param ospfProcesses OSPF processes
-     * @param attribute     attribute to delete
-     */
-    public void deleteConfig(List<OspfProcess> ospfProcesses, String attribute) {
-        log.info("Controller::UpdateConfig called");
-        if (processes != null) {
-            if (processes.size() == 0) {
-                log.debug("DeleteConfig:: No process exists");
-            } else {
-                deleteProcessWhenExists(ospfProcesses, attribute);
-            }
-        } else {
-            log.debug("DeleteConfig:: No process exists");
-        }
-    }
-
-    /**
-     * Creates a new process.
-     *
-     * @param processId process id
-     * @param process   OSPF process instance
-     */
-    private void createNewProcess(String processId, OspfProcess process) {
-        Set<String> interfaceIpList = new HashSet<>();
-        Set<String> areaIdList = new HashSet<>();
-
-        processes.add(process);
-        for (OspfArea area : process.areas()) {
-            areaIdList.add(area.areaId().toString());
-            for (OspfInterface interfc : area.getInterfacesLst()) {
-                interfaceIpList.add(interfc.ipAddress().toString());
-            }
-        }
-        log.debug("createNewProcess::List of areas in process::{} areas::{}", processId, areaIdList);
-
-        createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-
-        log.debug("createNewProcess:: all processes::{}", processes);
-    }
-
-    /**
-     * Creates a new area information in the process.
-     *
-     * @param processId process id
-     * @param areaId    area id
-     * @param area      OSPF area instance
-     */
-    private void createAreaInProcess(String processId, String areaId, OspfArea area) {
-        Set<String> interfaceIpList = new HashSet<>();
-        Set<String> areaIdList = new HashSet<>();
-
-        Iterator<OspfProcess> processItr = processes.iterator();
-        while (processItr.hasNext()) {
-            OspfProcess process = processItr.next();
-            List<OspfArea> areasInProcess = process.areas();
-            if (processId.equalsIgnoreCase(process.processId())) {
-                areasInProcess.add(area);
-
-                for (OspfInterface intrfc : area.getInterfacesLst()) {
-                    interfaceIpList.add(intrfc.ipAddress().toString());
-                }
-                areaIdList.add(area.areaId().toString());
-                log.debug("createAreaInProcess::List of areas in process Id::{} " +
-                                  "AreaId ::{} update process::{}",
-                          processId, areaId, process);
-            }
-        }
-        createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-        log.debug("createAreaInProcess:: all processes::{}", processes);
-    }
-
-    /**
-     * Creates an interface in the given area and process.
-     *
-     * @param processId     process id
-     * @param areaId        area id
-     * @param ospfInterface OSPF interface instance
-     */
-    private void createInterfaceInAreaInProcess(String processId,
-                                                String areaId, OspfInterface ospfInterface) {
-        Set<String> interfaceIpList = new HashSet<>();
-        Set<String> areaIdList = new HashSet<>();
-
-        Iterator<OspfProcess> processItr = processes.iterator();
-        while (processItr.hasNext()) {
-            OspfProcess process = processItr.next();
-            List<OspfArea> areasInProcess = process.areas();
-            if (processId.equalsIgnoreCase(process.processId())) {
-                Iterator<OspfArea> areaItr = areasInProcess.iterator();
-                while (areaItr.hasNext()) {
-                    OspfArea area = areaItr.next();
-                    if (areaId.equalsIgnoreCase(area.areaId().toString())) {
-                        area.getInterfacesLst().add(ospfInterface);
-                        interfaceIpList.add(ospfInterface.ipAddress().toString());
-
-                        log.debug("createInterfaceInAreaInProcess::Interface " +
-                                          "updated in process Id::{} AreaId ::{} Interface List{}",
-                                  processId, areaId, area.getInterfacesLst());
-
-                    }
-                }
-            }
-        }
-        createBootStrapForCreatedInterface(interfaceIpList, areaIdList);
-        log.debug("createInterfaceInAreaInProcess:: all processes::{}", processes);
-    }
-
-    /**
-     * Updates interface parameters.
-     *
-     * @param processId     process id
-     * @param areaId        area id
-     * @param interfaceId   interface id
-     * @param ospfInterface OSPF interface instance
-     */
-    private void updateInterfaceParameters(String processId, String areaId, String interfaceId,
-                                           OspfInterface ospfInterface) {
-        Iterator<OspfProcess> processItr = processes.iterator();
-        while (processItr.hasNext()) {
-            OspfProcess process = processItr.next();
-            if (processId.equalsIgnoreCase(process.processId())) {
-                Iterator<OspfArea> areItr = process.areas().iterator();
-                while (areItr.hasNext()) {
-                    OspfArea area = (OspfArea) areItr.next();
-                    if (area.areaId().toString().equalsIgnoreCase(areaId)) {
-                        Iterator<OspfInterface> intfcList = area.getInterfacesLst().iterator();
-                        while (intfcList.hasNext()) {
-                            OspfInterface intrfcObj = intfcList.next();
-                            if (interfaceId.equalsIgnoreCase(intrfcObj.ipAddress().toString())) {
-                                intrfcObj.setPollInterval(ospfInterface.pollInterval());
-                                intrfcObj.setTransmitDelay(ospfInterface.transmitDelay());
-                                intrfcObj.setBdr(ospfInterface.bdr());
-                                intrfcObj.setDr(ospfInterface.dr());
-                                intrfcObj.setAuthKey(ospfInterface.authKey());
-                                intrfcObj.setAuthType(ospfInterface.authType());
-                                intrfcObj.setHelloIntervalTime(ospfInterface.helloIntervalTime());
-                                intrfcObj.setReTransmitInterval(ospfInterface.reTransmitInterval());
-                                intrfcObj.setMtu(ospfInterface.mtu());
-                                intrfcObj.setInterfaceCost(ospfInterface.interfaceCost());
-                                intrfcObj.setInterfaceType(ospfInterface.interfaceType());
-                                intrfcObj.setRouterDeadIntervalTime(ospfInterface.routerDeadIntervalTime());
-                                intrfcObj.setRouterPriority(ospfInterface.routerPriority());
-                                intrfcObj.setIpNetworkMask(ospfInterface.ipNetworkMask());
-                                log.debug("updateInterfaceParameters::Interface updated in " +
-                                                  "process Id::{} AreaId ::{} Interface Id:{} " +
-                                                  "Updated Interface List: {}", processId, areaId,
-                                          interfaceId, intfcList);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        log.debug("updateInterfaceParameters:: all processes::{}", processes);
-    }
-
-    /**
-     * Creates server bootstrap for interface.
-     *
-     * @param interfaceIPs set of interfaces
-     * @param areaIds      set of area id's
-     */
-    private void createBootStrapForCreatedInterface(Set<String> interfaceIPs, Set<String> areaIds) {
-
-        log.debug("createBootStrapForCreatedInterface:: List of new Interfaces::{}, " +
-                          "List of new areas::{}", interfaceIPs, areaIds);
-        List<String> networkInterfaces = new ArrayList();
-        //get the connected interfaces
-        Enumeration<NetworkInterface> nets = null;
+    private Ip4Address getInterfaceIp(int interfaceIndex) {
+        Ip4Address ipAddress = null;
         try {
-            nets = NetworkInterface.getNetworkInterfaces();
-            // Check NetworkInterfaces and add the IP's
-            for (NetworkInterface netInt : Collections.list(nets)) {
-                // if the interface is up & not loopback
-                if (!netInt.isUp() && !netInt.isLoopback()) {
-                    continue;
-                }
-                //get all the InetAddresses
-                Enumeration<InetAddress> inetAddresses = netInt.getInetAddresses();
-                for (InetAddress inetAddress : Collections.list(inetAddresses)) {
-                    String ipAddress = inetAddress.getHostAddress();
-                    networkInterfaces.add(ipAddress);
+            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;
                 }
             }
-            //Search for the address in all configured areas interfaces
-            for (OspfProcess process : processes) {
-                for (OspfArea area : process.areas()) {
-                    for (OspfInterface ospfIf : area.getInterfacesLst()) {
-                        String ipFromConfig = ospfIf.ipAddress().toString();
-                        if (interfaceIPs.contains(ipFromConfig)) {
-                            log.debug("Ip address::{} for area {} is newly created" + ipFromConfig);
-                            if (networkInterfaces.contains(ipFromConfig)) {
-                                log.debug("Both Config and Interface have ipAddress {} for area {}",
-                                          ipFromConfig, area.areaId());
-                                // if same IP address create
-                                try {
-                                    log.debug("Creating ServerBootstrap for {} @ {}", ipFromConfig, ospfPort);
+        } catch (Exception e) {
+            log.debug("Error while getting Interface IP by index");
+            return OspfUtil.DEFAULTIP;
+        }
 
-                                    final ServerBootstrap bootstrap = createServerBootStrap();
+        return ipAddress;
+    }
 
-                                    bootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
-                                    bootstrap.setOption("receiveBufferSizePredictorFactory",
-                                                        new FixedReceiveBufferSizePredictorFactory(
-                                                                Controller.BUFFER_SIZE));
-                                    bootstrap.setOption("reuseAddress", true);
-                                    bootstrap.setOption("tcpNoDelay", true);
-                                    bootstrap.setOption("keepAlive", true);
+    /**
+     * Returns interface mask 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;
+        }
 
-                                    bootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
-                                    bootstrap.setOption("child.receiveBufferSizePredictorFactory",
-                                                        new FixedReceiveBufferSizePredictorFactory(
-                                                                Controller.BUFFER_SIZE));
-                                    bootstrap.setOption("child.reuseAddress", true);
-                                    bootstrap.setOption("child.tcpNoDelay", true);
-                                    bootstrap.setOption("child.keepAlive", true);
-                                    bootstrap.setOption("receiveBufferSizePredictorFactory",
-                                                        new FixedReceiveBufferSizePredictorFactory(
-                                                                Controller.BUFFER_SIZE));
-                                    bootstrap.setOption("receiveBufferSizePredictor",
-                                                        new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
+        return subnetMask;
+    }
 
-                                    ChannelPipelineFactory pfact = new OspfPipelineFactory(this, area, ospfIf);
-                                    bootstrap.setPipelineFactory(pfact);
-                                    InetSocketAddress sa = new InetSocketAddress(InetAddress.getByName(ipFromConfig),
-                                                                                 ospfPort);
+    /**
+     * Disconnects the executor.
+     */
+    public void disconnectExecutor() {
+        if (connectExecutor != null) {
+            connectExecutor.shutdown();
+            connectExecutor = null;
+        }
+    }
 
-                                    ChannelGroup cg = new DefaultChannelGroup();
-                                    cg.add(bootstrap.bind(sa));
-                                    cgList.add(cg);
+    /**
+     * Connects to peer.
+     */
+    public void connectPeer() {
+        scheduleConnectionRetry(this.connectRetryTime);
+    }
 
-                                    log.debug("Listening for connections on {}", sa);
+    /**
+     * 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);
+    }
 
-                                } catch (Exception e) {
-                                    throw new RuntimeException(e);
-                                }
+    /**
+     * 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 {}", OspfUtil.SHOST);
+            initConnection();
+            ospfChannelHandler.sentConfigPacket(configPacket);
+            InetSocketAddress connectToSocket = new InetSocketAddress(OspfUtil.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,
+                                      OspfUtil.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 {
-                            log.debug("Ip address::{} for area {} is not newly created" + ipFromConfig);
+                            //Send the config packet
+                            ospfChannelHandler.sentConfigPacket(configPacket);
+                            connectRetryCounter++;
+                            log.info("Connected to remote host {}, Connect Counter {}", OspfUtil.SHOST,
+                                     connectRetryCounter);
+                            disconnectExecutor();
+
+                            return;
                         }
                     }
-                    if (areaIds.contains(area.areaId().toString())) {
-                        area.initializeDb();
-                    }
-                }
-            }
-
-        } catch (SocketException e) {
-            log.error("Error occured due to SocketException::Class::{},Line::{},Method::{}",
-                      e.getStackTrace()[0].getFileName(), e.getStackTrace()[0].getLineNumber(),
-                      e.getStackTrace()[0].getMethodName());
-        }
-    }
-
-    /**
-     * Deletes given process.
-     *
-     * @param ospfProcesses list of OSPF process instance.
-     * @param attribute     attribute to delete
-     */
-    public void deleteProcessWhenExists(List<OspfProcess> ospfProcesses, String attribute) {
-        if (ospfProcesses != null) {
-            for (OspfProcess process : ospfProcesses) {
-                if (checkProcess(process.processId())) {
-                    if (PROCESS.equalsIgnoreCase(attribute)) {
-                        deleteProcess(process.processId(), process);
-                    } else {
-                        List<OspfArea> areas = process.areas();
-                        for (OspfArea area : areas) {
-                            if (checkArea(process.processId(), area.areaId().toString())) {
-                                if (AREA.equalsIgnoreCase(attribute)) {
-                                    deleteAreaFromProcess(process.processId(),
-                                                          area.areaId().toString(), area);
-                                } else {
-                                    for (OspfInterface interfc : area.getInterfacesLst()) {
-                                        if (checkInterface(process.processId(),
-                                                           area.areaId().toString(),
-                                                           interfc.ipAddress().toString())) {
-                                            if (INTERFACE.equalsIgnoreCase(attribute)) {
-                                                deleteInterfaceFromAreaProcess(process.processId(),
-                                                                               area.areaId().toString(),
-                                                                               interfc);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Deletes given process.
-     *
-     * @param processId process id
-     * @param process   OSPF process instance
-     */
-    private void deleteProcess(String processId, OspfProcess process) {
-        if (processes != null) {
-            Iterator<OspfProcess> itrProcess = processes.iterator();
-            while (itrProcess.hasNext()) {
-                OspfProcess ospfPrs = itrProcess.next();
-                if (processId.equalsIgnoreCase(ospfPrs.processId())) {
-                    itrProcess.remove();
-                }
-            }
-        }
-    }
-
-    /**
-     * Deletes area from process.
-     *
-     * @param processId process id
-     * @param areaId    area id
-     * @param area      OSPF area instance
-     */
-    private void deleteAreaFromProcess(String processId, String areaId, OspfArea area) {
-        if (processes != null) {
-            Iterator<OspfProcess> itrProcess = processes.iterator();
-            while (itrProcess.hasNext()) {
-                OspfProcess ospfPrs = itrProcess.next();
-                if (processId.equalsIgnoreCase(ospfPrs.processId())) {
-                    if (ospfPrs.areas() != null) {
-                        Iterator<OspfArea> itrArea = ospfPrs.areas().iterator();
-                        while (itrArea.hasNext()) {
-                            OspfArea ospfArea = itrArea.next();
-                            if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
-                                itrArea.remove();
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Deletes interface from area.
-     *
-     * @param processId         process id
-     * @param areaId            area id
-     * @param interfaceToDelete interface to delete
-     */
-    private void deleteInterfaceFromAreaProcess(String processId, String areaId, OspfInterface interfaceToDelete) {
-        if (processes != null) {
-            Iterator<OspfProcess> itrProcess = processes.iterator();
-            while (itrProcess.hasNext()) {
-                OspfProcess ospfPrs = itrProcess.next();
-                if (processId.equalsIgnoreCase(ospfPrs.processId())) {
-                    if (ospfPrs.areas() != null) {
-                        Iterator<OspfArea> itrArea = ospfPrs.areas().iterator();
-                        while (itrArea.hasNext()) {
-                            OspfArea ospfArea = itrArea.next();
-                            if (areaId.equalsIgnoreCase(ospfArea.areaId().toString())) {
-                                if (ospfArea.getInterfacesLst() != null) {
-                                    Iterator<OspfInterface> intrfcList = ospfArea.getInterfacesLst().iterator();
-                                    while (intrfcList.hasNext()) {
-                                        OspfInterface ospfItrfc = intrfcList.next();
-                                        if (interfaceToDelete.ipAddress().equals(ospfItrfc.ipAddress())) {
-                                            intrfcList.remove();
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
+                });
+            } catch (Exception e) {
+                log.info("Connect peer exception : " + e.toString());
+                disconnectExecutor();
             }
         }
     }
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfConfigUtil.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfConfigUtil.java
new file mode 100644
index 0000000..06af9bf
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfConfigUtil.java
@@ -0,0 +1,332 @@
+/*
+ * 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.ospf.controller.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfProcess;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
+import org.onosproject.ospf.controller.area.OspfProcessImpl;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * Representation of OSPF network configuration parsing util.
+ */
+public final class OspfConfigUtil {
+    public static final String PROCESSID = "processId";
+    public static final String AREAS = "areas";
+    public static final String INTERFACEINDEX = "interfaceIndex";
+    public static final String AREAID = "areaId";
+    public static final String ROUTERID = "routerId";
+    public static final String INTERFACE = "interface";
+    public static final String HELLOINTERVAL = "helloIntervalTime";
+    public static final String ROUTERDEADINTERVAL = "routerDeadIntervalTime";
+    public static final String INTERFACETYPE = "interfaceType";
+    public static final String EXTERNALROUTINGCAPABILITY = "externalRoutingCapability";
+    protected static final Logger log = LoggerFactory.getLogger(OspfConfigUtil.class);
+    private static final String ISOPAQUE = "isOpaqueEnable";
+
+    /**
+     * Creates an instance of this.
+     */
+    private OspfConfigUtil() {
+
+    }
+
+    /**
+     * Returns list of OSPF process from the json nodes.
+     *
+     * @param jsonNodes represents one or more OSPF process configuration
+     * @return list of OSPF processes.
+     */
+    public static List<OspfProcess> processes(JsonNode jsonNodes) {
+        List<OspfProcess> ospfProcesses = new ArrayList<>();
+        if (jsonNodes == null) {
+            return ospfProcesses;
+        }
+        //From each Process nodes, get area and related interface details.
+        jsonNodes.forEach(jsonNode -> {
+            List<OspfArea> areas = new ArrayList<>();
+            //Get configured areas for the process.
+            for (JsonNode areaNode : jsonNode.path(AREAS)) {
+                List<OspfInterface> interfaceList = new ArrayList<>();
+                for (JsonNode interfaceNode : areaNode.path(INTERFACE)) {
+                    OspfInterface ospfInterface = interfaceDetails(interfaceNode);
+                    if (ospfInterface != null) {
+                        interfaceList.add(ospfInterface);
+                    }
+                }
+                //Get the area details
+                OspfArea area = areaDetails(areaNode);
+                if (area != null) {
+                    area.setOspfInterfaceList(interfaceList);
+                    areas.add(area);
+                }
+            }
+            OspfProcess process = new OspfProcessImpl();
+            process.setProcessId(jsonNode.path(PROCESSID).asText());
+            process.setAreas(areas);
+            ospfProcesses.add(process);
+        });
+
+        return ospfProcesses;
+    }
+
+    /**
+     * Returns interface IP by index.
+     *
+     * @param interfaceIndex interface index
+     * @return interface IP by index
+     */
+    private static 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 OspfUtil.DEFAULTIP;
+        }
+        return ipAddress;
+    }
+
+    /**
+     * Returns interface MAC by index.
+     *
+     * @param interfaceIndex interface index
+     * @return interface IP by index
+     */
+    private static 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 valid digit or not.
+     *
+     * @param strInput input value
+     * @return true if valid else false
+     */
+    private static boolean isValidDigit(String strInput) {
+        boolean isValid = true;
+        if (isPrimitive(strInput)) {
+            int input = Integer.parseInt(strInput);
+            if (input < 1 || input > 255) {
+                log.debug("Wrong config input value: {}", strInput);
+                isValid = false;
+            } else {
+                isValid = true;
+            }
+
+        } else {
+            isValid = false;
+        }
+
+        return isValid;
+    }
+
+    /**
+     * Checks if primitive or not.
+     *
+     * @param value input value
+     * @return true if number else false
+     */
+    private static 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 boolean or not.
+     *
+     * @param value input value
+     * @return true if boolean else false
+     */
+    private static boolean isBoolean(String value) {
+        boolean status = false;
+        value = value.trim();
+        if (value.equals("true") || value.equals("false")) {
+            return true;
+        }
+
+        return status;
+    }
+
+    /**
+     * Checks if given id is valid or not.
+     *
+     * @param value input value
+     * @return true if valid else false
+     */
+    private static boolean isValidIpAddress(String value) {
+        boolean status = true;
+        try {
+            Ip4Address ipAddress = Ip4Address.valueOf(value);
+        } catch (Exception e) {
+            log.debug("Invalid IP address string: {}", value);
+            return false;
+        }
+
+        return status;
+    }
+
+    /**
+     * Returns OSPF area instance from configuration.
+     *
+     * @param areaNode area configuration
+     * @return OSPF area instance
+     */
+    private static OspfArea areaDetails(JsonNode areaNode) {
+        OspfArea area = new OspfAreaImpl();
+        String areaId = areaNode.path(AREAID).asText();
+        if (isValidIpAddress(areaId)) {
+            area.setAreaId(Ip4Address.valueOf(areaId));
+        } else {
+            log.debug("Wrong areaId: {}", areaId);
+            return null;
+        }
+        String routerId = areaNode.path(ROUTERID).asText();
+        if (isValidIpAddress(routerId)) {
+            area.setRouterId(Ip4Address.valueOf(routerId));
+        } else {
+            log.debug("Wrong routerId: {}", routerId);
+            return null;
+        }
+        String routingCapability = areaNode.path(EXTERNALROUTINGCAPABILITY).asText();
+        if (isBoolean(routingCapability)) {
+            area.setExternalRoutingCapability(Boolean.valueOf(routingCapability));
+        } else {
+            log.debug("Wrong routingCapability: {}", routingCapability);
+            return null;
+        }
+        String isOpaqueEnabled = areaNode.path(ISOPAQUE).asText();
+        if (isBoolean(isOpaqueEnabled)) {
+            area.setIsOpaqueEnabled(Boolean.valueOf(isOpaqueEnabled));
+        } else {
+            log.debug("Wrong isOpaqueEnabled: {}", isOpaqueEnabled);
+            return null;
+        }
+        area.setOptions(OspfUtil.HELLO_PACKET_OPTIONS);
+
+        return area;
+    }
+
+    /**
+     * Returns OSPF interface instance from configuration.
+     *
+     * @param interfaceNode interface configuration
+     * @return OSPF interface instance
+     */
+    private static OspfInterface interfaceDetails(JsonNode interfaceNode) {
+        OspfInterface ospfInterface = new OspfInterfaceImpl();
+        String index = interfaceNode.path(INTERFACEINDEX).asText();
+        if (isValidDigit(index)) {
+            ospfInterface.setInterfaceIndex(Integer.parseInt(index));
+        } else {
+            log.debug("Wrong interface index: {}", index);
+            return null;
+        }
+        Ip4Address interfaceIp = getInterfaceIp(ospfInterface.interfaceIndex());
+        if (interfaceIp.equals(OspfUtil.DEFAULTIP)) {
+            return null;
+        }
+        ospfInterface.setIpAddress(interfaceIp);
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf(getInterfaceMask(
+                ospfInterface.interfaceIndex())));
+        ospfInterface.setBdr(OspfUtil.DEFAULTIP);
+        ospfInterface.setDr(OspfUtil.DEFAULTIP);
+        String helloInterval = interfaceNode.path(HELLOINTERVAL).asText();
+        if (isValidDigit(helloInterval)) {
+            ospfInterface.setHelloIntervalTime(Integer.parseInt(helloInterval));
+        } else {
+            log.debug("Wrong hello interval: {}", helloInterval);
+            return null;
+        }
+        String routerDeadInterval = interfaceNode.path(ROUTERDEADINTERVAL).asText();
+        if (isValidDigit(routerDeadInterval)) {
+            ospfInterface.setRouterDeadIntervalTime(Integer.parseInt(routerDeadInterval));
+        } else {
+            log.debug("Wrong routerDeadInterval: {}", routerDeadInterval);
+            return null;
+        }
+        String interfaceType = interfaceNode.path(INTERFACETYPE).asText();
+        if (isValidDigit(interfaceType)) {
+            ospfInterface.setInterfaceType(Integer.parseInt(interfaceType));
+        } else {
+            log.debug("Wrong interfaceType: {}", interfaceType);
+            return null;
+        }
+        ospfInterface.setReTransmitInterval(OspfUtil.RETRANSMITINTERVAL);
+        ospfInterface.setMtu(OspfUtil.MTU);
+        ospfInterface.setRouterPriority(OspfUtil.ROUTER_PRIORITY);
+
+        return ospfInterface;
+    }
+}
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfControllerImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfControllerImpl.java
index 31067fc..83462ee 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfControllerImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfControllerImpl.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.ospf.controller.impl;
 
+import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -34,7 +35,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -111,27 +111,23 @@
     }
 
     @Override
-    public void updateConfig(List processes) {
-        List<OspfProcess> ospfProcesses = new ArrayList<>();
-        if (processes != null) {
-            for (Object process : processes) {
-                ospfProcesses.add((OspfProcess) process);
+    public void updateConfig(JsonNode processesNode) {
+        try {
+            List<OspfProcess> ospfProcesses = OspfConfigUtil.processes(processesNode);
+            //if there is interface details then update configuration
+            if (ospfProcesses.size() > 0 &&
+                    ospfProcesses.get(0).areas() != null && ospfProcesses.get(0).areas().size() > 0 &&
+                    ospfProcesses.get(0).areas().get(0) != null &&
+                    ospfProcesses.get(0).areas().get(0).ospfInterfaceList().size() > 0) {
+                ctrl.updateConfig(ospfProcesses);
             }
+        } catch (Exception e) {
+            log.debug("Error::updateConfig::{}", e.getMessage());
         }
-        log.debug("updateConfig::OspfList::processes::{}", ospfProcesses);
-        ctrl.updateConfig(ospfProcesses);
     }
 
     @Override
     public void deleteConfig(List<OspfProcess> processes, String attribute) {
-        List<OspfProcess> ospfProcesses = new ArrayList<>();
-        if (processes != null) {
-            for (Object process : processes) {
-                ospfProcesses.add((OspfProcess) process);
-            }
-        }
-        log.debug("deleteConfig::OspfList::processes::{}", ospfProcesses);
-        ctrl.deleteConfig(ospfProcesses, attribute);
     }
 
     /**
@@ -163,9 +159,9 @@
         }
 
         @Override
-        public void deleteLink(OspfRouter ospfRouter) {
+        public void deleteLink(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
             for (OspfLinkListener l : linkListener()) {
-                l.deleteLink(ospfRouter);
+                l.deleteLink(ospfRouter, ospfLinkTed);
             }
         }
     }
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandler.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandler.java
index 1a2e687..09a428f 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandler.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandler.java
@@ -13,13 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.onosproject.ospf.controller.impl;
 
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFuture;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.ChannelStateEvent;
 import org.jboss.netty.channel.ExceptionEvent;
@@ -27,235 +23,203 @@
 import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
 import org.jboss.netty.handler.timeout.ReadTimeoutException;
 import org.onlab.packet.Ip4Address;
-import org.onosproject.ospf.controller.LsaWrapper;
 import org.onosproject.ospf.controller.OspfArea;
 import org.onosproject.ospf.controller.OspfInterface;
-import org.onosproject.ospf.controller.OspfLinkTed;
-import org.onosproject.ospf.controller.OspfLsa;
+import org.onosproject.ospf.controller.OspfMessage;
 import org.onosproject.ospf.controller.OspfNbr;
-import org.onosproject.ospf.controller.OspfNeighborState;
-import org.onosproject.ospf.controller.OspfRouter;
-import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
-import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.controller.OspfProcess;
 import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
-import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
-import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
-import org.onosproject.ospf.controller.util.OspfEligibleRouter;
 import org.onosproject.ospf.controller.util.OspfInterfaceType;
 import org.onosproject.ospf.exceptions.OspfParseException;
-import org.onosproject.ospf.protocol.lsa.LsaHeader;
-import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
-import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
-import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
-import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
-import org.onosproject.ospf.protocol.ospfpacket.types.HelloPacket;
-import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
-import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
-import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
-import org.onosproject.ospf.protocol.util.ChecksumCalculator;
 import org.onosproject.ospf.protocol.util.OspfInterfaceState;
-import org.onosproject.ospf.protocol.util.OspfPacketType;
-import org.onosproject.ospf.protocol.util.OspfParameters;
-import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.nio.channels.ClosedChannelException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-import java.util.concurrent.Executors;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Channel handler deals with the OSPF channel connection.
- * Also it dispatches messages to the appropriate handlers.
+ * Also it dispatches messages to the appropriate handlers for processing.
  */
 public class OspfInterfaceChannelHandler extends IdleStateAwareChannelHandler {
 
-    private static final Logger log =
-            LoggerFactory.getLogger(OspfInterfaceChannelHandler.class);
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private OspfInterface ospfInterface;
-    private OspfArea ospfArea;
-    private boolean isClosed = false;
+    private static final Logger log = LoggerFactory.getLogger(OspfInterfaceChannelHandler.class);
+    private static Map<Integer, Object> isisDb = null;
+    private Channel channel = null;
     private Controller controller;
-    private Channel channel;
-    private long delay = 0;
-    private InternalHelloTimer helloTimerTask;
-    private InternalWaitTimer waitTimerTask;
-    private InternalDelayedAckTimer delayedAckTimerTask;
-    private ScheduledExecutorService exServiceHello;
-    private ScheduledExecutorService exServiceWait;
-    private ScheduledExecutorService exServiceDelayedAck;
-    private boolean isDelayedAckTimerScheduled = false;
-    private int delayedAckTimerInterval = 2500;
-    private TopologyForDeviceAndLink topologyForDeviceAndLink;
-
-    public OspfInterfaceChannelHandler() {
-
-    }
+    private List<OspfProcess> processes = null;
+    private byte[] configPacket = null;
+    private Map<Integer, OspfInterface> ospfInterfaceMap = new ConcurrentHashMap<>();
 
     /**
      * Creates an instance of OSPF channel handler.
      *
-     * @param controller    controller instance
-     * @param ospfArea      ospf area instance
-     * @param ospfInterface ospf interface instance
+     * @param controller controller instance
+     * @param processes  list of configured processes
      */
-    public OspfInterfaceChannelHandler(Controller controller, OspfArea ospfArea, OspfInterface ospfInterface) {
-
-        this.ospfArea = ospfArea;
-        this.ospfInterface = ospfInterface;
+    public OspfInterfaceChannelHandler(Controller controller, List<OspfProcess> processes) {
         this.controller = controller;
-        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DOWN);
-        this.ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
-        this.ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
-        this.topologyForDeviceAndLink = new TopologyForDeviceAndLinkImpl();
+        this.processes = processes;
     }
 
     /**
-     * Represents an interface is up and connected.
+     * Initializes the interface map with interface details.
      *
      * @throws Exception might throws exception
      */
-    public void interfaceUp() throws Exception {
-        log.debug("OSPFInterfaceChannelHandler::interfaceUp...!!!");
-        if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
-            ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.POINT2POINT);
-            log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} ",
-                      ospfInterface.interfaceType(), ((OspfInterfaceImpl) ospfInterface).state());
-        } else if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value()) {
-            //if router priority is 0, move the state to DROther
-            if (ospfInterface.routerPriority() == 0) {
-                ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DROTHER);
-            } else {
-                log.debug("OSPFInterfaceChannelHandler::InterfaceType {} state {} RouterPriority {}",
-                          ospfInterface.interfaceType(),
-                          ((OspfInterfaceImpl) ospfInterface).state(), ospfInterface.routerPriority());
-                ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.WAITING);
-                //start wait timer - like inactivity timer with router deadInterval
-                startWaitTimer();
+    public void initializeInterfaceMap() throws Exception {
+        for (OspfProcess process : processes) {
+            for (OspfArea area : process.areas()) {
+                for (OspfInterface ospfInterface : area.ospfInterfaceList()) {
+                    OspfInterface anInterface = ospfInterfaceMap.get(ospfInterface.interfaceIndex());
+                    if (anInterface == null) {
+                        ospfInterface.setOspfArea(area);
+                        ((OspfInterfaceImpl) ospfInterface).setController(controller);
+                        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DOWN);
+                        ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
+                        ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
+                        ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
+                    }
+                    ((OspfInterfaceImpl) ospfInterface).setChannel(channel);
+                    ospfInterface.interfaceUp();
+                    ospfInterface.startDelayedAckTimer();
+                }
+                //Initialize the LSDB and aging process
+                area.initializeDb();
             }
-
         }
-        // Start hello timer with interval from config - convert seconds to milliseconds
-        startHelloTimer(ospfInterface.helloIntervalTime());
-        ospfArea.refreshArea(ospfInterface);
     }
 
-
     /**
-     * Gets called when a BDR was detected before the wait timer expired.
+     * Updates the interface map with interface details.
      *
-     * @param ch channel instance
+     * @param ospfProcesses updated process instances
      * @throws Exception might throws exception
      */
-    public void backupSeen(Channel ch) throws Exception {
-        log.debug("OSPFInterfaceChannelHandler::backupSeen ");
-        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.WAITING) {
-            electRouter(ch);
+    public void updateInterfaceMap(List<OspfProcess> ospfProcesses) throws Exception {
+        for (OspfProcess ospfUpdatedProcess : ospfProcesses) {
+            for (OspfArea updatedArea : ospfUpdatedProcess.areas()) {
+                for (OspfInterface ospfUpdatedInterface : updatedArea.ospfInterfaceList()) {
+                    OspfInterface ospfInterface = ospfInterfaceMap.get(ospfUpdatedInterface.interfaceIndex());
+                    if (ospfInterface == null) {
+                        ospfUpdatedInterface.setOspfArea(updatedArea);
+                        ((OspfInterfaceImpl) ospfUpdatedInterface).setController(controller);
+                        ((OspfInterfaceImpl) ospfUpdatedInterface).setState(OspfInterfaceState.DOWN);
+                        ospfUpdatedInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
+                        ospfUpdatedInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
+                        ospfInterfaceMap.put(ospfUpdatedInterface.interfaceIndex(), ospfUpdatedInterface);
+                        ((OspfInterfaceImpl) ospfUpdatedInterface).setChannel(channel);
+                        ospfUpdatedInterface.interfaceUp();
+                        ospfUpdatedInterface.startDelayedAckTimer();
+                    } else {
+                        ospfInterface.setOspfArea(updatedArea);
+
+                        if (ospfInterface.routerDeadIntervalTime() != ospfUpdatedInterface.routerDeadIntervalTime()) {
+                            ospfInterface.setRouterDeadIntervalTime(ospfUpdatedInterface.routerDeadIntervalTime());
+                            Map<String, OspfNbr> neighbors = ospfInterface.listOfNeighbors();
+                            for (String key : neighbors.keySet()) {
+                                OspfNbr ospfNbr = ospfInterface.neighbouringRouter(key);
+                                ospfNbr.setRouterDeadInterval(ospfInterface.routerDeadIntervalTime());
+                                ospfNbr.stopInactivityTimeCheck();
+                                ospfNbr.startInactivityTimeCheck();
+                            }
+                        }
+                        if (ospfInterface.interfaceType() != ospfUpdatedInterface.interfaceType()) {
+                            ospfInterface.setInterfaceType(ospfUpdatedInterface.interfaceType());
+                            if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
+                                ospfInterface.setDr(Ip4Address.valueOf("0.0.0.0"));
+                                ospfInterface.setBdr(Ip4Address.valueOf("0.0.0.0"));
+                            }
+                            ospfInterface.removeNeighbors();
+                        }
+                        if (ospfInterface.helloIntervalTime() != ospfUpdatedInterface.helloIntervalTime()) {
+                            ospfInterface.setHelloIntervalTime(ospfUpdatedInterface.helloIntervalTime());
+                            ospfInterface.stopHelloTimer();
+                            ospfInterface.startHelloTimer();
+                        }
+                        ospfInterfaceMap.put(ospfInterface.interfaceIndex(), ospfInterface);
+                    }
+                }
+            }
         }
     }
 
     /**
-     * Gets called when no hello message received for particular period.
-     *
-     * @param ch channel instance
-     * @throws Exception might throws exception
+     * Initialize channel, start hello sender and initialize LSDB.
      */
-    public void waitTimer(Channel ch) throws Exception {
-        log.debug("OSPFInterfaceChannelHandler::waitTimer ");
-        //section 9.4
-        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.WAITING) {
-            electRouter(ch);
+    private void initialize() throws Exception {
+        log.debug("OspfChannelHandler initialize..!!!");
+        if (configPacket != null) {
+            log.debug("OspfChannelHandler initialize -> sentConfig packet of length ::"
+                              + configPacket.length);
+            sentConfigPacket(configPacket);
         }
-    }
-
-    /**
-     * Neighbor change event is triggered when the router priority gets changed.
-     *
-     * @throws Exception might throws exception
-     */
-    public void neighborChange() throws Exception {
-        log.debug("OSPFInterfaceChannelHandler::neighborChange ");
-        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR ||
-                ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR ||
-                ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER) {
-            electRouter(channel);
-        }
-    }
-
-    /**
-     * Gets called when an interface is down.
-     * All interface variables are reset, and interface timers disabled.
-     * Also all neighbor connections associated with the interface are destroyed.
-     */
-    public void interfaceDown() {
-        log.debug("OSPFInterfaceChannelHandler::interfaceDown ");
-        stopHelloTimer();
-        ospfInterface.listOfNeighbors().clear();
-        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DOWN);
+        initializeInterfaceMap();
     }
 
     @Override
     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) throws Exception {
         log.info("OSPF channelConnected from {}", evt.getChannel().getRemoteAddress());
-        channel = evt.getChannel();
-        interfaceUp();
-        startDelayedAckTimer();
+        this.channel = evt.getChannel();
+        initialize();
     }
 
     @Override
     public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent evt) {
-        interfaceDown();
-        stopDelayedAckTimer();
         log.debug("OspfChannelHandler::channelDisconnected...!!!");
-    }
 
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
-        log.info("[exceptionCaught]: " + e.toString());
-        if (e.getCause() instanceof ReadTimeoutException) {
-            // device timeout
-            log.error("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
-            return;
-        } else if (e.getCause() instanceof ClosedChannelException) {
-            log.debug("Channel for OSPF {} already closed", e.getChannel().getRemoteAddress());
-        } else if (e.getCause() instanceof IOException) {
-            log.error("Disconnecting OSPF {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
-                      e.getCause().getMessage());
-            if (log.isDebugEnabled()) {
-                log.debug("StackTrace for previous Exception: {}", e.getCause());
+        for (Integer interfaceIndex : ospfInterfaceMap.keySet()) {
+            OspfInterface anInterface = ospfInterfaceMap.get(interfaceIndex);
+            if (anInterface != null) {
+                anInterface.interfaceDown();
+                anInterface.stopDelayedAckTimer();
             }
-        } else if (e.getCause() instanceof OspfParseException) {
-            OspfParseException errMsg = (OspfParseException) e.getCause();
-            byte errorCode = errMsg.errorCode();
-            byte errorSubCode = errMsg.errorSubCode();
-            log.error("Error while parsing message from OSPF {}, 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 OSPF {}, state {}",
-                      e.getChannel().getRemoteAddress(), ((OspfInterfaceImpl) ospfInterface).state());
+        }
+
+        if (controller != null) {
+            controller.connectPeer();
         }
     }
 
     @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent
+            e) throws Exception {
+        log.debug("[exceptionCaught]: " + e.toString());
+        if (e.getCause() instanceof ReadTimeoutException) {
+            log.debug("Disconnecting device {} due to read timeout", e.getChannel().getRemoteAddress());
+            return;
+        } else if (e.getCause() instanceof ClosedChannelException) {
+            log.debug("Channel for OSPF {} already closed", e.getChannel().getRemoteAddress());
+        } else if (e.getCause() instanceof IOException) {
+            log.debug("Disconnecting OSPF {} due to IO Error: {}", e.getChannel().getRemoteAddress(),
+                      e.getCause().getMessage());
+        } else if (e.getCause() instanceof OspfParseException) {
+            OspfParseException errMsg = (OspfParseException) e.getCause();
+            byte errorCode = errMsg.errorCode();
+            byte errorSubCode = errMsg.errorSubCode();
+            log.debug("Error while parsing message from OSPF {}, ErrorCode {}",
+                      e.getChannel().getRemoteAddress(), errorCode);
+        } else if (e.getCause() instanceof RejectedExecutionException) {
+            log.debug("Could not process message: queue full");
+        } else {
+            log.debug("Error while processing message from OSPF {}, {}",
+                      e.getChannel().getRemoteAddress(), e.getCause().getMessage());
+        }
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent
+            e) throws Exception {
         log.debug("OspfChannelHandler::messageReceived...!!!");
         Object message = e.getMessage();
         if (message instanceof List) {
             List<OspfMessage> ospfMessageList = (List<OspfMessage>) message;
-            log.debug("OspfChannelHandler::List of OspfMessages Size {}", ospfMessageList.size());
+            log.debug("OspfChannelHandler::List of IsisMessages Size {}", ospfMessageList.size());
             if (ospfMessageList != null) {
                 for (OspfMessage ospfMessage : ospfMessageList) {
                     processOspfMessage(ospfMessage, ctx);
@@ -280,1121 +244,28 @@
      * @param ctx         channel handler context instance.
      * @throws Exception might throws exception
      */
-    public void processOspfMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
+    public void processOspfMessage(OspfMessage
+                                           ospfMessage, ChannelHandlerContext ctx) throws Exception {
         log.debug("OspfChannelHandler::processOspfMessage...!!!");
-
-        if (!validateMessage(ospfMessage)) {
-            return;
-        }
-
-        switch (ospfMessage.ospfMessageType().value()) {
-            case OspfParameters.HELLO:
-                processHelloMessage(ospfMessage, ctx);
-                break;
-            case OspfParameters.DD:
-                processDdMessage(ospfMessage, ctx);
-                break;
-            case OspfParameters.LSREQUEST:
-                processLsRequestMessage(ospfMessage, ctx);
-                break;
-            case OspfParameters.LSUPDATE:
-                processLsUpdateMessage(ospfMessage, ctx);
-                break;
-            case OspfParameters.LSACK:
-                processLsAckMessage(ospfMessage, ctx);
-                break;
-            default:
-                log.debug("Unknown packet to process...!!!");
-                break;
+        int interfaceIndex = ospfMessage.interfaceIndex();
+        OspfInterface ospfInterface = ospfInterfaceMap.get(interfaceIndex);
+        if (ospfInterface != null) {
+            ospfInterface.processOspfMessage(ospfMessage, ctx);
         }
     }
 
     /**
-     * Validates the OSPF message received.
+     * Sends the interface configuration packet to server.
      *
-     * @param ospfMessage OSPF message.
-     * @return true if it is a valid else false.
-     * @throws Exception might throws exception
+     * @param configPacket interface configuration
      */
-    private boolean validateMessage(OspfMessage ospfMessage) throws Exception {
-        boolean isValid = true;
-        OspfPacketHeader header = (OspfPacketHeader) ospfMessage;
-
-        //added the check to eliminate self origin packets also two interfaces on same router.
-        if (!header.sourceIp().equals(ospfInterface.ipAddress()) && !header.routerId().equals(
-                ospfArea.routerId())) {
-            //Verify the checksum
-            ChecksumCalculator checksum = new ChecksumCalculator();
-            if (!checksum.isValidOspfCheckSum(ospfMessage, OspfUtil.OSPFPACKET_CHECKSUM_POS1,
-                                              OspfUtil.OSPFPACKET_CHECKSUM_POS2)) {
-                log.debug("Checksum mismatch. Received packet type {} ", ospfMessage.ospfMessageType());
-                return false;
-            }
-            if (((OspfPacketHeader) ospfMessage).ospfVersion() != OspfUtil.OSPF_VERSION_2) {
-                log.debug("Received osfpMessage Version should match with Interface Version ");
-                return false;
-            }
-            if (!((OspfPacketHeader) ospfMessage).areaId().equals(ospfArea.areaId())) {
-                log.debug("Received ospf packets are from different area than our Area ID. " +
-                                  "Received Area ID {}, Our AreaId {} ",
-                          ((OspfPacketHeader) ospfMessage).areaId(), ospfArea.areaId());
-                return false;
-            }
-
-            //According to RFC-2328 (8.2)
-            /**
-             * ABR should receive packets from backbone 0.0.0.0 as we are not acting as ABR
-             * we are rejecting the packet.
-             */
-            if (((OspfPacketHeader) ospfMessage).areaId().equals(Ip4Address.valueOf("0.0.0.0"))) {
-                log.debug("ABR should receive packets from backbone 0.0.0.0 as we are not acting as " +
-                                  "ABR we are rejecting the ospf packet");
-                return false;
-            }
-            if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value() &&
-                    !OspfUtil.sameNetwork(((OspfPacketHeader) ospfMessage).sourceIp(),
-                                          ospfInterface.ipAddress(), ospfInterface.ipNetworkMask())) {
-                log.debug("Received packets from different subnets. Discarding...!!!");
-                return false;
-            }
+    public void sentConfigPacket(byte[] configPacket) {
+        if (channel != null) {
+            channel.write(configPacket);
+            log.debug("OspfChannelHandler sentConfigPacket packet sent..!!!");
         } else {
-            isValid = false;
-        }
-
-        return isValid;
-    }
-
-    /**
-     * Processes Hello message.
-     *
-     * @param ospfMessage OSPF message instance.
-     * @param ctx         context instance.
-     * @throws Exception might throws exception
-     */
-    void processHelloMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
-        log.debug("OspfChannelHandler::processHelloMessage...!!!");
-        HelloPacket helloPacket = (HelloPacket) ospfMessage;
-
-        // processing of hello packet as per RFC 2328 section 10.5
-        log.debug("OspfChannelHandler::processHelloMessage::Interface Type {} OSPFInterfaceState {} ",
-                  ospfInterface.interfaceType(), ((OspfInterfaceImpl) ospfInterface).state());
-
-        if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
-            if (!helloPacket.networkMask().equals(ospfInterface.ipNetworkMask())) {
-                log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received does not " +
-                                  "match the same network mask as the configure Interface");
-                return;
-            }
-        }
-        if (helloPacket.helloInterval() != ospfInterface.helloIntervalTime()) {
-            log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
-                              "hello interval as configured Interface");
-            return;
-        }
-        if (helloPacket.routerDeadInterval() != ospfInterface.routerDeadIntervalTime()) {
-            log.debug("OspfChannelHandler::processHelloMessage::Hello Packet Received have the same " +
-                              "Router Dead interval as configured Interface");
-            return;
-        }
-
-        if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
-            // to verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
-            OspfNbr nbr;
-            if (!ospfInterface.isNeighborInList(helloPacket.routerId().toString())) {
-                nbr = new OspfNbrImpl(ospfArea, ospfInterface, helloPacket.sourceIp(),
-                                      helloPacket.routerId(), helloPacket.options(), this, topologyForDeviceAndLink);
-                ospfInterface.addNeighbouringRouter(nbr);
-            } else {
-                nbr = ospfInterface.neighbouringRouter(helloPacket.routerId().toString());
-                nbr.setRouterPriority(helloPacket.routerPriority());
-            }
-            if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
-                ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
-            } else {
-                ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
-            }
-        } else if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value()) {
-
-            if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.WAITING) {
-                if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0"))) &&
-                        (!helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))) {
-                    stopWaitTimer();
-                    ospfInterface.setDr(helloPacket.dr());
-                    ospfInterface.setBdr(helloPacket.bdr());
-                    if (helloPacket.dr().equals(ospfInterface.ipAddress())) {
-                        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DR);
-                        //refresh router Lsa
-                        ospfArea.refreshArea(ospfInterface);
-                    } else if (helloPacket.bdr().equals(ospfInterface.ipAddress())) {
-                        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.BDR);
-                        //refresh router Lsa
-                        ospfArea.refreshArea(ospfInterface);
-                    } else {
-                        ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DROTHER);
-                        ospfArea.refreshArea(ospfInterface);
-                    }
-
-                } else if (!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
-                        !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
-                    ospfInterface.setDr(helloPacket.dr());
-                    ospfInterface.setBdr(helloPacket.bdr());
-                }
-                Ip4Address sourceIp = helloPacket.sourceIp();
-                OspfNbr nbr;
-                if (!ospfInterface.isNeighborInList(helloPacket.routerId().toString())) {
-                    nbr = new OspfNbrImpl(ospfArea, ospfInterface, sourceIp, helloPacket.routerId(),
-                                          helloPacket.options(), this, topologyForDeviceAndLink);
-                    nbr.setNeighborId(helloPacket.routerId());
-                    nbr.setNeighborBdr(helloPacket.bdr());
-                    nbr.setNeighborDr(helloPacket.dr());
-                    nbr.setRouterPriority(helloPacket.routerPriority());
-                    ospfInterface.addNeighbouringRouter(nbr);
-                } else {
-                    nbr = ospfInterface.neighbouringRouter(helloPacket.routerId().toString());
-                    nbr.setRouterPriority(helloPacket.routerPriority());
-                }
-                if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
-                    ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
-                } else {
-                    ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
-                }
-
-                if (helloPacket.dr().equals(sourceIp)) {
-                    if (helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0"))) {
-                        // call backup seen
-                        stopWaitTimer();
-                        backupSeen(ctx.getChannel());
-                    }
-                }
-
-                if (helloPacket.bdr().equals(sourceIp)) {
-                    // call backup seen
-                    stopWaitTimer();
-                    backupSeen(ctx.getChannel());
-                }
-            } else {
-
-                if ((!helloPacket.dr().equals(Ip4Address.valueOf("0.0.0.0")) ||
-                        !helloPacket.bdr().equals(Ip4Address.valueOf("0.0.0.0")))
-                        && ospfInterface.routerPriority() == 0) {
-                    ospfInterface.setDr(helloPacket.dr());
-                    ospfInterface.setBdr(helloPacket.bdr());
-                }
-                //To verify if the neighbor which sent the hello is present in the OSPF Interface neighboring list .
-                Ip4Address sourceIp = helloPacket.sourceIp();
-                OspfNbr nbr;
-                if (!ospfInterface.isNeighborInList(helloPacket.routerId().toString())) {
-                    nbr = new OspfNbrImpl(ospfArea, ospfInterface, sourceIp, helloPacket.routerId(),
-                                          helloPacket.options(), this, topologyForDeviceAndLink);
-                    nbr.setNeighborId(helloPacket.routerId());
-                    nbr.setNeighborBdr(helloPacket.bdr());
-                    nbr.setNeighborDr(helloPacket.dr());
-                    nbr.setRouterPriority(helloPacket.routerPriority());
-                    ospfInterface.addNeighbouringRouter(nbr);
-                    ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
-                } else {
-                    log.debug("OspfChannelHandler::NeighborInList::helloPacket.bdr(): {}, " +
-                                      "helloPacket.dr(): {}", helloPacket.bdr(), helloPacket.dr());
-                    nbr = ospfInterface.neighbouringRouter(helloPacket.routerId().toString());
-                    nbr.setRouterPriority(helloPacket.routerPriority());
-                    if (!helloPacket.containsNeighbour(ospfArea.routerId())) {
-                        ((OspfNbrImpl) nbr).oneWayReceived(helloPacket, channel);
-                    } else {
-                        ((OspfNbrImpl) nbr).twoWayReceived(helloPacket, ctx.getChannel());
-                    }
-                    if (nbr.routerPriority() != helloPacket.routerPriority()) {
-                        nbr.setNeighborBdr(helloPacket.bdr());
-                        nbr.setNeighborDr(helloPacket.dr());
-                        neighborChange();
-                    }
-
-
-                    if (nbr.neighborIpAddr().equals(helloPacket.dr()) &&
-                            !(nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
-                        nbr.setNeighborBdr(helloPacket.bdr());
-                        nbr.setNeighborDr(helloPacket.dr());
-                        neighborChange();
-                    }
-
-                    if (!(nbr.neighborIpAddr().equals(helloPacket.dr())) &&
-                            (nbr.neighborIpAddr().equals(nbr.neighborDr()))) {
-                        nbr.setNeighborBdr(helloPacket.bdr());
-                        nbr.setNeighborDr(helloPacket.dr());
-                        neighborChange();
-                    }
-
-                    if (nbr.neighborIpAddr().equals(helloPacket.bdr()) &&
-                            !(nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
-                        nbr.setNeighborBdr(helloPacket.bdr());
-                        nbr.setNeighborDr(helloPacket.dr());
-                        neighborChange();
-                    }
-
-                    if (!(nbr.neighborIpAddr().equals(helloPacket.bdr())) &&
-                            (nbr.neighborIpAddr().equals(nbr.neighborBdr()))) {
-                        nbr.setNeighborBdr(helloPacket.bdr());
-                        nbr.setNeighborDr(helloPacket.dr());
-                        neighborChange();
-                    }
-
-                    nbr.setNeighborBdr(helloPacket.bdr());
-                    nbr.setNeighborDr(helloPacket.dr());
-                }
-
-            }
-        }
-    }
-
-    /**
-     * process the DD message which received.
-     *
-     * @param ospfMessage OSPF message instance.
-     * @param ctx         channel handler context instance
-     * @throws Exception might throws exception
-     */
-    void processDdMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
-        log.debug("OspfChannelHandler::processDdMessage...!!!");
-
-        DdPacket ddPacket = (DdPacket) ospfMessage;
-        log.debug("Got DD packet from {}", ddPacket.sourceIp());
-        //check it is present in listOfNeighbors
-        Ip4Address neighbourId = ddPacket.routerId();
-        OspfNbr nbr = ospfInterface.neighbouringRouter(neighbourId.toString());
-
-        if (nbr != null) {
-            log.debug("OspfChannelHandler::processDdMessage:: OSPFNeighborState {}", nbr.getState());
-            // set options for the NBR
-            nbr.setIsOpaqueCapable(ddPacket.isOpaqueCapable());
-            if (ddPacket.imtu() > ospfInterface.mtu()) {
-                log.debug("the MTU size is greater than the interface MTU");
-                return;
-            }
-            if (nbr.getState() == OspfNeighborState.DOWN) {
-                return;
-            }
-            if (nbr.getState() == OspfNeighborState.ATTEMPT) {
-                return;
-            }
-            if (nbr.getState() == OspfNeighborState.TWOWAY) {
-                nbr.adjOk(channel);
-                return;
-            }
-            //if init is the state call twoWayReceived
-            if (nbr.getState() == OspfNeighborState.INIT) {
-                ((OspfNbrImpl) nbr).twoWayReceived(ddPacket, ctx.getChannel());
-            } else if (nbr.getState() == OspfNeighborState.EXSTART) {
-                //get I,M,MS Bits
-                int initialize = ddPacket.isInitialize();
-                int more = ddPacket.isMore();
-                int masterOrSlave = ddPacket.isMaster();
-                int options = ddPacket.options();
-                nbr.setOptions(options);
-
-                if (initialize == OspfUtil.INITIALIZE_SET && more == OspfUtil.MORE_SET &&
-                        masterOrSlave == OspfUtil.IS_MASTER) {
-                    if (ddPacket.getLsaHeaderList().isEmpty()) {
-                        if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) >
-                                OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
-                            nbr.setIsMaster(OspfUtil.IS_MASTER);
-                            ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
-                            nbr.setDdSeqNum(ddPacket.sequenceNo());
-                            nbr.setOptions(ddPacket.options());
-                            ((OspfNbrImpl) nbr).negotiationDone(ddPacket, true, ddPacket.getLsaHeaderList(),
-                                                                ctx.getChannel());
-                        }
-                    }
-                }
-                if (initialize == OspfUtil.INITIALIZE_NOTSET && masterOrSlave == OspfUtil.NOT_MASTER) {
-                    if (nbr.ddSeqNum() == ddPacket.sequenceNo()) {
-                        if (OspfUtil.ipAddressToLong(ddPacket.routerId().toString()) <
-                                OspfUtil.ipAddressToLong(ospfArea.routerId().toString())) {
-                            ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
-                            nbr.setOptions(ddPacket.options());
-                            nbr.setDdSeqNum(nbr.ddSeqNum() + 1);
-                            ((OspfNbrImpl) nbr).negotiationDone(ddPacket, false, ddPacket.getLsaHeaderList(),
-                                                                ctx.getChannel());
-                        }
-                    }
-                }
-
-            } else if (nbr.getState() == OspfNeighborState.EXCHANGE) {
-                //get I,M,MS Bits
-                log.debug("Neighbor state:: EXCHANGE");
-                boolean isDuplicateDDPacket = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
-                int initialize = ddPacket.isInitialize();
-                int more = ddPacket.isMore();
-                int masterOrSlave = ddPacket.isMaster();
-                int options = ddPacket.options();
-
-                if (!isDuplicateDDPacket) {
-                    //if dd packet is not duplicate  then continue
-                    if (nbr.isMaster() != masterOrSlave) {
-                        DdPacket newResPacket =
-                                (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Master/Slave Inconsistency");
-                        newResPacket.setDestinationIp(ddPacket.sourceIp());
-                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
-                        ctx.getChannel().write(newResPacket);
-                    } else if (initialize == 1) {
-                        DdPacket newResPacket =
-                                (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
-                        newResPacket.setDestinationIp(ddPacket.sourceIp());
-                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
-                        ctx.getChannel().write(newResPacket);
-                    } else {
-
-                        if (masterOrSlave == OspfUtil.NOT_MASTER) {
-                            if (ddPacket.sequenceNo() == nbr.ddSeqNum()) {
-                                //Process the DD Packet
-                                ((OspfNbrImpl) nbr).processDdPacket(false, ddPacket, ctx.getChannel());
-                                log.debug("Received DD Packet");
-                            } else {
-                                DdPacket newResPacket =
-                                        (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("Sequence Number Mismatch");
-                                newResPacket.setDestinationIp(ddPacket.sourceIp());
-                                log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
-                                ctx.getChannel().write(newResPacket);
-                            }
-                        } else {
-                            //we are the slave
-                            if (ddPacket.sequenceNo() == (nbr.ddSeqNum() + 1)) {
-                                ((OspfNbrImpl) nbr).setLastDdPacket(ddPacket);
-                                ((OspfNbrImpl) nbr).processDdPacket(true, ddPacket, ctx.getChannel());
-                                log.debug("Process DD Packet");
-                            } else {
-                                DdPacket newResPacket =
-                                        (DdPacket) ((OspfNbrImpl) nbr).seqNumMismatch("options inconsistency");
-                                newResPacket.setDestinationIp(ddPacket.sourceIp());
-                                log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
-                                ctx.getChannel().write(newResPacket);
-                            }
-                        }
-                    }
-                } else {
-                    if (masterOrSlave == OspfUtil.NOT_MASTER) {
-                        return;
-                    } else {
-                        DdPacket newResPacket = ((OspfNbrImpl) nbr).lastSentDdPacket();
-                        log.debug("Sending back DDPacket to {}", ddPacket.sourceIp());
-                        ctx.getChannel().write(newResPacket);
-                    }
-                }
-            } else if (nbr.getState() == OspfNeighborState.LOADING || nbr.getState() == OspfNeighborState.FULL) {
-                //In case if we are slave then we have to send the last received DD Packet
-                int options = ddPacket.options();
-                if (nbr.options() != options) {
-                    OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
-                    newResPacket.setDestinationIp(ddPacket.sourceIp());
-                    ctx.getChannel().write(newResPacket);
-                } else if (ddPacket.isInitialize() == OspfUtil.INITIALIZE_SET) {
-                    OspfMessage newResPacket = ((OspfNbrImpl) nbr).seqNumMismatch("Initialize bit inconsistency");
-                    newResPacket.setDestinationIp(ddPacket.sourceIp());
-                    ctx.getChannel().write(newResPacket);
-                }
-                boolean isDuplicate = compareDdPackets(ddPacket, ((OspfNbrImpl) nbr).lastDdPacket());
-                //we are master
-                if (nbr.isMaster() != OspfUtil.IS_MASTER) {
-                    // check if the packet is duplicate, duplicates should be discarded by the master
-                    if (isDuplicate) {
-                        log.debug("received a duplicate DD packet");
-                    }
-                } else {
-                    //The slave must respond to duplicates by repeating the last Database Description packet
-                    //that it had sent.
-                    if (isDuplicate) {
-                        ddPacket.setDestinationIp(ddPacket.sourceIp());
-                        ctx.getChannel().write(((OspfNbrImpl) nbr).lastSentDdPacket());
-                        log.debug("Sending back the duplicate packet ");
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Process the Ls Request message.
-     *
-     * @param ospfMessage OSPF message instance.
-     * @param ctx         channel handler context instance.
-     * @throws Exception might throws exception
-     */
-    void processLsRequestMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
-        log.debug("OspfChannelHandler::processLsRequestMessage...!!!");
-        LsRequest lsrPacket = (LsRequest) ospfMessage;
-        OspfNbr nbr = ospfInterface.neighbouringRouter(lsrPacket.routerId().toString());
-
-        if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING ||
-                nbr.getState() == OspfNeighborState.FULL) {
-
-            LsRequest reqMsg = (LsRequest) ospfMessage;
-            if (reqMsg.getLinkStateRequests().isEmpty()) {
-                log.debug("Received Link State Request Vector is Empty ");
-                return;
-            } else {
-                //Send the LsUpdate back
-                ListIterator<LsRequestPacket> listItr = reqMsg.getLinkStateRequests().listIterator();
-                while (listItr.hasNext()) {
-                    LsUpdate lsupdate = new LsUpdate();
-                    lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
-                    lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
-                    lsupdate.setRouterId(ospfArea.routerId());
-                    lsupdate.setAreaId(ospfArea.areaId());
-                    lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
-                    lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
-                    lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
-                    lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
-
-                    //limit to mtu
-                    int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
-                    int maxSize = ospfInterface.mtu() -
-                            OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
-                    int noLsa = 0;
-                    while (listItr.hasNext()) {
-                        LsRequestPacket lsRequest = (LsRequestPacket) listItr.next();
-                        // to verify length of the LSA
-                        LsaWrapper wrapper = ospfArea.getLsa(lsRequest.lsType(), lsRequest.linkStateId(),
-                                                             lsRequest.ownRouterId());
-                        OspfLsa ospflsa = wrapper.ospfLsa();
-                        if ((currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen()) >= maxSize) {
-                            listItr.previous();
-                            break;
-                        }
-                        if (ospflsa != null) {
-                            lsupdate.addLsa(ospflsa);
-                            noLsa++;
-
-                            currentLength = currentLength + ((LsaWrapperImpl) wrapper).lsaHeader().lsPacketLen();
-                        } else {
-                            nbr.badLSReq(channel);
-                        }
-                    }
-                    lsupdate.setNumberOfLsa(noLsa);
-                    //set the destination
-                    if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR ||
-                            ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR ||
-                            ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT) {
-                        lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
-                    } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER) {
-                        lsupdate.setDestinationIp(OspfUtil.ALL_DROUTERS);
-                    }
-                    ctx.getChannel().write(lsupdate);
-                }
-            }
-        }
-    }
-
-    /**
-     * Process the ls update message.
-     *
-     * @param ospfMessage OSPF message instance.
-     * @param ctx         channel handler context instance.
-     * @throws Exception might throws exception
-     */
-    void processLsUpdateMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
-        log.debug("OspfChannelHandler::processLsUpdateMessage");
-        LsUpdate lsUpdate = (LsUpdate) ospfMessage;
-        String neighbourId = lsUpdate.routerId().toString();
-        //LSUpdate packet has been associated with a particular neighbor.
-        //Neighbor should not be in lesser state than Exchange.
-        if (ospfInterface.isNeighborInList(neighbourId)) {
-            OspfNbrImpl nbr = (OspfNbrImpl) ospfInterface.neighbouringRouter(neighbourId);
-            if (nbr.getState() == OspfNeighborState.EXCHANGE ||
-                    nbr.getState() == OspfNeighborState.LOADING) {
-                nbr.processLsUpdate(lsUpdate, ctx.getChannel());
-            } else if (nbr.getState() == OspfNeighborState.FULL) {
-                if (lsUpdate.noLsa() != 0) {
-                    List<OspfLsa> list = lsUpdate.getLsaList();
-                    Iterator itr = list.iterator();
-                    while (itr.hasNext()) {
-                        LsaHeader lsa = (LsaHeader) itr.next();
-                        nbr.processReceivedLsa(lsa, true, ctx.getChannel(), lsUpdate.sourceIp());
-                    }
-                } else {
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * Process the ls acknowledge message.
-     *
-     * @param ospfMessage OSPF message instance.
-     * @param ctx         channel handler context instance.
-     * @throws Exception might throws exception
-     */
-    void processLsAckMessage(OspfMessage ospfMessage, ChannelHandlerContext ctx) throws Exception {
-        log.debug("OspfChannelHandler::processLsAckMessage");
-        LsAcknowledge lsAckPacket = (LsAcknowledge) ospfMessage;
-        //check it is present in listOfNeighbors
-        OspfNbrImpl nbr = (OspfNbrImpl) ospfInterface.neighbouringRouter(lsAckPacket.routerId().toString());
-        if (nbr != null) {
-            if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
-                // discard the packet.
-                return;
-            } else {
-                // process ls acknowledgements
-                Iterator itr = lsAckPacket.getLinkStateHeaders().iterator();
-                while (itr.hasNext()) {
-                    LsaHeader lsRequest = (LsaHeader) itr.next();
-
-                    OspfLsa ospfLsa =
-                            (OspfLsa) nbr.getPendingReTxList().get(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
-                    if (lsRequest != null && ospfLsa != null) {
-                        String isSame = ((OspfLsdbImpl) ospfArea.database()).isNewerOrSameLsa(
-                                lsRequest, (LsaHeader) ospfLsa);
-                        if (isSame.equals("same")) {
-                            nbr.getPendingReTxList().remove(((OspfAreaImpl) ospfArea).getLsaKey(lsRequest));
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Compares two Dd Packets to check whether its duplicate or not.
-     *
-     * @param receivedDPacket received DD packet from network.
-     * @param lastDdPacket    Last DdPacket which we sent.
-     * @return true if it is a duplicate packet else false.
-     */
-    public boolean compareDdPackets(DdPacket receivedDPacket, DdPacket lastDdPacket) {
-        if (receivedDPacket.isInitialize() == lastDdPacket.isInitialize()) {
-            if (receivedDPacket.isMaster() == lastDdPacket.isMaster()) {
-                if (receivedDPacket.isMore() == lastDdPacket.isMore()) {
-                    if (receivedDPacket.options() == lastDdPacket.options()) {
-                        if (receivedDPacket.sequenceNo() == lastDdPacket.sequenceNo()) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Closes the Netty channel.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    void closeChannel(ChannelHandlerContext ctx) {
-        log.debug("OspfChannelHandler::closeChannel");
-        isClosed = true;
-        ctx.getChannel().close();
-    }
-
-    /**
-     * Starts the hello timer which sends hello packet every configured seconds.
-     *
-     * @param period the interval to run task
-     */
-    private void startHelloTimer(long period) {
-        log.debug("OSPFInterfaceChannelHandler::startHelloTimer");
-        exServiceHello = Executors.newSingleThreadScheduledExecutor();
-        helloTimerTask = new InternalHelloTimer();
-        final ScheduledFuture<?> helloHandle =
-                exServiceHello.scheduleAtFixedRate(helloTimerTask, delay, period, TimeUnit.SECONDS);
-    }
-
-    /**
-     * Stops the hello timer.
-     */
-    private void stopHelloTimer() {
-        log.debug("OSPFInterfaceChannelHandler::stopHelloTimer ");
-        exServiceHello.shutdown();
-    }
-
-    /**
-     * Starts the wait timer.
-     */
-    private void startWaitTimer() {
-        log.debug("OSPFNbr::startWaitTimer");
-        exServiceWait = Executors.newSingleThreadScheduledExecutor();
-        waitTimerTask = new InternalWaitTimer();
-        final ScheduledFuture<?> waitTimerHandle =
-                exServiceWait.schedule(waitTimerTask, ospfInterface.routerDeadIntervalTime(),
-                                       TimeUnit.SECONDS);
-    }
-
-    /**
-     * Stops the wait timer.
-     */
-    private void stopWaitTimer() {
-        log.debug("OSPFNbr::stopWaitTimer ");
-        exServiceWait.shutdown();
-    }
-
-    /**
-     * Starts the timer which waits for configured seconds and sends Delayed Ack Packet.
-     */
-    private void startDelayedAckTimer() {
-        if (!isDelayedAckTimerScheduled) {
-            log.debug("Started DelayedAckTimer...!!!");
-            exServiceDelayedAck = Executors.newSingleThreadScheduledExecutor();
-            delayedAckTimerTask = new InternalDelayedAckTimer();
-            final ScheduledFuture<?> delayAckHandle =
-                    exServiceDelayedAck.scheduleAtFixedRate(delayedAckTimerTask, delayedAckTimerInterval,
-                                                            delayedAckTimerInterval, TimeUnit.MILLISECONDS);
-            isDelayedAckTimerScheduled = true;
-        }
-    }
-
-    /**
-     * Stops the delayed acknowledge timer.
-     */
-    private void stopDelayedAckTimer() {
-        if (isDelayedAckTimerScheduled) {
-            log.debug("Stopped DelayedAckTimer...!!!");
-            isDelayedAckTimerScheduled = false;
-            exServiceDelayedAck.shutdown();
-        }
-    }
-
-    /**
-     * Performs DR election.
-     *
-     * @param ch Netty Channel instance.
-     * @throws Exception might throws exception
-     */
-    public void electRouter(Channel ch) throws Exception {
-
-        Ip4Address currentDr = ospfInterface.dr();
-        Ip4Address currentBdr = ospfInterface.bdr();
-        OspfInterfaceState oldState = ((OspfInterfaceImpl) ospfInterface).state();
-        OspfInterfaceState newState;
-
-        log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
-                  currentDr, currentBdr);
-        List<OspfEligibleRouter> eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
-
-        log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
-        OspfEligibleRouter electedBdr = electBdr(eligibleRouters);
-        OspfEligibleRouter electedDr = electDr(eligibleRouters, electedBdr);
-
-        ospfInterface.setBdr(electedBdr.getIpAddress());
-        ospfInterface.setDr(electedDr.getIpAddress());
-
-        if (electedBdr.getIpAddress().equals(ospfInterface.ipAddress()) &&
-                !electedBdr.getIpAddress().equals(currentBdr)) {
-            ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.BDR);
-        }
-
-        if (electedDr.getIpAddress().equals(ospfInterface.ipAddress()) &&
-                !electedDr.getIpAddress().equals(currentDr)) {
-            ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DR);
-        }
-
-        if (((OspfInterfaceImpl) ospfInterface).state() != oldState &&
-                !(((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER &&
-                        oldState.value() < OspfInterfaceState.DROTHER.value())) {
-            log.debug("Recalculating as the State is changed ");
-            log.debug("OSPFInterfaceChannelHandler::electRouter -> currentDr: {}, currentBdr: {}",
-                      currentDr, currentBdr);
-            eligibleRouters = calculateListOfEligibleRouters(new OspfEligibleRouter());
-
-            log.debug("OSPFInterfaceChannelHandler::electRouter -> eligibleRouters: {}", eligibleRouters);
-            electedBdr = electBdr(eligibleRouters);
-            electedDr = electDr(eligibleRouters, electedBdr);
-
-            ospfInterface.setBdr(electedBdr.getIpAddress());
-            ospfInterface.setDr(electedDr.getIpAddress());
-        }
-
-        if (electedBdr.getIpAddress().equals(ospfInterface.ipAddress()) &&
-                !electedBdr.getIpAddress().equals(currentBdr)) {
-            ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.BDR);
-            ospfArea.refreshArea(ospfInterface);
-        }
-
-        if (electedDr.getIpAddress().equals(ospfInterface.ipAddress()) &&
-                !electedDr.getIpAddress().equals(currentDr)) {
-            ((OspfInterfaceImpl) ospfInterface).setState(OspfInterfaceState.DR);
-            //Refresh Router Lsa & Network Lsa
-            ospfArea.refreshArea(ospfInterface);
-        }
-
-        if (currentDr != electedDr.getIpAddress() || currentBdr != electedBdr.getIpAddress()) {
-            Set<String> negibhorIdList;
-            negibhorIdList = ospfInterface.listOfNeighbors().keySet();
-            for (String routerid : negibhorIdList) {
-                OspfNbrImpl nbr = (OspfNbrImpl) ospfInterface.neighbouringRouter(routerid);
-                if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue()) {
-                    nbr.adjOk(ch);
-                }
-            }
-        }
-
-        log.debug("OSPFInterfaceChannelHandler::electRouter -> ElectedDR: {}, ElectedBDR: {}",
-                  electedDr.getIpAddress(), electedBdr.getIpAddress());
-    }
-
-
-    /**
-     * BDR Election process. Find the list of eligible router to participate in the process.
-     *
-     * @param electedDr router elected as DR.
-     * @return list of eligible routers
-     */
-    public List<OspfEligibleRouter> calculateListOfEligibleRouters(OspfEligibleRouter electedDr) {
-        log.debug("OSPFNbr::calculateListOfEligibleRouters ");
-        Set<String> neighborIdList;
-        List<OspfEligibleRouter> eligibleRouters = new ArrayList<>();
-
-        neighborIdList = ospfInterface.listOfNeighbors().keySet();
-        for (String routerId : neighborIdList) {
-            OspfNbrImpl nbr = (OspfNbrImpl) ospfInterface.neighbouringRouter(routerId);
-            if (nbr.getState().getValue() >= OspfNeighborState.TWOWAY.getValue() &&
-                    nbr.routerPriority() > 0) {
-                OspfEligibleRouter router = new OspfEligibleRouter();
-                router.setIpAddress(nbr.neighborIpAddr());
-                router.setRouterId(nbr.neighborId());
-                router.setRouterPriority(nbr.routerPriority());
-                if (nbr.neighborDr().equals(nbr.neighborIpAddr()) ||
-                        electedDr.getIpAddress().equals(nbr.neighborIpAddr())) {
-                    router.setIsDr(true);
-                } else if (nbr.neighborBdr().equals(nbr.neighborIpAddr())) {
-                    router.setIsBdr(true);
-                }
-                eligibleRouters.add(router);
-            }
-        }
-        // interface does not have states like two and all
-        if (ospfInterface.routerPriority() > 0) {
-            OspfEligibleRouter router = new OspfEligibleRouter();
-            router.setIpAddress(ospfInterface.ipAddress());
-            router.setRouterId(ospfArea.routerId());
-            router.setRouterPriority(ospfInterface.routerPriority());
-            if (ospfInterface.dr().equals(ospfInterface.ipAddress()) ||
-                    electedDr.getIpAddress().equals(ospfInterface.ipAddress())) {
-                router.setIsDr(true);
-            } else if (ospfInterface.bdr().equals(ospfInterface.ipAddress()) &&
-                    !ospfInterface.dr().equals(ospfInterface.ipAddress())) {
-                router.setIsBdr(true);
-            }
-
-            eligibleRouters.add(router);
-        }
-
-        return eligibleRouters;
-    }
-
-    /**
-     * Based on router priority assigns BDR.
-     *
-     * @param eligibleRouters list of routers to participate in bdr election.
-     * @return OSPF Eligible router instance.
-     */
-    public OspfEligibleRouter electBdr(List<OspfEligibleRouter> eligibleRouters) {
-        log.debug("OSPFInterfaceChannelHandler::electBdr -> eligibleRouters: {}", eligibleRouters);
-        List<OspfEligibleRouter> declaredAsBdr = new ArrayList<>();
-        List<OspfEligibleRouter> notDrAndBdr = new ArrayList<>();
-        for (OspfEligibleRouter router : eligibleRouters) {
-            if (router.isBdr()) {
-                declaredAsBdr.add(router);
-            }
-            if (!router.isBdr() && !router.isDr()) {
-                notDrAndBdr.add(router);
-            }
-        }
-
-        OspfEligibleRouter electedBdr = new OspfEligibleRouter();
-        if (!declaredAsBdr.isEmpty()) {
-            if (declaredAsBdr.size() == 1) {
-                electedBdr = declaredAsBdr.get(0);
-            } else if (declaredAsBdr.size() > 1) {
-                electedBdr = selectRouterBasedOnPriority(declaredAsBdr);
-            }
-        } else {
-            if (notDrAndBdr.size() == 1) {
-                electedBdr = notDrAndBdr.get(0);
-            } else if (notDrAndBdr.size() > 1) {
-                electedBdr = selectRouterBasedOnPriority(notDrAndBdr);
-            }
-        }
-
-        electedBdr.setIsBdr(true);
-        electedBdr.setIsDr(false);
-
-        return electedBdr;
-    }
-
-    /**
-     * DR Election process.
-     *
-     * @param eligibleRouters list of eligible routers.
-     * @param electedBdr      Elected Bdr, OSPF eligible router instance.
-     * @return OSPF eligible router instance.
-     */
-    public OspfEligibleRouter electDr(List<OspfEligibleRouter> eligibleRouters,
-                                      OspfEligibleRouter electedBdr) {
-
-        List<OspfEligibleRouter> declaredAsDr = new ArrayList<>();
-        for (OspfEligibleRouter router : eligibleRouters) {
-            if (router.isDr()) {
-                declaredAsDr.add(router);
-            }
-        }
-
-        OspfEligibleRouter electedDr = new OspfEligibleRouter();
-        if (!declaredAsDr.isEmpty()) {
-            if (declaredAsDr.size() == 1) {
-                electedDr = declaredAsDr.get(0);
-            } else if (eligibleRouters.size() > 1) {
-                electedDr = selectRouterBasedOnPriority(declaredAsDr);
-            }
-        } else {
-            electedDr = electedBdr;
-            electedDr.setIsDr(true);
-            electedDr.setIsBdr(false);
-        }
-
-        return electedDr;
-    }
-
-    /**
-     * DR election process.
-     *
-     * @param routersList list of eligible routers.
-     * @return OSPF eligible router instance.
-     */
-    public OspfEligibleRouter selectRouterBasedOnPriority(List<OspfEligibleRouter> routersList) {
-
-        OspfEligibleRouter initialRouter = routersList.get(0);
-
-        for (int i = 1; i < routersList.size(); i++) {
-            OspfEligibleRouter router = routersList.get(i);
-            if (router.getRouterPriority() > initialRouter.getRouterPriority()) {
-                initialRouter = router;
-            } else if (router.getRouterPriority() == initialRouter.getRouterPriority()) {
-                try {
-                    //if (router.getIpAddress().toInt() > initialRouter.getIpAddress().toInt()) {
-                    if (OspfUtil.ipAddressToLong(router.getIpAddress().toString()) >
-                            OspfUtil.ipAddressToLong(initialRouter.getIpAddress().toString())) {
-                        initialRouter = router;
-                    }
-                } catch (Exception e) {
-                    log.debug("OSPFInterfaceChannelHandler::selectRouterBasedOnPriority ->" +
-                                      " eligibleRouters: {}", initialRouter);
-                }
-            }
-        }
-
-        return initialRouter;
-    }
-
-    /**
-     * Adds device information.
-     *
-     * @param ospfRouter OSPF router instance
-     */
-    public void addDeviceInformation(OspfRouter ospfRouter) {
-        controller.addDeviceDetails(ospfRouter);
-    }
-
-    /**
-     * removes device information.
-     *
-     * @param ospfRouter OSPF neighbor instance
-     */
-    public void removeDeviceInformation(OspfRouter ospfRouter) {
-        controller.removeDeviceDetails(ospfRouter);
-    }
-
-    /**
-     * Adds link information.
-     *
-     * @param ospfRouter  OSPF router instance
-     * @param ospfLinkTed list link ted instances
-     */
-    public void addLinkInformation(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
-        controller.addLinkDetails(ospfRouter, ospfLinkTed);
-    }
-
-    /**
-     * Removes link information.
-     *
-     * @param ospfNbr OSPF neighbor instance
-     */
-    public void removeLinkInformation(OspfNbr ospfNbr) {
-        controller.removeLinkDetails(buildOspfRouterDetails(ospfNbr));
-    }
-
-    /**
-     * Builds router details.
-     *
-     * @param ospfNbr OSPF neighbor instance
-     * @return OSPF router instance
-     */
-    private OspfRouter buildOspfRouterDetails(OspfNbr ospfNbr) {
-        OspfRouter ospfRouter = new OspfRouterImpl();
-        ospfRouter.setRouterIp(ospfNbr.neighborId());
-        ospfRouter.setInterfaceId(ospfInterface.ipAddress());
-        ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
-
-        ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
-
-        return ospfRouter;
-    }
-
-    /**
-     * Represents a Hello task which sent a hello message every configured time interval.
-     */
-    private class InternalHelloTimer implements Runnable {
-
-        /**
-         * Creates an instance of Hello Timer.
-         */
-        InternalHelloTimer() {
-        }
-
-        @Override
-        public void run() {
-            if (!isClosed && channel != null && channel.isOpen() && channel.isConnected()) {
-
-                HelloPacket hellopacket = new HelloPacket();
-                //Headers
-                hellopacket.setOspfVer(OspfUtil.OSPF_VERSION);
-                hellopacket.setOspftype(OspfPacketType.HELLO.value());
-                hellopacket.setOspfPacLength(0); //will be modified while encoding
-                hellopacket.setRouterId(ospfArea.routerId());
-                hellopacket.setAreaId(ospfArea.areaId());
-                hellopacket.setChecksum(0); //will be modified while encoding
-                hellopacket.setAuthType(Integer.parseInt(ospfInterface.authType()));
-                hellopacket.setAuthentication(Integer.parseInt(ospfInterface.authKey()));
-                //Body
-                hellopacket.setNetworkMask(ospfInterface.ipNetworkMask());
-                hellopacket.setOptions(ospfArea.options());
-                hellopacket.setHelloInterval(ospfInterface.helloIntervalTime());
-                hellopacket.setRouterPriority(ospfInterface.routerPriority());
-                hellopacket.setRouterDeadInterval(ospfInterface.routerDeadIntervalTime());
-                hellopacket.setDr(ospfInterface.dr());
-                hellopacket.setBdr(ospfInterface.bdr());
-
-                HashMap<String, OspfNbr> listOfNeighbors = ospfInterface.listOfNeighbors();
-                Set<String> keys = listOfNeighbors.keySet();
-                Iterator itr = keys.iterator();
-                while (itr.hasNext()) {
-                    String nbrKey = (String) itr.next();
-                    OspfNbrImpl nbr = (OspfNbrImpl) listOfNeighbors.get(nbrKey);
-                    if (nbr.getState() != OspfNeighborState.DOWN) {
-                        hellopacket.addNeighbor(Ip4Address.valueOf(nbrKey));
-                    }
-                }
-                // build a hello Packet
-                if (channel == null || !channel.isOpen() || !channel.isConnected()) {
-                    log.debug("Hello Packet not sent !!.. Channel Issue...");
-                    return;
-                }
-
-                hellopacket.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
-                ChannelFuture future = channel.write(hellopacket);
-                if (future.isSuccess()) {
-                    log.debug("Hello Packet successfully sent !!");
-                } else {
-                    future.awaitUninterruptibly();
-                }
-
-            }
-        }
-    }
-
-    /**
-     * Represents a Wait Timer task which waits the interface state to become WAITING.
-     * It initiates DR election process.
-     */
-    private class InternalWaitTimer implements Runnable {
-        Channel ch;
-
-        /**
-         * Creates an instance of Wait Timer.
-         */
-        InternalWaitTimer() {
-            this.ch = channel;
-        }
-
-        @Override
-        public void run() {
-            log.debug("Wait timer expires...");
-            if (ch != null && ch.isConnected()) {
-                try {
-                    waitTimer(ch);
-                } catch (Exception e) {
-                    log.debug("Exception at wait timer ...!!!");
-                }
-
-            }
-        }
-    }
-
-    /**
-     * Represents a task which sent a LS Acknowledge from the link state headers list.
-     */
-    private class InternalDelayedAckTimer implements Runnable {
-        Channel ch;
-
-        /**
-         * Creates an instance of Delayed acknowledge timer.
-         */
-        InternalDelayedAckTimer() {
-            this.ch = channel;
-        }
-
-        @Override
-        public void run() {
-            if (!((OspfInterfaceImpl) ospfInterface).linkStateHeaders().isEmpty()) {
-                isDelayedAckTimerScheduled = true;
-                if (ch != null && ch.isConnected()) {
-
-                    List<LsaHeader> listOfLsaHeadersAcknowledged = new ArrayList<>();
-                    List<LsaHeader> listOfLsaHeaders = ((OspfInterfaceImpl) ospfInterface).linkStateHeaders();
-                    log.debug("Delayed Ack, Number of Lsa's to Ack {}", listOfLsaHeaders.size());
-                    Iterator itr = listOfLsaHeaders.iterator();
-                    while (itr.hasNext()) {
-                        LsAcknowledge ackContent = new LsAcknowledge();
-                        //Setting OSPF Header
-                        ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
-                        ackContent.setOspftype(OspfPacketType.LSAACK.value());
-                        ackContent.setRouterId(ospfArea.routerId());
-                        ackContent.setAreaId(ospfArea.areaId());
-                        ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
-                        ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
-                        ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
-                        ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
-                        //limit to mtu
-                        int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
-                        int maxSize = ospfInterface.mtu() -
-                                OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
-                        while (itr.hasNext()) {
-                            if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) >= maxSize) {
-                                break;
-                            }
-                            LsaHeader lsaHeader = (LsaHeader) itr.next();
-                            ackContent.addLinkStateHeader(lsaHeader);
-                            currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
-                            listOfLsaHeadersAcknowledged.add(lsaHeader);
-                            log.debug("Delayed Ack, Added Lsa's to Ack {}", lsaHeader);
-                        }
-
-                        log.debug("Delayed Ack, Number of Lsa's in LsAck packet {}",
-                                  ackContent.getLinkStateHeaders().size());
-
-                        //set the destination
-                        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR ||
-                                ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR
-                                || ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT) {
-                            ackContent.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
-                        } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER) {
-                            ackContent.setDestinationIp(OspfUtil.ALL_DROUTERS);
-                        }
-                        ch.write(ackContent);
-                        for (LsaHeader lsa : listOfLsaHeadersAcknowledged) {
-                            ((OspfInterfaceImpl) ospfInterface).linkStateHeaders().remove(lsa);
-                            ospfInterface.removeLsaFromNeighborMap(((OspfAreaImpl) ospfArea).getLsaKey(lsa));
-                        }
-                    }
-                }
-            }
+            log.debug("OspfChannelHandler sentConfigPacket channel not connected - re try..!!!");
+            this.configPacket = configPacket;
         }
     }
 }
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageDecoder.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageDecoder.java
index baeae99..1d6ae23 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageDecoder.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageDecoder.java
@@ -19,8 +19,10 @@
 import org.jboss.netty.channel.Channel;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.OspfMessage;
 import org.onosproject.ospf.protocol.ospfpacket.OspfMessageReader;
+import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,24 +37,35 @@
     private static final Logger log = LoggerFactory.getLogger(OspfMessageDecoder.class);
 
     @Override
-    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer channelBuffer) throws Exception {
-        log.debug("OspfMessageDecoder::Message received <:> length {}", channelBuffer.readableBytes());
-        log.debug("channelBuffer.readableBytes - decode {}", channelBuffer.readableBytes());
+    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
+        log.debug("OspfMessageDecoder::Message received <:> length {}", buffer.readableBytes());
         if (!channel.isConnected()) {
             log.info("Channel is not connected.");
             return null;
         }
-
         OspfMessageReader messageReader = new OspfMessageReader();
         List<OspfMessage> ospfMessageList = new LinkedList<>();
-
-        while (channelBuffer.readableBytes() > 0) {
-            OspfMessage message = messageReader.readFromBuffer(channelBuffer);
+        while (buffer.readableBytes() >= OspfUtil.MINIMUM_FRAME_LEN) {
+            ChannelBuffer ospfDataBuffer = buffer.readBytes(OspfUtil.MINIMUM_FRAME_LEN);
+            int readableBytes = ospfDataBuffer.readableBytes();
+            OspfMessage message = messageReader.readFromBuffer(ospfDataBuffer);
             if (message != null) {
+                if (ospfDataBuffer.readableBytes() >= OspfUtil.METADATA_LEN) {
+                    ospfDataBuffer.readerIndex(readableBytes - OspfUtil.METADATA_LEN);
+                    log.debug("IsisMessageDecoder::Reading metadata <:> length {}", ospfDataBuffer.readableBytes());
+
+
+                    int interfaceIndex = ospfDataBuffer.readByte();
+                    byte[] sourceIpBytes = new byte[OspfUtil.FOUR_BYTES];
+                    ospfDataBuffer.readBytes(sourceIpBytes, 0, OspfUtil.FOUR_BYTES);
+                    Ip4Address sourceIP = Ip4Address.valueOf(sourceIpBytes);
+
+                    message.setSourceIp(sourceIP);
+                    message.setInterfaceIndex(interfaceIndex);
+                }
                 ospfMessageList.add(message);
             }
         }
-
-        return ospfMessageList;
+        return (ospfMessageList.size() > 0) ? ospfMessageList : null;
     }
 }
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageEncoder.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageEncoder.java
index 95bdcdc..8ac971c 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageEncoder.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfMessageEncoder.java
@@ -17,15 +17,10 @@
 package org.onosproject.ospf.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.onosproject.ospf.controller.OspfInterface;
-import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
-import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
-import org.onosproject.ospf.protocol.ospfpacket.OspfMessageWriter;
-import org.onosproject.ospf.protocol.util.OspfInterfaceState;
-import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,46 +30,15 @@
 public class OspfMessageEncoder extends OneToOneEncoder {
 
     private static final Logger log = LoggerFactory.getLogger(OspfMessageEncoder.class);
-    private OspfInterface ospfInterface;
-
-
-    /**
-     * Creates an instance of OSPF message encoder.
-     */
-    OspfMessageEncoder() {
-    }
-
-    /**
-     * Creates an instance of OSPF message encoder.
-     *
-     * @param ospfInterface OSPF interface instance
-     */
-    OspfMessageEncoder(OspfInterface ospfInterface) {
-        this.ospfInterface = ospfInterface;
-    }
 
     @Override
     protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
 
-        log.debug("Encoding ospfMessage...!!!");
-        if (!(msg instanceof OspfMessage)) {
-            log.debug("Invalid msg.");
-            return msg;
-        }
+        byte[] byteMsg = (byte[]) msg;
+        log.debug("Encoding ospfMessage of length {}", byteMsg.length);
+        ChannelBuffer channelBuffer = ChannelBuffers.buffer(byteMsg.length);
+        channelBuffer.writeBytes(byteMsg);
 
-        OspfMessage ospfMessage = (OspfMessage) msg;
-        OspfMessageWriter messageWriter = new OspfMessageWriter();
-        if (((OspfInterfaceImpl) ospfInterface).state().equals(OspfInterfaceState.POINT2POINT)) {
-            ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
-        }
-        ChannelBuffer buf = messageWriter.writeToBuffer(ospfMessage,
-                                                        ((OspfInterfaceImpl) ospfInterface).state().value(),
-                                                        ospfInterface.interfaceType());
-        log.info("OspfMessageEncoder sending packet of lenght {}", buf.readableBytes());
-        log.debug("OspfMessageEncoder sending packet of lenght {}", buf.readableBytes());
-        log.debug("Sending {} Message to {}, Length :: {}, <=> {}", ospfMessage.ospfMessageType(),
-                  ospfMessage.destinationIp(), buf.readableBytes(), buf.array());
-
-        return buf;
+        return channelBuffer;
     }
 }
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java
index 1233c28..800d571 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java
@@ -28,8 +28,10 @@
 import org.onosproject.ospf.controller.OspfLsa;
 import org.onosproject.ospf.controller.OspfLsaType;
 import org.onosproject.ospf.controller.OspfLsdb;
+import org.onosproject.ospf.controller.OspfMessage;
 import org.onosproject.ospf.controller.OspfNbr;
 import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.OspfPacketType;
 import org.onosproject.ospf.controller.OspfRouter;
 import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
 import org.onosproject.ospf.controller.area.OspfAreaImpl;
@@ -40,7 +42,7 @@
 import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
 import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
 import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
-import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
+import org.onosproject.ospf.protocol.ospfpacket.OspfMessageWriter;
 import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
 import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
 import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
@@ -49,7 +51,6 @@
 import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
 import org.onosproject.ospf.protocol.util.ChecksumCalculator;
 import org.onosproject.ospf.protocol.util.OspfInterfaceState;
-import org.onosproject.ospf.protocol.util.OspfPacketType;
 import org.onosproject.ospf.protocol.util.OspfParameters;
 import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
@@ -181,7 +182,6 @@
      * A link to the OSPF-Area this Neighbor Data Structure belongs to.
      */
     private OspfArea ospfArea;
-    private OspfInterfaceChannelHandler handler;
     private List<TopLevelTlv> topLevelTlvs = new ArrayList<>();
     private List<DeviceInformation> deviceInformationList = new ArrayList<>();
 
@@ -195,12 +195,11 @@
      * @param ipAddr                         IP address
      * @param routerId                       router id
      * @param options                        options
-     * @param handler                        channel handler instance
      * @param topologyForDeviceAndLinkCommon topology for device and link instance
      */
     public OspfNbrImpl(OspfArea paramOspfArea, OspfInterface paramOspfInterface,
                        Ip4Address ipAddr, Ip4Address routerId, int options,
-                       OspfInterfaceChannelHandler handler, TopologyForDeviceAndLink topologyForDeviceAndLinkCommon) {
+                       TopologyForDeviceAndLink topologyForDeviceAndLinkCommon) {
         this.ospfArea = paramOspfArea;
         this.ospfInterface = paramOspfInterface;
         state = OspfNeighborState.DOWN;
@@ -211,7 +210,6 @@
         this.options = options;
         lastDdPacket = new DdPacket();
         routerDeadInterval = paramOspfInterface.routerDeadIntervalTime();
-        this.handler = handler;
         this.topologyForDeviceAndLink = topologyForDeviceAndLinkCommon;
     }
 
@@ -243,6 +241,15 @@
     }
 
     /**
+     * Sets router dead interval.
+     *
+     * @param routerDeadInterval router dead interval
+     */
+    public void setRouterDeadInterval(int routerDeadInterval) {
+        this.routerDeadInterval = routerDeadInterval;
+    }
+
+    /**
      * Have seen a Neighbor, but the Neighbor doesn't know about me.
      *
      * @param ospfHello Hello Packet instance
@@ -313,7 +320,8 @@
                 startRxMtDdTimer(channel);
                 //setting destination ip
                 ddPacket.setDestinationIp(packet.sourceIp());
-                channel.write(ddPacket);
+                byte[] messageToWrite = getMessage(ddPacket);
+                channel.write(messageToWrite);
             } else {
                 state = OspfNeighborState.TWOWAY;
             }
@@ -409,7 +417,8 @@
                 setLastSentDdPacket(ddPacket);
                 getIsMoreBit();
 
-                ch.write(lastSentDdPacket());
+                byte[] messageToWrite = getMessage(lastSentDdPacket);
+                ch.write(messageToWrite);
             } else {
                 // process LSA Vector's List, Add it to LSRequestList.
                 processLsas(payload);
@@ -437,7 +446,8 @@
                 setLastSentDdPacket(ddPacket);
                 getIsMoreBit();
                 ddPacket.setDestinationIp(packet.sourceIp());
-                ch.write(lastSentDdPacket());
+                byte[] messageToWrite = getMessage(lastSentDdPacket);
+                ch.write(messageToWrite);
                 startRxMtDdTimer(ch);
             }
         }
@@ -594,7 +604,8 @@
             //setting destination ip
             ddPacket.setDestinationIp(neighborIpAddr());
             setLastSentDdPacket(ddPacket);
-            ch.write(ddPacket);
+            byte[] messageToWrite = getMessage(ddPacket);
+            ch.write(messageToWrite);
         }
     }
 
@@ -651,7 +662,8 @@
                 getIsMoreBit();
                 //Set the destination IP Address
                 ddPacket.setDestinationIp(dataDescPkt.sourceIp());
-                ch.write(lastSentDdPacket());
+                byte[] messageToWrite = getMessage(lastSentDdPacket());
+                ch.write(messageToWrite);
 
                 startRxMtDdTimer(ch);
             }
@@ -692,7 +704,8 @@
             }
 
             ddPacket.setDestinationIp(dataDescPkt.sourceIp());
-            ch.write(ddPacket);
+            byte[] messageToWrite = getMessage(ddPacket);
+            ch.write(messageToWrite);
         }
     }
 
@@ -753,7 +766,8 @@
                 LsRequest lsRequest = buildLsRequest();
                 //Setting the destination address
                 lsRequest.setDestinationIp(header.sourceIp());
-                ch.write(lsRequest);
+                byte[] messageToWrite = getMessage(lsRequest);
+                ch.write(messageToWrite);
 
                 setLastSentLsrPacket(lsRequest);
                 startRxMtLsrTimer(ch);
@@ -859,7 +873,8 @@
                     //setting destination ip
                     ddPacket.setDestinationIp(neighborIpAddr());
                     setLastSentDdPacket(ddPacket);
-                    ch.write(ddPacket);
+                    byte[] messageToWrite = getMessage(ddPacket);
+                    ch.write(messageToWrite);
                 }
             } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
                 if (!formAdjacencyOrNot()) {
@@ -942,39 +957,55 @@
      */
     private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
         Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
+        Map<String, DeviceInformation> deviceInformationMapForPointToPoint =
+                topologyForDeviceAndLink.deviceInformationMapForPointToPoint();
+        Map<String, DeviceInformation> deviceInformationMapToDelete =
+                topologyForDeviceAndLink.deviceInformationMapToDelete();
         Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
+        Map<String, LinkInformation> linkInformationMapForPointToPoint =
+                topologyForDeviceAndLink.linkInformationMapForPointToPoint();
         OspfRouter ospfRouter = new OspfRouterImpl();
-        log.debug("Device Information in list format along with size {}", deviceInformationMap.size());
-        for (String key : deviceInformationMap.keySet()) {
-            DeviceInformation value = deviceInformationMap.get(key);
-            ospfRouter.setRouterIp(value.routerId());
-            ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
-            ospfRouter.setNeighborRouterId(value.deviceId());
-            OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
-            List<Ip4Address> ip4Addresses = value.interfaceId();
-            ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
-            ospfRouter.setDeviceTed(ospfDeviceTed);
-            ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
-            if (value.isDr()) {
-                ospfRouter.setDr(value.isDr());
-            } else {
-                ospfRouter.setDr(false);
+
+        if (deviceInformationMap.size() != 0) {
+            for (String key : deviceInformationMap.keySet()) {
+                DeviceInformation value = deviceInformationMap.get(key);
+                ospfRouter.setRouterIp(value.routerId());
+                ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
+                ospfRouter.setNeighborRouterId(value.deviceId());
+                OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
+                List<Ip4Address> ip4Addresses = value.interfaceId();
+                ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
+                ospfRouter.setDeviceTed(ospfDeviceTed);
+                ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
+                if (value.isDr()) {
+                    ospfRouter.setDr(value.isDr());
+                } else {
+                    ospfRouter.setDr(false);
+                }
+                int size = value.interfaceId().size();
+                for (int i = 0; i < size; i++) {
+                    ospfRouter.setInterfaceId(value.interfaceId().get(i));
+                }
+                ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
             }
-            int size = value.interfaceId().size();
-            for (int i = 0; i < size; i++) {
-                ospfRouter.setInterfaceId(value.interfaceId().get(i));
+        }
+        if (deviceInformationMapForPointToPoint.size() != 0) {
+            for (String key : deviceInformationMapForPointToPoint.keySet()) {
+                DeviceInformation value = deviceInformationMapForPointToPoint.get(key);
+                ospfRouter.setRouterIp(value.routerId());
+                ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
+                ospfRouter.setNeighborRouterId(value.deviceId());
+                OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
+                List<Ip4Address> ip4Addresses = value.interfaceId();
+                ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
+                ospfRouter.setDeviceTed(ospfDeviceTed);
+                ospfRouter.setOpaque(value.isDr());
+                int size = value.interfaceId().size();
+                for (int i = 0; i < size; i++) {
+                    ospfRouter.setInterfaceId(value.interfaceId().get(i));
+                }
+                ((OspfInterfaceImpl) ospfInterface).addDeviceInformation(ospfRouter);
             }
-            if (value.isAlreadyCreated()) {
-                removeDeviceDetails(value.routerId());
-                OspfRouter ospfRouter1 = new OspfRouterImpl();
-                ospfRouter1.setRouterIp(value.routerId());
-                ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
-                ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
-                ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
-                topologyForDeviceAndLink.removeLinks(value.routerId());
-                handler.removeDeviceInformation(ospfRouter1);
-            }
-            handler.addDeviceInformation(ospfRouter);
         }
         for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
             String key = entry.getKey();
@@ -983,8 +1014,8 @@
             ospfRouterForLink.setInterfaceId(value.interfaceIp());
             ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
             ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
-            OspfLinkTed ospfLinkTed =
-                    topologyForDeviceAndLink.getOspfLinkTedHashMap(value.linkDestinationId().toString());
+            OspfLinkTed ospfLinkTed = topologyForDeviceAndLink.getOspfLinkTedHashMap(
+                    value.linkDestinationId().toString());
             if (ospfLinkTed == null) {
                 ospfLinkTed = new OspfLinkTedImpl();
                 ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
@@ -996,13 +1027,9 @@
                 ospfRouterForLink.setRouterIp(value.linkSourceId());
                 ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
                 try {
-                    handler.addLinkInformation(ospfRouterForLink, ospfLinkTed);
-                    log.debug("LinkId, LinkSrc , LinkDest , LinkInterface values are : "
-                                      + value.linkId() + " , " + value.linkSourceId() + "  , "
-                                      + value.linkDestinationId() + " , "
-                                      + value.interfaceIp());
+                    ((OspfInterfaceImpl) ospfInterface).addLinkInformation(ospfRouterForLink, ospfLinkTed);
                 } catch (Exception e) {
-                    log.debug("Got Exception : {}", e.getMessage());
+                    log.debug("Exception addLinkInformation: " + e.getMessage());
                 }
             }
         }
@@ -1178,11 +1205,31 @@
                 }
             }
         }
+
+        constructDeviceInformationFromDb();
         callDeviceAndLinkAdding(topologyForDeviceAndLink);
+
         return true;
     }
 
     /**
+     * Constructs device and link information from link state database.
+     */
+    private void constructDeviceInformationFromDb() {
+        OspfLsdb database = ospfArea.database();
+        List lsas = database.getAllLsaHeaders(true, true);
+        Iterator iterator = lsas.iterator();
+        while (iterator.hasNext()) {
+            OspfLsa ospfLsa = (OspfLsa) iterator.next();
+            if (ospfLsa.getOspfLsaType().value() == OspfLsaType.ROUTER.value()) {
+                topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
+            } else if (ospfLsa.getOspfLsaType().value() == OspfLsaType.NETWORK.value()) {
+                topologyForDeviceAndLink.addLocalDevice(ospfLsa, ospfInterface, ospfArea);
+            }
+        }
+    }
+
+    /**
      * Checks Link State ID is equal to one of the router's own IP interface addresses.
      *
      * @param linkStateId link state id
@@ -1190,7 +1237,7 @@
      */
     private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
         boolean isLinkStateMatches = false;
-        List<OspfInterface> interfaceLst = ospfArea.getInterfacesLst();
+        List<OspfInterface> interfaceLst = ospfArea.ospfInterfaceList();
         for (OspfInterface ospfInterface : interfaceLst) {
             if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
                 isLinkStateMatches = true;
@@ -1262,7 +1309,8 @@
 
         //setting the destination.
         responseLsUpdate.setDestinationIp(destination);
-        ch.write(responseLsUpdate);
+        byte[] messageToWrite = getMessage(responseLsUpdate);
+        ch.write(messageToWrite);
     }
 
     /**
@@ -1288,7 +1336,8 @@
         ackContent.addLinkStateHeader(ackLsa);
         //setting the destination IP
         ackContent.setDestinationIp(sourceIp);
-        ch.write(ackContent);
+        byte[] messageToWrite = getMessage(ackContent);
+        ch.write(messageToWrite);
     }
 
     /**
@@ -1314,7 +1363,7 @@
         ddSummaryList.clear();
         if (neighborIpAddr.equals(neighborBdr) ||
                 neighborIpAddr.equals(neighborDr)) {
-            handler.neighborChange();
+            ((OspfInterfaceImpl) ospfInterface).neighborChange();
         }
         log.debug("Neighbor Went Down : "
                           + this.neighborIpAddr + " , " + this.neighborId);
@@ -1324,16 +1373,14 @@
         ospfRouter.setInterfaceId(ospfInterface.ipAddress());
         ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
         ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
-        handler.removeDeviceInformation(ospfRouter);
+        ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter);
         removeDeviceDetails(this.neighborIpAddr);
         OspfRouter ospfRouter1 = new OspfRouterImpl();
         ospfRouter1.setRouterIp(this.neighborIpAddr);
         ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
         ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
         ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
-        handler.removeDeviceInformation(ospfRouter1);
-        handler.removeLinkInformation(this);
-        callDeviceAndLinkAdding(topologyForDeviceAndLink);
+        ((OspfInterfaceImpl) ospfInterface).removeDeviceInformation(ospfRouter1);
     }
 
     /**
@@ -1344,13 +1391,12 @@
     private void removeDeviceDetails(Ip4Address routerId) {
         String key = "device:" + routerId;
         topologyForDeviceAndLink.removeDeviceInformationMap(key);
-        topologyForDeviceAndLink.removeLinks(routerId);
     }
 
     /**
      * Starts the inactivity timer.
      */
-    private void startInactivityTimeCheck() {
+    public void startInactivityTimeCheck() {
         if (!inActivityTimerScheduled) {
             log.debug("OSPFNbr::startInactivityTimeCheck");
             inActivityTimeCheckTask = new InternalInactivityTimeCheck();
@@ -1364,7 +1410,7 @@
     /**
      * Stops the inactivity timer.
      */
-    private void stopInactivityTimeCheck() {
+    public void stopInactivityTimeCheck() {
         if (inActivityTimerScheduled) {
             log.debug("OSPFNbr::stopInactivityTimeCheck ");
             exServiceInActivity.shutdown();
@@ -1393,7 +1439,7 @@
     /**
      * Stops the flooding timer.
      */
-    private void stopFloodingTimer() {
+    public void stopFloodingTimer() {
         if (floodingTimerScheduled) {
             log.debug("OSPFNbr::stopFloodingTimer ");
             exServiceFlooding.shutdown();
@@ -1420,7 +1466,7 @@
     /**
      * Stops the Dd Retransmission executor task.
      */
-    private void stopRxMtDdTimer() {
+    public void stopRxMtDdTimer() {
         if (rxmtDdPacketTimerScheduled) {
             exServiceRxmtDDPacket.shutdown();
             rxmtDdPacketTimerScheduled = false;
@@ -1447,7 +1493,7 @@
     /**
      * Stops Ls request retransmission executor task.
      */
-    private void stopRxMtLsrTimer() {
+    public void stopRxMtLsrTimer() {
         if (rxmtLsrTimerScheduled) {
             exServiceRxmtLsr.shutdown();
             rxmtLsrTimerScheduled = false;
@@ -1679,6 +1725,21 @@
         return pendingReTxList;
     }
 
+    /**
+     * Gets message as bytes.
+     *
+     * @param ospfMessage OSPF message
+     * @return OSPF message
+     */
+    private byte[] getMessage(OspfMessage ospfMessage) {
+        OspfMessageWriter messageWriter = new OspfMessageWriter();
+        if (((OspfInterfaceImpl) ospfInterface).state().equals(OspfInterfaceState.POINT2POINT)) {
+            ospfMessage.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+        }
+        return (messageWriter.getMessage(ospfMessage, ospfInterface.interfaceIndex(),
+                                         ((OspfInterfaceImpl) ospfInterface).state().value()));
+    }
+
 
     /**
      * Represents a Task which will do an inactivity time check.
@@ -1720,7 +1781,8 @@
         public void run() {
             if ((ch != null) && ch.isConnected()) {
                 DdPacket ddPacket = lastSentDdPacket();
-                ch.write(ddPacket);
+                byte[] messageToWrite = getMessage(ddPacket);
+                ch.write(messageToWrite);
                 log.debug("Re-Transmit DD Packet .");
             } else {
                 log.debug(
@@ -1748,7 +1810,8 @@
         public void run() {
             if ((ch != null) && ch.isConnected()) {
                 LsRequest lsrPacket = getLastSentLsrPacket();
-                ch.write(lsrPacket);
+                byte[] messageToWrite = getMessage(lsrPacket);
+                ch.write(messageToWrite);
                 log.debug("Re-Transmit LSRequest Packet .");
             } else {
                 log.debug(
@@ -1783,7 +1846,8 @@
                     for (LsUpdate lsupdate : lsUpdateList) {
                         //Pending for acknowledge directly sent it to neighbor
                         lsupdate.setDestinationIp(neighborIpAddr);
-                        channel.write(lsupdate);
+                        byte[] messageToWrite = getMessage(lsupdate);
+                        channel.write(messageToWrite);
                     }
                 }
 
@@ -1799,7 +1863,8 @@
                                 (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
                             lsupdate.setDestinationIp(neighborDr);
                         }
-                        channel.write(lsupdate);
+                        byte[] messageToWrite = getMessage(lsupdate);
+                        channel.write(messageToWrite);
                     }
                 }
             }
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfPipelineFactory.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfPipelineFactory.java
index 394f783..1b1a108 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfPipelineFactory.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfPipelineFactory.java
@@ -18,57 +18,29 @@
 import org.jboss.netty.channel.ChannelPipeline;
 import org.jboss.netty.channel.ChannelPipelineFactory;
 import org.jboss.netty.channel.Channels;
-import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
-import org.jboss.netty.util.ExternalResourceReleasable;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timer;
-import org.onosproject.ospf.controller.OspfArea;
-import org.onosproject.ospf.controller.OspfInterface;
 
 /**
- * Creates a ChannelPipeline for a server-side OSPF channel.
+ * Creates a ChannelPipeline for a client-side OSPF channel.
  */
-public class OspfPipelineFactory implements ChannelPipelineFactory, ExternalResourceReleasable {
-
-    private static final Timer TIMER = new HashedWheelTimer();
-    private Controller controller;
-    private ReadTimeoutHandler readTimeoutHandler;
-    private OspfArea ospfArea;
-    private OspfInterface ospfInterface;
-    private int holdTime = 120 * 1000;
+public class OspfPipelineFactory implements ChannelPipelineFactory {
+    private OspfInterfaceChannelHandler ospfChannelHandler;
 
     /**
-     * Creates an instance of OSPF pipeline factory.
+     * Creates an instance of OSPF channel pipeline factory.
      *
-     * @param controller    controller instance.
-     * @param ospfArea      OSPF area instance.
-     * @param ospfInterface OSPF interface instance.
+     * @param ospfChannelHandler OSPF channel handler instance
      */
-    public OspfPipelineFactory(Controller controller, OspfArea ospfArea, OspfInterface ospfInterface) {
-        super();
-        this.controller = controller;
-        this.ospfArea = ospfArea;
-        this.ospfInterface = ospfInterface;
-        readTimeoutHandler = new ReadTimeoutHandler(TIMER, holdTime);
+    public OspfPipelineFactory(OspfInterfaceChannelHandler ospfChannelHandler) {
+        this.ospfChannelHandler = ospfChannelHandler;
     }
 
     @Override
     public ChannelPipeline getPipeline() throws Exception {
-        OspfInterfaceChannelHandler interfaceHandler = new OspfInterfaceChannelHandler(
-                controller, ospfArea, ospfInterface);
-
         ChannelPipeline pipeline = Channels.pipeline();
-        pipeline.addLast("encoder", new OspfMessageEncoder(ospfInterface));
-        pipeline.addLast("decoder", new OspfMessageDecoder());
-        pipeline.addLast("holdTime", readTimeoutHandler);
-        pipeline.addLast("interfacehandler", interfaceHandler);
+        pipeline.addLast("encoder", new OspfMessageDecoder());
+        pipeline.addLast("decoder", new OspfMessageEncoder());
+        pipeline.addLast("handler", ospfChannelHandler);
 
         return pipeline;
     }
-
-    @Override
-    public void releaseExternalResources() {
-        TIMER.stop();
-    }
-
 }
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/TopologyForDeviceAndLinkImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/TopologyForDeviceAndLinkImpl.java
index e488e31..86dd2cf 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/TopologyForDeviceAndLinkImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/TopologyForDeviceAndLinkImpl.java
@@ -38,6 +38,7 @@
 import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
 import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
 import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
+import org.onosproject.ospf.protocol.util.OspfUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,6 +50,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 
 /**
  * Represents device and link topology information.
@@ -56,7 +58,11 @@
 public class TopologyForDeviceAndLinkImpl implements TopologyForDeviceAndLink {
 
     private static final Logger log = LoggerFactory.getLogger(TopologyForDeviceAndLinkImpl.class);
+    Set<Ip4Address> routerSet = new TreeSet<Ip4Address>();
+    Ip4Address firstValue = Ip4Address.valueOf("0.0.0.0");
     private Map<String, DeviceInformation> deviceInformationMap = new LinkedHashMap();
+    private Map<Ip4Address, List<Ip4Address>> networkLsaMap = new LinkedHashMap();
+    private Map<String, DeviceInformation> deviceInformationMapForPointToPoint = new LinkedHashMap();
     private Map<String, DeviceInformation> deviceInformationMapToDelete = new LinkedHashMap();
     private HashMap<String, Set<OspfLsaLink>> deviceAndLinkInformation = new HashMap();
     private HashMap<String, OspfLinkTed> ospfLinkTedHashMap = new LinkedHashMap();
@@ -64,6 +70,7 @@
     private Ip4Address drRouterOld = Ip4Address.valueOf("0.0.0.0");
     private Ip4Address adRouterId = Ip4Address.valueOf("0.0.0.0");
     private Map<String, LinkInformation> linkInformationMap = new LinkedHashMap();
+    private Map<String, LinkInformation> linkInformationMapForPointToPoint = new LinkedHashMap();
     private List<String> toRemove = new ArrayList<>();
 
     /**
@@ -89,9 +96,31 @@
     }
 
     /**
-     * Gets device information.
+     * Gets deviceInformation as map for Point-To-Point.
      *
-     * @return device information to delete from core
+     * @return deviceInformationMap
+     */
+    public Map<String, DeviceInformation> deviceInformationMapForPointToPoint() {
+        return deviceInformationMapForPointToPoint;
+    }
+
+    /**
+     * Sets deviceInformation as map for Point-To-Point..
+     *
+     * @param key                  key to store device information
+     * @param deviceInformationMap device information instance
+     */
+    public void setDeviceInformationMapForPointToPoint(String key, DeviceInformation deviceInformationMap) {
+        if (deviceInformationMap != null) {
+            this.deviceInformationMapForPointToPoint.put(key, deviceInformationMap);
+        }
+
+    }
+
+    /**
+     * Gets deviceInformation as map.
+     *
+     * @return deviceInformationMap to delete from core
      */
     public Map<String, DeviceInformation> deviceInformationMapToDelete() {
         return deviceInformationMapToDelete;
@@ -103,8 +132,7 @@
      * @param key                          ket used to add in map
      * @param deviceInformationMapToDelete map from device information to remove
      */
-    public void setDeviceInformationMapToDelete(String key,
-                                                DeviceInformation deviceInformationMapToDelete) {
+    public void setDeviceInformationMapToDelete(String key, DeviceInformation deviceInformationMapToDelete) {
         if (deviceInformationMapToDelete != null) {
             this.deviceInformationMapToDelete.put(key, deviceInformationMapToDelete);
         }
@@ -153,6 +181,11 @@
         return linkInformationMap;
     }
 
+    private LinkInformation getLinkInformation(String key) {
+        LinkInformation linkInformation = this.linkInformationMap.get(key);
+        return linkInformation;
+    }
+
     /**
      * Sets link information in map.
      *
@@ -166,9 +199,30 @@
     }
 
     /**
-     * Removes Link Information from map.
+     * Gets linkInformation as map for PointToPoint.
      *
-     * @param key key used to remove from map
+     * @return linkInformationMap
+     */
+    public Map<String, LinkInformation> linkInformationMapForPointToPoint() {
+        return linkInformationMap;
+    }
+
+    /**
+     * Sets linkInformation as map for PointToPoint.
+     *
+     * @param key                key to store link information
+     * @param linkInformationMap link information instance
+     */
+    public void setLinkInformationMapForPointToPoint(String key, LinkInformation linkInformationMap) {
+        if (!this.linkInformationMap.containsKey(key)) {
+            this.linkInformationMap.put(key, linkInformationMap);
+        }
+    }
+
+    /**
+     * Removes Link Information from linkInformationMap.
+     *
+     * @param key key to remove link information
      */
     public void removeLinkInformationMap(String key) {
         if (this.linkInformationMap.containsKey(key)) {
@@ -242,108 +296,136 @@
         List<OspfLsaLink> ospfLsaLinkList = routerLsa.routerLink();
         Iterator iterator = ospfLsaLinkList.iterator();
         Ip4Address advertisingRouterId = routerLsa.advertisingRouter();
-        adRouterId = advertisingRouterId;
         while (iterator.hasNext()) {
             OspfLsaLink ospfLsaLink = (OspfLsaLink) iterator.next();
             Ip4Address linkId = Ip4Address.valueOf(ospfLsaLink.linkId());
             Ip4Address linkData = Ip4Address.valueOf(ospfLsaLink.linkData());
             if (ospfLsaLink.linkType() == 1) {
                 if ((advertisingRouterId.equals(ospfArea.routerId())) || (linkId.equals(ospfArea.routerId()))) {
-                    System.out.println("OspfInterface information will not display in web ");
-                } else {
-                    removeDevice(advertisingRouterId);
-                    removeLinks(advertisingRouterId);
-                    DeviceInformation deviceInformationPointToPoint =
-                            createDeviceInformation(false, linkId, linkId, advertisingRouterId, linkData,
-                                                    ospfArea.areaId(), false);
-                    String key = "device:" + advertisingRouterId;
-                    setDeviceInformationMap(key, deviceInformationPointToPoint);
-                    String linkIdKey = "linkId:" + advertisingRouterId + "-" + linkId;
-                    addLocalLink(linkIdKey, linkData, advertisingRouterId, linkId, true, false);
-                }
-            } else if (ospfLsaLink.linkType() == 2) {
-
-                if ((advertisingRouterId.equals(ospfArea.routerId())) || (linkId.equals(ospfArea.routerId()))) {
-                    log.debug("OspfInterface information will not display in web ");
-                } else {
-                    if (linkId.equals(linkData)) {
-                        if (drRouter.equals(Ip4Address.valueOf("0.0.0.0"))) {
-                            log.debug("drRouter not elected {} ", drRouter.toString());
-                        } else {
-                            if (drRouterOld.equals(linkId)) {
-                                log.debug("drRouterOld same as link id {} ", drRouterOld.toString());
-                            } else {
-                                String key = "device:" + drRouterOld;
-                                DeviceInformation deviceInformation1 = deviceInformation(key);
-                                if (deviceInformation1 != null) {
-                                    deviceInformation1.setAlreadyCreated(true);
-                                    setDeviceInformationMapToDelete(key, deviceInformation1);
-                                    String linkIdKey = "linkId:" + linkId + "-" + deviceInformation1.neighborId();
-                                    addLocalLink(linkIdKey, linkData, linkId, deviceInformation1.neighborId(),
-                                                 true, false);
-                                    String linkIdKey1 = "linkId:" + linkId + "-" + advertisingRouterId;
-                                    addLocalLink(linkIdKey1, linkData, linkId, advertisingRouterId, true, false);
-                                } else {
-                                    DeviceInformation deviceInformationToDelete =
-                                            createDeviceInformation(true, drRouterOld, drRouterOld,
-                                                                    drRouterOld, drRouterOld,
-                                                                    drRouterOld, true);
-                                    setDeviceInformationMapToDelete(key, deviceInformationToDelete);
-                                    String linkIdKey1 = "linkId:" + linkId + "-" + advertisingRouterId;
-                                    addLocalLink(linkIdKey1, linkData, linkId, advertisingRouterId, true, false);
-                                }
-                            }
-                        }
-                        drRouter = linkId;
-                        drRouterOld = linkId;
-                        DeviceInformation deviceInformationForDr =
-                                createDeviceInformation(false, linkId, advertisingRouterId, linkId, linkData,
-                                                        ospfArea.areaId(), true);
-                        String key = "device:" + linkId;
-                        setDeviceInformationMap(key, deviceInformationForDr);
-                        DeviceInformation deviceInformationForAdvertisingRouter =
-                                createDeviceInformation(false, linkId, advertisingRouterId, advertisingRouterId,
-                                                        linkData, ospfArea.areaId(), false);
-                        String key1 = "device:" + advertisingRouterId;
-                        setDeviceInformationMap(key1, deviceInformationForAdvertisingRouter);
-                        if (drRouter.equals(Ip4Address.valueOf("0.0.0.0"))) {
-                            System.out.println("Link will not get create since dr is not valid");
-                            //Need to analysis since this place will not get Dr information
-                            String linkIdKey = "linkId:" + linkId + "-" + advertisingRouterId;
-                            addLocalLink(linkIdKey, linkData, linkId, advertisingRouterId, true, false);
-                        } else {
-                            String linkIdKey = "linkId:" + drRouter + "-" + advertisingRouterId;
-                            addLocalLink(linkIdKey, linkData, drRouter, advertisingRouterId, true, false);
-                        }
-                    } else {
-                        DeviceInformation deviceInformationDrOther =
-                                createDeviceInformation(false, linkId, linkId, advertisingRouterId,
-                                                        linkData, ospfArea.areaId(), false);
+                    if (!advertisingRouterId.equals(ospfArea.routerId())) {
+                        DeviceInformation deviceInformationPointToPoint =
+                                createDeviceInformation(false, linkId, linkId, advertisingRouterId, linkData,
+                                                        ospfArea.areaId(), false);
                         String key = "device:" + advertisingRouterId;
-                        setDeviceInformationMap(key, deviceInformationDrOther);
-                        if (drRouter.equals(Ip4Address.valueOf("0.0.0.0"))) {
-                            String linkIdKey = "linkId:" + linkId + "-" + advertisingRouterId;
-                            addLocalLink(linkIdKey, linkData, linkId, advertisingRouterId, true, false);
-                        } else {
-                            String linkIdKey = "linkId:" + drRouter + "-" + advertisingRouterId;
-                            addLocalLink(linkIdKey, linkData, drRouter, advertisingRouterId, true, false);
-                        }
+                        setDeviceInformationMapForPointToPoint(key, deviceInformationPointToPoint);
                     }
+                } else {
+                    DeviceInformation deviceInformationPointToPoint =
+                            createDeviceInformation(false, linkId, linkId, advertisingRouterId,
+                                                    linkData, ospfArea.areaId(), false);
+                    String key = "device:" + advertisingRouterId;
+                    setDeviceInformationMapForPointToPoint(key, deviceInformationPointToPoint);
+                    String linkIdKey = "linkId:" + advertisingRouterId + "-" + linkId;
+                    addLocalLinkForPointToPoint(linkIdKey, linkData, advertisingRouterId, linkId, true, false);
                 }
             }
         }
     }
 
     /**
-     * Creates Device and Link instance from the NetworkLsa parameters.
+     * Creates device and link instance from the network LSA parameters.
      *
      * @param ospfLsa  OSPF LSA instance
      * @param ospfArea OSPF area instance
      */
     private void createDeviceAndLinkFromNetworkLsa(OspfLsa ospfLsa, OspfArea ospfArea) {
         NetworkLsa networkLsa = (NetworkLsa) ospfLsa;
-        Ip4Address advertisingRouterId = networkLsa.networkMask();
-        System.out.println("AdvertisingRouterId is : " + advertisingRouterId);
+        Ip4Address linkStateId = Ip4Address.valueOf(networkLsa.linkStateId());
+        Set<Ip4Address> drList = networkLsaMap.keySet();
+        try {
+            Ip4Address drToReplace = null;
+            for (Ip4Address drIp : drList) {
+                if (!drIp.equals(linkStateId)) {
+                    if (OspfUtil.sameNetwork(drIp, linkStateId, networkLsa.networkMask())) {
+                        drToReplace = drIp;
+                        String key = "device:" + drToReplace;
+                        DeviceInformation deleteDr = deviceInformation(key);
+                        if (deleteDr != null) {
+                            deleteDr.setAlreadyCreated(true);
+                            setDeviceInformationMapToDelete(key, deleteDr);
+                        }
+
+                        networkLsaMap.remove(drToReplace);
+                        break;
+                    }
+                }
+            }
+            networkLsaMap.put(linkStateId, networkLsa.attachedRouters());
+
+        } catch (Exception e) {
+            log.debug("Error::TopologyForDeviceAndLinkImpl:: {}", e.getMessage());
+        }
+        constructDeviceForBroadCastTopology(ospfArea);
+        disp();
+
+    }
+
+    private void constructDeviceForBroadCastTopology(OspfArea ospfArea) {
+
+        for (Map.Entry<Ip4Address, List<Ip4Address>> entry : networkLsaMap.entrySet()) {
+            Ip4Address key = entry.getKey();
+            DeviceInformation deviceInformationForDr = createDeviceInformation(false, key, key, key,
+                                                                               key, ospfArea.areaId(), true);
+            String dr = "device:" + key;
+            setDeviceInformationMap(dr, deviceInformationForDr);
+            List<Ip4Address> value = entry.getValue();
+            for (Ip4Address connectedRouter : value) {
+                if (!connectedRouter.equals(ospfArea.routerId())) {
+                    DeviceInformation deviceInformationAttachedRouters =
+                            createDeviceInformation(false, connectedRouter, key, connectedRouter,
+                                                    key, ospfArea.areaId(), false);
+                    String attachedRouters = "device:" + connectedRouter;
+                    setDeviceInformationMap(attachedRouters, deviceInformationAttachedRouters);
+                    String linkIdKey = "linkId:" + key + "-" + connectedRouter;
+                    addLocalLink(linkIdKey, key, key, connectedRouter, true, false);
+                }
+            }
+        }
+
+    }
+
+    private void disp() {
+        for (String key : deviceInformationMap.keySet()) {
+            DeviceInformation deviceInformation = deviceInformationMap.get(key);
+            log.debug("************************************************************************");
+            log.debug("DeviceInfoList RouterId is : {} and neighbour is  {} and linkdata {}",
+                      deviceInformation.routerId(), deviceInformation.neighborId(), deviceInformation.interfaceId());
+        }
+
+        for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
+            String linkDetail = entry.getKey();
+            log.debug("Link From and to is  " + linkDetail);
+        }
+        log.debug("Devices Needs to delete from Core are  : " + deviceInformationMapToDelete.size());
+        for (String key : deviceInformationMapToDelete.keySet()) {
+            DeviceInformation value = deviceInformationMapToDelete.get(key);
+            if (value.isAlreadyCreated()) {
+                log.debug("Device is deleted from list " + value.routerId());
+            }
+        }
+    }
+
+    private void getLinksToDelete(Set<Ip4Address> list, Ip4Address value, OspfArea ospfArea) {
+
+        Iterator iterator = list.iterator();
+
+        while (iterator.hasNext()) {
+            Ip4Address secondValue = (Ip4Address) iterator.next();
+            if (!value.equals("0.0.0.0")) {
+                if ((!value.equals(secondValue))) {
+                    if ((!secondValue.equals(ospfArea.routerId()))) {
+                        String key = "link:" + value.toString() + "-" + secondValue.toString();
+                        String key1 = "link:" + secondValue.toString() + "-" + value.toString();
+                        LinkInformation linkDetails = getLinkInformation(key);
+                        LinkInformation linkDetailsOther = getLinkInformation(key1);
+                        linkInformationMapForPointToPoint.put(key, linkDetails);
+                        linkInformationMapForPointToPoint.put(key1, linkDetailsOther);
+                    }
+                }
+            }
+
+        }
+
     }
 
     /**
@@ -444,13 +526,40 @@
     }
 
     /**
+     * Adds link information to LinkInformationMap for PointToPoint.
+     *
+     * @param advertisingRouter    advertising router
+     * @param linkData             link data
+     * @param linkSrc              link source
+     * @param linkDest             link destination
+     * @param opaqueEnabled        whether opaque is enabled or not
+     * @param linkSrcIdNotRouterId whether link is source id or router id
+     */
+    public void addLocalLinkForPointToPoint(String advertisingRouter, Ip4Address linkData, Ip4Address linkSrc,
+                                            Ip4Address linkDest, boolean opaqueEnabled, boolean linkSrcIdNotRouterId) {
+        String linkKey = "link:";
+        LinkInformation linkInformation = new LinkInformationImpl();
+        linkInformation.setLinkId(advertisingRouter);
+        linkInformation.setLinkSourceId(linkSrc);
+        linkInformation.setLinkDestinationId(linkDest);
+        linkInformation.setAlreadyCreated(false);
+        linkInformation.setLinkSrcIdNotRouterId(linkSrcIdNotRouterId);
+        linkInformation.setInterfaceIp(linkData);
+        if (linkDest != null) {
+            linkInformation.setLinkSrcIdNotRouterId(false);
+        }
+        linkKey = linkKey + "-" + linkSrc + "-" + linkDest;
+        setLinkInformationMapForPointToPoint(linkKey, linkInformation);
+    }
+
+    /**
      * Removes links from LinkInformationMap.
      *
      * @param routerId router id
      */
     public void removeLinks(Ip4Address routerId) {
-        Map<String, LinkInformation> linkInformationMaplocal = linkInformationMap;
-        if (linkInformationMaplocal != null) {
+        Map<String, LinkInformation> linkInformationMapLocal = linkInformationMap;
+        if (linkInformationMapLocal != null) {
             for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
                 String key = entry.getKey();
                 boolean check = key.contains(routerId.toString());
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaWrapperImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaWrapperImpl.java
index 42f05cd..a883f72 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaWrapperImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaWrapperImpl.java
@@ -49,6 +49,15 @@
     private int binNumber = -1;
     private OspfInterface ospfInterface;
     private LsdbAge lsdbAge;
+    private int ageCounterRollOverWhenAdded;
+
+    public int getAgeCounterRollOverWhenAdded() {
+        return ageCounterRollOverWhenAdded;
+    }
+
+    public void setAgeCounterRollOverWhenAdded(int ageCounterRollOverWhenAdded) {
+        this.ageCounterRollOverWhenAdded = ageCounterRollOverWhenAdded;
+    }
 
     /**
      * Gets the LSA type.
@@ -318,6 +327,8 @@
 
         if (currentAge >= OspfParameters.MAXAGE) {
             return OspfParameters.MAXAGE;
+        } else if ((currentAge == lsaAgeReceived) && ageCounterRollOverWhenAdded != lsdbAge.getAgeCounterRollOver()) {
+            return OspfParameters.MAXAGE;
         }
 
         return currentAge;
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsdbAgeImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsdbAgeImpl.java
index 24bb717..348de07 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsdbAgeImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsdbAgeImpl.java
@@ -41,7 +41,7 @@
 
     private static final Logger log =
             LoggerFactory.getLogger(LsdbAgeImpl.class);
-    protected int ageCounter = 0;
+    protected static int ageCounter = 0;
     private InternalAgeTimer dbAgeTimer;
     private ScheduledExecutorService exServiceage;
     // creating age bins of MAXAGE
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java
index 3df627d..f76a4db 100644
--- a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java
@@ -267,6 +267,7 @@
         lsaWrapper.setLsaHeader(newLsa);
         lsaWrapper.setLsaAgeReceived(newLsa.age());
         lsaWrapper.setAgeCounterWhenReceived(lsdbAge.getAgeCounter());
+        lsaWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.getAgeCounterRollOver());
         lsaWrapper.setIsSelfOriginated(isSelfOriginated);
         lsaWrapper.setIsSelfOriginated(isSelfOriginated);
         lsaWrapper.setOspfInterface(ospfInterface);
