diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
index 1472082..654c79d 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -14,7 +14,6 @@
  * limitations under the License.
  *
  */
-
 package org.onosproject.dhcprelay;
 
 import com.google.common.collect.HashMultimap;
@@ -42,7 +41,6 @@
 import org.onlab.packet.VlanId;
 import org.onlab.packet.dhcp.Dhcp6RelayOption;
 import org.onlab.packet.dhcp.Dhcp6InterfaceIdOption;
-import org.onlab.packet.dhcp.Dhcp6Option;
 import org.onlab.packet.dhcp.Dhcp6IaNaOption;
 import org.onlab.packet.dhcp.Dhcp6IaTaOption;
 import org.onlab.packet.dhcp.Dhcp6IaPdOption;
@@ -50,6 +48,7 @@
 import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
 import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
 import org.onlab.packet.dhcp.Dhcp6Duid;
+import org.onlab.packet.DHCP6.MsgType;
 import org.onlab.util.HexString;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
@@ -100,7 +99,7 @@
 import org.slf4j.LoggerFactory;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
-
+import org.onosproject.dhcprelay.Dhcp6HandlerUtil.InternalPacket;
 
 import java.nio.ByteBuffer;
 import java.util.List;
@@ -108,9 +107,8 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.ArrayList;
+
 import java.util.concurrent.atomic.AtomicInteger;
-
-
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
@@ -181,8 +179,20 @@
 
     private Boolean dhcpFpmEnabled = false;
 
+    private Dhcp6HandlerUtil dhcp6HandlerUtil = new Dhcp6HandlerUtil();
+
     private List<DhcpServerInfo> defaultServerInfoList = Lists.newArrayList();
     private List<DhcpServerInfo> indirectServerInfoList = Lists.newArrayList();
+    private class IpAddressInfo {
+        Ip6Address ip6Address;
+        long    prefTime;
+    }
+    private class PdPrefixInfo {
+        IpPrefix pdPrefix;
+        long    prefTime;
+    }
+    protected int dhcp6PollInterval = 24 * 3600; // 24 hr period
+
 
 
     // CLIENT message types
@@ -278,16 +288,19 @@
         Ethernet receivedPacket = context.inPacket().parsed();
 
         if (!configured()) {
-            log.warn("Missing DHCP6 relay server config. Abort packet processing");
-            log.trace("dhcp6 payload {}", dhcp6Payload);
-
+            log.warn("Missing DHCP6 relay server config. Abort packet processing dhcp6 payload {}", dhcp6Payload);
             return;
         }
+        byte msgTypeVal = dhcp6Payload.getMsgType();
+        MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
+        log.debug("msgType is {}", msgType);
 
-        byte msgType = dhcp6Payload.getMsgType();
 
         ConnectPoint inPort = context.inPacket().receivedFrom();
 
+        if (inPort == null) {
+            log.warn("incomming ConnectPoint is null");
+        }
         Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
         //ignore the packets if dhcp client interface is not configured on onos.
         if (receivingInterfaces.isEmpty()) {
@@ -295,27 +308,25 @@
             return;
         }
 
+        if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
 
-        if (MSG_TYPE_FROM_CLIENT.contains(msgType)) {
-            InternalPacket ethernetClientPacket =
+            List<InternalPacket> ethernetClientPacket =
                     processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
-            if (ethernetClientPacket != null) {
-                forwardPacket(ethernetClientPacket);
+            for (InternalPacket internalPacket : ethernetClientPacket) {
+                forwardPacket(internalPacket);
             }
-
-        } else if (MSG_TYPE_FROM_SERVER.contains(msgType)) {
-            log.debug("calling processDhcp6PacketFromServer with RELAY_REPL", msgType);
+        } else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
+            log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}", msgTypeVal);
             InternalPacket ethernetPacketReply =
                     processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
             if (ethernetPacketReply != null) {
                 forwardPacket(ethernetPacketReply);
             }
         } else {
-            log.warn("DHCP type {} not supported yet", msgType);
+            log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
         }
     }
 
-
     /**
      * Checks if this app has been configured.
      *
@@ -335,19 +346,7 @@
         // Do nothing here
     }
 
-    // the new class the contains Ethernet packet and destination port, kind of like adding
-    // internal header to the packet
-    private class InternalPacket {
-        Ethernet packet;
-        ConnectPoint destLocation;
-        public InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
-            packet = newPacket;
-            destLocation = newLocation;
-        }
-        void setLocation(ConnectPoint newLocation) {
-            destLocation = newLocation;
-        }
-    }
+
 
     //forward the packet to ConnectPoint where the DHCP server is attached.
     private void forwardPacket(InternalPacket packet) {
@@ -364,168 +363,17 @@
         } // if
     }
 
-    /**
-     * Check if the host is directly connected to the network or not.
-     *
-     * @param dhcp6Payload the dhcp6 payload
-     * @return true if the host is directly connected to the network; false otherwise
-     */
-    private boolean directlyConnected(DHCP6 dhcp6Payload) {
-        log.debug("directlyConnected enters");
-
-        if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
-                dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
-            log.debug("directlyConnected true. MsgType {}", dhcp6Payload.getMsgType());
-
-            return true;
-        }
-
-        // Regardless of relay-forward or relay-replay, check if we see another relay message
-        DHCP6 dhcp6Payload2 = dhcp6PacketFromRelayPacket(dhcp6Payload);
-        if (dhcp6Payload2 != null) {
-            if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELAY_FORW.value()) {
-                log.debug("directlyConnected  false. 1st realy-foward, 2nd MsgType {}", dhcp6Payload2.getMsgType());
-                return false;
-            } else {
-                // relay-reply
-                if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
-                    log.debug("directlyConnected  true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
-                    return true;  // must be directly connected
-                } else {
-                    log.debug("directlyConnected  false. 1st relay-reply, 2nd relay-reply MsgType {}",
-                               dhcp6Payload2.getMsgType());
-                    return false;  // must be indirectly connected
-                }
-            }
-        } else {
-            log.debug("directlyConnected  true.");
-            return true;
-        }
-    }
-
-    /**
-     * extract DHCP6 payload from dhcp6 relay message within relay-forwrd/reply.
-     *
-     * @param dhcp6 dhcp6 relay-reply or relay-foward
-     * @return dhcp6Packet dhcp6 packet extracted from relay-message
-     */
-    private DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
-        log.debug("dhcp6PacketFromRelayPacket  enters. dhcp6 {}", dhcp6);
-
-        // extract the relay message if exist
-        DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
-                    .filter(opt -> opt instanceof Dhcp6RelayOption)
-                    .map(BasePacket::getPayload)
-                    .map(pld -> (DHCP6) pld)
-                    .findFirst()
-                    .orElse(null);
 
 
-        if (dhcp6Payload == null) {
-            // Can't find dhcp payload
-            log.debug("Can't find dhcp6 payload from relay message");
-        } else {
-            log.debug("dhcp6 payload found from relay message {}", dhcp6Payload);
-        }
-
-        return dhcp6Payload;
-    }
-
-    /**
-     * find the leaf DHCP6 packet from multi-level relay packet.
-     *
-     * @param relayPacket dhcp6 relay packet
-     * @return leafPacket non-relay dhcp6 packet
-     */
-    private DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
-        DHCP6 dhcp6Parent = relayPacket;
-        DHCP6 dhcp6Child = null;
-
-        log.debug("getDhcp6Leaf entered.");
-        while (dhcp6Parent != null) {
-            dhcp6Child = dhcp6PacketFromRelayPacket(dhcp6Parent);
-
-            if (dhcp6Child != null) {
-                if (dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
-                        dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
-                    log.debug("leaf dhcp6 packet found.");
-                    break;
-                } else {
-                    // found another relay
-                    // go for another loop
-                    dhcp6Parent = dhcp6Child;
-                }
-            } else {
-                log.warn("Expected dhcp6 within relay pkt, but no dhcp6 leaf found.");
-                break;
-            }
-        }
-        return dhcp6Child;
-    }
-
-    /**
-     * check if DHCP6 relay-reply is reply.
-     *
-     * @param relayPacket dhcp6 relay-reply
-     * @return boolean relay-reply contains ack
-     */
-    private boolean isDhcp6Reply(DHCP6 relayPacket) {
-        log.debug("isDhcp6Reply  entered.");
-
-        DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
-
-        if (leafDhcp6 != null) {
-            if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
-                log.debug("isDhcp6Reply  true.");
-                return true;  // must be directly connected
-            } else {
-                log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
-            }
-        } else {
-            log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
-        }
-        log.debug("isDhcp6Reply  false.");
-        return false;
-    }
-
-    /**
-     * check if DHCP6 is release or relay-forward contains release.
-     *
-     * @param dhcp6Payload dhcp6 packet
-     * @return boolean dhcp6 contains release
-     */
-    private boolean isDhcp6Release(DHCP6 dhcp6Payload) {
-
-        log.debug("isDhcp6Release  entered.");
-
-        if (dhcp6Payload.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
-            log.debug("isDhcp6Release  true.");
-            return true;  // must be directly connected
-        } else {
-            DHCP6 dhcp6Leaf = getDhcp6Leaf(dhcp6Payload);
-            if (dhcp6Leaf != null) {
-                if (dhcp6Leaf.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
-                    log.debug("isDhcp6Release  true. indirectlry connected");
-                    return true;
-                } else {
-                    log.debug("leaf dhcp6 is not release. MsgType {}",  dhcp6Leaf.getMsgType());
-                    return false;
-                }
-            } else {
-                log.debug("isDhcp6Release  false. dhcp6 is niether relay nor release.");
-                return false;
-            }
-        }
-    }
 
     /**
      * extract from dhcp6 packet client ipv6 address of given by dhcp server.
      *
      * @param dhcp6 the dhcp6 packet
-     * @return Ip6Address  Ip6Address given by dhcp server, or null if not exists
+     * @return IpAddressInfo  IpAddressInfo given by dhcp server, or null if not exists
      */
-    private Ip6Address extractIpAddress(DHCP6 dhcp6) {
-        Ip6Address ip = null;
+    private IpAddressInfo extractIpAddress(DHCP6 dhcp6) {
+        IpAddressInfo ipInfo = new IpAddressInfo();
 
         log.debug("extractIpAddress  enters dhcp6 {}.", dhcp6);
         // Extract IPv6 address from IA NA ot IA TA option
@@ -555,18 +403,18 @@
                     .map(opt -> (Dhcp6IaAddressOption) opt)
                     .findFirst();
         } else {
+            log.info("No IPv6 address found from iaTaOption {}", iaTaOption);
             iaAddressOption = Optional.empty();
         }
         if (iaAddressOption.isPresent()) {
-            ip = iaAddressOption.get().getIp6Address();
+            ipInfo.ip6Address = iaAddressOption.get().getIp6Address();
+            ipInfo.prefTime = iaAddressOption.get().getPreferredLifetime();
             log.debug("Found IPv6 address from iaAddressOption {}", iaAddressOption);
-
-
         } else {
             log.debug("Can't find IPv6 address from DHCPv6 {}", dhcp6);
+            return null;
         }
-
-        return ip;
+        return ipInfo;
     }
     /**
      * extract from dhcp6 packet Prefix prefix provided by dhcp server.
@@ -574,11 +422,11 @@
      * @param dhcp6 the dhcp6 payload
      * @return IpPrefix Prefix Delegation prefix, or null if not exists.
      */
-    private IpPrefix extractPrefix(DHCP6 dhcp6) {
-        log.trace("extractPrefix  enters {}", dhcp6);
+    private PdPrefixInfo extractPrefix(DHCP6 dhcp6) {
+        log.debug("extractPrefix  enters {}", dhcp6);
 
         // extract prefix
-        IpPrefix  prefixPrefix = null;
+        PdPrefixInfo  pdPrefixInfo = new PdPrefixInfo();
 
         Ip6Address prefixAddress = null;
 
@@ -591,29 +439,30 @@
 
         Optional<Dhcp6IaPrefixOption> iaPrefixOption;
         if (iaPdOption.isPresent()) {
-            log.trace("IA_PD option found {}", iaPdOption);
+            log.debug("IA_PD option found {}", iaPdOption);
 
             iaPrefixOption = iaPdOption.get().getOptions().stream()
                     .filter(opt -> opt instanceof Dhcp6IaPrefixOption)
                     .map(opt -> (Dhcp6IaPrefixOption) opt)
                     .findFirst();
         } else {
-            log.trace("IA_PD option NOT found");
+            log.debug("IA_PD option NOT found");
 
             iaPrefixOption = Optional.empty();
         }
         if (iaPrefixOption.isPresent()) {
-            log.trace("IAPrefix Option within IA_PD option found {}", iaPrefixOption);
+            log.debug("IAPrefix Option within IA_PD option found {}", iaPrefixOption);
 
             prefixAddress = iaPrefixOption.get().getIp6Prefix();
             int prefixLen = (int) iaPrefixOption.get().getPrefixLength();
-            log.trace("Prefix length is  {} bits", prefixLen);
-            prefixPrefix = IpPrefix.valueOf(prefixAddress, prefixLen);
+            log.debug("Prefix length is  {} bits", prefixLen);
+            pdPrefixInfo.pdPrefix = IpPrefix.valueOf(prefixAddress, prefixLen);
+            pdPrefixInfo.prefTime = iaPrefixOption.get().getPreferredLifetime();
         } else {
-            log.trace("Can't find IPv6 prefix from DHCPv6 {}", dhcp6);
+            log.debug("Can't find IPv6 prefix from DHCPv6 {}", dhcp6);
+            return null;
         }
-
-        return prefixPrefix;
+        return pdPrefixInfo;
     }
 
     /**
@@ -634,7 +483,7 @@
                     .findFirst()
                     .orElse(null);
         } else {
-            DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Payload);
+            DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Payload);
             clientIdOption = leafDhcp.getOptions()
                     .stream()
                     .filter(opt -> opt instanceof Dhcp6ClientIdOption)
@@ -646,9 +495,10 @@
         return clientIdOption;
     }
     /**
-     * remove host or route.
+     * remove host or route and update dhcp relay record attributes.
      *
      * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param location  client side connect point
      * @param dhcp6Packet the dhcp6 payload
      * @param clientPacket client's ethernet packet
      * @param clientIpv6 client's Ipv6 packet
@@ -658,78 +508,15 @@
                                    DHCP6 dhcp6Packet,
                                    Ethernet clientPacket, IPv6 clientIpv6,
                                    Interface clientInterface) {
-        log.debug("extractPrefix  enters {}", dhcp6Packet);
+        log.debug("removeHostOrRoute  enters {}", dhcp6Packet);
         VlanId vlanId = clientInterface.vlan();
-        MacAddress gwMac = clientPacket.getSourceMAC();  // could be gw or host
+        MacAddress srcMac = clientPacket.getSourceMAC();  // could be gw or host
         MacAddress leafClientMac;
         byte leafMsgType;
-        log.debug("client mac {} client vlan {}", HexString.toHexString(gwMac.toBytes(), ":"), vlanId);
-
-        // add host or route
-        boolean isMsgRelease = isDhcp6Release(dhcp6Packet);
-        IpAddress ip;
-        IpPrefix ipPrefix = null;
-        if (directConnFlag) {
-            // Add to host store if it is connected to network directly
-            ip = extractIpAddress(dhcp6Packet);
-            if (ip != null) {
-                if (isMsgRelease) {
-                    HostId hostId = HostId.hostId(gwMac, vlanId);
-                    log.debug("remove Host {} ip for directly connected.", hostId.toString());
-                    // Remove host's ip of  when dhcp release msg is received
-                    providerService.removeIpFromHost(hostId, ip);
-                }
-            } else {
-                log.debug("ipAddress not found. Do not remove Host {} for directly connected.",
-                        HostId.hostId(gwMac, vlanId).toString());
-            }
-            leafMsgType = dhcp6Packet.getMsgType();
-        } else {
-            // Remove from route store if it is not connected to network directly
-            // pick out the first link-local ip address
-            IpAddress nextHopIp = getFirstIpByHost(gwMac, vlanId);
-            if (nextHopIp == null) {
-                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}",
-                        gwMac, vlanId);
-                return;
-            }
-
-            DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet);
-            ip = extractIpAddress(leafDhcp);
-            if (ip == null) {
-                log.debug("ip is null");
-            } else {
-                if (isMsgRelease) {
-                    Route routeForIP = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp);
-                    log.debug("removing route of 128 address for indirectly connected.");
-                    log.debug("128 ip {}, nexthop {}", HexString.toHexString(ip.toOctets(), ":"),
-                            HexString.toHexString(nextHopIp.toOctets(), ":"));
-                    routeStore.removeRoute(routeForIP);
-                }
-            }
-
-            ipPrefix = extractPrefix(leafDhcp);
-            if (ipPrefix == null) {
-                log.debug("ipPrefix is null ");
-            } else {
-                if (isMsgRelease) {
-                    Route routeForPrefix = new Route(Route.Source.STATIC, ipPrefix, nextHopIp);
-                    log.debug("removing route of PD for indirectly connected.");
-                    log.debug("pd ip {}, nexthop {}", HexString.toHexString(ipPrefix.address().toOctets(), ":"),
-                            HexString.toHexString(nextHopIp.toOctets(), ":"));
-
-                    routeStore.removeRoute(routeForPrefix);
-                    if (this.dhcpFpmEnabled) {
-                        dhcpFpmPrefixStore.removeFpmRecord(ipPrefix);
-                    }
-                }
-            }
-            leafMsgType = leafDhcp.getMsgType();
-        }
+        log.debug("client mac {} client vlan {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId);
 
         Dhcp6ClientIdOption clientIdOption = extractClinedId(directConnFlag, dhcp6Packet);
         if (clientIdOption != null) {
-            log.warn("CLIENTID option found {}", clientIdOption);
             if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) ||
                     (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
                 leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
@@ -737,151 +524,126 @@
                 log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
                 return;
             }
-
         } else {
-            log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
+            log.warn("CLIENTID option NOT found. Don't create DhcpRelay Record.");
             return;
         }
 
-        HostId hostId = HostId.hostId(leafClientMac, vlanId);
-        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
-
-        if (leafMsgType == DHCP6.MsgType.RELEASE.value()) {
-            log.debug("DHCP6 RELEASE msg.");
-            if (record != null) {
-                if (ip != null) {
-                    log.warn("DhcpRelay Record ip6Address is set to null.");
-                    record.ip6Address(null);
-                }
-                if (ipPrefix != null) {
-                    log.warn("DhcpRelay Record pdPrefix is set to null.");
-                    record.pdPrefix(null);
-                }
-                log.debug("ip {} pd {}", record.ip6Address(), record.pdPrefix());
-
-                if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
-                    log.warn("IP6 address and IP6 PD both are null. Remove record.");
-                    dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId));
-                }
-            }
-            return;
-        }
+        HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
         if (record == null) {
-            record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
-        } else {
-            record = record.clone();
+            record = new DhcpRecord(leafHostId);
         }
-        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
-        record.ip6Status(DHCP6.MsgType.getType(dhcp6Packet.getMsgType()));
-        record.setDirectlyConnected(directConnFlag);
-        if (!directConnFlag) {
-            // Update gateway mac address if the host is not directly connected
-            record.nextHop(gwMac);
-        }
-        record.updateLastSeen();
-        dhcpRelayStore.updateDhcpRecord(HostId.hostId(leafClientMac, vlanId), record);
 
-
-    }
-
-    /**
-     * add host or route.
-     *
-     * @param directConnFlag  flag to show that packet is from directly connected client
-     * @param location  client side connect point
-     * @param dhcp6Relay the dhcp6 payload
-     * @param embeddedDhcp6 the dhcp6 payload within relay
-     * @param gwMac client gw/host macAddress
-     * @param clientInterface client interface
-     */
-    private void addHostOrRoute(boolean directConnFlag,
-                                ConnectPoint location,
-                                DHCP6 dhcp6Relay,
-                                DHCP6 embeddedDhcp6,
-                                MacAddress gwMac,
-                                Interface clientInterface) {
-        log.debug("addHostOrRoute entered.");
-        VlanId vlanId = clientInterface.vlan();
-        Boolean isMsgReply = isDhcp6Reply(dhcp6Relay);
-        MacAddress leafClientMac;
-        Byte leafMsgType;
-
-        // add host or route
-        IpAddress ip;
-        IpPrefix ipPrefix = null;
+        Boolean isMsgRelease = dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
+        IpAddressInfo ipInfo;
+        PdPrefixInfo pdInfo = null;
         if (directConnFlag) {
-            // Add to host store if it connect to network directly
-            ip = extractIpAddress(embeddedDhcp6);
-            if (ip != null) {
-                if (isMsgReply) {
-                    Set<IpAddress> ips = Sets.newHashSet(ip);
-
-                    HostId hostId = HostId.hostId(gwMac, vlanId);
-                    Host host = hostService.getHost(hostId);
-                    HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(),
-                            System.currentTimeMillis());
-                    Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
-
-                    if (host != null) {
-                        // Dual homing support:
-                        // if host exists, use old locations and new location
-                        hostLocations.addAll(host.locations());
-                    }
-                    HostDescription desc = new DefaultHostDescription(gwMac, vlanId,
-                            hostLocations, ips,
-                            false);
-                    log.debug("adding Host for directly connected.");
-                    log.debug("client mac {} client vlan {} hostlocation {}",
-                            HexString.toHexString(gwMac.toBytes(), ":"),
-                            vlanId, hostLocation.toString());
-
-                    // Replace the ip when dhcp server give the host new ip address
-                    providerService.hostDetected(hostId, desc, false);
+            // Add to host store if it is connected to network directly
+            ipInfo = extractIpAddress(dhcp6Packet);
+            if (ipInfo != null) {
+                if (isMsgRelease) {
+                    HostId hostId = HostId.hostId(srcMac, vlanId);
+                    log.debug("remove Host {} ip for directly connected.", hostId.toString());
+                    providerService.removeIpFromHost(hostId, ipInfo.ip6Address);
                 }
             } else {
-                log.warn("ipAddress not found. Do not add Host {} for directly connected.",
-                        HostId.hostId(gwMac, vlanId).toString());
+                log.debug("ipAddress not found. Do not remove Host {} for directly connected.",
+                        HostId.hostId(srcMac, vlanId).toString());
             }
-            leafMsgType = embeddedDhcp6.getMsgType();
+            leafMsgType = dhcp6Packet.getMsgType();
         } else {
-            // Add to route store if it does not connect to network directly
+            // Remove from route store if it is not connected to network directly
             // pick out the first link-local ip address
-            IpAddress nextHopIp = getFirstIpByHost(gwMac, vlanId);
+            IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
             if (nextHopIp == null) {
-                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}",
-                        gwMac, vlanId);
+                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
                 return;
             }
 
-            DHCP6 leafDhcp = getDhcp6Leaf(embeddedDhcp6);
-            ip = extractIpAddress(leafDhcp);
-            if (ip == null) {
-                    log.debug("ip is null");
+            DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
+            ipInfo = extractIpAddress(leafDhcp);
+            if (ipInfo == null) {
+                log.debug("ip is null");
             } else {
-                if (isMsgReply) {
-                    Route routeForIP = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp);
-                    log.debug("adding Route of 128 address for indirectly connected.");
-                    routeStore.updateRoute(routeForIP);
+                if (isMsgRelease) {
+                    Route routeForIP = new Route(Route.Source.STATIC, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
+                    log.debug("removing route of 128 address for indirectly connected.");
+                    log.debug("128 ip {}, nexthop {}",
+                            HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"),
+                            HexString.toHexString(nextHopIp.toOctets(), ":"));
+                    routeStore.removeRoute(routeForIP);
                 }
             }
 
-            ipPrefix = extractPrefix(leafDhcp);
-            if (ipPrefix == null) {
-                    log.debug("ipPrefix is null ");
+            pdInfo = extractPrefix(leafDhcp);
+            if (pdInfo == null) {
+                log.debug("ipPrefix is null ");
             } else {
-                if (isMsgReply) {
-                    Route routeForPrefix = new Route(Route.Source.STATIC, ipPrefix, nextHopIp);
-                    log.debug("adding Route of PD for indirectly connected.");
-                    routeStore.updateRoute(routeForPrefix);
+                if (isMsgRelease) {
+                    Route routeForPrefix = new Route(Route.Source.STATIC, pdInfo.pdPrefix, nextHopIp);
+                    log.debug("removing route of PD for indirectly connected.");
+                    log.debug("pd ip {}, nexthop {}",
+                            HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"),
+                            HexString.toHexString(nextHopIp.toOctets(), ":"));
+
+                    routeStore.removeRoute(routeForPrefix);
                     if (this.dhcpFpmEnabled) {
-                        FpmRecord record = new FpmRecord(ipPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
-                        dhcpFpmPrefixStore.addFpmRecord(ipPrefix, record);
+                        dhcpFpmPrefixStore.removeFpmRecord(pdInfo.pdPrefix);
                     }
                 }
             }
             leafMsgType = leafDhcp.getMsgType();
         }
 
+        if (isMsgRelease) {
+            log.debug("DHCP6 RELEASE msg.");
+            if (record != null) {
+                if (ipInfo != null) {
+                    log.debug("DhcpRelay Record ip6Address is set to null.");
+                    record.ip6Address(null);
+                }
+                if (pdInfo != null) {
+                    log.debug("DhcpRelay Record pdPrefix is set to null.");
+                }
+
+                if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
+                    log.warn("IP6 address and IP6 PD both are null. Remove record.");
+                    // do not remove a record. Let timer task handler it.
+                    //dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId));
+                }
+            }
+        }
+
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+        record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
+        record.setDirectlyConnected(directConnFlag);
+        if (!directConnFlag) {
+            // Update gateway mac address if the host is not directly connected
+            record.nextHop(srcMac);
+        }
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(leafHostId, record);
+    }
+
+    /**
+     * add host or route and update dhcp relay record.
+     *
+     * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param location  client side connect point
+     * @param dhcp6Relay the dhcp6 payload
+     * @param embeddedDhcp6 the dhcp6 payload within relay
+     * @param srcMac client gw/host macAddress
+     * @param clientInterface client interface
+     */
+    private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay,
+                                DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface) {
+        log.debug("addHostOrRoute entered.");
+        VlanId vlanId = clientInterface.vlan();
+        Boolean isMsgReply = dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
+        MacAddress leafClientMac;
+        Byte leafMsgType;
+
         Dhcp6ClientIdOption clientIdOption = extractClinedId(directConnFlag, embeddedDhcp6);
         if (clientIdOption != null) {
             log.debug("CLIENTID option found {}", clientIdOption);
@@ -892,328 +654,223 @@
                 log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
                 return;
             }
-
         } else {
             log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
             return;
         }
-
-        if (leafMsgType == DHCP6.MsgType.RELEASE.value() ||
-                (leafMsgType == DHCP6.MsgType.REPLY.value()) && ip == null) {
-            log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", DHCP6.MsgType.getType(leafMsgType));
-            return;
-        }
-
-        HostId hostId = HostId.hostId(leafClientMac, vlanId);
-        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+        HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
         if (record == null) {
             record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
-        } else {
-            record = record.clone();
         }
+
+        IpAddressInfo ipInfo;
+        PdPrefixInfo pdInfo = null;
+        if (directConnFlag) {
+            // Add to host store if it connect to network directly
+            ipInfo = extractIpAddress(embeddedDhcp6);
+            if (ipInfo != null) {
+                if (isMsgReply) {
+                    Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
+                    HostId hostId = HostId.hostId(srcMac, vlanId);
+                    Host host = hostService.getHost(hostId);
+                    HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(),
+                            System.currentTimeMillis());
+                    Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
+                    if (host != null) {
+                        // Dual homing support:
+                        // if host exists, use old locations and new location
+                        hostLocations.addAll(host.locations());
+                    }
+                    HostDescription desc = new DefaultHostDescription(srcMac, vlanId, hostLocations, ips,
+                            false);
+                    log.debug("adding Host for directly connected.");
+                    log.debug("client mac {} client vlan {} hostlocation {}",
+                            HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
+                    // Replace the ip when dhcp server give the host new ip address
+                    providerService.hostDetected(hostId, desc, false);
+                }
+            } else {
+                log.warn("ipAddress not found. Do not add Host {} for directly connected.",
+                        HostId.hostId(srcMac, vlanId).toString());
+            }
+            leafMsgType = embeddedDhcp6.getMsgType();
+        } else {
+            // Add to route store if it does not connect to network directly
+            // pick out the first link-local ip address
+            IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
+            if (nextHopIp == null) {
+                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
+                return;
+            }
+
+            DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
+            ipInfo = extractIpAddress(leafDhcp);
+            if (ipInfo == null) {
+                log.debug("ip is null");
+            } else {
+                if (isMsgReply) {
+                    Route routeForIP = new Route(Route.Source.STATIC, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
+                    log.debug("adding Route of 128 address for indirectly connected.");
+                    routeStore.updateRoute(routeForIP);
+                }
+            }
+
+            pdInfo = extractPrefix(leafDhcp);
+            if (pdInfo == null) {
+                log.debug("ipPrefix is null ");
+            } else {
+                if (isMsgReply) {
+                    Route routeForPrefix = new Route(Route.Source.STATIC, pdInfo.pdPrefix, nextHopIp);
+                    log.debug("adding Route of PD for indirectly connected.");
+                    routeStore.updateRoute(routeForPrefix);
+                    if (this.dhcpFpmEnabled) {
+                        FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
+                        dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
+                    }
+                }
+            }
+            leafMsgType = leafDhcp.getMsgType();
+        }
+        if (leafMsgType == DHCP6.MsgType.RELEASE.value() ||
+                (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
+            log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
+            //return;
+        }
+
         record.addLocation(new HostLocation(location, System.currentTimeMillis()));
         if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
-            if (ip != null) {
+            if (ipInfo != null) {
                 log.debug("IP6 address is being stored into dhcp-relay store.");
-                log.debug("IP6 address {}", HexString.toHexString(ip.toOctets(), ":"));
-                record.ip6Address(ip.getIp6Address());
+                log.debug("IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
+                record.ip6Address(ipInfo.ip6Address);
             } else {
                 log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
             }
-            if (ipPrefix != null) {
-                log.debug("IP6 PD address is being stored into dhcp-relay store.");
-                log.debug("IP6 PD address {}", HexString.toHexString(ipPrefix.address().toOctets(), ":"));
-                record.pdPrefix(ipPrefix);
+            if (pdInfo != null) {
+                log.debug("IP6 PD address {}",
+                        HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
             } else {
                 log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
             }
         }
-        record.ip6Status(DHCP6.MsgType.getType(dhcp6Relay.getMsgType()));
+        record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
         record.setDirectlyConnected(directConnFlag);
         record.updateLastSeen();
-        dhcpRelayStore.updateDhcpRecord(HostId.hostId(leafClientMac, vlanId), record);
-
+        dhcpRelayStore.updateDhcpRecord(leafHostId, record);
     }
 
     /**
-     * Build the DHCP6 solicit/request packet with gatewayip.
-     * TODO: method too long, need to be refactored.
+     * build the DHCP6 solicit/request packet with gatewayip.
      *
      * @param context packet context
      * @param clientPacket client ethernet packet
      * @param clientInterfaces set of client side interfaces
      */
-    private InternalPacket processDhcp6PacketFromClient(PacketContext context,
-                                                        Ethernet clientPacket, Set<Interface> clientInterfaces) {
+    private List<InternalPacket> processDhcp6PacketFromClient(PacketContext context,
+                                                              Ethernet clientPacket,
+                                                              Set<Interface> clientInterfaces) {
         ConnectPoint receivedFrom = context.inPacket().receivedFrom();
         DeviceId receivedFromDevice = receivedFrom.deviceId();
-        DhcpServerInfo serverInfo;
-        Ip6Address dhcpServerIp = null;
-        ConnectPoint dhcpServerConnectPoint = null;
-        MacAddress dhcpConnectMac = null;
-        VlanId dhcpConnectVlan = null;
-        Ip6Address dhcpGatewayIp = null;
-        Ip6Address indirectDhcpServerIp = null;
-        ConnectPoint indirectDhcpServerConnectPoint = null;
-        MacAddress indirectDhcpConnectMac = null;
-        VlanId indirectDhcpConnectVlan = null;
-        Ip6Address indirectDhcpGatewayIp = null;
-        Ip6Address indirectRelayAgentIpFromCfg = null;
-        if (!defaultServerInfoList.isEmpty()) {
-            serverInfo = defaultServerInfoList.get(0);
-            dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
-            dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
-            dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
-            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
-        }
-        if (!indirectServerInfoList.isEmpty()) {
-            serverInfo = indirectServerInfoList.get(0);
-            indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
-            indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
-            indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
-            indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
-            indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
-        }
-        Ip6Address relayAgentIp = getRelayAgentIPv6Address(clientInterfaces);
+        Ip6Address relayAgentIp = dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
         MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
         if (relayAgentIp == null || relayAgentMac == null) {
             log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
-                             + "packet from client on port: {}. Aborting packet processing",
-                     clientInterfaces.iterator().next().connectPoint());
-            return null;
-        }
-        // get dhcp6 header.
-        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
-        UDP clientUdp = (UDP) clientIpv6.getPayload();
-        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
-        boolean directConnFlag = directlyConnected(clientDhcp6);
-        Interface serverInterface;
-        if (directConnFlag) {
-            serverInterface = getServerInterface();
-        } else {
-            serverInterface = getIndirectServerInterface();
-            if (serverInterface == null) {
-                // Indirect server interface not found, use default server interface
-                serverInterface = getServerInterface();
-            }
-        }
-        if (serverInterface == null) {
-            log.warn("Can't get {} server interface, ignore", directConnFlag ? "direct" : "indirect");
-            return null;
-        }
-        Ip6Address ipFacingServer = getFirstIpFromInterface(serverInterface);
-        MacAddress macFacingServer = serverInterface.mac();
-        if (ipFacingServer == null || macFacingServer == null) {
-            log.warn("No IP v6 address for server Interface {}", serverInterface);
-            return null;
-        }
-        Ethernet etherReply = clientPacket.duplicate();
-        etherReply.setSourceMACAddress(macFacingServer);
-        if ((directConnFlag && dhcpConnectMac == null)  ||
-                !directConnFlag && indirectDhcpConnectMac == null && dhcpConnectMac == null)   {
-            log.trace("Packet received from {} connected client.", directConnFlag ? "directly" : "indirectly");
-            log.debug("DHCP6 {} not yet resolved .. Aborting DHCP packet processing from client on port: {}",
-                     (dhcpGatewayIp == null) ? "server IP " + dhcpServerIp
-                             : "gateway IP " + dhcpGatewayIp,
-                     clientInterfaces.iterator().next().connectPoint());
-            return null;
-        }
-        if (dhcpServerConnectPoint == null) {
-            log.warn("DHCP6 server connection point direct {} directConn {} indirectConn {} is not set up yet",
-                     directConnFlag, dhcpServerConnectPoint, indirectDhcpServerConnectPoint);
+                      + "packet from client on port: {}. Aborting packet processing",
+                      clientInterfaces.iterator().next().connectPoint());
             return null;
         }
 
-        etherReply.setDestinationMACAddress(dhcpConnectMac);
-        etherReply.setVlanID(dhcpConnectVlan.toShort());
-        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
-        byte[] peerAddress = clientIpv6.getSourceAddress();
-        ipv6Packet.setSourceAddress(ipFacingServer.toOctets());
-        ipv6Packet.setDestinationAddress(dhcpServerIp.toOctets());
-        UDP udpPacket = (UDP) ipv6Packet.getPayload();
-        udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
-        DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
-        byte[] dhcp6PacketByte = dhcp6Packet.serialize();
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+
+        boolean directConnFlag = dhcp6HandlerUtil.directlyConnected(clientDhcp6);
 
         ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
         VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
         Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
-                .stream().filter(iface -> interfaceContainsVlan(iface, vlanIdInUse))
-                .findFirst().orElse(null);
+                .stream().filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst()
+                .orElse(null);
 
-        removeHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Packet, clientPacket,
-                          clientIpv6, clientInterface);
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
 
-        DHCP6 dhcp6Relay = new DHCP6();
-        dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
-        if (directConnFlag) {
-            dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
-            log.debug("direct connection: relayAgentIp obtained dynamically {}",
-                      HexString.toHexString(relayAgentIp.toOctets(), ":"));
+        for (DhcpServerInfo serverInfo : copyServerInfoList) {
+            if (!dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
+                log.warn("Can't get server connect point, ignore");
+                continue;
+            }
+            DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
+            if (newServerInfo == null) {
+                log.warn("Can't get server interface with host info resolved, ignore");
+                continue;
+            }
 
-        } else {
-            if (indirectDhcpServerIp == null) {
-                log.debug("indirect DhcpServerIp not available, use default DhcpServerIp {}",
-                         HexString.toHexString(dhcpServerIp.toOctets()));
-             } else {
-                 // Indirect case, replace destination to indirect dhcp server if exist
-                 // Check if mac is obtained for valid server ip
-                 if (indirectDhcpConnectMac == null) {
-                     log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
-                                      + "packet processing from client on port: {}",
-                              (indirectDhcpGatewayIp == null) ? "server IP " + indirectDhcpServerIp
-                                      : "gateway IP " + indirectDhcpGatewayIp,
-                              clientInterfaces.iterator().next().connectPoint());
-                     return null;
-                 }
-                 etherReply.setDestinationMACAddress(indirectDhcpConnectMac);
-                 etherReply.setVlanID(indirectDhcpConnectVlan.toShort());
-                 ipv6Packet.setDestinationAddress(indirectDhcpServerIp.toOctets());
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
 
+            Ethernet etherReply = dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket,
+                                                              clientInterfaces, newServerInfo, serverInterface);
+            removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket,
+                    clientIpv6, clientInterface);
 
-             }
-             if (indirectRelayAgentIpFromCfg == null) {
-                 dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
-                 log.trace("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}",
-                          HexString.toHexString(relayAgentIp.toOctets(), ":"));
-             } else {
-                 dhcp6Relay.setLinkAddress(indirectRelayAgentIpFromCfg.toOctets());
-                 log.trace("indirect connection: relayAgentIp from config file is available! {}",
-                           HexString.toHexString(indirectRelayAgentIpFromCfg.toOctets(), ":"));
-             }
-         }
+            InternalPacket internalPacket = new Dhcp6HandlerUtil().new InternalPacket(etherReply,
+                    serverInfo.getDhcpServerConnectPoint().get());
+            internalPackets.add(internalPacket);
+        }
+        log.debug("num of client packets to send is{}", internalPackets.size());
 
-         // peer address: address of the client or relay agent from which
-         // the message to be relayed was received.
-         dhcp6Relay.setPeerAddress(peerAddress);
-         List<Dhcp6Option> options = new ArrayList<>();
-         // directly connected case, hop count is zero; otherwise, hop count + 1
-         if (directConnFlag) {
-             dhcp6Relay.setHopCount((byte) 0);
-         } else {
-             dhcp6Relay.setHopCount((byte) (dhcp6Packet.getHopCount() + 1));
-         }
-         // create relay message option
-         Dhcp6Option relayMessage = new Dhcp6Option();
-         relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
-         relayMessage.setLength((short) dhcp6PacketByte.length);
-         relayMessage.setData(dhcp6PacketByte);
-         options.add(relayMessage);
-         // create interfaceId option
-         String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
-         Dhcp6Option interfaceId = new Dhcp6Option();
-         interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
-         byte[] clientSoureMacBytes = clientPacket.getSourceMACAddress();
-         byte[] inPortStringBytes = inPortString.getBytes();
-         byte[] vlanIdBytes = new byte[2];
-         vlanIdBytes[0] = (byte) (clientPacket.getVlanID() & 0xff);
-         vlanIdBytes[1] = (byte) ((clientPacket.getVlanID() >> 8) & 0xff);
-         byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +
-                 inPortStringBytes.length + vlanIdBytes.length];
-         log.trace("Length: interfaceIdBytes  {} clientSoureMacBytes {} inPortStringBytes {} vlan {}",
-                   interfaceIdBytes.length, clientSoureMacBytes.length, inPortStringBytes.length,
-                   vlanIdBytes.length);
-         System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
-         System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length, inPortStringBytes.length);
-         System.arraycopy(vlanIdBytes, 0, interfaceIdBytes, clientSoureMacBytes.length + inPortStringBytes.length,
-                          vlanIdBytes.length);
-         interfaceId.setData(interfaceIdBytes);
-         interfaceId.setLength((short) interfaceIdBytes.length);
-         options.add(interfaceId);
-         log.debug("interfaceId write srcMac {} portString {}",
-                   HexString.toHexString(clientSoureMacBytes, ":"), inPortString);
-         dhcp6Relay.setOptions(options);
-         udpPacket.setPayload(dhcp6Relay);
-         udpPacket.resetChecksum();
-         ipv6Packet.setPayload(udpPacket);
-         ipv6Packet.setHopLimit((byte) 64);
-         etherReply.setPayload(ipv6Packet);
-         if (directConnFlag || indirectDhcpServerIp == null) {
-             return new InternalPacket(etherReply, dhcpServerConnectPoint);
-         } else {
-             return new InternalPacket(etherReply, indirectDhcpServerConnectPoint);
-         }
-     }
+        return internalPackets;
+    }
 
     /**
-     *
      * process the DHCP6 relay-reply packet from dhcp server.
      *
      * @param context packet context
      * @param receivedPacket server ethernet packet
      * @param recevingInterfaces set of server side interfaces
+     * @return internalPacket toward client
      */
     private InternalPacket processDhcp6PacketFromServer(PacketContext context,
                                                         Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
-
-        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
-        DeviceId receivedFromDevice = receivedFrom.deviceId();
-
-        // TODO: refactor
-        DhcpServerInfo serverInfo;
-        Ip6Address dhcpServerIp = null;
-        ConnectPoint dhcpServerConnectPoint = null;
-        MacAddress dhcpConnectMac = null;
-        VlanId dhcpConnectVlan = null;
-        Ip6Address dhcpGatewayIp = null;
-
-        Ip6Address indirectDhcpServerIp = null;
-        ConnectPoint indirectDhcpServerConnectPoint = null;
-        MacAddress indirectDhcpConnectMac = null;
-        VlanId indirectDhcpConnectVlan = null;
-        Ip6Address indirectDhcpGatewayIp = null;
-        Ip6Address indirectRelayAgentIpFromCfg = null;
-
-        if (!defaultServerInfoList.isEmpty()) {
-            serverInfo = defaultServerInfoList.get(0);
-            dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
-            dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
-            dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
-            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
-        }
-
-        if (!indirectServerInfoList.isEmpty()) {
-            serverInfo = indirectServerInfoList.get(0);
-            indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
-            indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
-            indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
-            indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
-            indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
-        }
-
         // get dhcp6 header.
         Ethernet etherReply = receivedPacket.duplicate();
         IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
         UDP udpPacket = (UDP) ipv6Packet.getPayload();
         DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
+        Boolean directConnFlag = dhcp6HandlerUtil.directlyConnected(dhcp6Relay);
 
-        Boolean directConnFlag = directlyConnected(dhcp6Relay);
+        DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream()
+                .filter(opt -> opt instanceof Dhcp6RelayOption)
+                .map(BasePacket::getPayload)
+                .map(pld -> (DHCP6) pld)
+                .findFirst()
+                .orElse(null);
+
         ConnectPoint inPort = context.inPacket().receivedFrom();
-        if ((directConnFlag || indirectDhcpServerIp == null)
-             && !inPort.equals(dhcpServerConnectPoint)) {
-            log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null",
-                    inPort, dhcpServerConnectPoint);
-            return null;
-        }
+        DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
 
-        if (!directConnFlag && indirectDhcpServerIp != null &&
-                                !inPort.equals(indirectDhcpServerConnectPoint)) {
-            log.warn("Receiving port {} is not the same as server connect point {} for indirect",
-                    inPort, indirectDhcpServerConnectPoint);
+        if (foundServerInfo == null) {
+            log.warn("Cannot find server info");
             return null;
+        } else {
+            if (dhcp6HandlerUtil.isServerIpEmpty(foundServerInfo)) {
+                log.warn("Cannot find server info's ipaddress");
+                return null;
+            }
         }
 
-
         Dhcp6InterfaceIdOption interfaceIdOption = dhcp6Relay.getOptions().stream()
                 .filter(opt -> opt instanceof Dhcp6InterfaceIdOption)
                 .map(opt -> (Dhcp6InterfaceIdOption) opt)
                 .findFirst()
                 .orElse(null);
-
         if (interfaceIdOption == null) {
             log.warn("Interface Id option is not present, abort packet...");
             return null;
@@ -1221,14 +878,11 @@
 
         MacAddress peerMac = interfaceIdOption.getMacAddress();
         String clientConnectionPointStr = new String(interfaceIdOption.getInPort());
-
         ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
         VlanId vlanIdInUse = VlanId.vlanId(interfaceIdOption.getVlanId());
         Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
-                .stream()
-                .filter(iface -> interfaceContainsVlan(iface, vlanIdInUse))
-                .findFirst()
-                .orElse(null);
+                .stream().filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst().orElse(null);
         if (clientInterface == null) {
             log.warn("Cannot get client interface for from packet, abort... vlan {}", vlanIdInUse.toString());
             return null;
@@ -1256,10 +910,8 @@
                 return null;
             }
             log.trace("Client mac address found from getHostByIp");
-
         }
         etherReply.setDestinationMACAddress(clientMac);
-
         // ip header
         ipv6Packet.setSourceAddress(dhcp6Relay.getLinkAddress());
         ipv6Packet.setDestinationAddress(dhcp6Relay.getPeerAddress());
@@ -1270,15 +922,6 @@
         } else {
             udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
         }
-
-        DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream()
-                    .filter(opt -> opt instanceof Dhcp6RelayOption)
-                    .map(BasePacket::getPayload)
-                    .map(pld -> (DHCP6) pld)
-                    .findFirst()
-                    .orElse(null);
-
-
         // add host or route
         addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6, clientMac, clientInterface);
 
@@ -1286,23 +929,9 @@
         udpPacket.resetChecksum();
         ipv6Packet.setPayload(udpPacket);
         etherReply.setPayload(ipv6Packet);
-
-        return new InternalPacket(etherReply, clientConnectionPoint);
+        return new Dhcp6HandlerUtil().new InternalPacket(etherReply, clientConnectionPoint);
     }
 
-    // Returns the first v6 interface ip out of a set of interfaces or null.
-    // Checks all interfaces, and ignores v6 interface ips
-    private Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
-        for (Interface intf : intfs) {
-            for (InterfaceIpAddress ip : intf.ipAddressesList()) {
-                Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
-                if (relayAgentIp != null) {
-                    return relayAgentIp;
-                }
-            }
-        }
-        return null;
-    }
 
     @Override
     public void setDhcpFpmEnabled(Boolean enabled) {
@@ -1311,33 +940,39 @@
 
     @Override
     public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        log.debug("setDefaultDhcpServerConfigs is called.");
+
         setDhcpServerConfigs(configs, defaultServerInfoList);
     }
 
     @Override
     public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        log.debug("setIndirectDhcpServerConfigs is called.");
+
         setDhcpServerConfigs(configs, indirectServerInfoList);
     }
 
     public void setDhcpServerConfigs(Collection<DhcpServerConfig> configs, List<DhcpServerInfo> serverInfoList) {
+        log.debug("config size {}.", configs.size());
+
         if (configs.size() == 0) {
             // no config to update
             return;
         }
-
         // TODO: currently we pick up first DHCP server config.
         // Will use other server configs in the future for HA.
-        DhcpServerConfig serverConfig = configs.iterator().next();
-
-        if (!serverConfig.getDhcpServerIp6().isPresent()) {
-            // not a DHCPv6 config
-            return;
+        Boolean isConfigValid = false;
+        for (DhcpServerConfig serverConfig : configs) {
+            if (serverConfig.getDhcpServerIp6().isPresent()) {
+                isConfigValid = true;
+                break;
+            }
         }
-
-        if (!serverInfoList.isEmpty()) {
-            // remove old server info
-            DhcpServerInfo oldServerInfo = serverInfoList.remove(0);
-
+        if (!isConfigValid) {
+            log.warn("No IP V6 server address found.");
+            return;  // No IP V6 address found
+        }
+        for (DhcpServerInfo oldServerInfo : serverInfoList) {
             // stop monitoring gateway or server
             oldServerInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
                 hostService.stopMonitoringIp(gatewayIp);
@@ -1347,43 +982,50 @@
                 cancelDhcpPacket(serverIp);
             });
         }
+        serverInfoList.clear();
+        for (DhcpServerConfig serverConfig : configs) {
+            // Create new server info according to the config
+            DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
+                    DhcpServerInfo.Version.DHCP_V6);
+            checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
+                    "Connect point not exists");
+            checkState(newServerInfo.getDhcpServerIp6().isPresent(),
+                    "IP of DHCP server not exists");
 
-        // Create new server info according to the config
-        DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
-                                                          DhcpServerInfo.Version.DHCP_V6);
-        checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
-                   "Connect point not exists");
-        checkState(newServerInfo.getDhcpServerIp6().isPresent(),
-                   "IP of DHCP server not exists");
+            log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
+            log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp6().orElse(null));
 
-        log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
-        log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp6().orElse(null));
+            Ip6Address serverIp = newServerInfo.getDhcpServerIp6().get();
+            Ip6Address ipToProbe;
+            if (newServerInfo.getDhcpGatewayIp6().isPresent()) {
+                ipToProbe = newServerInfo.getDhcpGatewayIp6().get();
+            } else {
+                ipToProbe = newServerInfo.getDhcpServerIp6().orElse(null);
+            }
+            String hostToProbe = newServerInfo.getDhcpGatewayIp6()
+                    .map(ip -> "gateway").orElse("server");
 
-        Ip6Address serverIp = newServerInfo.getDhcpServerIp6().get();
-        Ip6Address ipToProbe;
-        if (newServerInfo.getDhcpGatewayIp6().isPresent()) {
-            ipToProbe = newServerInfo.getDhcpGatewayIp6().get();
-        } else {
-            ipToProbe = newServerInfo.getDhcpServerIp6().orElse(null);
+            log.warn("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                Host host = hosts.iterator().next();
+                newServerInfo.setDhcpConnectVlan(host.vlan());
+                newServerInfo.setDhcpConnectMac(host.mac());
+                log.warn("Host found host {}", host);
+
+            } else {
+                log.warn("No host found host ip {}", ipToProbe);
+            }
+            // Add new server info
+            synchronized (this) {
+                serverInfoList.add(newServerInfo);
+            }
+            if (!hosts.isEmpty()) {
+                requestDhcpPacket(serverIp);
+            }
         }
-        String hostToProbe = newServerInfo.getDhcpGatewayIp6()
-                .map(ip -> "gateway").orElse("server");
-
-        log.debug("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
-        hostService.startMonitoringIp(ipToProbe);
-
-        Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
-        if (!hosts.isEmpty()) {
-            Host host = hosts.iterator().next();
-            newServerInfo.setDhcpConnectVlan(host.vlan());
-            newServerInfo.setDhcpConnectMac(host.mac());
-        }
-        // Add new server info
-        synchronized (this) {
-            serverInfoList.clear();
-            serverInfoList.add(0, newServerInfo);
-        }
-        requestDhcpPacket(serverIp);
     }
 
     class InternalHostListener implements HostListener {
@@ -1425,7 +1067,6 @@
             if (targetIp == null) {
                 targetIp = serverIp;
             }
-
             if (targetIp != null) {
                 if (host.ipAddresses().contains(targetIp)) {
                     serverInfo.setDhcpConnectMac(host.mac());
@@ -1459,7 +1100,6 @@
             if (targetIp == null) {
                 targetIp = serverIp;
             }
-
             if (targetIp != null) {
                 if (host.ipAddresses().contains(targetIp)) {
                     serverInfo.setDhcpConnectVlan(null);
@@ -1488,79 +1128,80 @@
     }
 
     /**
+     * Checks if serverInfo's host info (mac and vlan) is filled in; if not, fills in.
+     *
+     * @param serverInfo server information
+     * @return newServerInfo if host info can be either found or filled in.
+     */
+    private DhcpServerInfo getHostInfoForServerInfo(DhcpServerInfo serverInfo, List<DhcpServerInfo> sererInfoList) {
+        DhcpServerInfo newServerInfo = null;
+        MacAddress  dhcpServerConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+
+        if (dhcpServerConnectMac != null && dhcpConnectVlan != null) {
+            newServerInfo = serverInfo;
+            log.info("DHCP server {} host info found. ConnectPt{}  Mac {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+        } else {
+            log.warn("DHCP server {} not resolve yet connectPt {} mac {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+
+            Ip6Address ipToProbe;
+            if (serverInfo.getDhcpGatewayIp6().isPresent()) {
+                ipToProbe = serverInfo.getDhcpGatewayIp6().get();
+            } else {
+                ipToProbe = serverInfo.getDhcpServerIp6().orElse(null);
+            }
+            String hostToProbe = serverInfo.getDhcpGatewayIp6()
+                    .map(ip -> "gateway").orElse("server");
+
+            log.info("Dynamically probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                int serverInfoIndex = sererInfoList.indexOf(serverInfo);
+                Host host = hosts.iterator().next();
+                serverInfo.setDhcpConnectVlan(host.vlan());
+                serverInfo.setDhcpConnectMac(host.mac());
+                // replace the serverInfo in the list
+                sererInfoList.set(serverInfoIndex, serverInfo);
+                newServerInfo = serverInfo;
+                log.warn("Dynamically host found host {}", host);
+            } else {
+                log.warn("No host found host ip {} dynamically", ipToProbe);
+            }
+        }
+        return newServerInfo;
+    }
+
+    /**
      * Gets Interface facing to the server for default host.
      *
+     * @param serverInfo server information
      * @return the Interface facing to the server; null if not found
      */
-    private Interface getServerInterface() {
-        DhcpServerInfo serverInfo;
-        ConnectPoint dhcpServerConnectPoint;
-        VlanId dhcpConnectVlan;
+    private Interface getServerInterface(DhcpServerInfo serverInfo) {
+        Interface serverInterface = null;
 
-        if (!defaultServerInfoList.isEmpty()) {
-            serverInfo = defaultServerInfoList.get(0);
-            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+
+        if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
+        serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                    .stream()
+                    .filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
+                    .findFirst()
+                    .orElse(null);
         } else {
-            return null;
+            log.warn("DHCP server {} not resolve yet connectPoint {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpConnectVlan);
         }
-        if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
-            log.info("Default DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
-            return null;
-        }
-        return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
-                .stream()
-                .filter(iface -> interfaceContainsVlan(iface, dhcpConnectVlan))
-                .findFirst()
-                .orElse(null);
+
+        return serverInterface;
     }
 
-    /**
-     * Gets Interface facing to the server for indirect hosts.
-     * Use default server Interface if indirect server not configured.
-     *
-     * @return the Interface facing to the server; null if not found
-     */
-    private Interface getIndirectServerInterface() {
-        DhcpServerInfo serverInfo;
-
-        ConnectPoint indirectDhcpServerConnectPoint;
-        VlanId indirectDhcpConnectVlan;
-
-        if (!indirectServerInfoList.isEmpty()) {
-            serverInfo = indirectServerInfoList.get(0);
-            indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
-            indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
-        } else {
-            return getServerInterface();
-        }
-        if (indirectDhcpServerConnectPoint == null || indirectDhcpConnectVlan == null) {
-            log.info("Indirect DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
-            return null;
-        }
-        return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint)
-                .stream()
-                .filter(iface -> interfaceContainsVlan(iface, indirectDhcpConnectVlan))
-                .findFirst()
-                .orElse(null);
-    }
-
-    /**
-     * Determind if an Interface contains a vlan id.
-     *
-     * @param iface the Interface
-     * @param vlanId the vlan id
-     * @return true if the Interface contains the vlan id
-     */
-    private boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
-        if (vlanId.equals(VlanId.NONE)) {
-            // untagged packet, check if vlan untagged or vlan native is not NONE
-            return !iface.vlanUntagged().equals(VlanId.NONE) ||
-                    !iface.vlanNative().equals(VlanId.NONE);
-        }
-        // tagged packet, check if the interface contains the vlan
-        return iface.vlanTagged().contains(vlanId);
-    }
 
     private void requestDhcpPacket(Ip6Address serverIp) {
         requestServerDhcpPacket(serverIp);
@@ -1724,7 +1365,6 @@
             flowObjectiveService.apply(deviceId, fwd);
         });
     }
-
     /**
      * Find first ipaddress for a given Host info i.e.  mac and vlan.
      *
@@ -1732,7 +1372,7 @@
      * @param vlanId  packet's vlan
      * @return next-hop link-local ipaddress for a given host
      */
-    private IpAddress getFirstIpByHost(MacAddress clientMac, VlanId vlanId) {
+    private IpAddress getFirstIpByHost(Boolean directConnFlag, MacAddress clientMac, VlanId vlanId) {
         IpAddress nextHopIp;
         // pick out the first link-local ip address
         HostId gwHostId = HostId.hostId(clientMac, vlanId);
@@ -1741,14 +1381,67 @@
             log.warn("Can't find gateway host for hostId {}", gwHostId);
             return null;
         }
-        nextHopIp = gwHost.ipAddresses()
-                .stream()
-                .filter(IpAddress::isIp6)
-                .filter(IpAddress::isLinkLocal)
-                .map(IpAddress::getIp6Address)
-                .findFirst()
-                .orElse(null);
+        if (directConnFlag) {
+            nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp6)
+                    .map(IpAddress::getIp6Address)
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp6)
+                    .filter(ip6 -> ip6.isLinkLocal())
+                    .map(IpAddress::getIp6Address)
+                    .findFirst()
+                    .orElse(null);
+        }
         return nextHopIp;
     }
 
+    private List<DhcpServerInfo> findValidServerInfo(boolean directConnFlag) {
+        List<DhcpServerInfo> validServerInfo;
+
+        if (directConnFlag || indirectServerInfoList.isEmpty()) {
+            validServerInfo = new ArrayList<DhcpServerInfo>(defaultServerInfoList);
+        } else {
+            validServerInfo = new ArrayList<DhcpServerInfo>(indirectServerInfoList);
+        }
+        return validServerInfo;
+    }
+
+    private DhcpServerInfo findServerInfoFromServer(boolean directConnFlag, ConnectPoint inPort) {
+        List<DhcpServerInfo> validServerInfoList = findValidServerInfo(directConnFlag);
+        DhcpServerInfo  foundServerInfo = null;
+        for (DhcpServerInfo serverInfo : validServerInfoList) {
+            if (inPort.equals(serverInfo.getDhcpServerConnectPoint().get())) {
+                foundServerInfo = serverInfo;
+                log.warn("ServerInfo found for Rcv port {} Server Connect Point {} for {}",
+                        inPort, serverInfo.getDhcpServerConnectPoint(), directConnFlag ? "direct" : "indirect");
+                break;
+            } else {
+                log.warn("Rcv port {} not the same as Server Connect Point {} for {}",
+                        inPort, serverInfo.getDhcpServerConnectPoint(), directConnFlag ? "direct" : "indirect");
+            }
+        }
+        return foundServerInfo;
+    }
+    /**
+     * Set the dhcp6 lease expiry poll interval value.
+     *
+     * @param val poll interval value in seconds
+     */
+    public void setDhcp6PollInterval(int val) {
+        dhcp6PollInterval = val;
+    }
+
+    /**
+     * Get the dhcp6 lease expiry poll interval value.
+     *
+     * @return poll interval value in seconds
+     */
+    public int getDhcp6PollInterval() {
+        return dhcp6PollInterval;
+    }
 }
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
new file mode 100644
index 0000000..5eb71b6
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.dhcprelay;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.DHCP6.MsgType;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onlab.packet.dhcp.Dhcp6Option;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+
+import org.onlab.util.HexString;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.DeviceId;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+
+
+public class Dhcp6HandlerUtil {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    // Returns the first v6 interface ip out of a set of interfaces or null.
+    // Checks all interfaces, and ignores v6 interface ips
+    public Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
+        for (Interface intf : intfs) {
+            for (InterfaceIpAddress ip : intf.ipAddressesList()) {
+                Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
+                if (relayAgentIp != null) {
+                    return relayAgentIp;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the first interface ip from interface.
+     *
+     * @param iface interface of one connect point
+     * @return the first interface IP; null if not exists an IP address in
+     *         these interfaces
+     */
+    public Ip6Address getFirstIpFromInterface(Interface iface) {
+        checkNotNull(iface, "Interface can't be null");
+        return iface.ipAddressesList().stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(IpAddress::isIp6)
+                .map(IpAddress::getIp6Address)
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * extract DHCP6 payload from dhcp6 relay message within relay-forwrd/reply.
+     *
+     * @param dhcp6 dhcp6 relay-reply or relay-foward
+     * @return dhcp6Packet dhcp6 packet extracted from relay-message
+     */
+    public DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
+
+        // extract the relay message if exist
+        DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
+                .filter(opt -> opt instanceof Dhcp6RelayOption)
+                .map(BasePacket::getPayload)
+                .map(pld -> (DHCP6) pld)
+                .findFirst()
+                .orElse(null);
+        if (dhcp6Payload == null) {
+            // Can't find dhcp payload
+            log.debug("Can't find dhcp6 payload from relay message");
+        } else {
+            log.debug("dhcp6 payload found from relay message {}", dhcp6Payload);
+        }
+        return dhcp6Payload;
+    }
+
+    /**
+     * find the leaf DHCP6 packet from multi-level relay packet.
+     *
+     * @param relayPacket dhcp6 relay packet
+     * @return leafPacket non-relay dhcp6 packet
+     */
+    public DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
+        DHCP6 dhcp6Parent = relayPacket;
+        DHCP6 dhcp6Child = null;
+
+        log.debug("getDhcp6Leaf entered.");
+        while (dhcp6Parent != null) {
+            dhcp6Child = dhcp6PacketFromRelayPacket(dhcp6Parent);
+            if (dhcp6Child != null) {
+                if (dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
+                        dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
+                    log.debug("leaf dhcp6 packet found.");
+                    break;
+                } else {
+                    // found another relay, go for another loop
+                    dhcp6Parent = dhcp6Child;
+                }
+            } else {
+                log.debug("Expected dhcp6 within relay pkt, but no dhcp6 leaf found.");
+                break;
+            }
+        }
+        return dhcp6Child;
+    }
+
+    /**
+     * check if DHCP6 relay-reply is reply.
+     *
+     * @param relayPacket dhcp6 relay-reply
+     * @return boolean relay-reply contains ack
+     */
+    public boolean isDhcp6Reply(DHCP6 relayPacket) {
+        DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
+        if (leafDhcp6 != null) {
+            if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
+                log.debug("isDhcp6Reply  true.");
+                return true;  // must be directly connected
+            } else {
+                log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
+            }
+        } else {
+            log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
+        }
+        log.debug("isDhcp6Reply  false.");
+        return false;
+    }
+
+    /**
+     * check if DHCP6 is release or relay-forward contains release.
+     *
+     * @param dhcp6Payload dhcp6 packet
+     * @return boolean dhcp6 contains release
+     */
+    public boolean isDhcp6Release(DHCP6 dhcp6Payload) {
+        if (dhcp6Payload.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
+            log.debug("isDhcp6Release  true.");
+            return true;  // must be directly connected
+        } else {
+            DHCP6 dhcp6Leaf = getDhcp6Leaf(dhcp6Payload);
+            if (dhcp6Leaf != null) {
+                if (dhcp6Leaf.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
+                    log.debug("isDhcp6Release  true. indirectlry connected");
+                    return true;
+                } else {
+                    log.debug("leaf dhcp6 is not release. MsgType {}",  dhcp6Leaf.getMsgType());
+                    return false;
+                }
+            } else {
+                log.debug("isDhcp6Release  false. dhcp6 is niether relay nor release.");
+                return false;
+            }
+        }
+    }
+
+
+    /**
+     * convert dhcp6 msgType to String.
+     *
+     * @param msgTypeVal msgType byte of dhcp6 packet
+     * @return String string value of dhcp6 msg type
+     */
+    public String getMsgTypeStr(byte msgTypeVal) {
+        MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
+        return DHCP6.MsgType.getMsgTypeStr(msgType);
+    }
+
+    /**
+     * find the string of dhcp6 leaf packets's msg type.
+     *
+     * @param directConnFlag boolean value indicating direct/indirect connection
+     * @param dhcp6Packet dhcp6 packet
+     * @return String string value of dhcp6 leaf packet msg type
+     */
+    public String findLeafMsgType(boolean directConnFlag, DHCP6  dhcp6Packet) {
+        if (directConnFlag) {
+            return getMsgTypeStr(dhcp6Packet.getMsgType());
+        } else {
+            DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet);
+            if (leafDhcp != null) {
+                return getMsgTypeStr(leafDhcp.getMsgType());
+            } else {
+                return "INVALID"; //DhcpRelayCounters.INVALID_PACKET;
+            }
+        }
+    }
+
+    /**
+     * find the string of dhcp6 leaf packets's msg type.
+     *
+     * @param fromClient indicate from what side a packet is received
+     * @param directConnFlag boolean value indicating direct/indirect connection
+     * @param dhcp6Packet dhcp6 packet
+     * @return String string value of dhcp6 leaf packet msg type
+     */
+    public String findMsgType(boolean fromClient, boolean directConnFlag, DHCP6  dhcp6Packet) {
+        if (fromClient) {
+            return findLeafMsgType(directConnFlag, dhcp6Packet);
+        } else {
+            DHCP6 embeddedDhcp6 = dhcp6Packet.getOptions().stream()
+                    .filter(opt -> opt instanceof Dhcp6RelayOption)
+                    .map(BasePacket::getPayload)
+                    .map(pld -> (DHCP6) pld)
+                    .findFirst()
+                    .orElse(null);
+            if (embeddedDhcp6 != null) {
+                return findLeafMsgType(directConnFlag, embeddedDhcp6);
+            } else {
+                return "INVALID"; //DhcpRelayCounters.INVALID_PACKET;
+            }
+        }
+    }
+
+    /**
+     * Determind if an Interface contains a vlan id.
+     *
+     * @param iface the Interface
+     * @param vlanId the vlan id
+     * @return true if the Interface contains the vlan id
+     */
+    public boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
+        if (vlanId.equals(VlanId.NONE)) {
+            // untagged packet, check if vlan untagged or vlan native is not NONE
+            return !iface.vlanUntagged().equals(VlanId.NONE) ||
+                    !iface.vlanNative().equals(VlanId.NONE);
+        }
+        // tagged packet, check if the interface contains the vlan
+        return iface.vlanTagged().contains(vlanId);
+    }
+
+    /**
+     * the new class the contains Ethernet packet and destination port.
+     */
+    public class InternalPacket {
+        Ethernet packet;
+        ConnectPoint destLocation;
+        public InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
+            packet = newPacket;
+            destLocation = newLocation;
+        }
+        void setLocation(ConnectPoint newLocation) {
+            destLocation = newLocation;
+        }
+    }
+    /**
+     * Check if the host is directly connected to the network or not.
+     *
+     * @param dhcp6Payload the dhcp6 payload
+     * @return true if the host is directly connected to the network; false otherwise
+     */
+    public boolean directlyConnected(DHCP6 dhcp6Payload) {
+        log.debug("directlyConnected enters");
+
+        if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
+                dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
+            log.debug("directlyConnected true. MsgType {}", dhcp6Payload.getMsgType());
+
+            return true;
+        }
+        // Regardless of relay-forward or relay-replay, check if we see another relay message
+        DHCP6 dhcp6Payload2 = dhcp6PacketFromRelayPacket(dhcp6Payload);
+        if (dhcp6Payload2 != null) {
+            if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELAY_FORW.value()) {
+                log.debug("directlyConnected  false. 1st realy-foward, 2nd MsgType {}", dhcp6Payload2.getMsgType());
+                return false;
+            } else {
+                // relay-reply
+                if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
+                    log.debug("directlyConnected  true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
+                    return true;  // must be directly connected
+                } else {
+                    log.debug("directlyConnected  false. 1st relay-reply, 2nd relay-reply MsgType {}",
+                            dhcp6Payload2.getMsgType());
+                    return false;  // must be indirectly connected
+                }
+            }
+        } else {
+            log.debug("directlyConnected  true.");
+            return true;
+        }
+    }
+    /**
+     * Check if a given server info has v6 ipaddress.
+     *
+     * @param serverInfo server info to check
+     * @return true if server info has v6 ip address; false otherwise
+     */
+    public boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
+        if (!serverInfo.getDhcpServerIp6().isPresent()) {
+            log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
+                    HexString.toHexString(serverInfo.getDhcpServerIp6().get().toOctets()));
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isConnectMacEmpty(DhcpServerInfo serverInfo, Set<Interface> clientInterfaces) {
+        if (!serverInfo.getDhcpConnectMac().isPresent()) {
+            log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
+                            + "packet processing from client on port: {}",
+                    !serverInfo.getDhcpGatewayIp6().isPresent() ? "server IP " + serverInfo.getDhcpServerIp6()
+                            : "gateway IP " + serverInfo.getDhcpGatewayIp6(),
+                    clientInterfaces.iterator().next().connectPoint());
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isRelayAgentIpFromCfgEmpty(DhcpServerInfo serverInfo, DeviceId receivedFromDevice) {
+        if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
+            log.warn("indirect connection: relayAgentIp NOT availale from config file! Use dynamic.");
+            return true;
+        }
+        return false;
+    }
+
+    private Dhcp6Option getInterfaceIdIdOption(PacketContext context, Ethernet clientPacket) {
+        String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
+        Dhcp6Option interfaceId = new Dhcp6Option();
+        interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
+        byte[] clientSoureMacBytes = clientPacket.getSourceMACAddress();
+        byte[] inPortStringBytes = inPortString.getBytes();
+        byte[] vlanIdBytes = new byte[2];
+        vlanIdBytes[0] = (byte) (clientPacket.getVlanID() & 0xff);
+        vlanIdBytes[1] = (byte) ((clientPacket.getVlanID() >> 8) & 0xff);
+        byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +
+                inPortStringBytes.length + vlanIdBytes.length];
+        log.debug("Length: interfaceIdBytes  {} clientSoureMacBytes {} inPortStringBytes {} vlan {}",
+                interfaceIdBytes.length, clientSoureMacBytes.length, inPortStringBytes.length,
+                vlanIdBytes.length);
+
+        System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
+        System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length,
+                inPortStringBytes.length);
+        System.arraycopy(vlanIdBytes, 0, interfaceIdBytes,
+                clientSoureMacBytes.length + inPortStringBytes.length,
+                vlanIdBytes.length);
+        interfaceId.setData(interfaceIdBytes);
+        interfaceId.setLength((short) interfaceIdBytes.length);
+        log.debug("interfaceId write srcMac {} portString {}",
+                HexString.toHexString(clientSoureMacBytes, ":"), inPortString);
+        return interfaceId;
+    }
+
+    private void addDhcp6OptionsFromClient(List<Dhcp6Option> options, byte[] dhcp6PacketByte,
+                                           PacketContext context, Ethernet clientPacket) {
+        Dhcp6Option relayMessage = new Dhcp6Option();
+        relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
+        relayMessage.setLength((short) dhcp6PacketByte.length);
+        relayMessage.setData(dhcp6PacketByte);
+        options.add(relayMessage);
+        // create interfaceId option
+        Dhcp6Option interfaceId = getInterfaceIdIdOption(context, clientPacket);
+        options.add(interfaceId);
+    }
+
+    /**
+     * build the DHCP6 solicit/request packet with gatewayip.
+     *
+     * @param context packet context
+     * @param clientPacket client ethernet packet
+     * @param clientInterfaces set of client side interfaces
+     * @param serverInfo target server which a packet is generated for
+     * @param serverInterface target server interface
+     * @return ethernet packet with dhcp6 packet info
+     */
+    public Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket,
+                                               Set<Interface> clientInterfaces, DhcpServerInfo serverInfo,
+                                               Interface serverInterface) {
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        DeviceId receivedFromDevice = receivedFrom.deviceId();
+
+        Ip6Address relayAgentIp = getRelayAgentIPv6Address(clientInterfaces);
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentIp == null || relayAgentMac == null) {
+            log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
+                            + "packet from client on port: {}. Aborting packet processing",
+                    clientInterfaces.iterator().next().connectPoint());
+            return null;
+        }
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+        boolean directConnFlag = directlyConnected(clientDhcp6);
+
+        Ip6Address serverIpFacing = getFirstIpFromInterface(serverInterface);
+        if (serverIpFacing == null || serverInterface.mac() == null) {
+            log.warn("No IP v6 address for server Interface {}", serverInterface);
+            return null;
+        }
+
+        Ethernet etherReply = clientPacket.duplicate();
+        etherReply.setSourceMACAddress(serverInterface.mac());
+
+        // set default info and replace with indirect if available later on.
+        if (serverInfo.getDhcpConnectMac().isPresent()) {
+            etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
+        }
+        if (serverInfo.getDhcpConnectVlan().isPresent()) {
+            etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
+        }
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        byte[] peerAddress = clientIpv6.getSourceAddress();
+        ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
+        ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+        DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
+        byte[] dhcp6PacketByte = dhcp6Packet.serialize();
+
+        DHCP6 dhcp6Relay = new DHCP6();
+
+        dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
+
+        if (directConnFlag) {
+            dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
+        } else {
+            if (isServerIpEmpty(serverInfo)) {
+                log.warn("indirect DhcpServerIp empty... use default server ");
+            } else {
+                // Indirect case, replace destination to indirect dhcp server if exist
+                // Check if mac is obtained for valid server ip
+                if (isConnectMacEmpty(serverInfo, clientInterfaces)) {
+                    log.warn("indirect Dhcp ConnectMac empty ...");
+                    return null;
+                }
+                etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
+                etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
+                ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
+            }
+            if (isRelayAgentIpFromCfgEmpty(serverInfo, receivedFromDevice)) {
+                dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
+                log.debug("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}",
+                        HexString.toHexString(relayAgentIp.toOctets(), ":"));
+            } else {
+                dhcp6Relay.setLinkAddress(serverInfo.getRelayAgentIp6(receivedFromDevice).get().toOctets());
+            }
+        }
+        // peer address: address of the client or relay agent from which the message to be relayed was received.
+        dhcp6Relay.setPeerAddress(peerAddress);
+        // directly connected case, hop count is zero; otherwise, hop count + 1
+        if (directConnFlag) {
+            dhcp6Relay.setHopCount((byte) 0);
+        } else {
+            dhcp6Relay.setHopCount((byte) (dhcp6Packet.getHopCount() + 1));
+        }
+
+        List<Dhcp6Option> options = new ArrayList<>();
+        addDhcp6OptionsFromClient(options, dhcp6PacketByte, context, clientPacket);
+        dhcp6Relay.setOptions(options);
+        udpPacket.setPayload(dhcp6Relay);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        ipv6Packet.setHopLimit((byte) 64);
+        etherReply.setPayload(ipv6Packet);
+
+        return etherReply;
+    }
+
+    /**
+     * build the DHCP6 solicit/request packet with gatewayip.
+     *
+     * @param directConnFlag flag indicating if packet is from direct client or not
+     * @param serverInfo server to check its connect point
+     * @return boolean true if serverInfo is found; false otherwise
+     */
+    public boolean checkDhcpServerConnPt(boolean directConnFlag,
+                                          DhcpServerInfo serverInfo) {
+        if (serverInfo.getDhcpServerConnectPoint() == null) {
+            log.warn("DHCP6 server connect point for {} connPt {}",
+                    directConnFlag ? "direct" : "indirect", serverInfo.getDhcpServerConnectPoint());
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
index 74e1379..018c450 100644
--- a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
+++ b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
@@ -54,6 +54,8 @@
 import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
 import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
 import org.onlab.packet.dhcp.Dhcp6Option;
+import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
+import org.onlab.packet.dhcp.Dhcp6Duid;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.TestApplicationId;
 import org.onosproject.cfg.ComponentConfigService;
@@ -358,6 +360,7 @@
         // properties
         Dictionary<String, Object> dictionary = createNiceMock(Dictionary.class);
         expect(dictionary.get("arpEnabled")).andReturn(true).anyTimes();
+        expect(dictionary.get("dhcpPollInterval")).andReturn(120).anyTimes();
         ComponentContext context = createNiceMock(ComponentContext.class);
         expect(context.getProperties()).andReturn(dictionary).anyTimes();
 
@@ -1233,6 +1236,14 @@
         iaAddressOption.setValidLifetime(1200);
         iaAddressOption.setLength((short) Dhcp6IaAddressOption.DEFAULT_LEN);
 
+        Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
+        Dhcp6Duid dhcp6Duip = new Dhcp6Duid();
+        dhcp6Duip.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
+        dhcp6Duip.setHardwareType((short) 0x01);   // Ethernet
+        dhcp6Duip.setDuidTime(1234);
+        dhcp6Duip.setLinkLayerAddress(CLIENT_MAC.toBytes());
+        clientIdOption.setDuid(dhcp6Duip);
+
         Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
         iaNaOption.setCode(DHCP6.OptionCode.IA_NA.value());
         iaNaOption.setIaId(0);
@@ -1265,6 +1276,7 @@
         dhcp6.setMsgType(msgType);
         List<Dhcp6Option> dhcp6Options = new ArrayList<Dhcp6Option>();
         dhcp6Options.add(iaNaOption);
+        dhcp6Options.add(clientIdOption);
         dhcp6Options.add(iaPdOption);
         dhcp6.setOptions(dhcp6Options);
 
diff --git a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
index 25ef6a3..8dbd1dc 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
@@ -111,6 +111,38 @@
                     return null;
             }
         }
+        public static String  getMsgTypeStr(final MsgType msgType) {
+            switch (msgType) {
+                case SOLICIT:
+                    return "SOLICIT";
+                case ADVERTISE:
+                    return "ADVERTISE";
+                case REQUEST:
+                    return "REQUEST";
+                case CONFIRM:
+                    return "CONFIRM";
+                case RENEW:
+                    return "RENEW";
+                case REBIND:
+                    return "REBIND";
+                case REPLY:
+                    return "REPLY";
+                case RELEASE:
+                    return "RELEASE";
+                case DECLINE:
+                    return "DECLINE";
+                case RECONFIGURE:
+                    return "RECONFIGURE";
+                case INFORMATION_REQUEST:
+                    return "INFORMATION_REQUEST";
+                case RELAY_FORW:
+                    return "RELAY_FORW";
+                case RELAY_REPL:
+                    return "RELAY_REPL";
+                default:
+                    return "NULL";
+            }
+        }
     }
 
     /**
