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 19123dc..27d59d9 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -17,78 +17,1228 @@
 
 package org.onosproject.dhcprelay;
 
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.BasePacket;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip6Address;
 import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
 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;
+import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
+import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
+import org.onlab.util.HexString;
 import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.net.host.HostStore;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteStore;
 import org.onosproject.dhcprelay.config.DhcpServerConfig;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
 
+
+import java.nio.ByteBuffer;
+import java.util.List;
 import java.util.Collection;
 import java.util.Optional;
+import java.util.Set;
+import java.util.ArrayList;
+
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 
 @Component
 @Service
 @Property(name = "version", value = "6")
 public class Dhcp6HandlerImpl implements DhcpHandler {
+    private static Logger log = LoggerFactory.getLogger(Dhcp6HandlerImpl.class);
 
-    @Override
-    public void processDhcpPacket(PacketContext context, BasePacket dhcp6Payload) {
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayStore dhcpRelayStore;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostStore hostStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteStore routeStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    private InternalHostListener hostListener = new InternalHostListener();
+
+    private Ip6Address dhcpServerIp = null;
+    // dhcp server may be connected directly to the SDN network or
+    // via an external gateway. When connected directly, the dhcpConnectPoint, dhcpConnectMac,
+    // and dhcpConnectVlan refer to the server. When connected via the gateway, they refer
+    // to the gateway.
+    private ConnectPoint dhcpServerConnectPoint = null;
+    private MacAddress dhcpConnectMac = null;
+    private VlanId dhcpConnectVlan = null;
+    private Ip6Address dhcpGatewayIp = null;
+    private Ip6Address relayAgentIpFromCfg = null;
+
+    private Ip6Address indirectDhcpServerIp = null;
+    private ConnectPoint indirectDhcpServerConnectPoint = null;
+    private MacAddress indirectDhcpConnectMac = null;
+    private VlanId indirectDhcpConnectVlan = null;
+    private Ip6Address indirectDhcpGatewayIp = null;
+    private Ip6Address indirectRelayAgentIpFromCfg = null;
+
+
+    // CLIENT message types
+    public static final Set<Byte> MSG_TYPE_FROM_CLIENT =
+            ImmutableSet.of(DHCP6.MsgType.SOLICIT.value(),
+                            DHCP6.MsgType.REQUEST.value(),
+                            DHCP6.MsgType.REBIND.value(),
+                            DHCP6.MsgType.RENEW.value(),
+                            DHCP6.MsgType.RELEASE.value(),
+                            DHCP6.MsgType.DECLINE.value(),
+                            DHCP6.MsgType.CONFIRM.value(),
+                            DHCP6.MsgType.RELAY_FORW.value());
+    // SERVER message types
+    public static final Set<Byte> MSG_TYPE_FROM_SERVER =
+            ImmutableSet.of(DHCP6.MsgType.RELAY_REPL.value());
+
+    @Activate
+    protected void activate() {
+        hostService.addListener(hostListener);
     }
 
-    @Override
-    public Optional<IpAddress> getDhcpServerIp() {
-        return null;
+    @Deactivate
+    protected void deactivate() {
+        hostService.removeListener(hostListener);
+        this.dhcpConnectMac = null;
+        this.dhcpConnectVlan = null;
+
+        if (dhcpGatewayIp != null) {
+            hostService.stopMonitoringIp(dhcpGatewayIp);
+        } else if (dhcpServerIp != null) {
+            hostService.stopMonitoringIp(dhcpServerIp);
+        }
     }
 
-    @Override
-    public Optional<IpAddress> getDhcpGatewayIp() {
-        return null;
-    }
 
     @Override
-    public Optional<MacAddress> getDhcpConnectMac() {
-        return null;
-    }
-
-    @Override
-    public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
-
-    }
-
-    @Override
-    public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
-
-    }
-
-    @Override
-    public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
-
+    public void setDhcpServerIp(IpAddress dhcpServerIp) {
+        checkNotNull(dhcpServerIp, "DHCP server IP can't be null");
+        checkState(dhcpServerIp.isIp6(), "Invalid server IP for DHCPv6 relay handler");
+        this.dhcpServerIp = dhcpServerIp.getIp6Address();
     }
 
     @Override
     public void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
-
+        checkNotNull(dhcpServerConnectPoint, "Server connect point can't null");
+        this.dhcpServerConnectPoint = dhcpServerConnectPoint;
     }
 
     @Override
-    public void setDhcpServerIp(IpAddress dhcpServerIp) {
+    public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
+        this.dhcpConnectMac = dhcpConnectMac;
+    }
 
+    @Override
+    public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
+        this.dhcpConnectVlan = dhcpConnectVlan;
+    }
+
+    @Override
+    public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
+        if (dhcpGatewayIp != null) {
+            checkState(dhcpGatewayIp.isIp6(), "Invalid gateway IP for DHCPv6 relay handler");
+            this.dhcpGatewayIp = dhcpGatewayIp.getIp6Address();
+        } else {
+            // removes gateway config
+            this.dhcpGatewayIp = null;
+        }
+    }
+    @Override
+    public Optional<IpAddress> getDhcpServerIp() {
+        return Optional.ofNullable(dhcpServerIp);
+    }
+
+    @Override
+    public Optional<IpAddress> getDhcpGatewayIp() {
+        return Optional.ofNullable(dhcpGatewayIp);
+    }
+
+    @Override
+    public Optional<MacAddress> getDhcpConnectMac() {
+        return Optional.ofNullable(dhcpConnectMac);
+    }
+
+    // Indirect DHCP server
+
+    public void setIndirectDhcpServerIp(IpAddress dhcpServerIp) {
+        checkNotNull(dhcpServerIp, "DHCP indirect server IP can't be null");
+        checkState(dhcpServerIp.isIp6(), "Invalid indirect server IP for DHCPv6 relay handler");
+        this.indirectDhcpServerIp = dhcpServerIp.getIp6Address();
+    }
+
+
+    public void setIndirectDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
+        checkNotNull(dhcpServerConnectPoint, "Indirect Server connect point can't null");
+        this.indirectDhcpServerConnectPoint = dhcpServerConnectPoint;
+    }
+
+
+    public void setIndirectDhcpConnectMac(MacAddress dhcpConnectMac) {
+        this.indirectDhcpConnectMac = dhcpConnectMac;
+    }
+
+
+    public void setIndirectDhcpConnectVlan(VlanId dhcpConnectVlan) {
+        this.indirectDhcpConnectVlan = dhcpConnectVlan;
+    }
+
+
+    public void setIndirectDhcpGatewayIp(IpAddress dhcpGatewayIp) {
+        if (dhcpGatewayIp != null) {
+            checkState(dhcpGatewayIp.isIp6(), "Invalid indirect gateway IP for DHCPv6 relay handler");
+            this.indirectDhcpGatewayIp = dhcpGatewayIp.getIp6Address();
+        } else {
+            // removes gateway config
+            this.indirectDhcpGatewayIp = null;
+        }
+    }
+
+    public Optional<IpAddress> getIndirectDhcpServerIp() {
+        return Optional.ofNullable(indirectDhcpServerIp);
+    }
+
+
+    public Optional<IpAddress> getIndirectDhcpGatewayIp() {
+        return Optional.ofNullable(indirectDhcpGatewayIp);
+    }
+
+
+    public Optional<MacAddress> getIndirectDhcpConnectMac() {
+        return Optional.ofNullable(indirectDhcpConnectMac);
+    }
+
+
+    @Override
+    public void processDhcpPacket(PacketContext context, BasePacket payload) {
+        checkNotNull(payload, "DHCP6 payload can't be null");
+        checkState(payload instanceof DHCP6, "Payload is not a DHCP6");
+        DHCP6 dhcp6Payload = (DHCP6) payload;
+        Ethernet receivedPacket = context.inPacket().parsed();
+
+        if (!configured()) {
+            log.warn("Missing DHCP6 relay server config. Abort packet processing");
+            log.warn("dhcp6 payload {}", dhcp6Payload);
+
+            return;
+        }
+
+        byte msgType = dhcp6Payload.getMsgType();
+        log.warn("msgType is {}", msgType);
+
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        if (inPort == null) {
+            log.warn("incommin ConnectPoint is null");
+        }
+        Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
+        //ignore the packets if dhcp client interface is not configured on onos.
+        if (receivingInterfaces.isEmpty()) {
+            log.warn("Virtual interface is not configured on {}", inPort);
+            return;
+        }
+
+
+        if (MSG_TYPE_FROM_CLIENT.contains(msgType)) {
+
+            InternalPacket ethernetClientPacket =
+                    processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
+            if (ethernetClientPacket != null) {
+                forwardPacket(ethernetClientPacket);
+            }
+
+        } else if (MSG_TYPE_FROM_SERVER.contains(msgType)) {
+            log.warn("calling processDhcp6PacketFromServer with RELAY_REPL", msgType);
+            InternalPacket ethernetPacketReply =
+                    processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
+            if (ethernetPacketReply != null) {
+                forwardPacket(ethernetPacketReply);
+            }
+        } else {
+            log.warn("Not so fast, packet type {} not supported yet", msgType);
+        }
+    }
+
+
+    /**
+     * Checks if this app has been configured.
+     *
+     * @return true if all information we need have been initialized
+     */
+    public boolean configured() {
+        log.warn("dhcpServerConnectPoint {} dhcpServerIp {}",
+                this.dhcpServerConnectPoint, this.dhcpServerIp);
+        return this.dhcpServerConnectPoint != null && this.dhcpServerIp != null;
+    }
+
+    // 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) {
+        //send Packetout to dhcp server connectpoint.
+        if (packet.destLocation != null) {
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(packet.destLocation.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    packet.destLocation.deviceId(), t, ByteBuffer.wrap(packet.packet.serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying packet to destination {}", packet.destLocation);
+            }
+            packetService.emit(o);
+        } // 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.warn("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("malformed pkt! 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
+     */
+    private Ip6Address extractIpAddress(DHCP6 dhcp6) {
+        Ip6Address ip = null;
+
+        log.debug("extractIpAddress  enters dhcp6 {}.", dhcp6);
+        // Extract IPv6 address from IA NA ot IA TA option
+        Optional<Dhcp6IaNaOption> iaNaOption = dhcp6.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6IaNaOption)
+                .map(opt -> (Dhcp6IaNaOption) opt)
+                .findFirst();
+        Optional<Dhcp6IaTaOption> iaTaOption = dhcp6.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6IaTaOption)
+                .map(opt -> (Dhcp6IaTaOption) opt)
+                .findFirst();
+        Optional<Dhcp6IaAddressOption> iaAddressOption;
+        if (iaNaOption.isPresent()) {
+            log.debug("Found IPv6 address from iaNaOption {}", iaNaOption);
+
+            iaAddressOption = iaNaOption.get().getOptions().stream()
+                    .filter(opt -> opt instanceof Dhcp6IaAddressOption)
+                    .map(opt -> (Dhcp6IaAddressOption) opt)
+                    .findFirst();
+        } else if (iaTaOption.isPresent()) {
+            log.debug("Found IPv6 address from iaTaOption {}", iaTaOption);
+
+            iaAddressOption = iaTaOption.get().getOptions().stream()
+                    .filter(opt -> opt instanceof Dhcp6IaAddressOption)
+                    .map(opt -> (Dhcp6IaAddressOption) opt)
+                    .findFirst();
+        } else {
+            iaAddressOption = Optional.empty();
+        }
+        if (iaAddressOption.isPresent()) {
+            ip = iaAddressOption.get().getIp6Address();
+            log.debug("Found IPv6 address from iaAddressOption {}", iaAddressOption);
+
+
+        } else {
+            log.debug("Can't find IPv6 address from DHCPv6 {}", dhcp6);
+        }
+
+        return ip;
+    }
+    /**
+     * extract from dhcp6 packet Prefix prefix provided by dhcp server.
+     *
+     * @param dhcp6 the dhcp6 payload
+     * @return IpPrefix Prefix Delegation prefix, or null if not exists.
+     */
+    private IpPrefix extractPrefix(DHCP6 dhcp6) {
+        log.warn("extractPrefix  enters {}", dhcp6);
+
+        // extract prefix
+        IpPrefix  prefixPrefix = null;
+
+        Ip6Address prefixAddress = null;
+
+        // Extract IPv6 prefix from IA PD option
+        Optional<Dhcp6IaPdOption> iaPdOption = dhcp6.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6IaPdOption)
+                .map(opt -> (Dhcp6IaPdOption) opt)
+                .findFirst();
+
+        Optional<Dhcp6IaPrefixOption> iaPrefixOption;
+        if (iaPdOption.isPresent()) {
+            log.warn("IA_PD option found {}", iaPdOption);
+
+            iaPrefixOption = iaPdOption.get().getOptions().stream()
+                    .filter(opt -> opt instanceof Dhcp6IaPrefixOption)
+                    .map(opt -> (Dhcp6IaPrefixOption) opt)
+                    .findFirst();
+        } else {
+            log.warn("IA_PD option NOT found");
+
+            iaPrefixOption = Optional.empty();
+        }
+        if (iaPrefixOption.isPresent()) {
+            log.warn("IAPrefix Option within IA_PD option found {}", iaPrefixOption);
+
+            prefixAddress = iaPrefixOption.get().getIp6Prefix();
+            int prefixLen = (int) iaPrefixOption.get().getPrefixLength();
+            log.warn("Prefix length is  {} bits", prefixLen);
+            prefixPrefix = IpPrefix.valueOf(prefixAddress, prefixLen);
+
+        } else {
+            log.warn("Can't find IPv6 prefix from DHCPv6 {}", dhcp6);
+        }
+
+        return prefixPrefix;
+    }
+
+    /**
+     * remove host or route.
+     *
+     * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param dhcp6Packet the dhcp6 payload
+     * @param clientPacket client's ethernet packet
+     * @param clientIpv6 client's Ipv6 packet
+     * @param clientInterfaces set of client interfaces
+     */
+    private void removeHostOrRoute(boolean directConnFlag, DHCP6 dhcp6Packet,
+                                   Ethernet clientPacket, IPv6 clientIpv6,
+                                   Set<Interface> clientInterfaces) {
+        log.debug("extractPrefix  enters {}", dhcp6Packet);
+        // add host or route
+        if (isDhcp6Release(dhcp6Packet)) {
+            IpAddress ip = null;
+            if (directConnFlag) {
+                // Add to host store if it is connected to network directly
+                ip = extractIpAddress(dhcp6Packet);
+                if (ip != null) {
+                    VlanId vlanId = clientInterfaces.iterator().next().vlan();
+                    MacAddress clientMac = clientPacket.getSourceMAC();
+                    HostId hostId = HostId.hostId(clientMac, vlanId);
+                    log.debug("remove Host {} ip for directly connected.", hostId.toString());
+
+                    log.debug("client mac {} client vlan {}", HexString.toHexString(clientMac.toBytes(), ":"), vlanId);
+
+
+                    // Remove host's ip of  when dhcp release msg is received
+                    hostStore.removeIp(hostId, ip);
+                } else {
+                    log.debug("ipAddress not found. Do not add Host for directly connected.");
+                }
+            } else {
+                // Remove from route store if it is not connected to network directly
+                IpAddress nextHopIp = IpAddress.valueOf(IpAddress.Version.INET6, clientIpv6.getSourceAddress());
+
+                DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet);
+                ip = extractIpAddress(leafDhcp);
+                if (ip == null) {
+                    log.debug("ip is null");
+                } else {
+                    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 ipPrefix = extractPrefix(leafDhcp);
+                if (ipPrefix == null) {
+                    log.debug("ipPrefix is null ");
+                } else {
+                    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);
+                }
+            }
+        }
+    }
+
+    /**
+     * add host or route.
+     *
+     * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param dhcp6Relay the dhcp6 payload
+     * @param embeddedDhcp6 client's ethernet packetthe dhcp6 payload within relay
+     * @param clientMac client macAddress
+     * @param clientInterfaces set of client interfaces
+     */
+    private void addHostOrRoute(boolean directConnFlag, DHCP6 dhcp6Relay,
+                                   DHCP6 embeddedDhcp6,
+                                   MacAddress clientMac,
+                                   Set<Interface> clientInterfaces) {
+        log.debug("addHostOrRoute entered.");
+        // add host or route
+        if (isDhcp6Reply(dhcp6Relay)) {
+            IpAddress ip = null;
+            if (directConnFlag) {
+                // Add to host store if it connect to network directly
+                ip = extractIpAddress(embeddedDhcp6);
+                if (ip != null) {
+                    Set<IpAddress> ips = Sets.newHashSet(ip);
+                    VlanId vlanId = clientInterfaces.iterator().next().vlan();
+                    HostId hostId = HostId.hostId(clientMac, vlanId);
+                    HostLocation hostLocation = new HostLocation(clientInterfaces.iterator().next().connectPoint(),
+                            System.currentTimeMillis());
+                    HostDescription desc = new DefaultHostDescription(clientMac, vlanId,
+                            hostLocation, ips);
+                    log.debug("adding Host for directly connected.");
+                    log.debug("client mac {} client vlan {} hostlocation {}",
+                            HexString.toHexString(clientMac.toBytes(), ":"),
+                            vlanId, hostLocation.toString());
+
+                    // Replace the ip when dhcp server give the host new ip address
+                    hostStore.createOrUpdateHost(DhcpRelayManager.PROVIDER_ID, hostId, desc, true);
+                } else {
+                    log.warn("ipAddress not found. Do not add Host for directly connected.");
+                }
+            } else {
+                // Add to route store if it does not connect to network directly
+                IpAddress nextHopIp = IpAddress.valueOf(IpAddress.Version.INET6, dhcp6Relay.getPeerAddress());
+
+                DHCP6 leafDhcp = getDhcp6Leaf(embeddedDhcp6);
+                ip = extractIpAddress(leafDhcp);
+                if (ip == null) {
+                    log.warn("ip is null");
+                } else {
+                    Route routeForIP = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp);
+                    log.warn("adding Route of 128 address for indirectly connected.");
+                    routeStore.updateRoute(routeForIP);
+                }
+
+                IpPrefix ipPrefix = extractPrefix(leafDhcp);
+                if (ipPrefix == null) {
+                    log.warn("ipPrefix is null ");
+                } else {
+                    Route routeForPrefix = new Route(Route.Source.STATIC, ipPrefix, nextHopIp);
+                    log.warn("adding Route of PD for indirectly connected.");
+                    routeStore.updateRoute(routeForPrefix);
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     * 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) {
+        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;
+        }
+
+        // get dhcp6 header.
+
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+
+        boolean directConnFlag = directlyConnected(clientDhcp6);
+
+        Ethernet etherReply = (Ethernet) clientPacket.clone();
+        etherReply.setSourceMACAddress(relayAgentMac);
+
+        if (directConnFlag && this.dhcpConnectMac == null) {
+            log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
+                            + "packet processing from client on port: {}",
+                    (this.dhcpGatewayIp == null) ? "server IP " + this.dhcpServerIp
+                            : "gateway IP " + this.dhcpGatewayIp,
+                    clientInterfaces.iterator().next().connectPoint());
+
+            return null;
+        }
+
+        if (!directConnFlag && this.indirectDhcpConnectMac == null) {
+            log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
+                            + "packet processing from client on port: {}",
+                    (this.indirectDhcpGatewayIp == null) ? "server IP " + this.indirectDhcpServerIp
+                            : "gateway IP " + this.indirectDhcpGatewayIp,
+                    clientInterfaces.iterator().next().connectPoint());
+
+            return null;
+
+        }
+
+        if (this.dhcpServerConnectPoint == null) {
+            log.warn("DHCP6 server connection point is not set up yet");
+            return null;
+        }
+
+        etherReply.setDestinationMACAddress(directConnFlag ? this.dhcpConnectMac : this.indirectDhcpConnectMac);
+        etherReply.setVlanID(directConnFlag ? this.dhcpConnectVlan.toShort() : this.indirectDhcpConnectVlan.toShort());
+
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        byte[] peerAddress = clientIpv6.getSourceAddress();
+        ipv6Packet.setSourceAddress(relayAgentIp.toOctets());
+        ipv6Packet.setDestinationAddress(directConnFlag ? this.dhcpServerIp.toOctets() :
+                                                          this.indirectDhcpServerIp.toOctets());
+
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+        DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
+        byte[] dhcp6PacketByte = dhcp6Packet.serialize();
+
+        // notify onos and quagga to release PD
+        //releasePD(dhcp6Packet);
+
+        removeHostOrRoute(directConnFlag, dhcp6Packet, clientPacket, clientIpv6, clientInterfaces);
+
+        DHCP6 dhcp6Relay = new DHCP6();
+        dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
+        // link address: server uses the address to identify the link on which the client
+        // is located.
+         if (directConnFlag) {
+             dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
+             log.debug("direct connection: relayAgentIp obtained dynamically {}",
+                     HexString.toHexString(relayAgentIp.toOctets(), ":"));
+
+         } else {
+             if (this.indirectRelayAgentIpFromCfg == null) {
+                 dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
+                 log.warn("indirect connection: relayAgentIp NOT availale from config file! {}",
+                         HexString.toHexString(relayAgentIp.toOctets(), ":"));
+
+             } else {
+                 dhcp6Relay.setLinkAddress(this.indirectRelayAgentIpFromCfg.toOctets());
+                 log.debug("indirect connection: relayAgentIp from config file is available! {}",
+                         HexString.toHexString(this.indirectRelayAgentIpFromCfg.toOctets(), ":"));
+             }
+         }
+
+        // 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<Dhcp6Option>();
+
+        // 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[] interfaceIdBytes = new byte[clientSoureMacBytes.length +  inPortStringBytes.length];
+        log.debug("Length: interfaceIdBytes  {} clientSoureMacBytes {} inPortStringBytes {} ",
+                interfaceIdBytes.length, clientSoureMacBytes.length, inPortStringBytes.length);
+
+        System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
+        System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length, inPortStringBytes.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);
+        //dhcp6Packet.setPayload(dhcp6Relay);
+        //udpPacket.setPayload(dhcp6Packet);
+        udpPacket.setPayload(dhcp6Relay);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv6Packet);
+
+
+        return new InternalPacket(etherReply, this.dhcpServerConnectPoint);
+    }
+
+    /**
+     *
+     * 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
+     */
+    private InternalPacket processDhcp6PacketFromServer(PacketContext context,
+                                                        Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        if (!inPort.equals(this.dhcpServerConnectPoint)) {
+            log.warn("Receiving port {} is not the same as server port {}",
+                    inPort, this.dhcpServerConnectPoint);
+            return null;
+        }
+        // get dhcp6 header.
+        Ethernet etherReply = (Ethernet) receivedPacket.clone();
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
+
+        Boolean directConnFlag = directlyConnected(dhcp6Relay);
+
+        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;
+        }
+
+        MacAddress peerMac = interfaceIdOption.getMacAddress();
+        String clientConnectionPointStr = new String(interfaceIdOption.getInPort());
+
+        ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
+
+        Set<Interface> clientInterfaces = interfaceService.getInterfacesByPort(clientConnectionPoint);
+        if (clientInterfaces.isEmpty()) {
+            log.warn("Can not get client interface from packet, abort..");
+            return null;
+        }
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentMac == null) {
+            log.warn("Can not get interface mac, abort packet..");
+            return null;
+        }
+        etherReply.setSourceMACAddress(relayAgentMac);
+
+        // find destMac
+        MacAddress clientMac = null;
+        Set<Host> clients = hostService.getHostsByIp(Ip6Address.valueOf(dhcp6Relay.getPeerAddress()));
+        if (clients.isEmpty()) {
+            log.warn("There's no host found for this address {}",
+                    HexString.toHexString(dhcp6Relay.getPeerAddress(), ":"));
+            log.warn("Let's look up interfaceId {}", HexString.toHexString(peerMac.toBytes(), ":"));
+            clientMac = peerMac;
+        } else {
+            clientMac = clients.iterator().next().mac();
+            if (clientMac == null) {
+                log.warn("No client mac address found, abort packet...");
+                return null;
+            }
+            log.warn("Client mac address found from getHostByIp");
+
+        }
+        etherReply.setDestinationMACAddress(clientMac);
+
+        // ip header
+        ipv6Packet.setSourceAddress(dhcp6Relay.getLinkAddress());
+        ipv6Packet.setDestinationAddress(dhcp6Relay.getPeerAddress());
+        // udp header
+        udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+        if (directConnFlag) {
+            udpPacket.setDestinationPort(UDP.DHCP_V6_CLIENT_PORT);
+        } 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, dhcp6Relay, embeddedDhcp6, clientMac, clientInterfaces);
+
+        udpPacket.setPayload(embeddedDhcp6);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv6Packet);
+
+        return new InternalPacket(etherReply, clientConnectionPoint);
+    }
+
+    // Returns the first v4 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 setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        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.getDhcpServerConnectPoint().isPresent()) {
+            log.warn("Connect point not exists");
+            return;
+        }
+        if (!serverConfig.getDhcpServerIp6().isPresent()) {
+            log.warn("IP of DHCP6 server not exists");
+            return;
+        }
+        Ip6Address oldServerIp = this.dhcpServerIp;
+        Ip6Address oldGatewayIp = this.dhcpGatewayIp;
+
+        // stop monitoring gateway or server
+        if (oldGatewayIp != null) {
+            hostService.stopMonitoringIp(oldGatewayIp);
+        } else if (oldServerIp != null) {
+            hostService.stopMonitoringIp(oldServerIp);
+        }
+
+        this.dhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
+        this.dhcpServerIp = serverConfig.getDhcpServerIp6().get();
+        this.dhcpGatewayIp = serverConfig.getDhcpGatewayIp6().orElse(null);
+        this.relayAgentIpFromCfg = serverConfig.getRelayAgentIp6().orElse(null);
+
+
+        // reset server mac and vlan
+        this.dhcpConnectMac = null;
+        this.dhcpConnectVlan = null;
+
+        log.info("DHCP6 server connect point: " + this.dhcpServerConnectPoint);
+        log.info("DHCP6 server IP: " + this.dhcpServerIp);
+
+        IpAddress ipToProbe = MoreObjects.firstNonNull(this.dhcpGatewayIp, this.dhcpServerIp);
+        String hostToProbe = this.dhcpGatewayIp != null ? "gateway" : "DHCP6 server";
+
+        if (ipToProbe == null) {
+            log.warn("Server IP6 not set, can't probe it");
+            return;
+        }
+
+        log.info("Probing to resolve {} IP6 {}", hostToProbe, ipToProbe);
+        hostService.startMonitoringIp(ipToProbe);
+
+        Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+        if (!hosts.isEmpty()) {
+            Host host = hosts.iterator().next();
+            this.dhcpConnectVlan = host.vlan();
+            this.dhcpConnectMac = host.mac();
+        }
 
     }
 
     @Override
     public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        if (configs.size() == 0) {
+            // no config to update
+            return;
+        }
 
+        // TODO: currently we pick up Second DHCP server config for indirect.
+        // Will use other server configs in the future for HA.
+        DhcpServerConfig serverConfig = configs.iterator().next();
+        checkState(serverConfig.getDhcpServerConnectPoint().isPresent(),
+                "Connect point not exists");
+        checkState(serverConfig.getDhcpServerIp6().isPresent(),
+                "IP of DHCP6 server not exists");
+        Ip6Address oldServerIp = this.indirectDhcpServerIp;
+        Ip6Address oldGatewayIp = this.indirectDhcpGatewayIp;
+
+        // stop monitoring gateway or server
+        if (oldGatewayIp != null) {
+            hostService.stopMonitoringIp(oldGatewayIp);
+        } else if (oldServerIp != null) {
+            hostService.stopMonitoringIp(oldServerIp);
+        }
+
+        this.indirectDhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
+        this.indirectDhcpServerIp = serverConfig.getDhcpServerIp6().get();
+        this.indirectDhcpGatewayIp = serverConfig.getDhcpGatewayIp6().orElse(null);
+        this.indirectRelayAgentIpFromCfg = serverConfig.getRelayAgentIp6().orElse(null);
+
+
+        // reset server mac and vlan
+        this.indirectDhcpConnectMac = null;
+        this.indirectDhcpConnectVlan = null;
+
+        log.info("DHCP6 server connect point: " + this.indirectDhcpServerConnectPoint);
+        log.info("DHCP6 server IP: " + this.indirectDhcpServerIp);
+
+        IpAddress ipToProbe = MoreObjects.firstNonNull(this.indirectDhcpGatewayIp, this.indirectDhcpServerIp);
+        String hostToProbe = this.indirectDhcpGatewayIp != null ? "gateway" : "DHCP6 server";
+
+        if (ipToProbe == null) {
+            log.warn("Server IP6 not set, can't probe it");
+            return;
+        }
+
+        log.info("Probing to resolve {} IP6 {}", hostToProbe, ipToProbe);
+        hostService.startMonitoringIp(ipToProbe);
+
+        Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+        if (!hosts.isEmpty()) {
+            Host host = hosts.iterator().next();
+            this.indirectDhcpConnectVlan = host.vlan();
+            this.indirectDhcpConnectMac = host.mac();
+        }
+    }
+
+    class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            switch (event.type()) {
+                case HOST_ADDED:
+                case HOST_UPDATED:
+                    hostUpdated(event.subject());
+                    break;
+                case HOST_REMOVED:
+                    hostRemoved(event.subject());
+                    break;
+                case HOST_MOVED:
+                    hostMoved(event.subject());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Handle host move.
+     * If the host DHCP server or gateway and it moved to the location different
+     * to user configured, unsets the connect mac and vlan
+     *
+     * @param host the host
+     */
+    private void hostMoved(Host host) {
+        if (this.dhcpServerConnectPoint == null && this.indirectDhcpServerConnectPoint == null) {
+            return;
+        }
+        if (this.dhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.dhcpGatewayIp) &&
+                    !host.locations().contains(this.dhcpServerConnectPoint)) {
+                this.dhcpConnectMac = null;
+                this.dhcpConnectVlan = null;
+            }
+        }
+        if (this.dhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.dhcpServerIp) &&
+                    !host.locations().contains(this.dhcpServerConnectPoint)) {
+                this.dhcpConnectMac = null;
+                this.dhcpConnectVlan = null;
+            }
+        }
+        if (this.indirectDhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpGatewayIp) &&
+                    !host.locations().contains(this.indirectDhcpServerConnectPoint)) {
+                this.indirectDhcpConnectMac = null;
+                this.indirectDhcpConnectVlan = null;
+            }
+        }
+        if (this.indirectDhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpServerIp) &&
+                    !host.locations().contains(this.indirectDhcpServerConnectPoint)) {
+                this.indirectDhcpConnectMac = null;
+                this.indirectDhcpConnectVlan = null;
+            }
+        }
+    }
+
+    /**
+     * Handle host updated.
+     * If the host is DHCP server or gateway, update connect mac and vlan.
+     *
+     * @param host the host
+     */
+    private void hostUpdated(Host host) {
+        if (this.dhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
+                this.dhcpConnectMac = host.mac();
+                this.dhcpConnectVlan = host.vlan();
+            }
+        }
+        if (this.dhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.dhcpServerIp)) {
+                this.dhcpConnectMac = host.mac();
+                this.dhcpConnectVlan = host.vlan();
+            }
+        }
+        if (this.indirectDhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
+                this.indirectDhcpConnectMac = host.mac();
+                this.indirectDhcpConnectVlan = host.vlan();
+            }
+        }
+        if (this.indirectDhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
+                this.indirectDhcpConnectMac = host.mac();
+                this.indirectDhcpConnectVlan = host.vlan();
+            }
+        }
+    }
+
+    /**
+     * Handle host removed.
+     * If the host is DHCP server or gateway, unset connect mac and vlan.
+     *
+     * @param host the host
+     */
+    private void hostRemoved(Host host) {
+        if (this.dhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
+                this.dhcpConnectMac = null;
+                this.dhcpConnectVlan = null;
+            }
+            //return;
+        }
+        if (this.dhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.dhcpServerIp)) {
+                this.dhcpConnectMac = null;
+                this.dhcpConnectVlan = null;
+            }
+        }
+        if (this.indirectDhcpGatewayIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
+                this.indirectDhcpConnectMac = null;
+                this.indirectDhcpConnectVlan = null;
+            }
+            //return;
+        }
+        if (this.indirectDhcpServerIp != null) {
+            if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
+                this.indirectDhcpConnectMac = null;
+                this.indirectDhcpConnectVlan = null;
+            }
+        }
     }
 }
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 4494ddb..3d89d76 100644
--- a/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
+++ b/apps/dhcprelay/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
@@ -36,6 +36,8 @@
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpPrefix;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.UDP;
@@ -43,11 +45,18 @@
 import org.onlab.packet.dhcp.CircuitId;
 import org.onlab.packet.dhcp.DhcpOption;
 import org.onlab.packet.dhcp.DhcpRelayAgentOption;
+import org.onlab.packet.dhcp.Dhcp6InterfaceIdOption;
+import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onlab.packet.dhcp.Dhcp6IaNaOption;
+import org.onlab.packet.dhcp.Dhcp6IaPdOption;
+import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
+import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
+import org.onlab.packet.dhcp.Dhcp6Option;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.TestApplicationId;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.dhcprelay.api.DhcpHandler;
 import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
 import org.onosproject.dhcprelay.config.DhcpServerConfig;
 import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
@@ -68,7 +77,6 @@
 import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.routeservice.Route;
 import org.onosproject.routeservice.RouteStoreAdapter;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultHost;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
@@ -89,11 +97,14 @@
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.StoreDelegate;
 import org.osgi.service.component.ComponentContext;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.IPv6;
 
 import java.nio.ByteBuffer;
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -109,10 +120,14 @@
     private static final DeviceId DEV_2_ID = DeviceId.deviceId("of:0000000000000002");
     // Ip address for interfaces
     private static final InterfaceIpAddress INTERFACE_IP = InterfaceIpAddress.valueOf("10.0.3.254/32");
-    private static final List<InterfaceIpAddress> INTERFACE_IPS = ImmutableList.of(INTERFACE_IP);
+    private static final InterfaceIpAddress INTERFACE_IP_V6 = InterfaceIpAddress.valueOf("2001:db8:1::254/128");
+    private static final List<InterfaceIpAddress> INTERFACE_IPS = ImmutableList.of(INTERFACE_IP, INTERFACE_IP_V6);
 
     // DHCP client (will send without option 82)
     private static final Ip4Address IP_FOR_CLIENT = Ip4Address.valueOf("10.0.0.1");
+    private static final Ip6Address IP_FOR_CLIENT_V6 = Ip6Address.valueOf("2001:db8:1::110");
+    private static final IpPrefix PREFIX_FOR_CLIENT_V6 = IpPrefix.valueOf("2001:db8:10::/56");
+    private static final IpPrefix PREFIX_FOR_ZERO = IpPrefix.valueOf("::/0");
     private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
     private static final VlanId CLIENT_VLAN = VlanId.vlanId("100");
     private static final ConnectPoint CLIENT_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
@@ -136,7 +151,8 @@
 
     // Outer relay information
     private static final Ip4Address OUTER_RELAY_IP = Ip4Address.valueOf("10.0.5.253");
-    private static final Set<IpAddress> OUTER_RELAY_IPS = ImmutableSet.of(OUTER_RELAY_IP);
+    private static final Ip6Address OUTER_RELAY_IP_V6 = Ip6Address.valueOf("2001:db8:1::4");
+    private static final Set<IpAddress> OUTER_RELAY_IPS = ImmutableSet.of(OUTER_RELAY_IP, OUTER_RELAY_IP_V6);
     private static final MacAddress OUTER_RELAY_MAC = MacAddress.valueOf("00:01:02:03:04:05");
     private static final VlanId OUTER_RELAY_VLAN = VlanId.NONE;
     private static final ConnectPoint OUTER_RELAY_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
@@ -156,8 +172,12 @@
             ConnectPoint.deviceConnectPoint("of:0000000000000001/5");
     private static final HostLocation SERVER_LOCATION =
             new HostLocation(SERVER_CONNECT_POINT, 0);
+    private static final Ip4Address GATEWAY_IP = Ip4Address.valueOf("10.0.5.253");
+    private static final Ip6Address GATEWAY_IP_V6 = Ip6Address.valueOf("2000::105:253");
     private static final Ip4Address SERVER_IP = Ip4Address.valueOf("10.0.3.253");
-    private static final Set<IpAddress> DHCP_SERVER_IPS = ImmutableSet.of(SERVER_IP);
+    private static final Ip6Address SERVER_IP_V6 = Ip6Address.valueOf("2000::103:253");
+    private static final Ip6Address SERVER_IP_V6_MCAST = Ip6Address.valueOf("ff02::1:2");
+    private static final Set<IpAddress> DHCP_SERVER_IPS = ImmutableSet.of(SERVER_IP, SERVER_IP_V6);
     private static final HostId SERVER_HOST_ID = HostId.hostId(SERVER_MAC, SERVER_VLAN);
     private static final Host SERVER_HOST = new DefaultHost(DhcpRelayManager.PROVIDER_ID,
                                                             SERVER_HOST_ID,
@@ -178,6 +198,7 @@
     // Components
     private static final ApplicationId APP_ID = TestApplicationId.create(DhcpRelayManager.DHCP_RELAY_APP);
     private static final DefaultDhcpRelayConfig CONFIG = new MockDefaultDhcpRelayConfig();
+    private static final IndirectDhcpRelayConfig CONFIG_INDIRECT = new MockIndirectDhcpRelayConfig();
     private static final Set<Interface> INTERFACES = ImmutableSet.of(
             CLIENT_INTERFACE,
             CLIENT2_INTERFACE,
@@ -204,7 +225,7 @@
 
         // TODO: add indirect test
         expect(manager.cfgService.getConfig(APP_ID, IndirectDhcpRelayConfig.class))
-                .andReturn(null)
+                .andReturn(CONFIG_INDIRECT)
                 .anyTimes();
 
         manager.coreService = createNiceMock(CoreService.class);
@@ -237,7 +258,14 @@
         manager.v4Handler = v4Handler;
 
         // TODO: initialize v6 handler.
-        DhcpHandler v6Handler = createNiceMock(DhcpHandler.class);
+        //DhcpHandler v6Handler = createNiceMock(DhcpHandler.class);
+        Dhcp6HandlerImpl v6Handler = new Dhcp6HandlerImpl();
+        v6Handler.dhcpRelayStore = mockDhcpRelayStore;
+        v6Handler.hostService = manager.hostService;
+        v6Handler.hostStore = mockHostStore;
+        v6Handler.interfaceService = manager.interfaceService;
+        v6Handler.packetService = manager.packetService;
+        v6Handler.routeStore = mockRouteStore;
         manager.v6Handler = v6Handler;
 
         // properties
@@ -446,6 +474,75 @@
         assertEquals(0, manager.ignoredVlans.size());
     }
 
+    /**
+     * Relay a DHCP6 packet without relay option
+     * Note: Should add new host to host store after dhcp ack.
+     */
+    @Test
+    public void relayDhcp6WithoutAgentInfo() {
+        // send request
+        packetService.processPacket(new TestDhcp6RequestPacketContext(CLIENT_MAC,
+                                                                     VlanId.NONE,
+                                                                     CLIENT_CP,
+                                                                     INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                                                                     0));
+
+        Set<Host> hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send reply
+        packetService.processPacket(new TestDhcp6ReplyPacketContext(CLIENT_CP, CLIENT_MAC,
+                                                                    CLIENT_VLAN,
+                                                                    INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                                                                    0));
+        hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(1, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        Host host = hosts.iterator().next();
+        assertEquals(CLIENT_MAC, host.mac());
+        assertEquals(CLIENT_VLAN, host.vlan());
+        assertEquals(CLIENT_CP.deviceId(), host.location().elementId());
+        assertEquals(CLIENT_CP.port(), host.location().port());
+        assertEquals(1, host.ipAddresses().size());
+        assertEquals(IP_FOR_CLIENT_V6, host.ipAddresses().iterator().next());
+        assertEquals(HostId.hostId(CLIENT_MAC, CLIENT_VLAN), host.id());
+    }
+
+    /**
+     * Relay a DHCP6 packet with Relay Message opion (Indirectly connected host).
+     */
+    @Test
+    public void relayDhcp6WithAgentInfo() {
+        // Assume outer dhcp6 relay agent exists in store already
+        // send request
+        packetService.processPacket(new TestDhcp6RequestPacketContext(CLIENT2_MAC,
+                CLIENT2_VLAN,
+                CLIENT2_CP,
+                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                1));
+
+        Set<Host> hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send reply
+        packetService.processPacket(new TestDhcp6ReplyPacketContext(CLIENT2_CP,
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                1));
+
+        hosts = ImmutableSet.copyOf(mockHostStore.getHosts());
+        assertEquals(0, hosts.size());
+        assertEquals(2, mockRouteStore.routes.size()); // ipAddress and prefix
+
+        Route route = mockRouteStore.routes.get(0);
+        assertEquals(OUTER_RELAY_IP_V6, route.nextHop());
+        assertEquals(IP_FOR_CLIENT_V6.toIpPrefix(), route.prefix());
+        assertEquals(Route.Source.STATIC, route.source());
+    }
     private static class MockDefaultDhcpRelayConfig extends DefaultDhcpRelayConfig {
         @Override
         public boolean isValid() {
@@ -458,6 +555,18 @@
         }
     }
 
+    private static class MockIndirectDhcpRelayConfig extends IndirectDhcpRelayConfig {
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        public List<DhcpServerConfig> dhcpServerConfigs() {
+            return ImmutableList.of(new MockDhcpServerConfig(null));
+        }
+    }
+
     private static class MockDhcpServerConfig extends DhcpServerConfig {
         Ip4Address relayAgentIp;
 
@@ -484,6 +593,21 @@
         public Optional<Ip4Address> getDhcpServerIp4() {
             return Optional.of(SERVER_IP);
         }
+
+        @Override
+        public Optional<Ip4Address> getDhcpGatewayIp4() {
+            return Optional.of(GATEWAY_IP);
+        }
+
+        @Override
+        public Optional<Ip6Address> getDhcpServerIp6() {
+            return Optional.of(SERVER_IP_V6);
+        }
+
+        @Override
+        public Optional<Ip6Address> getDhcpGatewayIp6() {
+            return Optional.of(GATEWAY_IP_V6);
+        }
     }
 
     private class MockHostStore extends HostStoreAdapter {
@@ -821,4 +945,266 @@
             return this.inPacket;
         }
     }
+
+    /**
+     * Generates DHCP6 REQUEST packet.
+     */
+    private void buildDhcp6Packet(DHCP6 dhcp6, byte msgType, Ip6Address ip6Addr, IpPrefix prefix) {
+
+        // build address option
+        Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
+        iaAddressOption.setCode(DHCP6.OptionCode.IAADDR.value());
+        iaAddressOption.setIp6Address(ip6Addr);
+        iaAddressOption.setPreferredLifetime(3600);
+        iaAddressOption.setValidLifetime(1200);
+        iaAddressOption.setLength((short) Dhcp6IaAddressOption.DEFAULT_LEN);
+
+        Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
+        iaNaOption.setCode(DHCP6.OptionCode.IA_NA.value());
+        iaNaOption.setIaId(0);
+        iaNaOption.setT1(302400);
+        iaNaOption.setT2(483840);
+        List<Dhcp6Option> iaNaSubOptions = new ArrayList<Dhcp6Option>();
+        iaNaSubOptions.add(iaAddressOption);
+        iaNaOption.setOptions(iaNaSubOptions);
+        iaNaOption.setLength((short) (Dhcp6IaNaOption.DEFAULT_LEN + iaAddressOption.getLength()));
+
+        // build prefix option
+        Dhcp6IaPrefixOption iaPrefixOption = new Dhcp6IaPrefixOption();
+        iaPrefixOption.setCode(DHCP6.OptionCode.IAPREFIX.value());
+        iaPrefixOption.setIp6Prefix(prefix.address().getIp6Address());
+        iaPrefixOption.setPrefixLength((byte) prefix.prefixLength());
+        iaPrefixOption.setPreferredLifetime(3601);
+        iaPrefixOption.setValidLifetime(1201);
+        iaPrefixOption.setLength((short) Dhcp6IaPrefixOption.DEFAULT_LEN);
+
+        Dhcp6IaPdOption iaPdOption = new Dhcp6IaPdOption();
+        iaPdOption.setCode(DHCP6.OptionCode.IA_PD.value());
+        iaPdOption.setIaId(0);
+        iaPdOption.setT1(302401);
+        iaPdOption.setT2(483841);
+        List<Dhcp6Option> iaPdSubOptions = new ArrayList<Dhcp6Option>();
+        iaPdSubOptions.add(iaPrefixOption);
+        iaPdOption.setOptions(iaPdSubOptions);
+        iaPdOption.setLength((short) (Dhcp6IaPdOption.DEFAULT_LEN + iaPrefixOption.getLength()));
+
+        dhcp6.setMsgType(msgType);
+        List<Dhcp6Option> dhcp6Options = new ArrayList<Dhcp6Option>();
+        dhcp6Options.add(iaNaOption);
+        dhcp6Options.add(iaPdOption);
+        dhcp6.setOptions(dhcp6Options);
+
+    }
+
+    private void buildRelayMsg(DHCP6 dhcp6Relay, byte msgType, Ip6Address linkAddr,
+                               Ip6Address peerAddr, byte hop, byte[] interfaceIdBytes,
+                               DHCP6 dhcp6Payload) {
+
+        dhcp6Relay.setMsgType(msgType);
+
+        dhcp6Relay.setLinkAddress(linkAddr.toOctets());
+        dhcp6Relay.setPeerAddress(peerAddr.toOctets());
+        dhcp6Relay.setHopCount(hop);
+        List<Dhcp6Option> options = new ArrayList<Dhcp6Option>();
+
+        // interfaceId  option
+        Dhcp6Option interfaceId = new Dhcp6Option();
+        interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
+
+
+        interfaceId.setData(interfaceIdBytes);
+        interfaceId.setLength((short) interfaceIdBytes.length);
+        Dhcp6InterfaceIdOption interfaceIdOption = new Dhcp6InterfaceIdOption(interfaceId);
+        ByteBuffer bb = ByteBuffer.wrap(interfaceIdBytes);
+
+        byte[] macAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
+        byte[] port =  new byte[21];
+        bb.get(macAddr);
+        bb.get();  // separator
+        bb.get(port);
+        interfaceIdOption.setMacAddress(MacAddress.valueOf(macAddr));
+        interfaceIdOption.setInPort(port);
+
+        options.add(interfaceIdOption);
+
+        // relay message option
+        Dhcp6Option relayMsgOption = new Dhcp6Option();
+        relayMsgOption.setCode(DHCP6.OptionCode.RELAY_MSG.value());
+        byte[] dhcp6PayloadByte = dhcp6Payload.serialize();
+        relayMsgOption.setLength((short) dhcp6PayloadByte.length);
+        relayMsgOption.setPayload(dhcp6Payload);
+        Dhcp6RelayOption relayOpt = new Dhcp6RelayOption(relayMsgOption);
+
+        options.add(relayOpt);
+
+        dhcp6Relay.setOptions(options);
+    }
+    private byte[] buildInterfaceId(MacAddress clientMac, ConnectPoint clientCp) {
+        String inPortString = "-" + clientCp.toString();
+        byte[] clientSoureMacBytes = clientMac.toBytes();
+        byte[] inPortStringBytes = inPortString.getBytes();
+        byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +  inPortStringBytes.length];
+
+        System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
+        System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length, inPortStringBytes.length);
+
+        return interfaceIdBytes;
+    }
+
+    private class TestDhcp6RequestPacketContext extends PacketContextAdapter {
+
+
+        private InboundPacket inPacket;
+
+
+        public TestDhcp6RequestPacketContext(MacAddress clientMac, VlanId vlanId,
+                                            ConnectPoint clientCp,
+                                            Ip6Address clientGwAddr,
+                                            int relayLevel) {
+            super(0, null, null, false);
+
+            DHCP6 dhcp6 = new DHCP6();
+            if (relayLevel > 0) {
+                DHCP6 dhcp6Payload = new DHCP6();
+                buildDhcp6Packet(dhcp6Payload, DHCP6.MsgType.REQUEST.value(),
+                                 IP_FOR_CLIENT_V6,
+                                 PREFIX_FOR_ZERO);
+                DHCP6 dhcp6Parent = null;
+                DHCP6 dhcp6Child = dhcp6Payload;
+                for (int i = 0; i < relayLevel; i++) {
+                    dhcp6Parent = new DHCP6();
+                    byte[] interfaceId = buildInterfaceId(clientMac, clientCp);
+                    buildRelayMsg(dhcp6Parent, DHCP6.MsgType.RELAY_FORW.value(),
+                            INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                            OUTER_RELAY_IP_V6,
+                            (byte) (relayLevel - 1), interfaceId,
+                            dhcp6Child);
+                    dhcp6Child = dhcp6Parent;
+                }
+                if (dhcp6Parent != null) {
+                    dhcp6 = dhcp6Parent;
+                }
+            } else {
+                buildDhcp6Packet(dhcp6, DHCP6.MsgType.REQUEST.value(),
+                                        IP_FOR_CLIENT_V6,
+                                        PREFIX_FOR_ZERO);
+            }
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp6);
+            if (relayLevel > 0) {
+                udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+            } else {
+                udp.setSourcePort(UDP.DHCP_V6_CLIENT_PORT);
+            }
+            udp.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
+
+            IPv6 ipv6 = new IPv6();
+            ipv6.setPayload(udp);
+            ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
+            ipv6.setDestinationAddress(SERVER_IP_V6_MCAST.toOctets());
+            ipv6.setSourceAddress(clientGwAddr.toOctets());
+
+            Ethernet eth = new Ethernet();
+            if (relayLevel > 0) {
+                eth.setEtherType(Ethernet.TYPE_IPV6)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(OUTER_RELAY_MAC)
+                        .setDestinationMACAddress(MacAddress.valueOf("33:33:00:01:00:02"))
+                        .setPayload(ipv6);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV6)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(clientMac)
+                        .setDestinationMACAddress(MacAddress.valueOf("33:33:00:01:00:02"))
+                        .setPayload(ipv6);
+            }
+            this.inPacket = new DefaultInboundPacket(clientCp, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+    /**
+     * Generates DHCP6 REPLY  packet.
+     */
+
+    private class TestDhcp6ReplyPacketContext extends PacketContextAdapter {
+        private InboundPacket inPacket;
+
+        public TestDhcp6ReplyPacketContext(ConnectPoint clientCp, MacAddress clientMac,
+                                        VlanId clientVlan, Ip6Address clientGwAddr,
+                                        int relayLevel) {
+            super(0, null, null, false);
+
+
+            DHCP6 dhcp6Payload = new DHCP6();
+            buildDhcp6Packet(dhcp6Payload, DHCP6.MsgType.REPLY.value(),
+                    IP_FOR_CLIENT_V6,
+                    PREFIX_FOR_CLIENT_V6);
+            byte[] interfaceId = buildInterfaceId(clientMac, clientCp);
+            DHCP6 dhcp6 = new DHCP6();
+            buildRelayMsg(dhcp6, DHCP6.MsgType.RELAY_REPL.value(),
+                    INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                    OUTER_RELAY_IP_V6,
+                    (byte) 0, interfaceId,
+                    dhcp6Payload);
+
+            DHCP6 dhcp6Parent = null;
+            DHCP6 dhcp6Child = dhcp6;
+            for (int i = 0; i < relayLevel; i++) {   // relayLevel 0 : no relay
+                dhcp6Parent = new DHCP6();
+
+                buildRelayMsg(dhcp6Parent, DHCP6.MsgType.RELAY_REPL.value(),
+                        INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                        OUTER_RELAY_IP_V6,
+                        (byte) relayLevel, interfaceId,
+                        dhcp6Child);
+
+                dhcp6Child = dhcp6Parent;
+            }
+            if (dhcp6Parent != null) {
+                dhcp6 = dhcp6Parent;
+            }
+
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp6);
+            udp.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+            udp.setDestinationPort(UDP.DHCP_V6_CLIENT_PORT);
+            IPv6 ipv6 = new IPv6();
+            ipv6.setPayload(udp);
+            ipv6.setNextHeader(IPv6.PROTOCOL_UDP);
+            ipv6.setDestinationAddress(IP_FOR_CLIENT_V6.toOctets());
+            ipv6.setSourceAddress(SERVER_IP_V6.toOctets());
+            Ethernet eth = new Ethernet();
+            if (relayLevel > 0) {
+                eth.setEtherType(Ethernet.TYPE_IPV6)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(OUTER_RELAY_MAC)
+                        .setPayload(ipv6);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV6)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(CLIENT_MAC)
+                        .setPayload(ipv6);
+            }
+
+            this.inPacket = new DefaultInboundPacket(SERVER_CONNECT_POINT, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
 }
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 924d181..f807000 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
@@ -23,8 +23,10 @@
 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.Dhcp6Option;
 import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onlab.packet.dhcp.Dhcp6InterfaceIdOption;
 
 import java.nio.ByteBuffer;
 import java.util.List;
@@ -88,7 +90,8 @@
         RELAY_MSG((short) 9), AUTH((short) 11), UNICAST((short) 12),
         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), SUBSCRIBER_ID((short) 38);
+        RECONF_MSG((short) 19), RECONF_ACCEPT((short) 20), IA_PD((short) 25), IAPREFIX((short) 26),
+        SUBSCRIBER_ID((short) 38);
 
         protected short value;
         OptionCode(final short value) {
@@ -100,11 +103,15 @@
     }
 
     private static final Map<Short, Deserializer<Dhcp6Option>> OPT_DESERIALIZERS =
-            ImmutableMap.of(OptionCode.IA_NA.value, Dhcp6IaNaOption.deserializer(),
-                            OptionCode.IA_TA.value, Dhcp6IaTaOption.deserializer(),
-                            OptionCode.IAADDR.value, Dhcp6IaAddressOption.deserializer(),
-                            OptionCode.RELAY_MSG.value, Dhcp6RelayOption.deserializer(),
-                            OptionCode.CLIENTID.value, Dhcp6ClientIdOption.deserializer());
+            ImmutableMap.<Short, Deserializer<Dhcp6Option>>builder()
+                            .put(OptionCode.IA_NA.value, Dhcp6IaNaOption.deserializer())
+                            .put(OptionCode.IA_TA.value, Dhcp6IaTaOption.deserializer())
+                            .put(OptionCode.IAADDR.value, Dhcp6IaAddressOption.deserializer())
+                            .put(OptionCode.RELAY_MSG.value, Dhcp6RelayOption.deserializer())
+                            .put(OptionCode.CLIENTID.value, Dhcp6ClientIdOption.deserializer())
+                            .put(OptionCode.IA_PD.value, Dhcp6IaPdOption.deserializer())
+                            .put(OptionCode.INTERFACE_ID.value, Dhcp6InterfaceIdOption.deserializer())
+                    .build();
 
     // general field
     private byte msgType; // 1 byte
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPdOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPdOption.java
new file mode 100644
index 0000000..e76f055
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPdOption.java
@@ -0,0 +1,247 @@
+/*
+ * 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.collect.Lists;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Deserializer;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * DHCPv6 Identity Association for Prefix Delegation Option.
+ * Based on RFC-3633
+ */
+public final class Dhcp6IaPdOption extends Dhcp6Option {
+    public static final int DEFAULT_LEN = 12;
+    private int iaId;
+    private int t1;
+    private int t2;
+    private List<Dhcp6Option> options;
+
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.IA_PD.value();
+    }
+
+    @Override
+    public short getLength() {
+        return (short) (DEFAULT_LEN + options.stream()
+                        .mapToInt(opt -> (int) opt.getLength() + Dhcp6Option.DEFAULT_LEN)
+                        .sum());
+
+    }
+
+    /**
+     * Gets Identity Association ID.
+     * The unique identifier for this IA_PD; the IAID must
+     * be unique among the identifiers for all of this
+     * requesting router's IA_PDs.
+     *
+     * @return the Identity Association ID
+     */
+    public int getIaId() {
+        return iaId;
+    }
+
+    /**
+     * Sets Identity Association ID.
+     *
+     * @param iaId the Identity Association ID.
+     */
+    public void setIaId(int iaId) {
+        this.iaId = iaId;
+    }
+
+    /**
+     * Gets time 1.
+     * The time at which the requesting router should
+     * contact the delegating router from which the
+     * prefixes in the IA_PD were obtained to extend the
+     * lifetimes of the prefixes delegated to the IA_PD;
+     * T1 is a time duration relative to the current time
+     * expressed in units of seconds.
+     *
+     * @return the value of time 1
+     */
+    public int getT1() {
+        return t1;
+    }
+
+    /**
+     * Sets time 1.
+     *
+     * @param t1 the value of time 1
+     */
+    public void setT1(int t1) {
+        this.t1 = t1;
+    }
+
+    /**
+     * Gets time 2.
+     * The time at which the requesting router should
+     * contact any available delegating router to extend
+     * the lifetimes of the prefixes assigned to the
+     * IA_PD; T2 is a time duration relative to the
+     * current time expressed in units of seconds.
+     *
+     * @return the value of time 2
+     */
+    public int getT2() {
+        return t2;
+    }
+
+    /**
+     * Sets time 2.
+     *
+     * @param t2 the value of time 2
+     */
+    public void setT2(int t2) {
+        this.t2 = t2;
+    }
+
+    /**
+     * Gets sub-options.
+     *
+     * @return sub-options of this option
+     */
+    public List<Dhcp6Option> getOptions() {
+        return options;
+    }
+
+    /**
+     * Sets sub-options.
+     *
+     * @param options the sub-options of this option
+     */
+    public void setOptions(List<Dhcp6Option> options) {
+        this.options = options;
+    }
+
+    /**
+     * Default constructor.
+     */
+    public Dhcp6IaPdOption() {
+    }
+
+    /**
+     * Constructs a DHCPv6 IA PD option with DHCPv6 option.
+     *
+     * @param dhcp6Option the DHCPv6 option
+     */
+    public Dhcp6IaPdOption(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 IA PD option data");
+            }
+            Dhcp6IaPdOption iaPdOption = new Dhcp6IaPdOption(dhcp6Option);
+            byte[] optionData = iaPdOption.getData();
+            ByteBuffer bb = ByteBuffer.wrap(optionData);
+            iaPdOption.iaId = bb.getInt();
+            iaPdOption.t1 = bb.getInt();
+            iaPdOption.t2 = bb.getInt();
+
+            iaPdOption.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.IAPREFIX.value()) {
+                    option = Dhcp6IaPrefixOption.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                } else {
+                    option = Dhcp6Option.deserializer()
+                            .deserialize(subOptData, 0, subOptData.length);
+                }
+                iaPdOption.options.add(option);
+            }
+            return iaPdOption;
+        };
+    }
+
+    @Override
+    public byte[] serialize() {
+        int payloadLen = DEFAULT_LEN + options.stream()
+                .mapToInt(opt -> (int) opt.getLength() + Dhcp6Option.DEFAULT_LEN)
+                .sum();
+        int len = Dhcp6Option.DEFAULT_LEN + payloadLen;
+        ByteBuffer bb = ByteBuffer.allocate(len);
+        bb.putShort(DHCP6.OptionCode.IA_PD.value());
+        bb.putShort((short) payloadLen);
+        bb.putInt(iaId);
+        bb.putInt(t1);
+        bb.putInt(t2);
+
+        options.stream().map(Dhcp6Option::serialize).forEach(bb::put);
+        return bb.array();
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + Objects.hash(iaId, t1, t2, options);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final Dhcp6IaPdOption other = (Dhcp6IaPdOption) obj;
+        return Objects.equals(this.iaId, other.iaId)
+                && Objects.equals(this.t1, other.t1)
+                && Objects.equals(this.t2, other.t2)
+                && Objects.equals(this.options, other.options);
+    }
+
+    @Override
+    public String toString() {
+        return getToStringHelper()
+                .add("iaId", iaId)
+                .add("t1", t1)
+                .add("t2", t2)
+                .add("options", options)
+                .toString();
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPrefixOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPrefixOption.java
new file mode 100644
index 0000000..997455d
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6IaPrefixOption.java
@@ -0,0 +1,226 @@
+/*
+ * 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.Data;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Deserializer;
+import org.onlab.packet.IPacket;
+import org.onlab.packet.Ip6Address;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * IA Address option for DHCPv6.
+ * Based on RFC-3633.
+ */
+public final class Dhcp6IaPrefixOption extends Dhcp6Option {
+    public static final int DEFAULT_LEN = 25;
+
+    private Ip6Address ip6Prefix;
+    private byte prefixLength;
+    private int preferredLifetime;
+    private int validLifetime;
+    private IPacket options;
+
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.IAPREFIX.value();
+    }
+
+    @Override
+    public short getLength() {
+        return (short) (options == null ? DEFAULT_LEN : DEFAULT_LEN + options.serialize().length);
+    }
+
+    /**
+     * Sets IPv6 prefix.
+     *
+     * @param ip6Prefix the IPv6 prefix
+     */
+    public void setIp6Prefix(Ip6Address ip6Prefix) {
+        this.ip6Prefix = ip6Prefix;
+    }
+
+    /**
+     * Sets prefix length.
+     *
+     * @param prefixLength the prefix length
+     */
+    public void setPrefixLength(byte prefixLength) {
+        this.prefixLength = prefixLength;
+    }
+
+    /**
+     * Sets preferred lifetime.
+     *
+     * @param preferredLifetime the preferred lifetime
+     */
+    public void setPreferredLifetime(int preferredLifetime) {
+        this.preferredLifetime = preferredLifetime;
+    }
+
+    /**
+     * Sets valid lifetime.
+     *
+     * @param validLifetime the valid lifetime
+     */
+    public void setValidLifetime(int validLifetime) {
+        this.validLifetime = validLifetime;
+    }
+
+    /**
+     * Sets options data.
+     *
+     * @param options the options data
+     */
+    public void setOptions(IPacket options) {
+        this.options = options;
+    }
+
+    /**
+     * Gets IPv6 address.
+     *
+     * @return the IPv6 address
+     */
+    public Ip6Address getIp6Prefix() {
+        return ip6Prefix;
+    }
+
+    /**
+     * Gets prefix length.
+     *
+     * @return the prefix length
+     */
+    public byte getPrefixLength() {
+        return prefixLength;
+    }
+
+    /**
+     * Gets preferred lifetime.
+     *
+     * @return the preferred lifetime
+     */
+    public int getPreferredLifetime() {
+        return preferredLifetime;
+    }
+
+    /**
+     * Gets valid lifetime.
+     *
+     * @return the valid lifetime
+     */
+    public int getValidLifetime() {
+        return validLifetime;
+    }
+
+    /**
+     * Gets options of IA Address option.
+     *
+     * @return the options data
+     */
+    public IPacket getOptions() {
+        return options;
+    }
+
+    public static Deserializer<Dhcp6Option> deserializer() {
+        return (data, offset, length) -> {
+            Dhcp6IaPrefixOption iaPrefixOption = new Dhcp6IaPrefixOption();
+            Dhcp6Option dhcp6Option =
+                    Dhcp6Option.deserializer().deserialize(data, offset, length);
+            iaPrefixOption.setPayload(dhcp6Option.getPayload());
+            if (dhcp6Option.getLength() < DEFAULT_LEN) {
+                throw new DeserializationException("Invalid length of IA prefix option");
+            }
+            ByteBuffer bb = ByteBuffer.wrap(dhcp6Option.getData());
+            iaPrefixOption.preferredLifetime = bb.getInt();
+            iaPrefixOption.validLifetime = bb.getInt();
+            iaPrefixOption.prefixLength = bb.get();
+            byte[] ipv6Pref = new byte[Ip6Address.BYTE_LENGTH];
+            bb.get(ipv6Pref);
+            iaPrefixOption.ip6Prefix = Ip6Address.valueOf(ipv6Pref);
+
+            // options length of IA Address option
+            int optionsLen = dhcp6Option.getLength() - DEFAULT_LEN;
+            if (optionsLen > 0) {
+                byte[] optionsData = new byte[optionsLen];
+                bb.get(optionsData);
+                iaPrefixOption.options =
+                        Data.deserializer().deserialize(optionsData, 0, optionsLen);
+            }
+            return iaPrefixOption;
+        };
+    }
+
+    @Override
+    public byte[] serialize() {
+        int payloadLen = options == null ? DEFAULT_LEN : DEFAULT_LEN + options.serialize().length;
+        ByteBuffer bb = ByteBuffer.allocate(payloadLen + Dhcp6Option.DEFAULT_LEN);
+        bb.putShort(DHCP6.OptionCode.IAPREFIX.value());
+        bb.putShort((short) payloadLen);
+        bb.putInt(preferredLifetime);
+        bb.putInt(validLifetime);
+        bb.put(prefixLength);
+        bb.put(ip6Prefix.toOctets());
+        if (options != null) {
+            bb.put(options.serialize());
+        }
+        return bb.array();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), ip6Prefix, prefixLength, preferredLifetime,
+                            validLifetime, options);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof Dhcp6IaAddressOption)) {
+            return false;
+        }
+        final Dhcp6IaPrefixOption other = (Dhcp6IaPrefixOption) obj;
+
+        return Objects.equals(getCode(), other.getCode()) &&
+                Objects.equals(getLength(), other.getLength()) &&
+                Objects.equals(preferredLifetime, other.preferredLifetime) &&
+                Objects.equals(validLifetime, other.validLifetime) &&
+                Objects.equals(prefixLength, other.prefixLength) &&
+                Objects.equals(ip6Prefix, other.ip6Prefix) &&
+                Objects.equals(options, other.options);
+    }
+
+    @Override
+    public String toString() {
+        return getToStringHelper()
+                .add("preferredLifetime", preferredLifetime)
+                .add("validLifetime", validLifetime)
+                .add("prefixLength", prefixLength)
+                .add("ip6Address", ip6Prefix)
+                .add("options", options)
+                .toString();
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6InterfaceIdOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6InterfaceIdOption.java
new file mode 100644
index 0000000..abb8257
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6InterfaceIdOption.java
@@ -0,0 +1,137 @@
+/*
+ * 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.MacAddress;
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.Deserializer;
+import org.onlab.packet.DeserializationException;
+
+
+import java.nio.ByteBuffer;
+
+/**
+ * Relay option for DHCPv6.
+ * Based on RFC-3315.
+ */
+public final class Dhcp6InterfaceIdOption extends Dhcp6Option {
+    private MacAddress peerMacAddr;
+    private byte[] inPort;
+    @Override
+    public short getCode() {
+        return DHCP6.OptionCode.INTERFACE_ID.value();
+    }
+
+    @Override
+    public short getLength() {
+        return (short) payload.serialize().length;
+    }
+
+    @Override
+    public byte[] getData() {
+        return this.payload.serialize();
+    }
+
+    /**
+     * Default constructor.
+     */
+    public Dhcp6InterfaceIdOption() {
+    }
+
+    /**
+     * Constructs a DHCPv6 relay option with DHCPv6 option.
+     *
+     * @param dhcp6Option the DHCPv6 option
+     */
+    public Dhcp6InterfaceIdOption(Dhcp6Option dhcp6Option) {
+        super(dhcp6Option);
+    }
+
+    /**
+     * Sets MacAddress address.
+     *
+     * @param macAddress the client peer MacAddress
+     */
+    public void setMacAddress(MacAddress macAddress) {
+        this.peerMacAddr = macAddress;
+    }
+
+    /**
+     * Gets Mac address.
+     *
+     * @return the client peer mac address
+     */
+    public MacAddress getMacAddress() {
+        return peerMacAddr;
+    }
+
+    /**
+     * Sets inPort string.
+     *
+     * @param port the port from which client packet is received
+     */
+    public void setInPort(byte[] port) {
+        this.inPort = port;
+    }
+
+    /**
+     * Gets inPort string.
+     *
+     * @return the port from which client packet is received
+     */
+    public byte[] getInPort() {
+        return inPort;
+    }
+
+    /**
+     * Gets deserializer for DHCPv6 relay option.
+     *
+     * @return the deserializer
+     */
+    public static Deserializer<Dhcp6Option> deserializer() {
+        return (data, offset, len) -> {
+            Dhcp6Option dhcp6Option = Dhcp6Option.deserializer().deserialize(data, offset, len);
+            if (dhcp6Option.getLength() < DEFAULT_LEN) {
+                throw new DeserializationException("Invalid InterfaceIoption data");
+            }
+            Dhcp6InterfaceIdOption interfaceIdOption = new Dhcp6InterfaceIdOption(dhcp6Option);
+            byte[] optionData = interfaceIdOption.getData();
+            if (optionData.length >= 28) {
+                ByteBuffer bb = ByteBuffer.wrap(optionData);
+
+                byte[] macAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
+                byte[] port = new byte[21];
+                bb.get(macAddr);
+                bb.get();  // separator
+                bb.get(port);
+                interfaceIdOption.setMacAddress(MacAddress.valueOf(macAddr));
+                interfaceIdOption.setInPort(port);
+            }
+            return interfaceIdOption;
+        };
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("code", getCode())
+                .add("length", getLength())
+                .add("data", payload.toString())
+                .toString();
+    }
+}
