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 09a118c..80d29fc 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -39,8 +39,11 @@
 import org.onlab.packet.TpPort;
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.Dhcp6ClientDataOption;
+import org.onlab.packet.dhcp.Dhcp6LeaseQueryOption;
 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;
@@ -102,8 +105,6 @@
 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;
 import java.util.Collection;
@@ -117,6 +118,7 @@
 import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
 import java.util.concurrent.Semaphore;
 
+
 @Component
 @Service
 @Property(name = "version", value = "6")
@@ -139,9 +141,18 @@
             .matchUdpSrc(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
             .matchUdpDst(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
             .build();
+    // lease query reply is from server to client (no relay in between) - so we need to
+    // catch that scenario also ..
+    private static final TrafficSelector LEASE_QUERY_RESPONSE_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV6)
+            .matchIPProtocol(IPv6.PROTOCOL_UDP)
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_V6_CLIENT_PORT))
+            .build();
     static final Set<TrafficSelector> DHCP_SELECTORS = ImmutableSet.of(
             CLIENT_SERVER_SELECTOR,
-            SERVER_RELAY_SELECTOR
+            SERVER_RELAY_SELECTOR,
+            LEASE_QUERY_RESPONSE_SELECTOR
     );
     private static Logger log = LoggerFactory.getLogger(Dhcp6HandlerImpl.class);
 
@@ -182,11 +193,8 @@
     protected ApplicationId appId;
     protected Multimap<DeviceId, VlanId> ignoredVlans = HashMultimap.create();
     private InternalHostListener hostListener = new InternalHostListener();
-
     private Boolean dhcpFpmEnabled = false;
-
     private Dhcp6HandlerUtil dhcp6HandlerUtil = new Dhcp6HandlerUtil();
-
     private List<DhcpServerInfo> defaultServerInfoList = Lists.newArrayList();
     private List<DhcpServerInfo> indirectServerInfoList = Lists.newArrayList();
     private class IpAddressInfo {
@@ -211,10 +219,12 @@
                             DHCP6.MsgType.RELEASE.value(),
                             DHCP6.MsgType.DECLINE.value(),
                             DHCP6.MsgType.CONFIRM.value(),
-                            DHCP6.MsgType.RELAY_FORW.value());
+                            DHCP6.MsgType.RELAY_FORW.value(),
+                            DHCP6.MsgType.LEASEQUERY.value());
     // SERVER message types
     public static final Set<Byte> MSG_TYPE_FROM_SERVER =
-            ImmutableSet.of(DHCP6.MsgType.RELAY_REPL.value());
+            ImmutableSet.of(DHCP6.MsgType.RELAY_REPL.value(),
+                            DHCP6.MsgType.LEASEQUERY_REPLY.value());
 
     @Activate
     protected void activate() {
@@ -267,7 +277,6 @@
             }
             processIgnoreVlanRule(deviceId, vlanId, ADD);
         });
-
         ignoredVlans.forEach((deviceId, vlanId) -> {
             if (!config.ignoredVlans().get(deviceId).contains(vlanId)) {
                 // not contains in new config, remove it
@@ -287,6 +296,160 @@
         });
     }
 
+    public DhcpRecord getDhcpRelayRecordFor(Ip6Address clientAddress) {
+
+        Collection<DhcpRecord>  records = dhcpRelayStore.getDhcpRecords();
+        DhcpRecord dr = null;
+        for (DhcpRecord e:records) {
+            if (e.ip6Address().isPresent()) {
+                if (e.ip6Address().get().equals(clientAddress)) {
+                    dr = e;
+                    break;
+                }
+            }
+        }
+        return dr;
+    }
+
+    public MacAddress findNextHopMacForIp6FromRelayStore(Ip6Address clientAddress,
+                                                         MacAddress clientMacAddress, VlanId vlanID) {
+
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+
+        if (dr != null) {
+           Optional<MacAddress> nextHopTempMac = dr.nextHopTemp();
+            if (nextHopTempMac.isPresent()) {
+                log.info("findNextHopForIp6FromRelayStore " + clientAddress + " got mac " + nextHopTempMac.toString());
+                return nextHopTempMac.get();
+            }
+        } else {
+            log.warn("findNextHopMacForIp6FromRelayStore could NOT find next hop for " + clientAddress);
+            return null;
+        }
+        return null;
+    }
+
+    public Ip6Address findNextHopIp6FromRelayStore(Ip6Address clientAddress) {
+
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+        if (dr != null) {
+            Optional<MacAddress> nextHopMac = dr.nextHop();
+            if (nextHopMac.isPresent()) {
+                // find the local ip6 from the host store
+                HostId gwHostId = HostId.hostId(nextHopMac.get(), dr.vlanId());
+                Host gwHost = hostService.getHost(gwHostId);
+                if (gwHost == null) {
+                    log.warn("Can't find next hop host ID {}", gwHostId);
+                    return null;
+                }
+                Ip6Address nextHopIp = gwHost.ipAddresses()
+                        .stream()
+                        .filter(IpAddress::isIp6)
+                        .filter(IpAddress::isLinkLocal)
+                        .map(IpAddress::getIp6Address)
+                        .findFirst()
+                        .orElse(null);
+
+                log.info("findNextHopIp6FromRelayStore " + clientAddress + " got mac " +
+                                 nextHopMac.toString() + " ip6 " + nextHopIp);
+                return nextHopIp;
+            }
+        } else {
+            log.warn("findNextHopIp6FromRelayStore could NOT find next hop for " + clientAddress);
+            return null;
+        }
+        return null;
+    }
+
+    private void setPotentialNextHopForIp6InRelayStore(Ip6Address clientAddress,
+                                                       VlanId vlanId, MacAddress nh) {
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+        if (dr != null) {
+            dr.nextHopTemp(nh);
+            log.debug("LQ6 potential NH mac " + nh.toString() + " UPDATED in RelayRecord client " + clientAddress);
+        } else {
+            log.warn("LQ6 potential NH mac" + nh.toString() +
+                             " NOT FOUND in RelayRecord for client - LQ rejected" + clientAddress);
+        }
+    }
+
+    public void handleLeaseQuery6ReplyMsg(PacketContext context, DHCP6 dhcp6Payload) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        log.info("Got LQV6-REPLY on port {}", inPort);
+        List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
+        log.info("Options list: {}", lopt);
+        // find out if this lease is known is
+        Dhcp6ClientDataOption clientDataOption = dhcp6Payload.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6ClientDataOption)
+                .map(pld -> (Dhcp6ClientDataOption) pld)
+                .findFirst()
+                .orElse(null);
+
+        if (clientDataOption == null) {
+            log.warn("clientDataOption option is not present, " +
+                             "lease is UNKNOWN - not adding any new route...");
+        } else {
+            Dhcp6IaAddressOption aiAddressOption = clientDataOption.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6IaAddressOption)
+                    .map(pld -> (Dhcp6IaAddressOption) pld)
+                    .findFirst()
+                    .orElse(null);
+
+            Dhcp6ClientIdOption clientIdOption = clientDataOption.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6ClientIdOption)
+                    .map(pld -> (Dhcp6ClientIdOption) pld)
+                    .findFirst()
+                    .orElse(null);
+
+            if (aiAddressOption == null) {
+                log.warn("clientDataOption from DHCP server does not " +
+                                 "contains Dhcp6IaAddressOption for the client - giving up...");
+            } else {
+                Ip6Address clientAddress = aiAddressOption.getIp6Address();
+                MacAddress clientMacAddress = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
+                Ethernet packet = context.inPacket().parsed();
+                VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+                MacAddress potentialNextHopMac =
+                        findNextHopMacForIp6FromRelayStore(clientAddress, clientMacAddress, vlanId);
+
+                if (potentialNextHopMac == null) {
+                    log.warn("Can't find next hop host mac for client {} mac:{}/{}",
+                             clientAddress, clientMacAddress, vlanId);
+                    return;
+                } else {
+                    log.info("Next hop mac for {}/{}/{} is {}", clientAddress,
+                             clientMacAddress, vlanId, potentialNextHopMac.toString());
+                }
+                // search the next hop in the hosts store
+                HostId gwHostId = HostId.hostId(potentialNextHopMac, vlanId);
+                Host gwHost = hostService.getHost(gwHostId);
+                if (gwHost == null) {
+                    log.warn("Can't find next hop host ID {}", gwHostId);
+                    return;
+                }
+                Ip6Address nextHopIp = gwHost.ipAddresses()
+                        .stream()
+                        .filter(IpAddress::isIp6)
+                        .filter(IpAddress::isLinkLocal)
+                        .map(IpAddress::getIp6Address)
+                        .findFirst()
+                        .orElse(null);
+                if (nextHopIp == null) {
+                    log.warn("Can't find IP6 address of next hop {}", gwHost);
+                    return;
+                }
+                log.info("client " + clientAddress + " is known !");
+                Route routeForIP6 = new Route(Route.Source.STATIC, clientAddress.toIpPrefix(), nextHopIp);
+                log.debug("updating route of Client for indirectly connected.");
+                log.debug("client ip: " + clientAddress + ", next hop ip6: " + nextHopIp);
+                routeStore.updateRoute(routeForIP6);
+            }
+        }
+    }
+
     @Override
     public void processDhcpPacket(PacketContext context, BasePacket payload) {
         checkNotNull(payload, "DHCP6 payload can't be null");
@@ -295,7 +458,8 @@
         Ethernet receivedPacket = context.inPacket().parsed();
 
         if (!configured()) {
-            log.warn("Missing DHCP6 relay server config. Abort packet processing dhcp6 payload {}", dhcp6Payload);
+            log.warn("Missing DHCP6 relay server config. " +
+                             "Abort packet processing dhcp6 payload {}", dhcp6Payload);
             return;
         }
         byte msgTypeVal = dhcp6Payload.getMsgType();
@@ -314,22 +478,47 @@
             return;
         }
 
-        if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
-
+        if (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
             List<InternalPacket> ethernetClientPacket =
-                    processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
+                    processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload);
             for (InternalPacket internalPacket : ethernetClientPacket) {
                 forwardPacket(internalPacket);
             }
-        } else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
-            log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}", msgTypeVal);
+        } else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
+
+            IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
+            UDP clientUdp = (UDP) clientIpv6.getPayload();
+            DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+            Interface serverInterface = dhcp6HandlerUtil.directlyConnected(clientDhcp6) ?
+                    getServerInterface() : getIndirectServerInterface();
             InternalPacket ethernetPacketReply =
-                    processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
+                    dhcp6HandlerUtil.processLQ6PacketFromServer(
+                            defaultServerInfoList, indirectServerInfoList,
+                            serverInterface, interfaceService,
+                            hostService,
+                            context, receivedPacket, receivingInterfaces);
             if (ethernetPacketReply != null) {
                 forwardPacket(ethernetPacketReply);
             }
+            handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
         } else {
-            log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
+            if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
+
+                List<InternalPacket> ethernetClientPacket =
+                        processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
+                for (InternalPacket internalPacket : ethernetClientPacket) {
+                    forwardPacket(internalPacket);
+                }
+            } 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("Not so fast, packet type {} not supported yet", msgTypeVal);
+            }
         }
     }
 
@@ -352,8 +541,6 @@
         // Do nothing here
     }
 
-
-
     //forward the packet to ConnectPoint where the DHCP server is attached.
     private void forwardPacket(InternalPacket packet) {
         //send Packetout to dhcp server connectpoint.
@@ -369,9 +556,6 @@
         } // if
     }
 
-
-
-
     /**
      * extract from dhcp6 packet client ipv6 address of given by dhcp server.
      *
@@ -422,6 +606,7 @@
         }
         return ipInfo;
     }
+
     /**
      * extract from dhcp6 packet Prefix prefix provided by dhcp server.
      *
@@ -500,6 +685,7 @@
 
         return clientIdOption;
     }
+
     /**
      * remove host or route and update dhcp relay record attributes.
      *
@@ -661,6 +847,7 @@
      * @param embeddedDhcp6 the dhcp6 payload within relay
      * @param srcMac client gw/host macAddress
      * @param clientInterface client interface
+     * @param dhcpServerIp6Address DHCP server IP
      */
     private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay,
                                 DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface) {
@@ -774,11 +961,11 @@
         if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
             if (ipInfo != null) {
                 log.debug("IP6 address is being stored into dhcp-relay store.");
-                log.debug("IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
+                log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
                 record.ip6Address(ipInfo.ip6Address);
                 record.updateAddrPrefTime(ipInfo.prefTime);
                 record.updateLastIp6Update();
-            } else {
+             } else {
                 log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
             }
             if (pdInfo != null) {
@@ -811,6 +998,103 @@
         }
     }
 
+    private List<InternalPacket> processLQ6PacketFromClient(PacketContext context,
+                                                              Ethernet clientPacket,
+                                                              Set<Interface> clientInterfaces,
+                                                              DHCP6 dhcp6Payload) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        log.info("Got LQ-REQUEST V6 on port {}", inPort);
+        List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
+        log.info("Options list: {}", lopt);
+        Dhcp6LeaseQueryOption lqoption = dhcp6Payload.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6LeaseQueryOption)
+                .map(pld -> (Dhcp6LeaseQueryOption) pld)
+                .findFirst()
+                .orElse(null);
+
+        if (lqoption == null) {
+            // Can't find dhcp payload
+            log.warn("Can't find dhcp6 lease query message - aborting");
+            return null;
+        } else {
+            log.info("dhcp6 lqv6 options found: {}", lqoption);
+        }
+        log.warn("LQv6 for " + lqoption.linkAddress.toString() + " comes from " + inPort.toString());
+        Ethernet packet = context.inPacket().parsed();
+        Ip6Address clientAddress = lqoption.linkAddress;
+        IPv6 ipv6Packet = (IPv6) packet.getPayload();
+        Ip6Address nextHopIp = findNextHopIp6FromRelayStore(clientAddress);
+
+        // 1. only if there is a route to remove - remove it
+        if (nextHopIp != null) {
+            Route routeForIP6 = new Route(Route.Source.STATIC, clientAddress.toIpPrefix(), nextHopIp);
+            log.debug("Removing route of Client " + clientAddress +
+                              " for indirectly connected - next hop ip6 " + nextHopIp);
+            routeStore.removeRoute(routeForIP6);
+        }
+
+        // 2. note the potential NH this packet came from in case it's a known lease
+        //    this NH will then be used to build the route
+        MacAddress potentialNH = packet.getSourceMAC();
+        VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+        setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
+
+        // 3. route this LQ6 to all relevant servers
+        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 -> dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst()
+                .orElse(null);
+
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
+
+        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;
+            }
+
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+
+
+            Ethernet etherRouted = (Ethernet) clientPacket.clone();
+            MacAddress macFacingServer = serverInterface.mac();
+            if (macFacingServer == null) {
+                log.warn("No MAC address for server Interface {}", serverInterface);
+                return null;
+            }
+            etherRouted.setSourceMACAddress(macFacingServer);
+            etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+            InternalPacket internalPacket =
+                    new Dhcp6HandlerUtil().new InternalPacket(etherRouted,
+                              serverInfo.getDhcpServerConnectPoint().get());
+            internalPackets.add(internalPacket);
+            log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
+        }
+        log.debug("num of client packets to send is{}", internalPackets.size());
+
+        return internalPackets;
+    }
+
     /**
      * build the DHCP6 solicit/request packet with gatewayip.
      *
@@ -980,7 +1264,9 @@
             udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
         }
         // add host or route
-        addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6, clientMac, clientInterface);
+        addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6,
+                       clientMac, clientInterface);
+
 
         udpPacket.setPayload(embeddedDhcp6);
         udpPacket.resetChecksum();
@@ -989,6 +1275,19 @@
         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) {
@@ -1131,7 +1430,6 @@
             }
         }
     }
-
     /**
      * Handle host removed.
      * If the host is DHCP server or gateway, unset connect mac and vlan.
@@ -1181,6 +1479,65 @@
                 .findFirst()
                 .orElse(null);
     }
+
+   /**
+     * Gets Interface facing to the server for default host.
+     *
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getServerInterface() {
+        DhcpServerInfo serverInfo;
+        ConnectPoint dhcpServerConnectPoint;
+        VlanId dhcpConnectVlan;
+
+        if (!defaultServerInfoList.isEmpty()) {
+            serverInfo = defaultServerInfoList.get(0);
+            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        } else {
+            return null;
+        }
+        if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
+            log.info("Default DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
+            return null;
+        }
+        return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                .stream()
+                .filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * 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 -> dhcp6HandlerUtil.interfaceContainsVlan(iface, indirectDhcpConnectVlan))
+                .findFirst()
+                .orElse(null);
+    }
+
     /**
      * Checks if serverInfo's host info (mac and vlan) is filled in; if not, fills in.
      *
@@ -1256,15 +1613,16 @@
         return serverInterface;
     }
 
-
     private void requestDhcpPacket(Ip6Address serverIp) {
         requestServerDhcpPacket(serverIp);
         requestClientDhcpPacket(serverIp);
+        requestServerLQPacket(serverIp);
     }
 
     private void cancelDhcpPacket(Ip6Address serverIp) {
         cancelServerDhcpPacket(serverIp);
         cancelClientDhcpPacket(serverIp);
+        cancelServerLQPacket(serverIp);
     }
 
     private void cancelServerDhcpPacket(Ip6Address serverIp) {
@@ -1277,6 +1635,16 @@
                                     appId);
     }
 
+    private void cancelServerLQPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(LEASE_QUERY_RESPONSE_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(serverSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
     private void requestServerDhcpPacket(Ip6Address serverIp) {
         TrafficSelector serverSelector =
                 DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
@@ -1287,6 +1655,16 @@
                                      appId);
     }
 
+    private void requestServerLQPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(LEASE_QUERY_RESPONSE_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(serverSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
     private void cancelClientDhcpPacket(Ip6Address serverIp) {
         // Packet comes from relay
         TrafficSelector indirectClientSelector =
@@ -1419,6 +1797,7 @@
             flowObjectiveService.apply(deviceId, fwd);
         });
     }
+
     /**
      * Find first ipaddress for a given Host info i.e.  mac and vlan.
      *
@@ -1481,6 +1860,7 @@
         }
         return foundServerInfo;
     }
+
     /**
      * Set the dhcp6 lease expiry poll interval value.
      *
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
index 6e47a0d..17456f9 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
@@ -44,8 +44,11 @@
 import java.util.Set;
 import java.util.List;
 import java.util.ArrayList;
+import org.onosproject.net.intf.InterfaceService;
 
-
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.HostLocation;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -69,6 +72,127 @@
     }
 
     /**
+     *
+     * process the LQ reply packet from dhcp server.
+     *
+     * @param defaultServerInfoList default server list
+     * @param indirectServerInfoList default indirect server list
+     * @param serverInterface server interface
+     * @param interfaceService interface service
+     * @param hostService host service
+     * @param context packet context
+     * @param receivedPacket server ethernet packet
+     * @param recevingInterfaces set of server side interfaces
+     * @return a packet ready to be sent to relevant output interface
+     */
+    public InternalPacket processLQ6PacketFromServer(
+            List<DhcpServerInfo> defaultServerInfoList,
+            List<DhcpServerInfo> indirectServerInfoList,
+            Interface serverInterface,
+            InterfaceService interfaceService,
+            HostService hostService,
+            PacketContext context,
+            Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
+        // get dhcp6 header.
+        Ethernet etherReply = (Ethernet) receivedPacket.clone();
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        DHCP6 lq6Reply = (DHCP6) udpPacket.getPayload();
+
+        // TODO: refactor
+        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;
+
+        // todo: refactor
+        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);
+        }
+
+        Boolean directConnFlag = directlyConnected(lq6Reply);
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        if ((directConnFlag || (!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;
+        }
+
+        if (!directConnFlag && indirectDhcpServerIp != null &&
+                !inPort.equals(indirectDhcpServerConnectPoint)) {
+            log.warn("Receiving port {} is not the same as server connect point {} for indirect",
+                     inPort, indirectDhcpServerConnectPoint);
+            return null;
+        }
+
+
+        Ip6Address nextHopIP =  Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
+        // use hosts store to find out the next hop mac and connection point
+        Set<Host> hosts = hostService.getHostsByIp(nextHopIP);
+        Host host;
+        if (!hosts.isEmpty()) {
+            host = hosts.iterator().next();
+        } else {
+            log.warn("Host {} is not in store", nextHopIP);
+            return null;
+        }
+
+        HostLocation hl = host.location();
+        String clientConnectionPointStr = hl.toString(); // iterator().next());
+        ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
+
+
+        VlanId originalPacketVlanId = VlanId.vlanId(etherReply.getVlanID());
+        Interface iface;
+        iface = interfaceService.getInterfacesByPort(clientConnectionPoint)
+                .stream()
+                .filter(iface1 -> interfaceContainsVlan(iface1, originalPacketVlanId))
+                .findFirst()
+                .orElse(null);
+
+        etherReply.setSourceMACAddress(iface.mac());
+        etherReply.setDestinationMACAddress(host.mac());
+
+
+        // add host or route
+        //addHostOrRoute(directConnFlag, clientConnectionPoint, lq6Reply, embeddedDhcp6, clientMac, clientInterface);
+        // workaround for a bug where core sends src port as 547 (server)
+        udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
+        udpPacket.setPayload(lq6Reply);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv6Packet);
+
+        return new Dhcp6HandlerUtil().new InternalPacket(etherReply, clientConnectionPoint);
+    }
+    /**
      * Returns the first interface ip from interface.
      *
      * @param iface interface of one connect point
@@ -258,7 +382,14 @@
      * @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.LEASEQUERY.value() ||
+                dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
+            log.debug("directlyConnected false. MsgType {}", dhcp6Payload.getMsgType());
+
+            return false;
+        }
 
         if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
                 dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java
index 44c6c3c..e4c2673 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java
@@ -53,7 +53,6 @@
     private IpPrefix pdPrefix;
     private DHCP6.MsgType ip6Status;
 
-
     private long lastSeen;
     private long lastIp6Update;
     private long lastPdUpdate;
@@ -418,7 +417,6 @@
         newRecord.addrPrefTime = addrPrefTime;
         newRecord.pdPrefTime = pdPrefTime;
         newRecord.v6Counters = v6Counters;
-
         return newRecord;
     }
 
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 8dbd1dc..50b11a1 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
@@ -19,11 +19,13 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import org.onlab.packet.dhcp.Dhcp6ClientDataOption;
 import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
 import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
 import org.onlab.packet.dhcp.Dhcp6IaNaOption;
 import org.onlab.packet.dhcp.Dhcp6IaTaOption;
 import org.onlab.packet.dhcp.Dhcp6IaPdOption;
+import org.onlab.packet.dhcp.Dhcp6LeaseQueryOption;
 import org.onlab.packet.dhcp.Dhcp6Option;
 import org.onlab.packet.dhcp.Dhcp6RelayOption;
 import org.onlab.packet.dhcp.Dhcp6InterfaceIdOption;
@@ -60,7 +62,12 @@
     // Relay message types
     public static final Set<Byte> RELAY_MSG_TYPES =
             ImmutableSet.of(MsgType.RELAY_FORW.value,
-                            MsgType.RELAY_REPL.value);
+                            MsgType.RELAY_REPL.value
+            );
+    public static final Set<Byte> LEASEQUERY_MSG_TYPES =
+            ImmutableSet.of(MsgType.LEASEQUERY.value,
+                            MsgType.LEASEQUERY_REPLY.value
+            );
 
     /**
      * DHCPv6 message type.
@@ -70,7 +77,8 @@
         CONFIRM((byte) 4), RENEW((byte) 5), REBIND((byte) 6),
         REPLY((byte) 7), RELEASE((byte) 8), DECLINE((byte) 9),
         RECONFIGURE((byte) 10), INFORMATION_REQUEST((byte) 11),
-        RELAY_FORW((byte) 12), RELAY_REPL((byte) 13);
+        RELAY_FORW((byte) 12), RELAY_REPL((byte) 13), LEASEQUERY((byte) 14),
+        LEASEQUERY_REPLY((byte) 15);
 
         protected byte value;
         MsgType(final byte value) {
@@ -107,6 +115,10 @@
                     return RELAY_FORW;
                 case 13:
                     return RELAY_REPL;
+                case 14:
+                    return LEASEQUERY;
+                case 15:
+                    return LEASEQUERY_REPLY;
                 default:
                     return null;
             }
@@ -155,7 +167,8 @@
         STATUS_CODE((short) 13), RAPID_COMMIT((short) 14), USER_CLASS((short) 15),
         VENDOR_CLASS((short) 16), VENDOR_OPTS((short) 17), INTERFACE_ID((short) 18),
         RECONF_MSG((short) 19), RECONF_ACCEPT((short) 20), IA_PD((short) 25), IAPREFIX((short) 26),
-        SUBSCRIBER_ID((short) 38);
+        SUBSCRIBER_ID((short) 38), OPTION_ERO((short) 43), LEASE_QUERY((short) 44),
+        CLIENT_DATA((short) 45),  CLIENT_LT((short) 48);
 
         protected short value;
         OptionCode(final short value) {
@@ -175,6 +188,8 @@
                             .put(OptionCode.CLIENTID.value, Dhcp6ClientIdOption.deserializer())
                             .put(OptionCode.IA_PD.value, Dhcp6IaPdOption.deserializer())
                             .put(OptionCode.INTERFACE_ID.value, Dhcp6InterfaceIdOption.deserializer())
+                            .put(OptionCode.LEASE_QUERY.value, Dhcp6LeaseQueryOption.deserializer())
+                            .put(OptionCode.CLIENT_DATA.value, Dhcp6ClientDataOption.deserializer())
                     .build();
 
     // general field
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6CLTOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6CLTOption.java
new file mode 100644
index 0000000..c509ee3
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6CLTOption.java
@@ -0,0 +1,141 @@
+/*
+ * 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.onlab.packet.dhcp;
+
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Deserializer;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+public final class Dhcp6CLTOption extends Dhcp6Option {
+    public static final int DEFAULT_LEN = 4;
+    private int clt; // client last transaction time
+
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.CLIENT_LT.value();
+    }
+
+    @Override
+    public short getLength() {
+        return (short) (DEFAULT_LEN);
+    }
+
+    /**
+     * Gets Client Last Transaction Time.
+     *
+     * @return Client Last Transaction Time
+     */
+    public int getClt() {
+        return clt;
+    }
+
+    /**
+     * Sets Identity Association ID.
+     *
+     * @param clt the Client Last Transaction Time.
+     */
+    public void setClt(int clt) {
+        this.clt = clt;
+    }
+
+
+    /**
+     * Default constructor.
+     */
+    public Dhcp6CLTOption() {
+    }
+
+    /**
+     * Constructs a DHCPv6  Client Last Transaction Time option.
+     *
+     * @param dhcp6Option the DHCPv6 option
+     */
+    public Dhcp6CLTOption(Dhcp6Option dhcp6Option) {
+        super(dhcp6Option);
+    }
+
+    /**
+     * Gets deserializer.
+     *
+     * @return the deserializer
+     */
+    public static Deserializer<Dhcp6Option> deserializer() {
+        return (data, offset, length) -> {
+            Dhcp6Option dhcp6Option =
+                    Dhcp6Option.deserializer().deserialize(data, offset, length);
+            if (dhcp6Option.getLength() < DEFAULT_LEN) {
+                throw new DeserializationException("Invalid CLT option data");
+            }
+            Dhcp6CLTOption cltOption = new Dhcp6CLTOption(dhcp6Option);
+            byte[] optionData = cltOption.getData();
+            ByteBuffer bb = ByteBuffer.wrap(optionData);
+            cltOption.clt = bb.getInt();
+
+            return cltOption;
+        };
+    }
+
+    @Override
+    public byte[] serialize() {
+        int payloadLen = DEFAULT_LEN;
+        int len = Dhcp6Option.DEFAULT_LEN + payloadLen;
+        ByteBuffer bb = ByteBuffer.allocate(len);
+        bb.putShort(DHCP6.OptionCode.CLIENT_LT.value());
+        bb.putShort((short) payloadLen);
+        bb.putInt(clt);
+        return bb.array();
+    }
+
+
+    @Override
+    public String toString() {
+        return getToStringHelper()
+                .add("clt", clt)
+                .toString();
+    }
+
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), clt);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Dhcp6CLTOption)) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final Dhcp6CLTOption other = (Dhcp6CLTOption) obj;
+
+        return Objects.equals(getCode(), other.getCode()) &&
+                Objects.equals(getLength(), other.getLength()) &&
+                Objects.equals(clt, other.clt);
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6ClientDataOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6ClientDataOption.java
new file mode 100644
index 0000000..01b4cc3
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6ClientDataOption.java
@@ -0,0 +1,161 @@
+/*
+ * 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.onlab.packet.dhcp;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Deserializer;
+import org.onlab.packet.Ip6Address;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * DHCPv6 Client Data Option.
+ */
+public final class Dhcp6ClientDataOption extends Dhcp6Option {
+    private List<Dhcp6Option> options;
+    private Ip6Address clientIaAddress;
+    public static final int DEFAULT_LEN = 1 + 16;
+
+    public Dhcp6ClientDataOption(Dhcp6Option dhcp6Option) {
+        super(dhcp6Option);
+    }
+
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.CLIENT_DATA.value();
+    }
+
+    @Override
+    public short getLength() {
+        //return (short) (DEFAULT_LEN + options.stream()
+        //        .mapToInt(opt -> (int) opt.getLength() + Dhcp6Option.DEFAULT_LEN)
+        //        .sum());
+        return (short) payload.serialize().length;
+    }
+
+    @Override
+    public byte[] getData() {
+        return payload.serialize();
+    }
+
+    public List<Dhcp6Option> getOptions() {
+        return options;
+    }
+
+    public Ip6Address getIaAddress() {
+        return clientIaAddress;
+    }
+
+    public static Deserializer<Dhcp6Option> deserializer() {
+        return (data, offset, length) -> {
+            Dhcp6Option dhcp6Option = Dhcp6Option.deserializer().deserialize(data, offset, length);
+            Dhcp6ClientDataOption clientData = new Dhcp6ClientDataOption(dhcp6Option);
+
+            if (dhcp6Option.getLength() < DEFAULT_LEN) {
+                throw new DeserializationException("Invalid length of Client Id option");
+            }
+
+            byte[] optionData = clientData.getData();
+
+            clientData.options = Lists.newArrayList();
+
+            ByteBuffer bb = ByteBuffer.wrap(optionData);
+
+            while (bb.remaining() >= Dhcp6Option.DEFAULT_LEN) {
+                Dhcp6Option option;
+                ByteBuffer optByteBuffer = ByteBuffer.wrap(optionData,
+                                                           bb.position(),
+                                                           optionData.length - bb.position());
+                short code = optByteBuffer.getShort();
+                short len = optByteBuffer.getShort();
+                int optLen = UNSIGNED_SHORT_MASK & len;
+                byte[] subOptData = new byte[Dhcp6Option.DEFAULT_LEN + optLen];
+                bb.get(subOptData);
+
+                // TODO: put more sub-options?
+                if (code == DHCP6.OptionCode.IAADDR.value()) {
+                    option = Dhcp6IaAddressOption.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                    clientData.clientIaAddress  = ((Dhcp6IaAddressOption) option).getIp6Address();
+                } else if (code == DHCP6.OptionCode.CLIENTID.value()) {
+                    option = Dhcp6ClientIdOption.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                } else if (code == DHCP6.OptionCode.CLIENT_LT.value()) {
+                    option = Dhcp6CLTOption.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                } else {
+                    option = Dhcp6Option.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                }
+                clientData.options.add(option);
+            }
+            return clientData;
+        };
+    }
+
+    @Override
+    public byte[] serialize() {
+        ByteBuffer bb = ByteBuffer.allocate(this.getLength() + Dhcp6Option.DEFAULT_LEN);
+        bb.putShort(getCode());
+        bb.putShort(getLength());
+        bb.put(payload.serialize());
+        return bb.array();
+    }
+
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("code", getCode())
+                .add("length", getLength())
+                .add("clientAddr", getIaAddress())
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), clientIaAddress, options);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Dhcp6ClientDataOption)) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final Dhcp6ClientDataOption other = (Dhcp6ClientDataOption) obj;
+
+        return Objects.equals(getCode(), other.getCode()) &&
+                Objects.equals(getLength(), other.getLength()) &&
+                Objects.equals(clientIaAddress, other.clientIaAddress) &&
+                Objects.equals(options, other.options);
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6LeaseQueryOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6LeaseQueryOption.java
new file mode 100644
index 0000000..5bcc8ba
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6LeaseQueryOption.java
@@ -0,0 +1,153 @@
+/*
+ * 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.onlab.packet.dhcp;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.Deserializer;
+import org.onlab.packet.Ip6Address;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * DHCPv6 Lease Query Option.
+ */
+public final class Dhcp6LeaseQueryOption extends Dhcp6Option {
+
+    public static final int DEFAULT_LEN = 1 + 16;
+    //public short QueryType;
+    public Ip6Address linkAddress;
+    private List<Dhcp6Option> options;
+
+    public Dhcp6LeaseQueryOption(Dhcp6Option dhcp6Option) {
+        super(dhcp6Option);
+    }
+
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.LEASE_QUERY.value();
+    }
+
+    @Override
+    public short getLength() {
+        //return (short) payload.serialize().length;
+        return (short) (DEFAULT_LEN + options.stream()
+                .mapToInt(opt -> (int) opt.getLength() + Dhcp6Option.DEFAULT_LEN)
+                .sum());
+    }
+
+    @Override
+    public byte[] getData() {
+        return payload.serialize();
+    }
+
+
+    public static Deserializer<Dhcp6Option> deserializer() {
+        return (data, offset, length) -> {
+            Dhcp6Option dhcp6Option = Dhcp6Option.deserializer().deserialize(data, offset, length);
+            Dhcp6LeaseQueryOption lQ6Option = new Dhcp6LeaseQueryOption(dhcp6Option);
+
+            byte[] optionData = lQ6Option.getData();
+            if (optionData.length >= 61) { // 61 is LQ option length + 4 header
+                ByteBuffer bb = ByteBuffer.wrap(optionData);
+                // fetch the Query type - just pop the byte from the byte buffer for subsequent parsing...
+                bb.get();
+                byte[] ipv6Addr = new byte[16];
+                bb.get(ipv6Addr);
+                lQ6Option.linkAddress = Ip6Address.valueOf(ipv6Addr);
+                //int optionsLen = dhcp6Option.getLength() - 1 - 16; // query type (1) + link address (16)
+
+                lQ6Option.options = Lists.newArrayList();
+
+                while (bb.remaining() >= Dhcp6Option.DEFAULT_LEN) {
+                    Dhcp6Option option;
+                    ByteBuffer optByteBuffer = ByteBuffer.wrap(optionData,
+                                                               bb.position(),
+                                                               optionData.length - bb.position());
+                    short code = optByteBuffer.getShort();
+                    short len = optByteBuffer.getShort();
+                    int optLen = UNSIGNED_SHORT_MASK & len;
+                    byte[] subOptData = new byte[Dhcp6Option.DEFAULT_LEN + optLen];
+                    bb.get(subOptData);
+
+                    // TODO: put more sub-options?
+                    if (code == DHCP6.OptionCode.IAADDR.value()) {
+                        option = Dhcp6IaAddressOption.deserializer()
+                                .deserialize(subOptData, 0, subOptData.length);
+                    } else if (code == DHCP6.OptionCode.ORO.value()) {
+                        option = Dhcp6Option.deserializer()
+                                    .deserialize(subOptData, 0, subOptData.length);
+                    } else {
+                        option = Dhcp6Option.deserializer()
+                                .deserialize(subOptData, 0, subOptData.length);
+                    }
+                    lQ6Option.options.add(option);
+                }
+            }
+            return lQ6Option;
+        };
+    }
+
+    @Override
+    public byte[] serialize() {
+        ByteBuffer bb = ByteBuffer.allocate(this.getLength() + Dhcp6Option.DEFAULT_LEN);
+        bb.putShort(getCode());
+        bb.putShort(getLength());
+        bb.put(payload.serialize());
+        return bb.array();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("code", getCode())
+                .add("length", getLength())
+                .toString();
+    }
+
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), linkAddress, options);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Dhcp6LeaseQueryOption)) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final Dhcp6LeaseQueryOption other = (Dhcp6LeaseQueryOption) obj;
+
+        return Objects.equals(getCode(), other.getCode()) &&
+                Objects.equals(getLength(), other.getLength()) &&
+                Objects.equals(linkAddress, other.linkAddress) &&
+                Objects.equals(options, other.options);
+    }
+}
