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
new file mode 100755
index 0000000..aac1322
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfInterfaceChannelHandler.java
@@ -0,0 +1,1400 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
+import org.jboss.netty.handler.timeout.ReadTimeoutException;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.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.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.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.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.
+ */
+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 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() {
+
+    }
+
+    /**
+     * Creates an instance of OSPF channel handler.
+     *
+     * @param controller    controller instance
+     * @param ospfArea      ospf area instance
+     * @param ospfInterface ospf interface instance
+     */
+    public OspfInterfaceChannelHandler(Controller controller, OspfArea ospfArea, OspfInterface ospfInterface) {
+
+        this.ospfArea = ospfArea;
+        this.ospfInterface = ospfInterface;
+        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();
+    }
+
+    /**
+     * Represents an interface is up and connected.
+     *
+     * @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();
+            }
+
+        }
+        // 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.
+     *
+     * @param ch channel instance
+     * @throws Exception might throws exception
+     */
+    public void backupSeen(Channel ch) throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::backupSeen ");
+        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.WAITING) {
+            electRouter(ch);
+        }
+    }
+
+    /**
+     * Gets called when no hello message received for particular period.
+     *
+     * @param ch channel instance
+     * @throws Exception might throws exception
+     */
+    public void waitTimer(Channel ch) throws Exception {
+        log.debug("OSPFInterfaceChannelHandler::waitTimer ");
+        //section 9.4
+        if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.WAITING) {
+            electRouter(ch);
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent evt) throws Exception {
+        log.info("OSPF channelConnected from {}", evt.getChannel().getRemoteAddress());
+        channel = evt.getChannel();
+        interfaceUp();
+        startDelayedAckTimer();
+    }
+
+    @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());
+            }
+        } 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());
+        }
+    }
+
+    @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());
+            if (ospfMessageList != null) {
+                for (OspfMessage ospfMessage : ospfMessageList) {
+                    processOSPFMessage(ospfMessage, ctx);
+                }
+            } else {
+                log.debug("OspfChannelHandler::OspfMessages Null List...!!");
+            }
+        }
+        if (message instanceof OspfMessage) {
+            OspfMessage ospfMessage = (OspfMessage) message;
+            log.debug("OspfChannelHandler::OspfMessages received...!!");
+            processOSPFMessage(ospfMessage, ctx);
+        }
+    }
+
+    /**
+     * 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(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;
+            }
+        } 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));
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaQueueConsumer.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaQueueConsumer.java
new file mode 100755
index 0000000..977ec35
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsaQueueConsumer.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.lsdb;
+
+import org.jboss.netty.channel.Channel;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLsaType;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
+import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
+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.concurrent.BlockingQueue;
+
+/**
+ * Consumes LSA from the Queue and processes it.
+ * Its a producer consumer implementation using Blocking queue.
+ */
+public class LsaQueueConsumer implements Runnable {
+    private static final Logger log = LoggerFactory.getLogger(LsaQueueConsumer.class);
+    private BlockingQueue queue = null;
+    private Channel channel;
+    private OspfArea ospfArea;
+
+    /**
+     * Creates an instance of LSA queue consumer.
+     *
+     * @param queue    queue instance
+     * @param channel  netty channel instance
+     * @param ospfArea OSPF area instance
+     */
+    public LsaQueueConsumer(BlockingQueue queue, Channel channel, OspfArea ospfArea) {
+        this.queue = queue;
+        this.channel = channel;
+        this.ospfArea = ospfArea;
+    }
+
+    /**
+     * Threads run method.
+     */
+    public void run() {
+        log.debug("LSAQueueConsumer:run...!!!");
+        try {
+            while (true) {
+                if (!queue.isEmpty()) {
+                    LsaWrapper wrapper = (LsaWrapper) queue.take();
+                    String lsaProcessing = wrapper.lsaProcessing();
+                    switch (lsaProcessing) {
+                        case OspfParameters.VERIFYCHECKSUM:
+                            log.debug("LSAQueueConsumer: Message - " + OspfParameters.VERIFYCHECKSUM + " consumed.");
+                            processVerifyChecksum(wrapper);
+                            break;
+                        case OspfParameters.REFRESHLSA:
+                            log.debug("LSAQueueConsumer: Message - " + OspfParameters.REFRESHLSA + " consumed.");
+                            processRefreshLsa(wrapper);
+                            break;
+                        case OspfParameters.MAXAGELSA:
+                            log.debug("LSAQueueConsumer: Message - " + OspfParameters.MAXAGELSA + " consumed.");
+                            processMaxAgeLsa(wrapper);
+                            break;
+                        default:
+                            log.debug("Unknown command to process the LSA in queue ...!!!");
+                            break;
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            log.debug("Error::LSAQueueConsumer::{}", e.getMessage());
+        }
+    }
+
+    /**
+     * Processes verify checksum - checkAges.
+     *
+     * @param wrapper LSA wrapper instance
+     */
+    private void processVerifyChecksum(LsaWrapper wrapper) throws Exception {
+        ChecksumCalculator checkSum = new ChecksumCalculator();
+        if (!checkSum.isValidLsaCheckSum(wrapper.ospfLsa(), ((LsaWrapperImpl) wrapper).lsaHeader().lsType(),
+                                         OspfUtil.LSAPACKET_CHECKSUM_POS1,
+                                         OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
+            log.debug("LSAQueueConsumer::Checksum mismatch. Received LSA packet type {} ",
+                      ((LsaWrapperImpl) wrapper).lsaHeader().lsType());
+
+            //Checksum Invalid
+            //RFC 2328 Restart the Router.
+            //Currently we are not restarting. We are not handling this case.
+        }
+    }
+
+    /**
+     * Process refresh LSA.
+     *
+     * @param wrapper LSA wrapper instance
+     */
+    private void processRefreshLsa(LsaWrapper wrapper) throws Exception {
+        if (wrapper.isSelfOriginated()) { //self originated
+            //set the destination
+            OspfInterface ospfInterface = wrapper.ospfInterface();
+            if (ospfInterface != null) {
+                LsaHeader header = ((LsaWrapperImpl) wrapper).lsaHeader();
+                header.setAge(wrapper.currentAge());
+                if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) {
+                    if (header.lsType() == OspfLsaType.ROUTER.value()) {
+                        RouterLsa routerLsa = ((OspfAreaImpl) ospfArea).buildRouterLsa(ospfInterface);
+                        ((OspfAreaImpl) ospfArea).addLsa(routerLsa, true, ospfInterface);
+                        ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(routerLsa);
+                    } else if (header.lsType() == OspfLsaType.NETWORK.value()) {
+                        if (ospfInterface.listOfNeighbors().size() > 0) {
+                            NetworkLsa networkLsa = ((OspfAreaImpl) ospfArea).buildNetworkLsa(
+                                    ospfInterface.ipAddress(), ospfInterface.ipNetworkMask());
+                            ospfArea.addLsa(networkLsa, true, ospfInterface);
+                            ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(networkLsa);
+                        }
+                    }
+                }
+
+                if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR ||
+                        ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT ||
+                        ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER) {
+                    ospfArea.refreshArea(ospfInterface);
+                }
+                log.debug("LSAQueueConsumer: processRefreshLsa - Flooded SelfOriginated LSA {}",
+                          ((LsaWrapperImpl) wrapper).lsaHeader());
+            }
+        }
+    }
+
+    /**
+     * Process max age LSA.
+     *
+     * @param wrapper LSA wrapper instance
+     */
+    private void processMaxAgeLsa(LsaWrapper wrapper) {
+        //set the destination
+        OspfInterface ospfInterface = wrapper.ospfInterface();
+        if (ospfInterface != null) {
+            LsaHeader header = (LsaHeader) wrapper.ospfLsa().lsaHeader();
+            header.setAge(OspfParameters.MAXAGE);
+            ((LsaWrapperImpl) wrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
+            if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR ||
+                    ((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT) {
+                //remove from db
+                ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(((LsaWrapperImpl) wrapper).lsaHeader());
+                ((OspfAreaImpl) ospfArea).deleteLsa(((LsaWrapperImpl) wrapper).lsaHeader());
+            } else {
+                ((OspfAreaImpl) ospfArea).deleteLsa(((LsaWrapperImpl) wrapper).lsaHeader());
+            }
+            log.debug("LSAQueueConsumer: processMaxAgeLsa - Flooded SelfOriginated-Max Age LSA {}",
+                      ((LsaWrapperImpl) wrapper).lsaHeader());
+        }
+    }
+
+    /**
+     * Sets the channel.
+     *
+     * @param channel channel instance
+     */
+    public void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+}
\ No newline at end of file
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
new file mode 100755
index 0000000..29af7c3
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/LsdbAgeImpl.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.lsdb;
+
+import com.google.common.base.Objects;
+import org.jboss.netty.channel.Channel;
+import org.onosproject.ospf.controller.LsaBin;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.LsdbAge;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of LSDB Aging process.
+ */
+public class LsdbAgeImpl implements LsdbAge {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(LsdbAgeImpl.class);
+    protected int ageCounter = 0;
+    private InternalAgeTimer dbAgeTimer;
+    private ScheduledExecutorService exServiceage;
+    // creating age bins of MAXAGE
+    private Map<Integer, LsaBin> ageBins = new ConcurrentHashMap<>(OspfParameters.MAXAGE);
+    private LsaBin maxAgeBin = new LsaBinImpl(OspfParameters.MAXAGE);
+    private int ageCounterRollOver = 0;
+    private Channel channel = null;
+    private LsaQueueConsumer queueConsumer = null;
+    private BlockingQueue<LsaWrapper> lsaQueue = new ArrayBlockingQueue(1024);
+    private OspfArea ospfArea = null;
+
+
+    /**
+     * Creates an instance of LSDB age.
+     *
+     * @param ospfArea OSPF area instance
+     */
+    public LsdbAgeImpl(OspfArea ospfArea) {
+        // create LSBin's in the HashMap.
+        for (int i = 0; i < OspfParameters.MAXAGE; i++) {
+            LsaBin lsaBin = new LsaBinImpl(i);
+            ageBins.put(i, lsaBin);
+        }
+        this.ospfArea = ospfArea;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LsdbAgeImpl that = (LsdbAgeImpl) o;
+        return Objects.equal(ageBins, that.ageBins) &&
+                Objects.equal(ageCounter, that.ageCounter) &&
+                Objects.equal(ageCounterRollOver, that.ageCounterRollOver) &&
+                Objects.equal(lsaQueue, lsaQueue);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(ageBins, ageCounter, ageCounterRollOver, lsaQueue);
+    }
+
+    /**
+     * Adds LSA to bin.
+     *
+     * @param binKey key to store in bin
+     * @param lsaBin LSA bin instance
+     */
+    public void addLsaBin(Integer binKey, LsaBin lsaBin) {
+        if (!ageBins.containsKey(binKey)) {
+            ageBins.put(binKey, lsaBin);
+        }
+    }
+
+    /**
+     * Gets LSA from Bin.
+     *
+     * @param binKey key
+     * @return bin instance
+     */
+    public LsaBin getLsaBin(Integer binKey) {
+
+        return ageBins.get(binKey);
+    }
+
+    /**
+     * Adds the LSA to maxAge bin.
+     *
+     * @param key     key
+     * @param wrapper wrapper instance
+     */
+    public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
+        maxAgeBin.addOspfLsa(key, wrapper);
+    }
+
+    /**
+     * Removes LSA from Bin.
+     *
+     * @param lsaWrapper wrapper instance
+     */
+    public void removeLsaFromBin(LsaWrapper lsaWrapper) {
+        if (ageBins.containsKey(lsaWrapper.binNumber())) {
+            LsaBin lsaBin = ageBins.get(lsaWrapper.binNumber());
+            lsaBin.removeOspfLsa(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
+                    lsaWrapper).lsaHeader()), lsaWrapper);
+        }
+    }
+
+    /**
+     * Starts the aging timer and queue consumer.
+     */
+    public void startDbAging() {
+        startDbAgeTimer();
+        queueConsumer = new LsaQueueConsumer(lsaQueue, channel, ospfArea);
+        new Thread(queueConsumer).start();
+    }
+
+
+    /**
+     * Gets called every 1 second as part of the timer.
+     */
+    public void ageLsaAndFlood() {
+        //every 5 mins checksum validation
+        checkAges();
+        //every 30 mins - flood LSA
+        refreshLsa();
+        //every 60 mins - flood LSA
+        maxAgeLsa();
+
+        if (ageCounter == OspfParameters.MAXAGE) {
+            ageCounter = 0;
+            ageCounterRollOver++;
+        } else {
+            //increment age bin
+            ageCounter++;
+        }
+    }
+
+    /**
+     * If the LSA have completed the MaxAge - they are moved called stop aging and flooded.
+     */
+    public void maxAgeLsa() {
+        if (ageCounter == 0) {
+            return;
+        }
+        //Get from Age Bins
+        LsaBin lsaBin = ageBins.get(ageCounter - 1);
+        if (lsaBin == null) {
+            return;
+        }
+        Map lsaBinMap = lsaBin.listOfLsa();
+        for (Object key : lsaBinMap.keySet()) {
+            LsaWrapper lsa = (LsaWrapper) lsaBinMap.get((String) key);
+            if (lsa.currentAge() == OspfParameters.MAXAGE) {
+                lsa.setLsaProcessing(OspfParameters.MAXAGELSA);
+                log.debug("Lsa picked for maxage flooding. Age Counter: {}, AgeCounterRollover: {}, " +
+                                  "AgeCounterRollover WhenAddedToDb: {}, LSA Type: {}, LSA Key: {}",
+                          ageCounter, ageCounterRollOver, lsa.currentAge(), lsa.lsaType(), key);
+                //add it to lsaQueue for processing
+                try {
+                    lsaQueue.put(lsa);
+                    //remove from bin
+                    lsaBin.removeOspfLsa((String) key, lsa);
+                } catch (InterruptedException e) {
+                    log.debug("Error::LSDBAge::maxAgeLsa::{}", e.getMessage());
+                }
+            }
+        }
+
+        //Get from maxAgeBin
+        Map lsaMaxAgeBinMap = maxAgeBin.listOfLsa();
+        for (Object key : lsaMaxAgeBinMap.keySet()) {
+            LsaWrapper lsa = (LsaWrapper) lsaMaxAgeBinMap.get((String) key);
+            lsa.setLsaProcessing(OspfParameters.MAXAGELSA);
+            log.debug("Lsa picked for maxage flooding. Age Counter: {}, LSA Type: {}, LSA Key: {}",
+                      ageCounter, lsa.lsaType(), key);
+            //add it to lsaQueue for processing
+            try {
+                lsaQueue.put(lsa);
+                //remove from bin
+                maxAgeBin.removeOspfLsa((String) key, lsa);
+            } catch (InterruptedException e) {
+                log.debug("Error::LSDBAge::maxAgeLsa::{}", e.getMessage());
+            }
+        }
+    }
+
+
+    /*
+     * If the LSA is in age bin of 1800 - it's pushed into refresh list.
+     */
+    public void refreshLsa() {
+        int binNumber;
+        if (ageCounter < OspfParameters.LSREFRESHTIME) {
+            binNumber = ageCounter + OspfParameters.LSREFRESHTIME;
+        } else {
+            binNumber = ageCounter - OspfParameters.LSREFRESHTIME;
+        }
+        LsaBin lsaBin = ageBins.get(binNumber);
+        if (lsaBin == null) {
+            return;
+        }
+        Map lsaBinMap = lsaBin.listOfLsa();
+        for (Object key : lsaBinMap.keySet()) {
+            LsaWrapper lsa = (LsaWrapper) lsaBinMap.get((String) key);
+            try {
+                if (lsa.isSelfOriginated()) {
+                    log.debug("Lsa picked for refreshLsa. binNumber: {}, LSA Type: {}, LSA Key: {}",
+                              binNumber, lsa.lsaType(), key);
+                    lsa.setLsaProcessing(OspfParameters.REFRESHLSA);
+                    lsaQueue.put(lsa);
+                    //remove from bin
+                    lsaBin.removeOspfLsa((String) key, lsa);
+                }
+            } catch (InterruptedException e) {
+                log.debug("Error::LSDBAge::refreshLsa::{}", e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Verify the checksum for the LSAs who are in bins of 300 and it's multiples.
+     */
+    public void checkAges() {
+        //evry 5 min age counter + multiples of 300
+        for (int age = OspfParameters.CHECKAGE; age < OspfParameters.MAXAGE;
+             age += OspfParameters.CHECKAGE) {
+            LsaBin lsaBin = ageBins.get(age2Bin(age));
+            if (lsaBin == null) {
+                continue;
+            }
+            Map lsaBinMap = lsaBin.listOfLsa();
+            for (Object key : lsaBinMap.keySet()) {
+                LsaWrapper lsa = (LsaWrapper) lsaBinMap.get((String) key);
+                lsa.setLsaProcessing(OspfParameters.VERIFYCHECKSUM);
+                try {
+                    lsaQueue.put(lsa);
+                } catch (InterruptedException e) {
+                    log.debug("Error::LSDBAge::checkAges::{}", e.getMessage());
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Starts DB age timer method start the aging task.
+     */
+    private void startDbAgeTimer() {
+        log.debug("OSPFNbr::startWaitTimer");
+        dbAgeTimer = new InternalAgeTimer();
+        //from 1 sec
+        exServiceage = Executors.newSingleThreadScheduledExecutor();
+        exServiceage.scheduleAtFixedRate(dbAgeTimer, OspfParameters.AGECOUNTER,
+                                         OspfParameters.AGECOUNTER, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Stops the aging task.
+     */
+    private void stopDbAgeTimer() {
+        log.debug("OSPFNbr::stopWaitTimer ");
+        exServiceage.shutdown();
+    }
+
+
+    /**
+     * Gets the netty channel.
+     *
+     * @return netty channel
+     */
+    public Channel getChannel() {
+        return channel;
+    }
+
+    /**
+     * Sets the netty channel.
+     *
+     * @param channel netty channel
+     */
+    public void setChannel(Channel channel) {
+
+        this.channel = channel;
+        if (queueConsumer != null) {
+            queueConsumer.setChannel(channel);
+        }
+    }
+
+    /**
+     * Gets the age counter.
+     *
+     * @return ageCounter
+     */
+    public int getAgeCounter() {
+        return ageCounter;
+    }
+
+    /**
+     * Gets the age counter roll over value.
+     *
+     * @return the age counter roll over value
+     */
+    public int getAgeCounterRollOver() {
+        return ageCounterRollOver;
+    }
+
+    /**
+     * Gets the max age bin.
+     *
+     * @return lsa bin instance
+     */
+    public LsaBin getMaxAgeBin() {
+        return maxAgeBin;
+    }
+
+    /**
+     * Gets the bin number.
+     *
+     * @param x Can be either age or ageCounter
+     * @return bin number.
+     */
+    public int age2Bin(int x) {
+        if (x <= ageCounter) {
+            return (ageCounter - x);
+        } else {
+            return ((OspfParameters.MAXAGE - 1) + (ageCounter - x));
+        }
+    }
+
+    /**
+     * Runnable task which runs every second and calls aging process.
+     */
+    private class InternalAgeTimer implements Runnable {
+
+        /**
+         * Constructor.
+         */
+        InternalAgeTimer() {
+            log.debug("Starts::LsdbAge::AgeTimer...!!! ");
+        }
+
+        @Override
+        public void run() {
+            ageLsaAndFlood();
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/package-info.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/package-info.java
new file mode 100755
index 0000000..91ebbb5
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of the OSPF controller.
+ */
+package org.onosproject.ospf.controller;
\ No newline at end of file
