diff --git a/apps/dhcprelay/app/BUCK b/apps/dhcprelay/app/BUCK
new file mode 100644
index 0000000..d698297
--- /dev/null
+++ b/apps/dhcprelay/app/BUCK
@@ -0,0 +1,21 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:JACKSON',
+    '//lib:KRYO',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli',
+    '//core/store/serializers:onos-core-serializers',
+    '//apps/route-service/api:onos-apps-route-service-api',
+    '//apps/routing/fpm/api:onos-apps-routing-fpm-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST',
+    '//apps/route-service/api:onos-apps-route-service-api-tests',
+    '//core/api:onos-api-tests',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
diff --git a/apps/dhcprelay/app/BUILD b/apps/dhcprelay/app/BUILD
new file mode 100644
index 0000000..29e4908
--- /dev/null
+++ b/apps/dhcprelay/app/BUILD
@@ -0,0 +1,15 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + CLI + [
+    "//core/store/serializers:onos-core-serializers",
+    "//apps/route-service/api:onos-apps-route-service-api",
+    "//apps/routing/fpm/api:onos-apps-routing-fpm-api",
+]
+
+TEST_DEPS = TEST + [
+    "//apps/route-service/api:onos-apps-route-service-api-tests",
+    "//core/api:onos-api-tests",
+]
+
+osgi_jar_with_tests(
+    test_deps = TEST_DEPS,
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
new file mode 100644
index 0000000..59310b5
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
@@ -0,0 +1,1985 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+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.DHCP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.CircuitId;
+import org.onlab.packet.dhcp.DhcpOption;
+import org.onlab.packet.dhcp.DhcpRelayAgentOption;
+import org.onlab.util.Tools;
+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.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
+import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.InterfaceIpAddress;
+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.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_CircuitID;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_END;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
+import static org.onlab.packet.MacAddress.valueOf;
+import static org.onlab.packet.dhcp.DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
+import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
+
+
+@Component
+@Service
+@Property(name = "version", value = "4")
+public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
+    public static final String DHCP_V4_RELAY_APP = "org.onosproject.Dhcp4HandlerImpl";
+    public static final ProviderId PROVIDER_ID = new ProviderId("dhcp4", DHCP_V4_RELAY_APP);
+    private static final String BROADCAST_IP = "255.255.255.255";
+    private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
+
+    private static final String LQ_ROUTE_PROPERTY_NAME = "learnRouteFromLeasequery";
+
+    private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV4)
+            .matchIPProtocol(IPv4.PROTOCOL_UDP)
+            .matchIPSrc(Ip4Address.ZERO.toIpPrefix())
+            .matchIPDst(Ip4Address.valueOf(BROADCAST_IP).toIpPrefix())
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
+            .build();
+    private static final TrafficSelector SERVER_RELAY_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV4)
+            .matchIPProtocol(IPv4.PROTOCOL_UDP)
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
+            .build();
+    static final Set<TrafficSelector> DHCP_SELECTORS = ImmutableSet.of(
+            CLIENT_SERVER_SELECTOR,
+            SERVER_RELAY_SELECTOR
+    );
+    private static Logger log = LoggerFactory.getLogger(Dhcp4HandlerImpl.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayStore dhcpRelayStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteStore routeStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry providerRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService cfgService;
+
+    protected HostProviderService providerService;
+    protected ApplicationId appId;
+    protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
+    private InternalHostListener hostListener = new InternalHostListener();
+
+    private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
+    private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
+
+    @Property(name = Dhcp4HandlerImpl.LQ_ROUTE_PROPERTY_NAME, boolValue = false,
+            label = "Enable learning routing information from LQ")
+    private Boolean learnRouteFromLeasequery = Boolean.TRUE;
+
+    private Executor hostEventExecutor = newSingleThreadExecutor(
+        groupedThreads("dhcp4-event-host", "%d", log));
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        cfgService.registerProperties(getClass());
+        modified(context);
+        appId = coreService.registerApplication(DHCP_V4_RELAY_APP);
+        hostService.addListener(hostListener);
+        providerService = providerRegistry.register(this);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        cfgService.unregisterProperties(getClass(), false);
+        providerRegistry.unregister(this);
+        hostService.removeListener(hostListener);
+        defaultServerInfoList.forEach(this::stopMonitoringIps);
+        defaultServerInfoList.forEach(info -> info.getDhcpServerIp4().ifPresent(this::cancelDhcpPacket));
+        defaultServerInfoList.clear();
+        indirectServerInfoList.forEach(this::stopMonitoringIps);
+        indirectServerInfoList.forEach(info -> info.getDhcpServerIp4().ifPresent(this::cancelDhcpPacket));
+        indirectServerInfoList.clear();
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        Boolean flag;
+        flag = Tools.isPropertyEnabled(properties, Dhcp4HandlerImpl.LQ_ROUTE_PROPERTY_NAME);
+        if (flag != null) {
+            learnRouteFromLeasequery = flag;
+            log.info("Learning routes from DHCP leasequery is {}",
+                    learnRouteFromLeasequery ? "enabled" : "disabled");
+        }
+    }
+
+    private void stopMonitoringIps(DhcpServerInfo serverInfo) {
+        serverInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
+            hostService.stopMonitoringIp(gatewayIp);
+        });
+        serverInfo.getDhcpServerIp4().ifPresent(serverIp -> {
+            hostService.stopMonitoringIp(serverIp);
+        });
+    }
+
+    @Override
+    public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        setDhcpServerConfigs(configs, defaultServerInfoList);
+    }
+
+    @Override
+    public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        setDhcpServerConfigs(configs, indirectServerInfoList);
+    }
+
+    @Override
+    public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
+        return defaultServerInfoList;
+    }
+
+    @Override
+    public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
+        return indirectServerInfoList;
+    }
+
+    @Override
+    public void updateIgnoreVlanConfig(IgnoreDhcpConfig config) {
+        if (config == null) {
+            ignoredVlans.forEach(((deviceId, vlanId) -> {
+                processIgnoreVlanRule(deviceId, vlanId, REMOVE);
+            }));
+            return;
+        }
+        config.ignoredVlans().forEach((deviceId, vlanId) -> {
+            if (ignoredVlans.get(deviceId).contains(vlanId)) {
+                // don't need to process if it already ignored
+                return;
+            }
+            processIgnoreVlanRule(deviceId, vlanId, ADD);
+        });
+
+        ignoredVlans.forEach((deviceId, vlanId) -> {
+            if (!config.ignoredVlans().get(deviceId).contains(vlanId)) {
+                // not contains in new config, remove it
+                processIgnoreVlanRule(deviceId, vlanId, REMOVE);
+            }
+        });
+    }
+
+    @Override
+    public void removeIgnoreVlanState(IgnoreDhcpConfig config) {
+        if (config == null) {
+            ignoredVlans.clear();
+            return;
+        }
+        config.ignoredVlans().forEach((deviceId, vlanId) -> {
+            ignoredVlans.remove(deviceId, vlanId);
+        });
+    }
+
+    public void setDhcpServerConfigs(Collection<DhcpServerConfig> configs, List<DhcpServerInfo> serverInfoList) {
+        if (configs.size() == 0) {
+            // no config to update
+            return;
+        }
+
+        Boolean isConfigValid = false;
+        for (DhcpServerConfig serverConfig : configs) {
+            if (serverConfig.getDhcpServerIp4().isPresent()) {
+                isConfigValid = true;
+                break;
+            }
+        }
+        if (!isConfigValid) {
+            log.warn("No IP V4 server address found.");
+            return;  // No IP V6 address found
+        }
+        // if (!serverInfoList.isEmpty()) {
+        for (DhcpServerInfo oldServerInfo : serverInfoList) {
+            log.info("In for (DhcpServerInfo oldServerInfo : serverInfoList) {");
+            // remove old server info
+            //DhcpServerInfo oldServerInfo = serverInfoList.remove(0);
+
+            // stop monitoring gateway or server
+            oldServerInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
+                hostService.stopMonitoringIp(gatewayIp);
+            });
+            oldServerInfo.getDhcpServerIp4().ifPresent(serverIp -> {
+                hostService.stopMonitoringIp(serverIp);
+                cancelDhcpPacket(serverIp);
+            });
+        }
+
+        // Create new server info according to the config
+        serverInfoList.clear();
+        for (DhcpServerConfig serverConfig : configs) {
+            log.debug("Create new server info according to the config");
+            DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
+                    DhcpServerInfo.Version.DHCP_V4);
+            checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
+                    "Connect point not exists");
+            checkState(newServerInfo.getDhcpServerIp4().isPresent(),
+                    "IP of DHCP server not exists");
+
+            log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
+            log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp4().orElse(null));
+
+            Ip4Address serverIp = newServerInfo.getDhcpServerIp4().get();
+            Ip4Address ipToProbe;
+            if (newServerInfo.getDhcpGatewayIp4().isPresent()) {
+                ipToProbe = newServerInfo.getDhcpGatewayIp4().get();
+            } else {
+                ipToProbe = newServerInfo.getDhcpServerIp4().orElse(null);
+            }
+            log.info("Probe_IP {}", ipToProbe);
+            String hostToProbe = newServerInfo.getDhcpGatewayIp4()
+                    .map(ip -> "gateway").orElse("server");
+
+            log.debug("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                Host host = hosts.iterator().next();
+                newServerInfo.setDhcpConnectVlan(host.vlan());
+                newServerInfo.setDhcpConnectMac(host.mac());
+            }
+
+            // Add new server info
+            synchronized (this) {
+                //serverInfoList.clear();
+                serverInfoList.add(newServerInfo);
+            }
+
+            requestDhcpPacket(serverIp);
+        }
+    }
+
+    @Override
+    public void processDhcpPacket(PacketContext context, BasePacket payload) {
+        checkNotNull(payload, "DHCP payload can't be null");
+        checkState(payload instanceof DHCP, "Payload is not a DHCP");
+        DHCP dhcpPayload = (DHCP) payload;
+        if (!configured()) {
+            log.warn("Missing default DHCP relay server config. Abort packet processing");
+            return;
+        }
+
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        checkNotNull(dhcpPayload, "Can't find DHCP payload");
+        Ethernet packet = context.inPacket().parsed();
+        DHCP.MsgType incomingPacketType = dhcpPayload.getOptions().stream()
+                .filter(dhcpOption -> dhcpOption.getCode() == OptionCode_MessageType.getValue())
+                .map(DhcpOption::getData)
+                .map(data -> DHCP.MsgType.getType(data[0]))
+                .findFirst()
+                .orElse(null);
+        checkNotNull(incomingPacketType, "Can't get message type from DHCP payload {}", dhcpPayload);
+        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;
+        }
+        switch (incomingPacketType) {
+            case DHCPDISCOVER:
+                // Add the gateway IP as virtual interface IP for server to understand
+                // the lease to be assigned and forward the packet to dhcp server.
+                List<InternalPacket> ethernetClientPacket =
+                        processDhcpPacketFromClient(context, packet, receivingInterfaces);
+                for (InternalPacket internalPacket : ethernetClientPacket) {
+                    log.debug("DHCPDISCOVER from {} Forward to server", inPort);
+                    writeRequestDhcpRecord(inPort, packet, dhcpPayload);
+                    forwardPacket(internalPacket);
+                }
+                break;
+            case DHCPOFFER:
+                //reply to dhcp client.
+                InternalPacket ethernetPacketOffer = processDhcpPacketFromServer(context, packet);
+                if (ethernetPacketOffer != null) {
+                    writeResponseDhcpRecord(ethernetPacketOffer.getPacket(), dhcpPayload);
+                    sendResponseToClient(ethernetPacketOffer, dhcpPayload);
+                }
+                break;
+            case DHCPREQUEST:
+                // add the gateway ip as virtual interface ip for server to understand
+                // the lease to be assigned and forward the packet to dhcp server.
+                List<InternalPacket> ethernetPacketRequest =
+                        processDhcpPacketFromClient(context, packet, receivingInterfaces);
+                for (InternalPacket internalPacket : ethernetPacketRequest) {
+                    log.debug("DHCPDISCOVER from {} Forward to server", inPort);
+                    writeRequestDhcpRecord(inPort, packet, dhcpPayload);
+                    forwardPacket(internalPacket);
+                }
+                break;
+            case DHCPDECLINE:
+                break;
+            case DHCPACK:
+                // reply to dhcp client.
+                InternalPacket ethernetPacketAck = processDhcpPacketFromServer(context, packet);
+                if (ethernetPacketAck != null) {
+                    writeResponseDhcpRecord(ethernetPacketAck.getPacket(), dhcpPayload);
+                    handleDhcpAck(ethernetPacketAck.getPacket(), dhcpPayload);
+                    sendResponseToClient(ethernetPacketAck, dhcpPayload);
+                }
+                break;
+            case DHCPNAK:
+                break;
+            case DHCPRELEASE:
+                // TODO: release the ip address from client
+                break;
+            case DHCPINFORM:
+                break;
+            case DHCPFORCERENEW:
+                break;
+            case DHCPLEASEQUERY:
+                handleLeaseQueryMsg(context, packet, dhcpPayload);
+                break;
+            case DHCPLEASEACTIVE:
+                handleLeaseQueryActivateMsg(packet, dhcpPayload);
+                break;
+            case DHCPLEASEUNASSIGNED:
+            case DHCPLEASEUNKNOWN:
+                handleLeaseQueryUnknown(packet, dhcpPayload);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Checks if this app has been configured.
+     *
+     * @return true if all information we need have been initialized
+     */
+    private boolean configured() {
+        return !defaultServerInfoList.isEmpty();
+    }
+
+    /**
+     * Returns the first interface ip from interface.
+     *
+     * @param iface interface of one connect point
+     * @return the first interface IP; null if not exists an IP address in
+     *         these interfaces
+     */
+    private Ip4Address getFirstIpFromInterface(Interface iface) {
+        checkNotNull(iface, "Interface can't be null");
+        return iface.ipAddressesList().stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(IpAddress::isIp4)
+                .map(IpAddress::getIp4Address)
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Gets Interface facing to the server for default host.
+     *
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getDefaultServerInterface() {
+        return getServerInterface(defaultServerInfoList);
+    }
+
+    /**
+     * Gets Interface facing to the server for indirect hosts.
+     * Use default server Interface if indirect server not configured.
+     *
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getIndirectServerInterface() {
+        return getServerInterface(indirectServerInfoList);
+    }
+
+    private Interface getServerInterface(List<DhcpServerInfo> serverInfos) {
+        return serverInfos.stream()
+                .findFirst()
+                .map(serverInfo -> {
+                    ConnectPoint dhcpServerConnectPoint =
+                            serverInfo.getDhcpServerConnectPoint().orElse(null);
+                    VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+                    if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
+                        return null;
+                    }
+                    return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                            .stream()
+                            .filter(iface -> interfaceContainsVlan(iface, dhcpConnectVlan))
+                            .findFirst()
+                            .orElse(null);
+                })
+                .orElse(null);
+    }
+
+    /**
+     * Determind if an Interface contains a vlan id.
+     *
+     * @param iface the Interface
+     * @param vlanId the vlan id
+     * @return true if the Interface contains the vlan id
+     */
+    private boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
+        if (vlanId.equals(VlanId.NONE)) {
+            // untagged packet, check if vlan untagged or vlan native is not NONE
+            return !iface.vlanUntagged().equals(VlanId.NONE) ||
+                    !iface.vlanNative().equals(VlanId.NONE);
+        }
+        // tagged packet, check if the interface contains the vlan
+        return iface.vlanTagged().contains(vlanId);
+    }
+
+    private void handleLeaseQueryActivateMsg(Ethernet packet, DHCP dhcpPayload) {
+        log.debug("LQ: Got DHCPLEASEACTIVE packet!");
+
+        if (learnRouteFromLeasequery) {
+            // TODO: release the ip address from client
+            MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+            VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+            HostId hostId = HostId.hostId(clientMacAddress, vlanId);
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+
+            if (record == null) {
+                log.warn("Can't find record for host {} when processing DHCPLEASEACTIVE", hostId);
+                return;
+            }
+
+            // need to update routes
+            log.debug("Lease Query for Client results in DHCPLEASEACTIVE - route needs to be modified");
+            // get current route
+            // find the ip of that client with the DhcpRelay store
+
+            Ip4Address clientIP = record.ip4Address().orElse(null);
+            log.debug("LQ: IP of host is " + clientIP.getIp4Address());
+
+            MacAddress nextHopMac = record.nextHop().orElse(null);
+            log.debug("LQ: MAC of resulting *OLD* NH for that host is " + nextHopMac.toString());
+
+            // find the new NH by looking at the src MAC of the dhcp request
+            // from the LQ store
+            MacAddress newNextHopMac = record.nextHopTemp().orElse(null);
+            log.debug("LQ: MAC of resulting *NEW* NH for that host is " + newNextHopMac.toString());
+
+            log.debug("LQ: updating dhcp relay record with new NH");
+            record.nextHop(newNextHopMac);
+
+            // find the next hop IP from its mac
+            HostId gwHostId = HostId.hostId(newNextHopMac, vlanId);
+            Host gwHost = hostService.getHost(gwHostId);
+
+            if (gwHost == null) {
+                log.warn("Can't find gateway for new NH host " + gwHostId);
+                return;
+            }
+
+            Ip4Address nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp4)
+                    .map(IpAddress::getIp4Address)
+                    .findFirst()
+                    .orElse(null);
+
+            if (nextHopIp == null) {
+                log.warn("Can't find IP address of gateway " + gwHost);
+                return;
+            }
+
+            log.debug("LQ: *NEW* NH IP for host is " + nextHopIp.getIp4Address());
+            Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
+            routeStore.updateRoute(route);
+        }
+
+        // and forward to client
+        InternalPacket ethernetPacket = processLeaseQueryFromServer(packet);
+        if (ethernetPacket != null) {
+            sendResponseToClient(ethernetPacket, dhcpPayload);
+        }
+    }
+
+    private void handleLeaseQueryMsg(PacketContext context, Ethernet packet, DHCP dhcpPayload) {
+        // If this flag is enabled we expect that DHCPLEASEQUERY-ies are sent from an access concentrator
+        // where queried client is connected to. Otherwise, DHCPLEASEQUERY source may be a separate connected agent
+        if (learnRouteFromLeasequery) {
+            log.debug("LQ: Got DHCPLEASEQUERY packet!");
+            MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+            log.debug("LQ: got DHCPLEASEQUERY with MAC " + clientMacAddress.toString());
+            // add the client mac (hostid) of this request to a store (the entry will be removed with
+            // the reply sent to the originator)
+            VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+            HostId hId = HostId.hostId(clientMacAddress, vlanId);
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hId).orElse(null);
+            if (record != null) {
+                //new NH is to be taken from src mac of LQ packet
+                MacAddress newNextHop = packet.getSourceMAC();
+                record.nextHopTemp(newNextHop);
+                record.ip4Status(dhcpPayload.getPacketType());
+                record.updateLastSeen();
+
+                // do a basic routing of the packet (this is unicast routing
+                // not a relay operation like for other broadcast dhcp packets
+                List<InternalPacket> ethernetPacketRequest = processLeaseQueryFromAgent(context, packet);
+                // and forward to server
+                for (InternalPacket internalPacket : ethernetPacketRequest) {
+                    log.debug("LeaseQueryMsg forward to server");
+                    forwardPacket(internalPacket);
+                }
+            } else {
+                log.warn("LQ: Error! - DHCP relay record for that client not found - ignoring LQ!");
+            }
+        } else {
+            log.debug("LQ: Got DHCPLEASEQUERY packet!");
+
+            int giaddr = dhcpPayload.getGatewayIPAddress();
+
+            log.debug("DHCPLEASEQUERY giaddr: {} ({}). Originators connectPoint: {}", giaddr,
+                    Ip4Address.valueOf(giaddr), context.inPacket().receivedFrom());
+
+            // do a basic routing of the packet (this is unicast routing
+            // not a relay operation like for other broadcast dhcp packets
+            List<InternalPacket> ethernetPacketRequest = processLeaseQueryFromAgent(context, packet);
+            // and forward to server
+            for (InternalPacket internalPacket : ethernetPacketRequest) {
+                log.trace("LeaseQueryMsg forward to server connected to {}", internalPacket.getDestLocation());
+                forwardPacket(internalPacket);
+            }
+        }
+    }
+
+    private void handleLeaseQueryUnknown(Ethernet packet, DHCP dhcpPayload) {
+        log.debug("Lease Query for Client results in DHCPLEASEUNASSIGNED or " +
+                          "DHCPLEASEUNKNOWN - removing route & forwarding reply to originator");
+        if (learnRouteFromLeasequery) {
+            MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+            VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+            HostId hostId = HostId.hostId(clientMacAddress, vlanId);
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+
+            if (record == null) {
+                log.warn("Can't find record for host {} when handling LQ UNKNOWN/UNASSIGNED message", hostId);
+                return;
+            }
+
+            Ip4Address clientIP = record.ip4Address().orElse(null);
+            log.debug("LQ: IP of host is " + clientIP.getIp4Address());
+
+            // find the new NH by looking at the src MAC of the dhcp request
+            // from the LQ store
+            MacAddress nextHopMac = record.nextHop().orElse(null);
+            log.debug("LQ: MAC of resulting *Existing* NH for that route is " + nextHopMac.toString());
+
+            // find the next hop IP from its mac
+            HostId gwHostId = HostId.hostId(nextHopMac, vlanId);
+            Host gwHost = hostService.getHost(gwHostId);
+
+            if (gwHost == null) {
+                log.warn("Can't find gateway for new NH host " + gwHostId);
+                return;
+            }
+
+            Ip4Address nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp4)
+                    .map(IpAddress::getIp4Address)
+                    .findFirst()
+                    .orElse(null);
+
+            if (nextHopIp == null) {
+                log.warn("Can't find IP address of gateway {}", gwHost);
+                return;
+            }
+
+            log.debug("LQ: *Existing* NH IP for host is " + nextHopIp.getIp4Address() + " removing route for it");
+            Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
+            routeStore.removeRoute(route);
+
+            // remove from temp store
+            dhcpRelayStore.removeDhcpRecord(hostId);
+        }
+        // and forward to client
+        InternalPacket ethernetPacket = processLeaseQueryFromServer(packet);
+        if (ethernetPacket != null) {
+            sendResponseToClient(ethernetPacket, dhcpPayload);
+        }
+    }
+
+    /**
+     * Build the DHCP discover/request packet with gateway IP(unicast packet).
+     *
+     * @param context the packet context
+     * @param ethernetPacket the ethernet payload to process
+     * @return processed packet
+     */
+    private List<InternalPacket> processDhcpPacketFromClient(PacketContext context,
+                                                             Ethernet ethernetPacket,
+                                                             Set<Interface> clientInterfaces) {
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        DeviceId receivedFromDevice = receivedFrom.deviceId();
+        Ip4Address relayAgentIp = null;
+        relayAgentIp = Dhcp4HandlerUtil.getRelayAgentIPv4Address(clientInterfaces);
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentIp == null || relayAgentMac == null) {
+            log.warn("Missing DHCP relay agent interface Ipv4 addr config for "
+                            + "packet from client on port: {}. Aborting packet processing",
+                    clientInterfaces.iterator().next().connectPoint());
+            return Lists.newArrayList();
+        }
+        log.debug("Multi DHCP V4 processDhcpPacketFromClient on port {}",
+                   clientInterfaces.iterator().next().connectPoint());
+
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+
+        Ip4Address clientInterfaceIp =
+                interfaceService.getInterfacesByPort(context.inPacket().receivedFrom())
+                        .stream()
+                        .map(Interface::ipAddressesList)
+                        .flatMap(Collection::stream)
+                        .map(InterfaceIpAddress::ipAddress)
+                        .filter(IpAddress::isIp4)
+                        .map(IpAddress::getIp4Address)
+                        .findFirst()
+                        .orElse(null);
+        if (clientInterfaceIp == null) {
+            log.warn("Can't find interface IP for client interface for port {}",
+                    context.inPacket().receivedFrom());
+            return Lists.newArrayList();
+        }
+
+        boolean isDirectlyConnected = directlyConnected(dhcpPacket);
+        boolean directConnFlag = directlyConnected(dhcpPacket);
+
+        // Multi DHCP Start
+        ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
+        VlanId vlanIdInUse = VlanId.vlanId(ethernetPacket.getVlanID());
+        Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
+                .stream().filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst()
+                .orElse(null);
+
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
+
+
+        for (DhcpServerInfo serverInfo : copyServerInfoList) {
+            etherReply = (Ethernet) ethernetPacket.clone();
+            ipv4Packet = (IPv4) etherReply.getPayload();
+            udpPacket = (UDP) ipv4Packet.getPayload();
+            dhcpPacket = (DHCP) udpPacket.getPayload();
+            if (!checkDhcpServerConnPt(directConnFlag, serverInfo)) {
+                log.warn("Can't get server connect point, ignore");
+                continue;
+            }
+            DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
+            if (newServerInfo == null) {
+                log.warn("Can't get server interface with host info resolved, ignore");
+                continue;
+            }
+
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+
+            Ip4Address ipFacingServer = getFirstIpFromInterface(serverInterface);
+            MacAddress macFacingServer = serverInterface.mac();
+            log.debug("Interfacing server {} Mac : {} ", ipFacingServer, macFacingServer);
+            if (ipFacingServer == null || macFacingServer == null) {
+                log.warn("No IP address for server Interface {}", serverInterface);
+                continue;
+            }
+
+
+            etherReply.setSourceMACAddress(macFacingServer);
+            // set default info and replace with indirect if available later on.
+            if (newServerInfo.getDhcpConnectMac().isPresent()) {
+                etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+            }
+            if (newServerInfo.getDhcpConnectVlan().isPresent()) {
+                etherReply.setVlanID(newServerInfo.getDhcpConnectVlan().get().toShort());
+            }
+            ipv4Packet.setSourceAddress(ipFacingServer.toInt());
+            ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
+            log.debug("Directly connected {}", isDirectlyConnected);
+            log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp4().get());
+            if (isDirectlyConnected) {
+
+                log.debug("Default DHCP server IP: {}", newServerInfo.getDhcpServerIp4().get());
+                if (newServerInfo.getDhcpConnectMac().isPresent()) {
+                    etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+                }
+                if (newServerInfo.getDhcpConnectVlan().isPresent()) {
+                    etherReply.setVlanID(newServerInfo.getDhcpConnectVlan().get().toShort());
+                }
+
+                ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
+
+
+                ConnectPoint inPort = context.inPacket().receivedFrom();
+                VlanId vlanId = VlanId.vlanId(ethernetPacket.getVlanID());
+                // add connected in port and vlan
+                CircuitId cid = new CircuitId(inPort.toString(), vlanId);
+                byte[] circuitId = cid.serialize();
+                DhcpOption circuitIdSubOpt = new DhcpOption();
+                circuitIdSubOpt
+                        .setCode(CIRCUIT_ID.getValue())
+                        .setLength((byte) circuitId.length)
+                        .setData(circuitId);
+
+                DhcpRelayAgentOption newRelayAgentOpt = new DhcpRelayAgentOption();
+                newRelayAgentOpt.setCode(OptionCode_CircuitID.getValue());
+                newRelayAgentOpt.addSubOption(circuitIdSubOpt);
+
+                // Removes END option first
+                List<DhcpOption> options = dhcpPacket.getOptions().stream()
+                        .filter(opt -> opt.getCode() != OptionCode_END.getValue())
+                        .collect(Collectors.toList());
+
+                // push relay agent option
+                options.add(newRelayAgentOpt);
+
+                // make sure option 255(End) is the last option
+                DhcpOption endOption = new DhcpOption();
+                endOption.setCode(OptionCode_END.getValue());
+                options.add(endOption);
+
+                dhcpPacket.setOptions(options);
+
+                relayAgentIp = serverInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
+
+                // Sets relay agent IP
+                int effectiveRelayAgentIp = relayAgentIp != null ?
+                        relayAgentIp.toInt() : clientInterfaceIp.toInt();
+                dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
+                log.debug("In Default, Relay Agent IP {}", effectiveRelayAgentIp);
+            } else {
+                if (!newServerInfo.getDhcpServerIp4().isPresent()) {
+                  // do nothing
+                } else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
+                    continue;
+                } else {
+                    relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
+                    // Sets relay agent IP
+                    int effectiveRelayAgentIp = relayAgentIp != null ?
+                            relayAgentIp.toInt() : clientInterfaceIp.toInt();
+                    Ip4Address effectiveRealRealyAgentIP = relayAgentIp != null ?
+                            relayAgentIp : clientInterfaceIp;
+                    dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
+                    ipv4Packet.setSourceAddress(effectiveRealRealyAgentIP.toInt());
+                    log.debug("Source IP address set as relay agent IP with value: {}", effectiveRealRealyAgentIP);
+                }
+            }
+
+            // Remove broadcast flag
+            dhcpPacket.setFlags((short) 0);
+
+            udpPacket.setPayload(dhcpPacket);
+            // As a DHCP relay, the source port should be server port( instead
+            // of client port.
+            udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
+            udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
+            ipv4Packet.setPayload(udpPacket);
+            ipv4Packet.setTtl((byte) 64);
+            etherReply.setPayload(ipv4Packet);
+            InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
+                    serverInfo.getDhcpServerConnectPoint().get());
+
+            internalPackets.add(internalPacket);
+        }
+        return internalPackets;
+    }
+
+
+    /**
+     * Do a basic routing for a packet from client (used for LQ processing).
+     *
+     * @param context the packet context
+     * @param ethernetPacket the ethernet payload to process
+     * @return processed packet
+     */
+    private List<InternalPacket> processLeaseQueryFromAgent(PacketContext context,
+                                                            Ethernet ethernetPacket) {
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        DeviceId receivedFromDevice = receivedFrom.deviceId();
+
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
+
+        Ip4Address relayAgentIp;
+
+        Ip4Address clientInterfaceIp =
+                interfaceService.getInterfacesByPort(context.inPacket().receivedFrom())
+                        .stream()
+                        .map(Interface::ipAddressesList)
+                        .flatMap(Collection::stream)
+                        .map(InterfaceIpAddress::ipAddress)
+                        .filter(IpAddress::isIp4)
+                        .map(IpAddress::getIp4Address)
+                        .findFirst()
+                        .orElse(null);
+        if (clientInterfaceIp == null) {
+            log.warn("Can't find interface IP for client interface for port {}",
+                    context.inPacket().receivedFrom());
+            return null;
+        }
+
+        boolean isDirectlyConnected = directlyConnected(dhcpPacket);
+        boolean directConnFlag = directlyConnected(dhcpPacket);
+
+        // Multi DHCP Start
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<>(serverInfoList);
+
+        for (DhcpServerInfo serverInfo : copyServerInfoList) {
+             // get dhcp header.
+             etherReply = (Ethernet) ethernetPacket.clone();
+             ipv4Packet = (IPv4) etherReply.getPayload();
+             udpPacket = (UDP) ipv4Packet.getPayload();
+             dhcpPacket = (DHCP) udpPacket.getPayload();
+
+            if (!checkDhcpServerConnPt(directConnFlag, serverInfo)) {
+                log.warn("Can't get server connect point, ignore");
+                continue;
+            }
+            DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
+            if (newServerInfo == null) {
+                log.warn("Can't get server interface with host info resolved, ignore");
+                continue;
+            }
+
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+            Ip4Address ipFacingServer = getFirstIpFromInterface(serverInterface);
+            MacAddress macFacingServer = serverInterface.mac();
+            if (ipFacingServer == null || macFacingServer == null) {
+                log.warn("No IP address for server Interface {}", serverInterface);
+                continue;
+            }
+
+            etherReply.setSourceMACAddress(macFacingServer);
+            etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+            etherReply.setVlanID(newServerInfo.getDhcpConnectVlan().get().toShort());
+            ipv4Packet.setSourceAddress(ipFacingServer.toInt());
+            ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
+            if (isDirectlyConnected) {
+                // set default info and replace with indirect if available later on.
+                if (newServerInfo.getDhcpConnectMac().isPresent()) {
+                    etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+                }
+                if (newServerInfo.getDhcpConnectVlan().isPresent()) {
+                    etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
+                }
+                if (learnRouteFromLeasequery) {
+                    relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
+                    // Sets relay agent IP
+                    int effectiveRelayAgentIp = relayAgentIp != null ?
+                            relayAgentIp.toInt() : clientInterfaceIp.toInt();
+                    dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
+                }
+            } else {
+                if (!newServerInfo.getDhcpServerIp4().isPresent()) {
+                  //do nothing
+                } else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
+                    continue;
+                } else if (learnRouteFromLeasequery) {
+                    relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
+                    // Sets relay agent IP
+                    int effectiveRelayAgentIp = relayAgentIp != null ?
+                            relayAgentIp.toInt() : clientInterfaceIp.toInt();
+                    dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
+                    log.debug("Relay Agent IP {}", relayAgentIp);
+                }
+
+                log.trace("Indirect");
+            }
+
+            // Remove broadcast flag
+            dhcpPacket.setFlags((short) 0);
+
+            udpPacket.setPayload(dhcpPacket);
+            // As a DHCP relay, the source port should be server port( instead
+            // of client port.
+            udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
+            udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
+            ipv4Packet.setPayload(udpPacket);
+            ipv4Packet.setTtl((byte) 64);
+            etherReply.setPayload(ipv4Packet);
+            udpPacket.resetChecksum();
+            ////return etherReply;
+            InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
+                    newServerInfo.getDhcpServerConnectPoint().get());
+
+            internalPackets.add(internalPacket);
+        }
+        log.debug("num of processLeaseQueryFromAgent packets to send is: {}", internalPackets.size());
+
+        return internalPackets;
+    }
+
+
+    /**
+     * Writes DHCP record to the store according to the request DHCP packet (Discover, Request).
+     *
+     * @param location the location which DHCP packet comes from
+     * @param ethernet the DHCP packet
+     * @param dhcpPayload the DHCP payload
+     */
+    private void writeRequestDhcpRecord(ConnectPoint location,
+                                        Ethernet ethernet,
+                                        DHCP dhcpPayload) {
+        VlanId vlanId = VlanId.vlanId(ethernet.getVlanID());
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
+        } else {
+            record = record.clone();
+        }
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+        record.ip4Status(dhcpPayload.getPacketType());
+        record.setDirectlyConnected(directlyConnected(dhcpPayload));
+        if (!directlyConnected(dhcpPayload)) {
+            // Update gateway mac address if the host is not directly connected
+            record.nextHop(ethernet.getSourceMAC());
+        }
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
+    }
+
+    /**
+     * Writes DHCP record to the store according to the response DHCP packet (Offer, Ack).
+     *
+     * @param ethernet the DHCP packet
+     * @param dhcpPayload the DHCP payload
+     */
+    private void writeResponseDhcpRecord(Ethernet ethernet,
+                                         DHCP dhcpPayload) {
+        Optional<Interface> outInterface = getClientInterface(ethernet, dhcpPayload);
+        if (!outInterface.isPresent()) {
+            log.warn("Failed to determine where to send {}", dhcpPayload.getPacketType());
+            return;
+        }
+
+        Interface outIface = outInterface.get();
+        ConnectPoint location = outIface.connectPoint();
+        VlanId vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
+        if (vlanId == null) {
+            vlanId = outIface.vlan();
+        }
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
+        } else {
+            record = record.clone();
+        }
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+        if (dhcpPayload.getPacketType() == DHCP.MsgType.DHCPACK) {
+            record.ip4Address(Ip4Address.valueOf(dhcpPayload.getYourIPAddress()));
+        }
+        record.ip4Status(dhcpPayload.getPacketType());
+        record.setDirectlyConnected(directlyConnected(dhcpPayload));
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
+    }
+
+    /**
+     * Build the DHCP offer/ack with proper client port.
+     *
+     * @param ethernetPacket the original packet comes from server
+     * @return new packet which will send to the client
+     */
+    private InternalPacket processDhcpPacketFromServer(PacketContext context, Ethernet ethernetPacket) {
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
+
+        // determine the vlanId of the client host - note that this vlan id
+        // could be different from the vlan in the packet from the server
+        Interface clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
+
+        if (clientInterface == null) {
+            log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
+            return null;
+        }
+        VlanId vlanId;
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        boolean directConnFlag = directlyConnected(dhcpPayload);
+        DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
+
+        if (foundServerInfo == null) {
+            log.warn("Cannot find server info for {} server, inPort {}",
+                      directConnFlag ? "direct" : "indirect", inPort);
+            return null;
+        } else {
+            if (Dhcp4HandlerUtil.isServerIpEmpty(foundServerInfo)) {
+                log.warn("Cannot find server info's ipaddress");
+                return null;
+            }
+        }
+        if (clientInterface.vlanTagged().isEmpty()) {
+            vlanId = clientInterface.vlan();
+        } else {
+            // might be multiple vlan in same interface
+            vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
+        }
+        if (vlanId == null) {
+            vlanId = VlanId.NONE;
+        }
+        etherReply.setVlanID(vlanId.toShort());
+        etherReply.setSourceMACAddress(clientInterface.mac());
+
+        if (!directlyConnected(dhcpPayload)) {
+            // if client is indirectly connected, try use next hop mac address
+            MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+            HostId hostId = HostId.hostId(macAddress, vlanId);
+            if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
+                DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+                if (record != null) {
+                    // if next hop can be found, use mac address of next hop
+                    record.nextHop().ifPresent(etherReply::setDestinationMACAddress);
+                } else {
+                    // otherwise, discard the packet
+                    log.warn("Can't find record for host id {}, discard packet", hostId);
+                    return null;
+                }
+            } else {
+                etherReply.setDestinationMACAddress(MacAddress.BROADCAST);
+            }
+        } else {
+            etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
+        }
+
+        // we leave the srcMac from the original packet
+        // figure out the relay agent IP corresponding to the original request
+        Ip4Address ipFacingClient = getFirstIpFromInterface(clientInterface);
+        if (ipFacingClient == null) {
+            log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. "
+                             + "Aborting relay for dhcp packet from server {}",
+                     etherReply.getDestinationMAC(), clientInterface.vlan(),
+                     ethernetPacket);
+            return null;
+        }
+        // SRC_IP: relay agent IP
+        // DST_IP: offered IP
+        ipv4Packet.setSourceAddress(ipFacingClient.toInt());
+        if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
+            ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
+        } else {
+            ipv4Packet.setDestinationAddress(BROADCAST_IP);
+        }
+        udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
+        if (directlyConnected(dhcpPayload)) {
+            udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+        } else {
+            // forward to another dhcp relay
+            // FIXME: Currently we assume the DHCP comes from a L2 relay with
+            // Option 82, this might not work if DHCP message comes from
+            // L3 relay.
+            udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+        }
+
+        udpPacket.setPayload(dhcpPayload);
+        ipv4Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv4Packet);
+        return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
+    }
+
+    /**
+     * Build the DHCP offer/ack with proper client port.
+     *
+     * @param ethernetPacket the original packet comes from server
+     * @return new packet which will send to the client
+     */
+    private InternalPacket processLeaseQueryFromServer(Ethernet ethernetPacket) {
+        // get dhcp header.
+        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv4Packet.getPayload();
+        DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
+
+        // determine the vlanId of the client host - note that this vlan id
+        // could be different from the vlan in the packet from the server
+        Interface clientInterface = null;
+        MacAddress destinationMac = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+
+        if (!learnRouteFromLeasequery) {
+            int giaddr = ipv4Packet.getDestinationAddress();
+            IpAddress destinationAddress = Ip4Address.valueOf(giaddr);
+            log.debug("DHCPLEASEQUERYRESP giaddr: {}({})", giaddr, destinationAddress);
+
+            Host destinationHost = hostService.getHostsByIp(destinationAddress).stream().findFirst().orElse(null);
+            if (destinationHost != null) {
+                destinationMac = destinationHost.mac();
+                log.trace("DHCPLEASEQUERYRESP destination mac is: {}", destinationMac);
+                ConnectPoint destinationLocation = destinationHost.location();
+                log.trace("Lookup for client interface by destination location {}", destinationLocation);
+                clientInterface = interfaceService.getInterfacesByPort(destinationLocation)
+                        .stream()
+                        .filter(iface -> interfaceContainsVlan(iface, VlanId.vlanId(etherReply.getVlanID())))
+                        .findFirst()
+                        .orElse(null);
+                log.trace("Found Host {} by ip {}", destinationHost, destinationAddress);
+                log.debug("DHCPLEASEQUERYRESP Client interface: {}",
+                        (clientInterface != null ? clientInterface : "not resolved"));
+
+            }
+        } else {
+            clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
+        }
+
+        if (clientInterface == null) {
+            log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
+            return null;
+        }
+        VlanId vlanId;
+        if (clientInterface.vlanTagged().isEmpty()) {
+            vlanId = clientInterface.vlan();
+        } else {
+            // might be multiple vlan in same interface
+            vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
+        }
+        if (vlanId == null) {
+            vlanId = VlanId.NONE;
+        }
+        etherReply.setVlanID(vlanId.toShort());
+        etherReply.setSourceMACAddress(clientInterface.mac());
+
+        if (!directlyConnected(dhcpPayload) && learnRouteFromLeasequery) {
+            // if client is indirectly connected, try use next hop mac address
+            MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+            HostId hostId = HostId.hostId(macAddress, vlanId);
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+            if (record != null) {
+                // if next hop can be found, use mac address of next hop
+                Optional<MacAddress> nextHop = record.nextHopTemp();
+                if (!nextHop.isPresent()) {
+                    nextHop = record.nextHop();
+                }
+                nextHop.ifPresent(etherReply::setDestinationMACAddress);
+            } else {
+                // otherwise, discard the packet
+                log.warn("Can't find record for host id {}, discard packet", hostId);
+                return null;
+            }
+        } else {
+            etherReply.setDestinationMACAddress(destinationMac);
+        }
+
+        udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
+        if (directlyConnected(dhcpPayload)) {
+            udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+        } else {
+            udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
+        }
+
+        udpPacket.setPayload(dhcpPayload);
+        ipv4Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv4Packet);
+        udpPacket.resetChecksum();
+
+        return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
+    }
+    /**
+     * Extracts VLAN ID from relay agent option.
+     *
+     * @param dhcpPayload the DHCP payload
+     * @return VLAN ID from DHCP payload; null if not exists
+     */
+    private VlanId getVlanIdFromRelayAgentOption(DHCP dhcpPayload) {
+        DhcpRelayAgentOption option = (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
+        if (option == null) {
+            return null;
+        }
+        DhcpOption circuitIdSubOption = option.getSubOption(CIRCUIT_ID.getValue());
+        if (circuitIdSubOption == null) {
+            return null;
+        }
+        try {
+            CircuitId circuitId = CircuitId.deserialize(circuitIdSubOption.getData());
+            return circuitId.vlanId();
+        } catch (IllegalArgumentException e) {
+            // can't deserialize the circuit ID
+            return null;
+        }
+    }
+
+    /**
+     * Removes DHCP relay agent information option (option 82) from DHCP payload.
+     * Also reset giaddr to 0
+     *
+     * @param ethPacket the Ethernet packet to be processed
+     * @return Ethernet packet processed
+     */
+    private Ethernet removeRelayAgentOption(Ethernet ethPacket) {
+        Ethernet ethernet = (Ethernet) ethPacket.duplicate();
+        IPv4 ipv4 = (IPv4) ethernet.getPayload();
+        UDP udp = (UDP) ipv4.getPayload();
+        DHCP dhcpPayload = (DHCP) udp.getPayload();
+
+        // removes relay agent information option
+        List<DhcpOption> options = dhcpPayload.getOptions();
+        options = options.stream()
+                .filter(option -> option.getCode() != OptionCode_CircuitID.getValue())
+                .collect(Collectors.toList());
+        dhcpPayload.setOptions(options);
+        dhcpPayload.setGatewayIPAddress(0);
+
+        udp.setPayload(dhcpPayload);
+        ipv4.setPayload(udp);
+        ethernet.setPayload(ipv4);
+        return ethernet;
+    }
+
+    private boolean isDhcpPacketLeasequery(DHCP dhcpPacket) {
+        switch (dhcpPacket.getPacketType()) {
+            case DHCPLEASEACTIVE:
+            case DHCPLEASEQUERY:
+            case DHCPLEASEUNASSIGNED:
+            case DHCPLEASEUNKNOWN:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Check if the host is directly connected to the network or not.
+     *
+     * @param dhcpPayload the dhcp payload
+     * @return true if the host is directly connected to the network; false otherwise
+     */
+    private boolean directlyConnected(DHCP dhcpPayload) {
+        // leasequery is always indirect
+        if (isDhcpPacketLeasequery(dhcpPayload)) {
+            return false;
+        }
+
+        DhcpRelayAgentOption relayAgentOption =
+                (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
+
+        // Doesn't contains relay option
+        if (relayAgentOption == null) {
+            return true;
+        }
+
+        // check circuit id, if circuit id is invalid, we say it is an indirect host
+        DhcpOption circuitIdOpt = relayAgentOption.getSubOption(CIRCUIT_ID.getValue());
+
+        try {
+            CircuitId.deserialize(circuitIdOpt.getData());
+            return true;
+        } catch (Exception e) {
+            // invalid circuit id
+            return false;
+        }
+    }
+
+
+    /**
+     * Send the DHCP ack to the requester host.
+     * Modify Host or Route store according to the type of DHCP.
+     *
+     * @param ethernetPacketAck the packet
+     * @param dhcpPayload the DHCP data
+     */
+    private void handleDhcpAck(Ethernet ethernetPacketAck, DHCP dhcpPayload) {
+        Optional<Interface> outInterface = getClientInterface(ethernetPacketAck, dhcpPayload);
+        if (!outInterface.isPresent()) {
+            log.warn("Can't find output interface for dhcp: {}", dhcpPayload);
+            return;
+        }
+
+        Interface outIface = outInterface.get();
+        HostLocation hostLocation = new HostLocation(outIface.connectPoint(), System.currentTimeMillis());
+        MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
+        VlanId vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
+        if (vlanId == null) {
+            vlanId = outIface.vlan();
+        }
+        HostId hostId = HostId.hostId(macAddress, vlanId);
+        Ip4Address ip = Ip4Address.valueOf(dhcpPayload.getYourIPAddress());
+
+        if (directlyConnected(dhcpPayload)) {
+            // Add to host store if it connect to network directly
+            Set<IpAddress> ips = Sets.newHashSet(ip);
+            Host host = hostService.getHost(hostId);
+
+            Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
+            if (host != null) {
+                // Dual homing support:
+                // if host exists, use old locations and new location
+                hostLocations.addAll(host.locations());
+            }
+            HostDescription desc = new DefaultHostDescription(macAddress, vlanId,
+                                                              hostLocations, ips, false);
+            // Add IP address when dhcp server give the host new ip address
+            providerService.hostDetected(hostId, desc, false);
+        } else {
+            // Add to route store if it does not connect to network directly
+            // Get gateway host IP according to host mac address
+            // TODO: remove relay store here
+            DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
+
+            if (record == null) {
+                log.warn("Can't find DHCP record of host {}", hostId);
+                return;
+            }
+
+            MacAddress gwMac = record.nextHop().orElse(null);
+            if (gwMac == null) {
+                log.warn("Can't find gateway mac address from record {}", record);
+                return;
+            }
+
+            HostId gwHostId = HostId.hostId(gwMac, record.vlanId());
+            Host gwHost = hostService.getHost(gwHostId);
+
+            if (gwHost == null) {
+                log.warn("Can't find gateway host {}", gwHostId);
+                return;
+            }
+
+            Ip4Address nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp4)
+                    .map(IpAddress::getIp4Address)
+                    .findFirst()
+                    .orElse(null);
+
+            if (nextHopIp == null) {
+                log.warn("Can't find IP address of gateway {}", gwHost);
+                return;
+            }
+
+            Route route = new Route(Route.Source.DHCP, ip.toIpPrefix(), nextHopIp);
+            routeStore.replaceRoute(route);
+        }
+    }
+
+    /**
+     * Gets output interface of a dhcp packet.
+     * If option 82 exists in the dhcp packet and the option was sent by
+     * ONOS (circuit format is correct), use the connect
+     * point and vlan id from circuit id; otherwise, find host by destination
+     * address and use vlan id from sender (dhcp server).
+     *
+     * @param ethPacket the ethernet packet
+     * @param dhcpPayload the dhcp packet
+     * @return an interface represent the output port and vlan; empty value
+     *         if the host or circuit id not found
+     */
+    private Optional<Interface> getClientInterface(Ethernet ethPacket, DHCP dhcpPayload) {
+        VlanId originalPacketVlanId = VlanId.vlanId(ethPacket.getVlanID());
+        DhcpRelayAgentOption option = (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
+
+        DhcpOption circuitIdSubOption = option.getSubOption(CIRCUIT_ID.getValue());
+        try {
+            CircuitId circuitId = CircuitId.deserialize(circuitIdSubOption.getData());
+            ConnectPoint connectPoint = ConnectPoint.deviceConnectPoint(circuitId.connectPoint());
+            VlanId vlanId = circuitId.vlanId();
+            return interfaceService.getInterfacesByPort(connectPoint)
+                    .stream()
+                    .filter(iface -> interfaceContainsVlan(iface, vlanId))
+                    .findFirst();
+        } catch (IllegalArgumentException ex) {
+            // invalid circuit format, didn't sent by ONOS
+            log.debug("Invalid circuit {}, use information from dhcp payload",
+                      circuitIdSubOption.getData());
+        }
+
+        // Use Vlan Id from DHCP server if DHCP relay circuit id was not
+        // sent by ONOS or circuit Id can't be parsed
+        // TODO: remove relay store from this method
+        MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
+        VlanId filteredVlanId = getVlanIdFromDhcpRecord(dstMac, originalPacketVlanId);
+        // Get the vlan from the dhcp record
+        if (filteredVlanId == null) {
+            log.debug("not find the matching DHCP record for mac: {} and vlan: {}", dstMac, originalPacketVlanId);
+            return Optional.empty();
+        }
+
+        Optional<DhcpRecord> dhcpRecord = dhcpRelayStore.getDhcpRecord(HostId.hostId(dstMac, filteredVlanId));
+        ConnectPoint clientConnectPoint = dhcpRecord
+                .map(DhcpRecord::locations)
+                .orElse(Collections.emptySet())
+                .stream()
+                .reduce((hl1, hl2) -> {
+                    // find latest host connect point
+                    if (hl1 == null || hl2 == null) {
+                        return hl1 == null ? hl2 : hl1;
+                    }
+                    return hl1.time() > hl2.time() ? hl1 : hl2;
+                })
+                .orElse(null);
+
+        if (clientConnectPoint != null) {
+            return interfaceService.getInterfacesByPort(clientConnectPoint)
+                    .stream()
+                    .filter(iface -> interfaceContainsVlan(iface, filteredVlanId))
+                    .findFirst();
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * Get the required vlanId in case the DCHP record has more than one vlanId for a given MAC.
+     *
+     * @param mac MAC address of the DHCP client
+     * @param vlan Expected vlan of the DHCP client
+     */
+    private VlanId getVlanIdFromDhcpRecord(MacAddress mac, VlanId vlan) {
+        // Get all the DHCP records matching with the mac address
+        // If only one entry is present then pick the vlan of that entry
+        // If more then one entry is present then look for an entry with matching vlan
+        // else return null
+        Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
+        List<DhcpRecord> filteredRecords = new ArrayList<>();
+        for (DhcpRecord e: records) {
+            if (e.macAddress().equals(mac)) {
+                filteredRecords.add(e);
+            }
+        }
+        log.debug("getVlanIdFromDhcpRecord mac: {} vlan: {}", mac, vlan);
+        log.debug("filteredRecords are: {}", filteredRecords);
+        if (filteredRecords.size() == 1) {
+            log.debug("Only one DHCP record entry. Returning back the vlan of that DHCP record: {}", filteredRecords);
+            return filteredRecords.get(0).vlanId();
+        }
+        // Check in the DHCP filtered record for matching vlan
+        for (DhcpRecord e: filteredRecords) {
+            if (e.vlanId().equals(vlan)) {
+                log.debug("Found a matching vlan entry in the DHCP record:{}", e);
+                return vlan;
+            }
+        }
+        // Found nothing return null
+        log.debug("Returning null as no matching or more than one matching entry found");
+        return null;
+
+    }
+
+
+
+    /**
+     * Send the response DHCP to the requester host.
+     *
+     * @param thePacket the packet
+     * @param dhcpPayload the DHCP data
+     */
+    private void sendResponseToClient(InternalPacket thePacket, DHCP dhcpPayload) {
+        checkNotNull(thePacket, "Nothing to send");
+        checkNotNull(thePacket.getPacket(), "Packet to send must not be empty");
+        checkNotNull(thePacket.getDestLocation(), "Packet destination not be empty");
+
+        Ethernet ethPacket = thePacket.getPacket();
+        if (directlyConnected(dhcpPayload)) {
+            ethPacket = removeRelayAgentOption(ethPacket);
+        }
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(thePacket.getDestLocation().port())
+                .build();
+        OutboundPacket o = new DefaultOutboundPacket(
+                thePacket.getDestLocation().deviceId(),
+                treatment,
+                ByteBuffer.wrap(ethPacket.serialize()));
+        if (log.isTraceEnabled()) {
+            log.trace("Relaying packet to DHCP client {} via {}",
+                      ethPacket,
+                      thePacket.getDestLocation());
+        }
+        packetService.emit(o);
+    }
+
+    @Override
+    public void triggerProbe(Host host) {
+        // Do nothing here
+    }
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            if (!configured()) {
+                return;
+            }
+            switch (event.type()) {
+                case HOST_ADDED:
+                case HOST_UPDATED:
+                case HOST_MOVED:
+                    log.trace("Scheduled host event {}", event);
+                    hostEventExecutor.execute(() -> hostUpdated(event.subject()));
+                    break;
+                case HOST_REMOVED:
+                    log.trace("Scheduled host event {}", event);
+                    hostEventExecutor.execute(() -> hostRemoved(event.subject()));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * 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) {
+        hostUpdated(host, defaultServerInfoList);
+        hostUpdated(host, indirectServerInfoList);
+    }
+
+    private void hostUpdated(Host host, List<DhcpServerInfo> srverInfoList) {
+        srverInfoList.stream().forEach(serverInfo -> {
+            Ip4Address targetIp = serverInfo.getDhcpGatewayIp4().orElse(null);
+            Ip4Address serverIp = serverInfo.getDhcpServerIp4().orElse(null);
+            if (targetIp == null) {
+                targetIp = serverIp;
+            }
+            if (targetIp != null) {
+                if (host.ipAddresses().contains(targetIp)) {
+                    serverInfo.setDhcpConnectMac(host.mac());
+                    serverInfo.setDhcpConnectVlan(host.vlan());
+                    requestDhcpPacket(serverIp);
+                }
+            }
+        });
+    }
+
+
+    /**
+     * 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) {
+        hostRemoved(host, defaultServerInfoList);
+        hostRemoved(host, indirectServerInfoList);
+    }
+
+    private void hostRemoved(Host host, List<DhcpServerInfo> serverInfoList) {
+        serverInfoList.stream().forEach(serverInfo -> {
+            Ip4Address targetIp = serverInfo.getDhcpGatewayIp4().orElse(null);
+            Ip4Address serverIp = serverInfo.getDhcpServerIp4().orElse(null);
+            if (targetIp == null) {
+                targetIp = serverIp;
+            }
+
+            if (targetIp != null) {
+                if (host.ipAddresses().contains(targetIp)) {
+                    serverInfo.setDhcpConnectVlan(null);
+                    serverInfo.setDhcpConnectMac(null);
+                    cancelDhcpPacket(serverIp);
+                }
+            }
+        });
+    }
+
+    private void requestDhcpPacket(Ip4Address serverIp) {
+        requestServerDhcpPacket(serverIp);
+        requestClientDhcpPacket(serverIp);
+    }
+
+    private void cancelDhcpPacket(Ip4Address serverIp) {
+        cancelServerDhcpPacket(serverIp);
+        cancelClientDhcpPacket(serverIp);
+    }
+
+    private void cancelServerDhcpPacket(Ip4Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPSrc(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(serverSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
+    private void requestServerDhcpPacket(Ip4Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPSrc(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(serverSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    private void cancelClientDhcpPacket(Ip4Address serverIp) {
+        // Packet comes from relay
+        TrafficSelector indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPDst(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(indirectClientSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+
+        // Packet comes from client
+        packetService.cancelPackets(CLIENT_SERVER_SELECTOR,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
+    private void requestClientDhcpPacket(Ip4Address serverIp) {
+        // Packet comes from relay
+        TrafficSelector indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPDst(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(indirectClientSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+
+        // Packet comes from client
+        packetService.requestPackets(CLIENT_SERVER_SELECTOR,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    /**
+     * Process the ignore rules.
+     *
+     * @param deviceId the device id
+     * @param vlanId the vlan to be ignored
+     * @param op the operation, ADD to install; REMOVE to uninstall rules
+     */
+    private void processIgnoreVlanRule(DeviceId deviceId, VlanId vlanId, Objective.Operation op) {
+        AtomicInteger installedCount = new AtomicInteger(DHCP_SELECTORS.size());
+        DHCP_SELECTORS.forEach(trafficSelector -> {
+            TrafficSelector selector = DefaultTrafficSelector.builder(trafficSelector)
+                    .matchVlanId(vlanId)
+                    .build();
+
+            ForwardingObjective.Builder builder = DefaultForwardingObjective.builder()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withSelector(selector)
+                    .withPriority(IGNORE_CONTROL_PRIORITY)
+                    .withTreatment(DefaultTrafficTreatment.emptyTreatment())
+                    .fromApp(appId);
+
+
+            ObjectiveContext objectiveContext = new ObjectiveContext() {
+                @Override
+                public void onSuccess(Objective objective) {
+                    log.info("Ignore rule {} (Vlan id {}, device {}, selector {})",
+                             op, vlanId, deviceId, selector);
+                    int countDown = installedCount.decrementAndGet();
+                    if (countDown != 0) {
+                        return;
+                    }
+                    switch (op) {
+                        case ADD:
+                            ignoredVlans.put(deviceId, vlanId);
+                            break;
+                        case REMOVE:
+                            ignoredVlans.remove(deviceId, vlanId);
+                            break;
+                        default:
+                            log.warn("Unsupported objective operation {}", op);
+                            break;
+                    }
+                }
+
+                @Override
+                public void onError(Objective objective, ObjectiveError error) {
+                    log.warn("Can't {} ignore rule (vlan id {}, selector {}, device {}) due to {}",
+                             op, vlanId, selector, deviceId, error);
+                }
+            };
+
+            ForwardingObjective fwd;
+            switch (op) {
+                case ADD:
+                    fwd = builder.add(objectiveContext);
+                    break;
+                case REMOVE:
+                    fwd = builder.remove(objectiveContext);
+                    break;
+                default:
+                    log.warn("Unsupported objective operation {}", op);
+                    return;
+            }
+
+            Device device = deviceService.getDevice(deviceId);
+            if (device == null || !device.is(Pipeliner.class)) {
+                log.warn("Device {} is not available now, wait until device is available", deviceId);
+                return;
+            }
+            flowObjectiveService.apply(deviceId, fwd);
+        });
+    }
+
+    @Override
+    public void setDhcpFpmEnabled(Boolean enabled) {
+        // v4 does not use fpm. Do nothing.
+    }
+    private List<DhcpServerInfo> findValidServerInfo(boolean directConnFlag) {
+        List<DhcpServerInfo> validServerInfo;
+
+        if (directConnFlag || indirectServerInfoList.isEmpty()) {
+            validServerInfo = new ArrayList<DhcpServerInfo>(defaultServerInfoList);
+        } else {
+            validServerInfo = new ArrayList<DhcpServerInfo>(indirectServerInfoList);
+        }
+        return validServerInfo;
+    }
+
+
+    private boolean checkDhcpServerConnPt(boolean directConnFlag,
+                                          DhcpServerInfo serverInfo) {
+        if (serverInfo.getDhcpServerConnectPoint() == null) {
+            log.warn("DHCP4 server connect point for {} connPt {}",
+                    directConnFlag ? "direct" : "indirect", serverInfo.getDhcpServerConnectPoint());
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks if serverInfo's host info (mac and vlan) is filled in; if not, fills in.
+     *
+     * @param serverInfo server information
+     * @return newServerInfo if host info can be either found or filled in.
+     */
+    private DhcpServerInfo getHostInfoForServerInfo(DhcpServerInfo serverInfo, List<DhcpServerInfo> sererInfoList) {
+        DhcpServerInfo newServerInfo = null;
+        MacAddress  dhcpServerConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+
+        if (dhcpServerConnectMac != null && dhcpConnectVlan != null) {
+            newServerInfo = serverInfo;
+            log.debug("DHCP server {} host info found. ConnectPt{}  Mac {} vlan {}", serverInfo.getDhcpServerIp4(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+        } else {
+            log.warn("DHCP server {} not resolve yet connectPt {} mac {} vlan {}", serverInfo.getDhcpServerIp4(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+
+            Ip4Address ipToProbe;
+            if (serverInfo.getDhcpGatewayIp4().isPresent()) {
+                ipToProbe = serverInfo.getDhcpGatewayIp4().get();
+            } else {
+                ipToProbe = serverInfo.getDhcpServerIp4().orElse(null);
+            }
+            String hostToProbe = serverInfo.getDhcpGatewayIp6()
+                    .map(ip -> "gateway").orElse("server");
+
+            log.warn("Dynamically probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                int serverInfoIndex = sererInfoList.indexOf(serverInfo);
+                Host host = hosts.iterator().next();
+                serverInfo.setDhcpConnectVlan(host.vlan());
+                serverInfo.setDhcpConnectMac(host.mac());
+                // replace the serverInfo in the list
+                sererInfoList.set(serverInfoIndex, serverInfo);
+                newServerInfo = serverInfo;
+                log.warn("Dynamically host found host {}", host);
+            } else {
+                log.warn("No host found host ip {} dynamically", ipToProbe);
+            }
+        }
+        return newServerInfo;
+    }
+
+    /**
+     * Gets Interface facing to the server for default host.
+     *
+     * @param serverInfo server information
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getServerInterface(DhcpServerInfo serverInfo) {
+        Interface serverInterface = null;
+
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+
+        if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
+            serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                    .stream()
+                    .filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            log.warn("DHCP server {} not resolve yet connectPoint {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpConnectVlan);
+        }
+
+        return serverInterface;
+    }
+
+    //forward the packet to ConnectPoint where the DHCP server is attached.
+    private void forwardPacket(InternalPacket packet) {
+        //send Packetout to dhcp server connectpoint.
+        if (packet.getDestLocation() != null) {
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(packet.getDestLocation().port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    packet.getDestLocation().deviceId(), t, ByteBuffer.wrap(packet.getPacket().serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying packet to destination {}", packet.getDestLocation());
+            }
+            log.debug("packetService.emit(o) to port {}", packet.getDestLocation());
+            packetService.emit(o);
+        }
+    }
+
+
+    private DhcpServerInfo findServerInfoFromServer(boolean directConnFlag, ConnectPoint inPort) {
+        List<DhcpServerInfo> validServerInfoList = findValidServerInfo(directConnFlag);
+        DhcpServerInfo  foundServerInfo = null;
+        for (DhcpServerInfo serverInfo : validServerInfoList) {
+            if (inPort.equals(serverInfo.getDhcpServerConnectPoint().get())) {
+                foundServerInfo = serverInfo;
+                log.debug("ServerInfo found for Rcv port {} Server Connect Point {} for {}",
+                        inPort, serverInfo.getDhcpServerConnectPoint(), directConnFlag ? "direct" : "indirect");
+                break;
+            }
+        }
+        return foundServerInfo;
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerUtil.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerUtil.java
new file mode 100644
index 0000000..a88bda8
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerUtil.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.VlanId;
+import org.onlab.util.HexString;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Set;
+
+public final class Dhcp4HandlerUtil {
+    private static final Logger log = LoggerFactory.getLogger(Dhcp4HandlerUtil.class);
+
+    private Dhcp4HandlerUtil() {
+    }
+
+    /**
+     * Returns the first v4 interface ip out of a set of interfaces or null.
+     *
+     * @param intfs set of interfaces
+     * @return Ip4Address / null if not present
+     */
+    public static Ip4Address getRelayAgentIPv4Address(Set<Interface> intfs) {
+        for (Interface intf : intfs) {
+            for (InterfaceIpAddress ip : intf.ipAddressesList()) {
+                Ip4Address relayAgentIp = ip.ipAddress().getIp4Address();
+                if (relayAgentIp != null) {
+                    return relayAgentIp;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Determind if an Interface contains a vlan id.
+     *
+     * @param iface the Interface
+     * @param vlanId the vlan id
+     * @return true if the Interface contains the vlan id
+     */
+    public static boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
+        if (vlanId.equals(VlanId.NONE)) {
+            // untagged packet, check if vlan untagged or vlan native is not NONE
+            return !iface.vlanUntagged().equals(VlanId.NONE) ||
+                    !iface.vlanNative().equals(VlanId.NONE);
+        }
+        // tagged packet, check if the interface contains the vlan
+        return iface.vlanTagged().contains(vlanId);
+   }
+
+    /**
+     * Check if a given server info has v6 ipaddress.
+     *
+     * @param serverInfo server info to check
+     * @return true if server info has v6 ip address; false otherwise
+     */
+    public static boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
+        if (!serverInfo.getDhcpServerIp4().isPresent()) {
+            log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
+                    HexString.toHexString(serverInfo.getDhcpServerIp4().get().toOctets()));
+            return true;
+        }
+        return false;
+    }
+}
+
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
new file mode 100644
index 0000000..a5a9eb5
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -0,0 +1,1965 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+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.TpPort;
+import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.Dhcp6ClientDataOption;
+import org.onlab.packet.dhcp.Dhcp6LeaseQueryOption;
+import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onlab.packet.dhcp.Dhcp6InterfaceIdOption;
+import org.onlab.packet.dhcp.Dhcp6Option;
+import org.onlab.packet.dhcp.Dhcp6IaNaOption;
+import org.onlab.packet.dhcp.Dhcp6IaTaOption;
+import org.onlab.packet.dhcp.Dhcp6IaPdOption;
+import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
+import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
+import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
+import org.onlab.packet.dhcp.Dhcp6Duid;
+import org.onlab.packet.DHCP6.MsgType;
+import org.onlab.util.HexString;
+import org.onlab.util.Tools;
+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.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpFpmPrefixStore;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
+import org.onosproject.dhcprelay.store.DhcpRelayCountersStore;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+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.net.packet.PacketPriority;
+import org.onosproject.net.provider.ProviderId;
+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.osgi.service.component.ComponentContext;
+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.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
+import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
+import java.util.concurrent.Semaphore;
+
+@Component
+@Service
+@Property(name = "version", value = "6")
+public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
+    public static final String DHCP_V6_RELAY_APP = "org.onosproject.Dhcp6HandlerImpl";
+    public static final ProviderId PROVIDER_ID = new ProviderId("dhcp6", DHCP_V6_RELAY_APP);
+    private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
+    private String gCount = "global";
+    private static final String LQ_ROUTE_PROPERTY_NAME = "learnRouteFromLeasequery";
+    private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV6)
+            .matchIPProtocol(IPv6.PROTOCOL_UDP)
+            .matchIPv6Src(IpPrefix.IPV6_LINK_LOCAL_PREFIX)
+            .matchIPv6Dst(Ip6Address.ALL_DHCP_RELAY_AGENTS_AND_SERVERS.toIpPrefix())
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_V6_CLIENT_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
+            .build();
+    private static final TrafficSelector SERVER_RELAY_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV6)
+            .matchIPProtocol(IPv6.PROTOCOL_UDP)
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
+            .build();
+    // lease query reply is from server to client (no relay in between) - so we need to
+    // catch that scenario also ..
+    private static final TrafficSelector LEASE_QUERY_RESPONSE_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_IPV6)
+            .matchIPProtocol(IPv6.PROTOCOL_UDP)
+            .matchUdpSrc(TpPort.tpPort(UDP.DHCP_V6_SERVER_PORT))
+            .matchUdpDst(TpPort.tpPort(UDP.DHCP_V6_CLIENT_PORT))
+            .build();
+    static final Set<TrafficSelector> DHCP_SELECTORS = ImmutableSet.of(
+            CLIENT_SERVER_SELECTOR,
+            SERVER_RELAY_SELECTOR,
+            LEASE_QUERY_RESPONSE_SELECTOR
+    );
+    private static Logger log = LoggerFactory.getLogger(Dhcp6HandlerImpl.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayStore dhcpRelayStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayCountersStore dhcpRelayCountersStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteStore routeStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry providerRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpFpmPrefixStore dhcpFpmPrefixStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService cfgService;
+
+    @Property(name = Dhcp6HandlerImpl.LQ_ROUTE_PROPERTY_NAME, boolValue = false,
+            label = "Enable learning routing information from LQ")
+    private Boolean learnRouteFromLeasequery = Boolean.TRUE;
+
+    protected HostProviderService providerService;
+    protected ApplicationId appId;
+    protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
+    private InternalHostListener hostListener = new InternalHostListener();
+    private Boolean dhcpFpmEnabled = false;
+    private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
+    private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
+
+    private Executor hostEventExecutor = newSingleThreadExecutor(
+        groupedThreads("dhcp6-event-host", "%d", log));
+
+    private class IpAddressInfo {
+        Ip6Address ip6Address;
+        long    prefTime;
+    }
+    private class PdPrefixInfo {
+        IpPrefix pdPrefix;
+        long    prefTime;
+    }
+    protected int dhcp6PollInterval = 24 * 3600; // 24 hr period
+
+    // max 1 thread
+    static Semaphore recordSemaphore = new Semaphore(1);
+
+    // 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(),
+                            DHCP6.MsgType.LEASEQUERY.value());
+    // SERVER message types
+    public static final Set<Byte> MSG_TYPE_FROM_SERVER =
+            ImmutableSet.of(DHCP6.MsgType.RELAY_REPL.value(),
+                            DHCP6.MsgType.LEASEQUERY_REPLY.value());
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        cfgService.registerProperties(getClass());
+        modified(context);
+        appId = coreService.registerApplication(DHCP_V6_RELAY_APP);
+        providerService = providerRegistry.register(this);
+        hostService.addListener(hostListener);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        cfgService.unregisterProperties(getClass(), false);
+        providerRegistry.unregister(this);
+        hostService.removeListener(hostListener);
+        defaultServerInfoList.forEach(this::stopMonitoringIps);
+        defaultServerInfoList.forEach(info -> info.getDhcpServerIp6().ifPresent(this::cancelDhcpPacket));
+        defaultServerInfoList.clear();
+        indirectServerInfoList.forEach(this::stopMonitoringIps);
+        indirectServerInfoList.forEach(info -> info.getDhcpServerIp6().ifPresent(this::cancelDhcpPacket));
+        indirectServerInfoList.clear();
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        Boolean flag;
+        flag = Tools.isPropertyEnabled(properties, Dhcp6HandlerImpl.LQ_ROUTE_PROPERTY_NAME);
+        if (flag != null) {
+            learnRouteFromLeasequery = flag;
+            log.info("Learning routes from DHCP leasequery is {}",
+                    learnRouteFromLeasequery ? "enabled" : "disabled");
+        }
+    }
+
+    private void stopMonitoringIps(DhcpServerInfo serverInfo) {
+        serverInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
+            hostService.stopMonitoringIp(gatewayIp);
+        });
+        serverInfo.getDhcpServerIp6().ifPresent(serverIp -> {
+            hostService.stopMonitoringIp(serverIp);
+        });
+    }
+
+    @Override
+    public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
+        return defaultServerInfoList;
+    }
+
+    @Override
+    public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
+        return indirectServerInfoList;
+    }
+
+    @Override
+    public void updateIgnoreVlanConfig(IgnoreDhcpConfig config) {
+        if (config == null) {
+            ignoredVlans.forEach(((deviceId, vlanId) -> {
+                processIgnoreVlanRule(deviceId, vlanId, REMOVE);
+            }));
+            return;
+        }
+        config.ignoredVlans().forEach((deviceId, vlanId) -> {
+            if (ignoredVlans.get(deviceId).contains(vlanId)) {
+                // don't need to process if it already ignored
+                return;
+            }
+            processIgnoreVlanRule(deviceId, vlanId, ADD);
+        });
+        ignoredVlans.forEach((deviceId, vlanId) -> {
+            if (!config.ignoredVlans().get(deviceId).contains(vlanId)) {
+                // not contains in new config, remove it
+                processIgnoreVlanRule(deviceId, vlanId, REMOVE);
+            }
+        });
+    }
+
+    @Override
+    public void removeIgnoreVlanState(IgnoreDhcpConfig config) {
+        if (config == null) {
+            ignoredVlans.clear();
+            return;
+        }
+        config.ignoredVlans().forEach((deviceId, vlanId) -> {
+            ignoredVlans.remove(deviceId, vlanId);
+        });
+    }
+
+    public DhcpRecord getDhcpRelayRecordFor(Ip6Address clientAddress) {
+
+        Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
+        DhcpRecord dr = null;
+        for (DhcpRecord e:records) {
+            if (e.ip6Address().isPresent()) {
+                if (e.ip6Address().get().equals(clientAddress)) {
+                    dr = e;
+                    break;
+                }
+            }
+        }
+        return dr;
+    }
+
+    public MacAddress findNextHopMacForIp6FromRelayStore(Ip6Address clientAddress,
+                                                         MacAddress clientMacAddress, VlanId vlanID) {
+
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+
+        if (dr != null) {
+           Optional<MacAddress> nextHopTempMac = dr.nextHopTemp();
+            if (nextHopTempMac.isPresent()) {
+                log.info("findNextHopForIp6FromRelayStore " + clientAddress + " got mac " + nextHopTempMac.toString());
+                return nextHopTempMac.get();
+            }
+        } else {
+            log.warn("findNextHopMacForIp6FromRelayStore could NOT find next hop for " + clientAddress);
+            return null;
+        }
+        return null;
+    }
+
+    public Ip6Address findNextHopIp6FromRelayStore(Ip6Address clientAddress) {
+
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+        if (dr != null) {
+            Optional<MacAddress> nextHopMac = dr.nextHop();
+            if (nextHopMac.isPresent()) {
+                // find the local ip6 from the host store
+                HostId gwHostId = HostId.hostId(nextHopMac.get(), dr.vlanId());
+                Host gwHost = hostService.getHost(gwHostId);
+                if (gwHost == null) {
+                    log.warn("Can't find next hop host ID {}", gwHostId);
+                    return null;
+                }
+                Ip6Address nextHopIp = gwHost.ipAddresses()
+                        .stream()
+                        .filter(IpAddress::isIp6)
+                        .filter(IpAddress::isLinkLocal)
+                        .map(IpAddress::getIp6Address)
+                        .findFirst()
+                        .orElse(null);
+
+                log.info("findNextHopIp6FromRelayStore " + clientAddress + " got mac " +
+                                 nextHopMac.toString() + " ip6 " + nextHopIp);
+                return nextHopIp;
+            }
+        } else {
+            log.warn("findNextHopIp6FromRelayStore could NOT find next hop for " + clientAddress);
+            return null;
+        }
+        return null;
+    }
+
+    private void setPotentialNextHopForIp6InRelayStore(Ip6Address clientAddress,
+                                                       VlanId vlanId, MacAddress nh) {
+        DhcpRecord dr = getDhcpRelayRecordFor(clientAddress);
+        if (dr != null) {
+            dr.nextHopTemp(nh);
+            log.debug("LQ6 potential NH mac " + nh.toString() + " UPDATED in RelayRecord client " + clientAddress);
+        } else {
+            log.warn("LQ6 potential NH mac" + nh.toString() +
+                             " NOT FOUND in RelayRecord for client - LQ rejected" + clientAddress);
+        }
+    }
+
+    public void handleLeaseQuery6ReplyMsg(PacketContext context, DHCP6 dhcp6Payload) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        log.info("Got LQV6-REPLY on port {}", inPort);
+        List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
+        log.info("Options list: {}", lopt);
+        // find out if this lease is known is
+        Dhcp6ClientDataOption clientDataOption = dhcp6Payload.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6ClientDataOption)
+                .map(pld -> (Dhcp6ClientDataOption) pld)
+                .findFirst()
+                .orElse(null);
+
+        if (clientDataOption == null) {
+            log.warn("clientDataOption option is not present, " +
+                             "lease is UNKNOWN - not adding any new route...");
+        } else {
+            Dhcp6IaAddressOption aiAddressOption = clientDataOption.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6IaAddressOption)
+                    .map(pld -> (Dhcp6IaAddressOption) pld)
+                    .findFirst()
+                    .orElse(null);
+
+            Dhcp6ClientIdOption clientIdOption = clientDataOption.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6ClientIdOption)
+                    .map(pld -> (Dhcp6ClientIdOption) pld)
+                    .findFirst()
+                    .orElse(null);
+
+            if (aiAddressOption == null) {
+                log.warn("clientDataOption from DHCP server does not " +
+                                 "contains Dhcp6IaAddressOption for the client - giving up...");
+            } else {
+                Ip6Address clientAddress = aiAddressOption.getIp6Address();
+                MacAddress clientMacAddress = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
+                Ethernet packet = context.inPacket().parsed();
+                VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+                MacAddress potentialNextHopMac =
+                        findNextHopMacForIp6FromRelayStore(clientAddress, clientMacAddress, vlanId);
+
+                if (potentialNextHopMac == null) {
+                    log.warn("Can't find next hop host mac for client {} mac:{}/{}",
+                             clientAddress, clientMacAddress, vlanId);
+                    return;
+                } else {
+                    log.info("Next hop mac for {}/{}/{} is {}", clientAddress,
+                             clientMacAddress, vlanId, potentialNextHopMac.toString());
+                }
+                // search the next hop in the hosts store
+                HostId gwHostId = HostId.hostId(potentialNextHopMac, vlanId);
+                Host gwHost = hostService.getHost(gwHostId);
+                if (gwHost == null) {
+                    log.warn("Can't find next hop host ID {}", gwHostId);
+                    return;
+                }
+                Ip6Address nextHopIp = gwHost.ipAddresses()
+                        .stream()
+                        .filter(IpAddress::isIp6)
+                        .filter(IpAddress::isLinkLocal)
+                        .map(IpAddress::getIp6Address)
+                        .findFirst()
+                        .orElse(null);
+                if (nextHopIp == null) {
+                    log.warn("Can't find IP6 address of next hop {}", gwHost);
+                    return;
+                }
+                log.info("client " + clientAddress + " is known !");
+                Route routeForIP6 = new Route(Route.Source.DHCP, clientAddress.toIpPrefix(), nextHopIp);
+                log.debug("updating route of Client for indirectly connected.");
+                log.debug("client ip: " + clientAddress + ", next hop ip6: " + nextHopIp);
+                routeStore.updateRoute(routeForIP6);
+            }
+        }
+    }
+
+    @Override
+    public void processDhcpPacket(PacketContext context, BasePacket payload) {
+        checkNotNull(payload, "DHCP6 payload can't be null");
+        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 dhcp6 payload {}", dhcp6Payload);
+            return;
+        }
+        byte msgTypeVal = dhcp6Payload.getMsgType();
+        MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
+        log.debug("msgType is {}", msgType);
+
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+
+        if (inPort == null) {
+            log.warn("incoming 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 (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
+            List<InternalPacket> ethernetClientPackets =
+                    learnRouteFromLeasequery ?
+                        processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload) :
+                        processDhcp6ForwardOnly(context, receivedPacket, receivingInterfaces, dhcp6Payload);
+            for (InternalPacket internalPacket : ethernetClientPackets) {
+                forwardPacket(internalPacket);
+            }
+        } else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value() && learnRouteFromLeasequery) {
+            IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
+            UDP clientUdp = (UDP) clientIpv6.getPayload();
+            DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+            Interface serverInterface = Dhcp6HandlerUtil.directlyConnected(clientDhcp6) ?
+                    getServerInterface() : getIndirectServerInterface();
+            InternalPacket ethernetPacketReply =
+                    Dhcp6HandlerUtil.processLQ6PacketFromServer(
+                            defaultServerInfoList, indirectServerInfoList,
+                            serverInterface, interfaceService,
+                            hostService,
+                            context, receivedPacket, receivingInterfaces);
+            if (ethernetPacketReply != null) {
+                forwardPacket(ethernetPacketReply);
+            }
+            handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
+        } else if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
+            List<InternalPacket> ethernetClientPacket =
+                    processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
+            for (InternalPacket internalPacket : ethernetClientPacket) {
+                forwardPacket(internalPacket);
+            }
+        } else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
+            log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}, {}", receivedPacket, dhcp6Payload);
+            InternalPacket ethernetPacketReply =
+                    processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
+            if (ethernetPacketReply != null) {
+                forwardPacket(ethernetPacketReply);
+            }
+        } else {
+            log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
+        }
+    }
+
+    /**
+     * Checks if this app has been configured.
+     *
+     * @return true if all information we need have been initialized
+     */
+    public boolean configured() {
+        return !defaultServerInfoList.isEmpty();
+    }
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    @Override
+    public void triggerProbe(Host host) {
+        // Do nothing here
+    }
+
+    //forward the packet to ConnectPoint where the DHCP server is attached.
+    private void forwardPacket(InternalPacket packet) {
+        //send Packetout to dhcp server connectpoint.
+        if (packet.getDestLocation() != null) {
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(packet.getDestLocation().port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    packet.getDestLocation().deviceId(), t, ByteBuffer.wrap(packet.getPacket().serialize()));
+            packetService.emit(o);
+            if (log.isTraceEnabled()) {
+                IPv6 ip6 = (IPv6) packet.getPacket().getPayload();
+                UDP udp = (UDP) ip6.getPayload();
+                DHCP6 dhcp6  = (DHCP6) udp.getPayload();
+                log.trace("Relaying packet to destination {} eth: {} dhcp: {}",
+                        packet.getDestLocation(), packet.getPacket(), dhcp6);
+            }
+
+        }
+    }
+
+    /**
+     * extract from dhcp6 packet client ipv6 address of given by dhcp server.
+     *
+     * @param dhcp6 the dhcp6 packet
+     * @return IpAddressInfo  IpAddressInfo given by dhcp server, or null if not exists
+     */
+    private IpAddressInfo extractIpAddress(DHCP6 dhcp6) {
+        IpAddressInfo ipInfo = new IpAddressInfo();
+
+        log.debug("extractIpAddress  enters dhcp6 {}.", dhcp6);
+        // Extract IPv6 address from IA NA ot IA TA option
+        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 {
+            log.info("No IPv6 address found from iaTaOption {}", iaTaOption);
+            iaAddressOption = Optional.empty();
+        }
+        if (iaAddressOption.isPresent()) {
+            ipInfo.ip6Address = iaAddressOption.get().getIp6Address();
+            ipInfo.prefTime = iaAddressOption.get().getPreferredLifetime();
+            log.debug("Found IPv6 address from iaAddressOption {}", iaAddressOption);
+        } else {
+            log.debug("Can't find IPv6 address from DHCPv6 {}", dhcp6);
+            return null;
+        }
+        return ipInfo;
+    }
+
+    /**
+     * 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 PdPrefixInfo extractPrefix(DHCP6 dhcp6) {
+        log.debug("extractPrefix  enters {}", dhcp6);
+
+        // extract prefix
+        PdPrefixInfo  pdPrefixInfo = new PdPrefixInfo();
+
+        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.debug("IA_PD option found {}", iaPdOption);
+
+            iaPrefixOption = iaPdOption.get().getOptions().stream()
+                    .filter(opt -> opt instanceof Dhcp6IaPrefixOption)
+                    .map(opt -> (Dhcp6IaPrefixOption) opt)
+                    .findFirst();
+        } else {
+            log.debug("IA_PD option NOT found");
+
+            iaPrefixOption = Optional.empty();
+        }
+        if (iaPrefixOption.isPresent()) {
+            log.debug("IAPrefix Option within IA_PD option found {}", iaPrefixOption);
+
+            prefixAddress = iaPrefixOption.get().getIp6Prefix();
+            int prefixLen = (int) iaPrefixOption.get().getPrefixLength();
+            log.debug("Prefix length is  {} bits", prefixLen);
+            pdPrefixInfo.pdPrefix = IpPrefix.valueOf(prefixAddress, prefixLen);
+            pdPrefixInfo.prefTime = iaPrefixOption.get().getPreferredLifetime();
+        } else {
+            log.debug("Can't find IPv6 prefix from DHCPv6 {}", dhcp6);
+            return null;
+        }
+        return pdPrefixInfo;
+    }
+
+    /**
+     * remove host or route and update dhcp relay record attributes.
+     *
+     * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param location  client side connect point
+     * @param dhcp6Packet the dhcp6 payload
+     * @param clientPacket client's ethernet packet
+     * @param clientIpv6 client's Ipv6 packet
+     * @param clientInterface client interfaces
+     */
+    private void removeHostOrRoute(boolean directConnFlag, ConnectPoint location,
+                                   DHCP6 dhcp6Packet,
+                                   Ethernet clientPacket, IPv6 clientIpv6,
+                                   Interface clientInterface) {
+        log.debug("removeHostOrRoute  enters {}", dhcp6Packet);
+        VlanId vlanId = clientInterface.vlan();
+        MacAddress srcMac = clientPacket.getSourceMAC();  // could be gw or host
+        MacAddress leafClientMac;
+        byte leafMsgType;
+        log.debug("client mac {} client vlan {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId);
+
+        Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, dhcp6Packet);
+        if (clientIdOption != null) {
+            if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) ||
+                    (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
+                leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
+            } else {
+                log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
+                return;
+            }
+        } else {
+            log.warn("CLIENTID option NOT found. Don't create DhcpRelay Record.");
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
+            return;
+        }
+
+        HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(leafHostId);
+        }  else {
+            record = record.clone();
+        }
+
+        Boolean isMsgRelease = Dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
+        IpAddressInfo ipInfo;
+        PdPrefixInfo pdInfo = null;
+        if (directConnFlag) {
+            // Add to host store if it is connected to network directly
+            ipInfo = extractIpAddress(dhcp6Packet);
+            if (ipInfo != null) {
+                if (isMsgRelease) {
+                    HostId hostId = HostId.hostId(srcMac, vlanId);
+                    log.debug("remove Host {} ip for directly connected.", hostId.toString());
+                    providerService.removeIpFromHost(hostId, ipInfo.ip6Address);
+                }
+            } else {
+                log.debug("ipAddress not found. Do not remove Host {} for directly connected.",
+                        HostId.hostId(srcMac, vlanId).toString());
+            }
+            leafMsgType = dhcp6Packet.getMsgType();
+        } else {
+            // Remove from route store if it is not connected to network directly
+            // pick out the first link-local ip address
+            IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
+            if (nextHopIp == null) {
+                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
+                return;
+            }
+
+            DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
+            ipInfo = extractIpAddress(leafDhcp);
+            if (ipInfo == null) {
+                log.debug("ip is null");
+            } else {
+                if (isMsgRelease) {
+                    Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
+                    log.debug("removing route of 128 address for indirectly connected.");
+                    log.debug("128 ip {}, nexthop {}",
+                            HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"),
+                            HexString.toHexString(nextHopIp.toOctets(), ":"));
+                    routeStore.removeRoute(routeForIP);
+                }
+            }
+
+            pdInfo = extractPrefix(leafDhcp);
+            if (pdInfo == null) {
+                log.debug("ipPrefix is null ");
+            } else {
+                if (isMsgRelease) {
+                    Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
+                    log.debug("removing route of PD for indirectly connected.");
+                    log.debug("pd ip {}, nexthop {}",
+                            HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"),
+                            HexString.toHexString(nextHopIp.toOctets(), ":"));
+
+                    routeStore.removeRoute(routeForPrefix);
+                    if (this.dhcpFpmEnabled) {
+                        dhcpFpmPrefixStore.removeFpmRecord(pdInfo.pdPrefix);
+                    }
+                }
+            }
+            leafMsgType = leafDhcp.getMsgType();
+       }
+
+        if (isMsgRelease) {
+            log.debug("DHCP6 RELEASE msg.");
+            if (record != null) {
+                if (ipInfo != null) {
+                    log.debug("DhcpRelay Record ip6Address is set to null.");
+                    record.ip6Address(null);
+                }
+                if (pdInfo != null) {
+                    log.debug("DhcpRelay Record pdPrefix is set to null.");
+                }
+
+                if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
+                    log.warn("IP6 address and IP6 PD both are null. Remove record.");
+                    // do not remove a record. Let timer task handler it.
+                    //dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId));
+                }
+            }
+        }
+
+        if (record != null) {
+            record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
+            record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+            record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
+            record.setDirectlyConnected(directConnFlag);
+            if (!directConnFlag) {
+                // Update gateway mac address if the host is not directly connected
+                record.nextHop(srcMac);
+            }
+            record.updateLastSeen();
+        }
+        dhcpRelayStore.updateDhcpRecord(leafHostId, record);
+        // TODO Use AtomicInteger for the counters
+        try {
+            recordSemaphore.acquire();
+            try {
+                dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
+            } finally {
+                // calling release() after a successful acquire()
+                recordSemaphore.release();
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * add host or route and update dhcp relay record.
+     *
+     * @param directConnFlag  flag to show that packet is from directly connected client
+     * @param location  client side connect point
+     * @param dhcp6Relay the dhcp6 payload
+     * @param embeddedDhcp6 the dhcp6 payload within relay
+     * @param srcMac client gw/host macAddress
+     * @param clientInterface client interface
+     */
+    private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay,
+                                DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface) {
+        log.debug("addHostOrRoute entered.");
+        VlanId vlanId = clientInterface.vlan();
+        Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
+        MacAddress leafClientMac;
+        Byte leafMsgType;
+
+        Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, embeddedDhcp6);
+        if (clientIdOption != null) {
+            log.debug("CLIENTID option found {}", clientIdOption);
+            if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) ||
+                    (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
+                leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
+            } else {
+                log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
+                return;
+            }
+        } else {
+            log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
+            return;
+        }
+        HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
+        DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
+        if (record == null) {
+            record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
+        } else {
+            record = record.clone();
+        }
+
+        IpAddressInfo ipInfo;
+        PdPrefixInfo pdInfo = null;
+        if (directConnFlag) {
+            // Add to host store if it connect to network directly
+            ipInfo = extractIpAddress(embeddedDhcp6);
+            if (ipInfo != null) {
+                if (isMsgReply) {
+                    Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
+                    HostId hostId = HostId.hostId(srcMac, vlanId);
+                    Host host = hostService.getHost(hostId);
+                    HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(),
+                            System.currentTimeMillis());
+                    Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
+                    if (host != null) {
+                        // Dual homing support:
+                        // if host exists, use old locations and new location
+                        hostLocations.addAll(host.locations());
+                    }
+                    HostDescription desc = new DefaultHostDescription(srcMac, vlanId, hostLocations, ips,
+                            false);
+                    log.debug("adding Host for directly connected.");
+                    log.debug("client mac {} client vlan {} hostlocation {}",
+                            HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
+                    // Replace the ip when dhcp server give the host new ip address
+                    providerService.hostDetected(hostId, desc, false);
+                }
+            } else {
+                log.warn("ipAddress not found. Do not add Host {} for directly connected.",
+                        HostId.hostId(srcMac, vlanId).toString());
+            }
+            leafMsgType = embeddedDhcp6.getMsgType();
+        } else {
+            // Add to route store if it does not connect to network directly
+            // pick out the first link-local ip address
+            IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
+            if (nextHopIp == null) {
+                log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
+                return;
+            }
+
+            DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
+            ipInfo = extractIpAddress(leafDhcp);
+            if (ipInfo == null) {
+                log.debug("ip is null");
+            } else {
+                if (isMsgReply) {
+                    Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
+                    log.debug("adding Route of 128 address for indirectly connected.");
+                    routeStore.replaceRoute(routeForIP);
+                }
+            }
+
+            pdInfo = extractPrefix(leafDhcp);
+            if (pdInfo == null) {
+                log.debug("ipPrefix is null ");
+            } else {
+                if (isMsgReply) {
+                    Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
+                    log.debug("adding Route of PD for indirectly connected.");
+                    routeStore.replaceRoute(routeForPrefix);
+                    if (this.dhcpFpmEnabled) {
+                        FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
+                        dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
+                    }
+                }
+            }
+            leafMsgType = leafDhcp.getMsgType();
+        }
+        if (leafMsgType == DHCP6.MsgType.RELEASE.value() ||
+                (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
+            log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
+            //return;
+        }
+
+        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
+
+        if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
+            if (ipInfo != null) {
+                log.debug("IP6 address is being stored into dhcp-relay store.");
+                log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
+                record.ip6Address(ipInfo.ip6Address);
+                record.updateAddrPrefTime(ipInfo.prefTime);
+                record.updateLastIp6Update();
+             } else {
+                log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
+            }
+            if (pdInfo != null) {
+                log.debug("IP6 PD address {}",
+                        HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
+                record.pdPrefix(pdInfo.pdPrefix);
+                record.updatePdPrefTime(pdInfo.prefTime);
+                record.updateLastPdUpdate();
+            } else {
+                log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
+            }
+        }
+
+        record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
+        record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
+        record.setDirectlyConnected(directConnFlag);
+        record.updateLastSeen();
+        dhcpRelayStore.updateDhcpRecord(leafHostId, record);
+        // TODO Use AtomicInteger for the counters
+        try {
+            recordSemaphore.acquire();
+            try {
+                dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
+            } finally {
+                // calling release() after a successful acquire()
+                recordSemaphore.release();
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private List<InternalPacket> processDhcp6ForwardOnly(PacketContext context,
+                                                         Ethernet clientPacket,
+                                                         Set<Interface> clientInterfaces,
+                                                         DHCP6 dhcpPacket) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        log.trace("Got DHCPv6 on port {}", inPort);
+        boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(dhcpPacket);
+
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+
+        for (DhcpServerInfo dhcpServer : serverInfoList) {
+            Interface serverInterface = getServerInterface(dhcpServer);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+
+            Ethernet newPacket = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context,
+                    clientPacket, clientInterfaces, dhcpServer, serverInterface);
+            log.trace("Built packet for server {} : {}", dhcpServer, newPacket);
+            internalPackets.add(InternalPacket.internalPacket(newPacket,
+                    dhcpServer.getDhcpServerConnectPoint().get()));
+        }
+
+        return internalPackets;
+    }
+
+    private List<InternalPacket> processLQ6PacketFromClient(PacketContext context,
+                                                              Ethernet clientPacket,
+                                                              Set<Interface> clientInterfaces,
+                                                              DHCP6 dhcp6Payload) {
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        log.info("Got LQ-REQUEST V6 on port {}", inPort);
+        List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
+        log.info("Options list: {}", lopt);
+        Dhcp6LeaseQueryOption lqoption = dhcp6Payload.getOptions()
+                .stream()
+                .filter(opt -> opt instanceof Dhcp6LeaseQueryOption)
+                .map(pld -> (Dhcp6LeaseQueryOption) pld)
+                .findFirst()
+                .orElse(null);
+
+        if (lqoption == null) {
+            // Can't find dhcp payload
+            log.warn("Can't find dhcp6 lease query message - aborting");
+            return null;
+        } else {
+            log.info("dhcp6 lqv6 options found: {}", lqoption);
+        }
+        log.warn("LQv6 for " + lqoption.linkAddress.toString() + " comes from " + inPort.toString());
+        Ethernet packet = context.inPacket().parsed();
+        Ip6Address clientAddress = lqoption.linkAddress;
+        IPv6 ipv6Packet = (IPv6) packet.getPayload();
+        Ip6Address nextHopIp = findNextHopIp6FromRelayStore(clientAddress);
+
+        // 1. only if there is a route to remove - remove it
+        if (nextHopIp != null) {
+            Route routeForIP6 = new Route(Route.Source.DHCP, clientAddress.toIpPrefix(), nextHopIp);
+            log.debug("Removing route of Client " + clientAddress +
+                              " for indirectly connected - next hop ip6 " + nextHopIp);
+            routeStore.removeRoute(routeForIP6);
+        }
+
+        // 2. note the potential NH this packet came from in case it's a known lease
+        //    this NH will then be used to build the route
+        MacAddress potentialNH = packet.getSourceMAC();
+        VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+        setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
+        // 3. route this LQ6 to all relevant servers
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+
+        boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
+
+        for (DhcpServerInfo serverInfo : copyServerInfoList) {
+            if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
+                log.warn("Can't get server connect point, ignore");
+                continue;
+            }
+            DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
+            if (newServerInfo == null) {
+                log.warn("Can't get server interface with host info resolved, ignore");
+                continue;
+            }
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+            Ethernet etherRouted = (Ethernet) clientPacket.clone();
+            MacAddress macFacingServer = serverInterface.mac();
+            if (macFacingServer == null) {
+                log.warn("No MAC address for server Interface {}", serverInterface);
+                return null;
+            }
+            etherRouted.setSourceMACAddress(macFacingServer);
+            etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
+            InternalPacket internalPacket =
+                    InternalPacket.internalPacket(etherRouted,
+                              serverInfo.getDhcpServerConnectPoint().get());
+            internalPackets.add(internalPacket);
+            log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
+        }
+        log.debug("num of client packets to send is{}", internalPackets.size());
+
+        return internalPackets;
+    }
+
+    /**
+     * build the DHCP6 solicit/request packet with gatewayip.
+     *
+     * @param context packet context
+     * @param clientPacket client ethernet packet
+     * @param clientInterfaces set of client side interfaces
+     */
+    private List<InternalPacket> processDhcp6PacketFromClient(PacketContext context,
+                                                              Ethernet clientPacket,
+                                                              Set<Interface> clientInterfaces) {
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        Ip6Address relayAgentIp = Dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentIp == null || relayAgentMac == null) {
+            log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
+                      + "packet from client on port: {}. Aborting packet processing",
+                      clientInterfaces.iterator().next().connectPoint());
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
+            return Lists.newArrayList();
+        }
+
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+
+        boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
+
+        ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
+        VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
+        Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
+                .stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst()
+                .orElse(null);
+
+        List<InternalPacket> internalPackets = new ArrayList<>();
+        List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
+        List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
+
+        for (DhcpServerInfo serverInfo : copyServerInfoList) {
+            if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
+                log.warn("Can't get server connect point, ignore");
+                continue;
+            }
+            DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
+            if (newServerInfo == null) {
+                log.warn("Can't get server interface with host info resolved, ignore");
+                continue;
+            }
+
+            Interface serverInterface = getServerInterface(newServerInfo);
+            if (serverInterface == null) {
+                log.warn("Can't get server interface, ignore");
+                continue;
+            }
+
+            Ethernet etherReply = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket,
+                                                              clientInterfaces, newServerInfo, serverInterface);
+            removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket,
+                    clientIpv6, clientInterface);
+
+            InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
+                    serverInfo.getDhcpServerConnectPoint().get());
+            internalPackets.add(internalPacket);
+        }
+        log.debug("num of client packets to send is{}", internalPackets.size());
+
+        return internalPackets;
+    }
+
+    /**
+     * process the DHCP6 relay-reply packet from dhcp server.
+     *
+     * @param context packet context
+     * @param receivedPacket server ethernet packet
+     * @param recevingInterfaces set of server side interfaces
+     * @return internalPacket toward client
+     */
+    private InternalPacket processDhcp6PacketFromServer(PacketContext context,
+                                                        Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
+        // get dhcp6 header.
+        Ethernet etherReply = receivedPacket.duplicate();
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
+        Boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(dhcp6Relay);
+
+        DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream()
+                .filter(opt -> opt instanceof Dhcp6RelayOption)
+                .map(BasePacket::getPayload)
+                .map(pld -> (DHCP6) pld)
+                .findFirst()
+                .orElse(null);
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
+
+        if (foundServerInfo == null) {
+            log.warn("Cannot find server info for {} server, inPort {}",
+                      directConnFlag ? "direct" : "indirect", inPort);
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_INFO);
+            return null;
+        } else {
+            if (Dhcp6HandlerUtil.isServerIpEmpty(foundServerInfo)) {
+                log.warn("Cannot find server info's ipaddress");
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_IP6ADDR);
+                return null;
+            }
+        }
+
+        Dhcp6InterfaceIdOption interfaceIdOption = dhcp6Relay.getOptions().stream()
+                .filter(opt -> opt instanceof Dhcp6InterfaceIdOption)
+                .map(opt -> (Dhcp6InterfaceIdOption) opt)
+                .findFirst()
+                .orElse(null);
+        if (interfaceIdOption == null) {
+            log.warn("Interface Id option is not present, abort packet...");
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.OPTION_MISSING_FAIL);
+            return null;
+        }
+
+        MacAddress peerMac = interfaceIdOption.getMacAddress();
+        String clientConnectionPointStr = new String(interfaceIdOption.getInPort());
+        ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
+        VlanId vlanIdInUse = VlanId.vlanId(interfaceIdOption.getVlanId());
+        Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
+                .stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
+                .findFirst().orElse(null);
+        if (clientInterface == null) {
+            log.warn("Cannot get client interface for from packet, abort... vlan {}", vlanIdInUse.toString());
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_MATCHING_INTF);
+            return null;
+        }
+        etherReply.setVlanID(vlanIdInUse.toShort());
+
+        MacAddress relayAgentMac = clientInterface.mac();
+        if (relayAgentMac == null) {
+            log.warn("Can not get client interface mac, abort packet..");
+            dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
+            return null;
+        }
+        etherReply.setSourceMACAddress(relayAgentMac);
+
+        // find destMac
+        MacAddress clientMac;
+        Ip6Address peerAddress = Ip6Address.valueOf(dhcp6Relay.getPeerAddress());
+        Set<Host> clients = hostService.getHostsByIp(peerAddress);
+        if (clients.isEmpty()) {
+            log.trace("There's no host found for this address {}",
+                    HexString.toHexString(dhcp6Relay.getPeerAddress(), ":"));
+            log.trace("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...");
+                dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
+                return null;
+            }
+            log.trace("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);
+        }
+
+
+        boolean hostOrRouteAllowed = learnRouteFromLeasequery ||
+                    Dhcp6HandlerUtil.getDhcp6LeafMessageType(dhcp6Relay) != MsgType.LEASEQUERY_REPLY;
+        log.debug("Can add host or route: {}", hostOrRouteAllowed);
+
+        if (hostOrRouteAllowed) {
+            // add host or route
+            addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6,
+                    clientMac, clientInterface);
+        }
+
+        udpPacket.setPayload(embeddedDhcp6);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv6Packet);
+        return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
+    }
+
+    @Override
+    public void setDhcpFpmEnabled(Boolean enabled) {
+       dhcpFpmEnabled = enabled;
+    }
+
+    @Override
+    public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        log.debug("setDefaultDhcpServerConfigs is called.");
+        setDhcpServerConfigs(configs, defaultServerInfoList);
+    }
+
+    @Override
+    public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+        log.debug("setIndirectDhcpServerConfigs is called.");
+        setDhcpServerConfigs(configs, indirectServerInfoList);
+    }
+
+    public void setDhcpServerConfigs(Collection<DhcpServerConfig> configs, List<DhcpServerInfo> serverInfoList) {
+        log.debug("config size {}.", configs.size());
+
+        if (configs.size() == 0) {
+            // no config to update
+            return;
+        }
+        // TODO: currently we pick up first DHCP server config.
+        // Will use other server configs in the future for HA.
+        Boolean isConfigValid = false;
+        for (DhcpServerConfig serverConfig : configs) {
+            if (serverConfig.getDhcpServerIp6().isPresent()) {
+                isConfigValid = true;
+                break;
+            }
+        }
+        if (!isConfigValid) {
+            log.warn("No IP V6 server address found.");
+            return;  // No IP V6 address found
+        }
+        for (DhcpServerInfo oldServerInfo : serverInfoList) {
+            // stop monitoring gateway or server
+            oldServerInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
+                hostService.stopMonitoringIp(gatewayIp);
+            });
+            oldServerInfo.getDhcpServerIp6().ifPresent(serverIp -> {
+                hostService.stopMonitoringIp(serverIp);
+                cancelDhcpPacket(serverIp);
+            });
+        }
+        serverInfoList.clear();
+        for (DhcpServerConfig serverConfig : configs) {
+            // Create new server info according to the config
+            DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
+                    DhcpServerInfo.Version.DHCP_V6);
+            checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
+                    "Connect point not exists");
+            checkState(newServerInfo.getDhcpServerIp6().isPresent(),
+                    "IP of DHCP server not exists");
+
+            log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
+            log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp6().orElse(null));
+
+            Ip6Address serverIp = newServerInfo.getDhcpServerIp6().get();
+            Ip6Address ipToProbe;
+            if (newServerInfo.getDhcpGatewayIp6().isPresent()) {
+                ipToProbe = newServerInfo.getDhcpGatewayIp6().get();
+            } else {
+                ipToProbe = newServerInfo.getDhcpServerIp6().orElse(null);
+            }
+            String hostToProbe = newServerInfo.getDhcpGatewayIp6()
+                    .map(ip -> "gateway").orElse("server");
+
+            log.warn("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                Host host = hosts.iterator().next();
+                newServerInfo.setDhcpConnectVlan(host.vlan());
+                newServerInfo.setDhcpConnectMac(host.mac());
+                log.warn("Host found host {}", host);
+
+            } else {
+                log.warn("No host found host ip {}", ipToProbe);
+            }
+            // Add new server info
+            synchronized (this) {
+                serverInfoList.add(newServerInfo);
+            }
+            if (!hosts.isEmpty()) {
+                requestDhcpPacket(serverIp);
+            }
+        }
+    }
+
+    class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            switch (event.type()) {
+                case HOST_ADDED:
+                case HOST_UPDATED:
+                case HOST_MOVED:
+                    log.trace("Scheduled host event {}", event);
+                    hostEventExecutor.execute(() -> hostUpdated(event.subject()));
+                    break;
+                case HOST_REMOVED:
+                    log.trace("Scheduled host event {}", event);
+                    hostEventExecutor.execute(() -> hostRemoved(event.subject()));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * 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) {
+        hostUpdated(host, defaultServerInfoList);
+        hostUpdated(host, indirectServerInfoList);
+    }
+
+    private void hostUpdated(Host host, List<DhcpServerInfo> serverInfoList) {
+        serverInfoList.stream().forEach(serverInfo -> {
+            Ip6Address serverIp = serverInfo.getDhcpServerIp6().orElse(null);
+            Ip6Address targetIp = serverInfo.getDhcpGatewayIp6().orElse(null);
+
+            if (targetIp == null) {
+                targetIp = serverIp;
+            }
+            if (targetIp != null) {
+                if (host.ipAddresses().contains(targetIp)) {
+                    serverInfo.setDhcpConnectMac(host.mac());
+                    serverInfo.setDhcpConnectVlan(host.vlan());
+                    requestDhcpPacket(serverIp);
+                }
+            }
+        });
+    }
+    /**
+     * 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) {
+        hostRemoved(host, defaultServerInfoList);
+        hostRemoved(host, indirectServerInfoList);
+    }
+
+    private void hostRemoved(Host host, List<DhcpServerInfo> serverInfoList) {
+        serverInfoList.stream().forEach(serverInfo -> {
+            Ip6Address serverIp = serverInfo.getDhcpServerIp6().orElse(null);
+            Ip6Address targetIp = serverInfo.getDhcpGatewayIp6().orElse(null);
+
+            if (targetIp == null) {
+                targetIp = serverIp;
+            }
+            if (targetIp != null) {
+                if (host.ipAddresses().contains(targetIp)) {
+                    serverInfo.setDhcpConnectVlan(null);
+                    serverInfo.setDhcpConnectMac(null);
+                    cancelDhcpPacket(serverIp);
+                }
+            }
+        });
+    }
+
+   /**
+     * Gets Interface facing to the server for default host.
+     *
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getServerInterface() {
+        DhcpServerInfo serverInfo;
+        ConnectPoint dhcpServerConnectPoint;
+        VlanId dhcpConnectVlan;
+
+        if (!defaultServerInfoList.isEmpty()) {
+            serverInfo = defaultServerInfoList.get(0);
+            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        } else {
+            return null;
+        }
+        if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
+            log.info("Default DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
+            return null;
+        }
+        return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                .stream()
+                .filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Gets Interface facing to the server for indirect hosts.
+     * Use default server Interface if indirect server not configured.
+     *
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getIndirectServerInterface() {
+        DhcpServerInfo serverInfo;
+
+        ConnectPoint indirectDhcpServerConnectPoint;
+        VlanId indirectDhcpConnectVlan;
+
+        if (!indirectServerInfoList.isEmpty()) {
+            serverInfo = indirectServerInfoList.get(0);
+            indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+            indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        } else {
+            return getServerInterface();
+        }
+        if (indirectDhcpServerConnectPoint == null || indirectDhcpConnectVlan == null) {
+            log.info("Indirect DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
+            return null;
+        }
+        return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint)
+                .stream()
+                .filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, indirectDhcpConnectVlan))
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Checks if serverInfo's host info (mac and vlan) is filled in; if not, fills in.
+     *
+     * @param serverInfo server information
+     * @return newServerInfo if host info can be either found or filled in.
+     */
+    private DhcpServerInfo getHostInfoForServerInfo(DhcpServerInfo serverInfo, List<DhcpServerInfo> sererInfoList) {
+        DhcpServerInfo newServerInfo = null;
+        MacAddress  dhcpServerConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+
+        if (dhcpServerConnectMac != null && dhcpConnectVlan != null) {
+            newServerInfo = serverInfo;
+            log.debug("DHCP server {} host info found. ConnectPt{}  Mac {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+        } else {
+            log.warn("DHCP server {} not resolve yet connectPt {} mac {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpServerConnectMac, dhcpConnectVlan);
+
+            Ip6Address ipToProbe;
+            if (serverInfo.getDhcpGatewayIp6().isPresent()) {
+                ipToProbe = serverInfo.getDhcpGatewayIp6().get();
+            } else {
+                ipToProbe = serverInfo.getDhcpServerIp6().orElse(null);
+            }
+            String hostToProbe = serverInfo.getDhcpGatewayIp6()
+                    .map(ip -> "gateway").orElse("server");
+
+            log.info("Dynamically probing to resolve {} IP {}", hostToProbe, ipToProbe);
+            hostService.startMonitoringIp(ipToProbe);
+
+            Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
+            if (!hosts.isEmpty()) {
+                int serverInfoIndex = sererInfoList.indexOf(serverInfo);
+                Host host = hosts.iterator().next();
+                serverInfo.setDhcpConnectVlan(host.vlan());
+                serverInfo.setDhcpConnectMac(host.mac());
+                // replace the serverInfo in the list
+                sererInfoList.set(serverInfoIndex, serverInfo);
+                newServerInfo = serverInfo;
+                log.warn("Dynamically host found host {}", host);
+            } else {
+                log.warn("No host found host ip {} dynamically", ipToProbe);
+            }
+        }
+        return newServerInfo;
+    }
+
+    /**
+     * Gets Interface facing to the server for default host.
+     *
+     * @param serverInfo server information
+     * @return the Interface facing to the server; null if not found
+     */
+    private Interface getServerInterface(DhcpServerInfo serverInfo) {
+        Interface serverInterface = null;
+
+        ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+        VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+
+        if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
+        serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
+                    .stream()
+                    .filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            log.warn("DHCP server {} not resolve yet connectPoint {} vlan {}", serverInfo.getDhcpServerIp6(),
+                    dhcpServerConnectPoint, dhcpConnectVlan);
+        }
+
+        return serverInterface;
+    }
+
+    private void requestDhcpPacket(Ip6Address serverIp) {
+        requestServerDhcpPacket(serverIp);
+        requestClientDhcpPacket(serverIp);
+        requestServerLQPacket(serverIp);
+    }
+
+    private void cancelDhcpPacket(Ip6Address serverIp) {
+        cancelServerDhcpPacket(serverIp);
+        cancelClientDhcpPacket(serverIp);
+        cancelServerLQPacket(serverIp);
+    }
+
+    private void cancelServerDhcpPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(serverSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
+    private void cancelServerLQPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(LEASE_QUERY_RESPONSE_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(serverSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
+    private void requestServerDhcpPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(serverSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    private void requestServerLQPacket(Ip6Address serverIp) {
+        TrafficSelector serverSelector =
+                DefaultTrafficSelector.builder(LEASE_QUERY_RESPONSE_SELECTOR)
+                        .matchIPv6Src(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(serverSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    private void cancelClientDhcpPacket(Ip6Address serverIp) {
+        // Packet comes from relay
+        TrafficSelector indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(serverIp.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(indirectClientSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+        indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(Ip6Address.ALL_DHCP_RELAY_AGENTS_AND_SERVERS.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(indirectClientSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+        indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(Ip6Address.ALL_DHCP_SERVERS.toIpPrefix())
+                        .build();
+        packetService.cancelPackets(indirectClientSelector,
+                                    PacketPriority.CONTROL,
+                                    appId);
+
+        // Packet comes from client
+        packetService.cancelPackets(CLIENT_SERVER_SELECTOR,
+                                    PacketPriority.CONTROL,
+                                    appId);
+    }
+
+    private void requestClientDhcpPacket(Ip6Address serverIp) {
+        // Packet comes from relay
+        TrafficSelector indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(serverIp.toIpPrefix())
+                        .build();
+        packetService.requestPackets(indirectClientSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+        indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(Ip6Address.ALL_DHCP_RELAY_AGENTS_AND_SERVERS.toIpPrefix())
+                        .build();
+        packetService.requestPackets(indirectClientSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+        indirectClientSelector =
+                DefaultTrafficSelector.builder(SERVER_RELAY_SELECTOR)
+                        .matchIPv6Dst(Ip6Address.ALL_DHCP_SERVERS.toIpPrefix())
+                        .build();
+        packetService.requestPackets(indirectClientSelector,
+                                     PacketPriority.CONTROL,
+                                     appId);
+
+        // Packet comes from client
+        packetService.requestPackets(CLIENT_SERVER_SELECTOR,
+                                     PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    /**
+     * Process the ignore rules.
+     *
+     * @param deviceId the device id
+     * @param vlanId the vlan to be ignored
+     * @param op the operation, ADD to install; REMOVE to uninstall rules
+     */
+    private void processIgnoreVlanRule(DeviceId deviceId, VlanId vlanId, Objective.Operation op) {
+        AtomicInteger installedCount = new AtomicInteger(DHCP_SELECTORS.size());
+        DHCP_SELECTORS.forEach(trafficSelector -> {
+            TrafficSelector selector = DefaultTrafficSelector.builder(trafficSelector)
+                    .matchVlanId(vlanId)
+                    .build();
+
+            ForwardingObjective.Builder builder = DefaultForwardingObjective.builder()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withSelector(selector)
+                    .withPriority(IGNORE_CONTROL_PRIORITY)
+                    .withTreatment(DefaultTrafficTreatment.emptyTreatment())
+                    .fromApp(appId);
+
+
+            ObjectiveContext objectiveContext = new ObjectiveContext() {
+                @Override
+                public void onSuccess(Objective objective) {
+                    log.info("Ignore rule {} (Vlan id {}, device {}, selector {})",
+                             op, vlanId, deviceId, selector);
+                    int countDown = installedCount.decrementAndGet();
+                    if (countDown != 0) {
+                        return;
+                    }
+                    switch (op) {
+                        case ADD:
+                            ignoredVlans.put(deviceId, vlanId);
+                            break;
+                        case REMOVE:
+                            ignoredVlans.remove(deviceId, vlanId);
+                            break;
+                        default:
+                            log.warn("Unsupported objective operation {}", op);
+                            break;
+                    }
+                }
+
+                @Override
+                public void onError(Objective objective, ObjectiveError error) {
+                    log.warn("Can't {} ignore rule (vlan id {}, selector {}, device {}) due to {}",
+                             op, vlanId, selector, deviceId, error);
+                }
+            };
+
+            ForwardingObjective fwd;
+            switch (op) {
+                case ADD:
+                    fwd = builder.add(objectiveContext);
+                    break;
+                case REMOVE:
+                    fwd = builder.remove(objectiveContext);
+                    break;
+                default:
+                    log.warn("Unsupported objective operation {}", op);
+                    return;
+            }
+
+            Device device = deviceService.getDevice(deviceId);
+            if (device == null || !device.is(Pipeliner.class)) {
+                log.warn("Device {} is not available now, wait until device is available", deviceId);
+                return;
+            }
+            flowObjectiveService.apply(deviceId, fwd);
+        });
+    }
+
+    /**
+     * Find first ipaddress for a given Host info i.e.  mac and vlan.
+     *
+     * @param clientMac client mac
+     * @param vlanId  packet's vlan
+     * @return next-hop link-local ipaddress for a given host
+     */
+    private IpAddress getFirstIpByHost(Boolean directConnFlag, MacAddress clientMac, VlanId vlanId) {
+        IpAddress nextHopIp;
+        // pick out the first link-local ip address
+        HostId gwHostId = HostId.hostId(clientMac, vlanId);
+        Host gwHost = hostService.getHost(gwHostId);
+        if (gwHost == null) {
+            log.warn("Can't find gateway host for hostId {}", gwHostId);
+            return null;
+        }
+        if (directConnFlag) {
+            nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp6)
+                    .map(IpAddress::getIp6Address)
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            nextHopIp = gwHost.ipAddresses()
+                    .stream()
+                    .filter(IpAddress::isIp6)
+                    .filter(ip6 -> ip6.isLinkLocal())
+                    .map(IpAddress::getIp6Address)
+                    .findFirst()
+                    .orElse(null);
+        }
+        return nextHopIp;
+    }
+
+    private List<DhcpServerInfo> findValidServerInfo(boolean directConnFlag) {
+        List<DhcpServerInfo> validServerInfo;
+
+        if (directConnFlag || indirectServerInfoList.isEmpty()) {
+            validServerInfo = new ArrayList<DhcpServerInfo>(defaultServerInfoList);
+        } else {
+            validServerInfo = new ArrayList<DhcpServerInfo>(indirectServerInfoList);
+        }
+        return validServerInfo;
+    }
+
+    private DhcpServerInfo findServerInfoFromServer(boolean directConnFlag, ConnectPoint inPort) {
+        List<DhcpServerInfo> validServerInfoList = findValidServerInfo(directConnFlag);
+        DhcpServerInfo  foundServerInfo = null;
+        for (DhcpServerInfo serverInfo : validServerInfoList) {
+            if (inPort.equals(serverInfo.getDhcpServerConnectPoint().get())) {
+                foundServerInfo = serverInfo;
+                log.debug("ServerInfo found for Rcv port {} Server Connect Point {} for {}",
+                        inPort, serverInfo.getDhcpServerConnectPoint(), directConnFlag ? "direct" : "indirect");
+                break;
+            }
+        }
+        return foundServerInfo;
+    }
+
+    /**
+     * Set the dhcp6 lease expiry poll interval value.
+     *
+     * @param val poll interval value in seconds
+     */
+    @Override
+    public void setDhcp6PollInterval(int val) {
+        dhcp6PollInterval = val;
+    }
+
+    /**
+     * get the dhcp6 lease expiry poll interval value.
+     * This is a private function
+     * @return  poll interval value in seconds
+     */
+    private int getDhcp6PollInterval() {
+        return dhcp6PollInterval;
+    }
+
+    /**
+     * Find lease-expired ipaddresses and pd prefixes.
+     * Removing host/route/fpm entries.
+     */
+    public void timeTick() {
+        long currentTime = System.currentTimeMillis();
+        Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
+
+        log.debug("timeTick called currenttime {} records num {} ", currentTime, records.size());
+
+        records.forEach(record -> {
+                    boolean addrOrPdRemoved = false;
+                    DHCP6.MsgType ip6Status = record.ip6Status().orElse(null);
+                    if (ip6Status == null) {
+                        log.debug("record is not valid v6 record.");
+                        return;
+                    }
+
+                    if ((currentTime - record.getLastIp6Update()) >
+                            ((record.addrPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
+                        // remove ipaddress from host/route table
+                        IpAddress ip = record.ip6Address().orElse(null);
+                        if (ip != null) {
+                            if (record.directlyConnected()) {
+                                providerService.removeIpFromHost(HostId.hostId(record.macAddress(),
+                                        record.vlanId()), ip);
+                            } else {
+                                MacAddress gwMac = record.nextHop().orElse(null);
+                                if (gwMac == null) {
+                                    log.warn("Can't find gateway mac address from record {} for ip6Addr", record);
+                                    return;
+                                }
+                                IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(),
+                                        gwMac,
+                                        record.vlanId());
+                                Route route = new Route(Route.Source.DHCP, ip.toIpPrefix(), nextHopIp);
+                                routeStore.removeRoute(route);
+                            }
+                            record.updateAddrPrefTime(0);
+                            record.ip6Address(null);
+                            addrOrPdRemoved = true;
+                            dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(),
+                                    record.vlanId()), record);
+                            log.warn("IP6 address is set to null. delta {} lastUpdate {} addrPrefTime {}",
+                                    (currentTime - record.getLastIp6Update()), record.getLastIp6Update(),
+                                    record.addrPrefTime());
+                        }
+                    }
+                    if ((currentTime - record.getLastPdUpdate()) >
+                            ((record.pdPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
+                        // remove PD from route/fpm table
+                        IpPrefix pdIpPrefix = record.pdPrefix().orElse(null);
+                        if (pdIpPrefix != null) {
+                            if (record.directlyConnected()) {
+                                providerService.removeIpFromHost(HostId.hostId(record.macAddress(), record.vlanId()),
+                                        pdIpPrefix.address().getIp6Address());
+                            } else {
+                                MacAddress gwMac = record.nextHop().orElse(null);
+                                if (gwMac == null) {
+                                    log.warn("Can't find gateway mac address from record {} for PD prefix", record);
+                                    return;
+                                }
+                                IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(),
+                                        gwMac,
+                                        record.vlanId());
+                                Route route = new Route(Route.Source.DHCP, pdIpPrefix, nextHopIp);
+                                routeStore.removeRoute(route);
+                                if (this.dhcpFpmEnabled) {
+                                    dhcpFpmPrefixStore.removeFpmRecord(pdIpPrefix);
+                                }
+                            }
+                            record.updatePdPrefTime(0);
+                            record.pdPrefix(null);
+                            addrOrPdRemoved = true;
+                            dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(),
+                                    record.vlanId()), record);
+                            log.warn("PD prefix is set to null.delta {} pdPrefTime {}",
+                                    (currentTime - record.getLastPdUpdate()), record.pdPrefTime());
+                        }
+                    }
+                    if (addrOrPdRemoved &&
+                            !record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
+                        log.warn("ip6Status {} IP6 address and IP6 PD both are null. Remove record.", ip6Status);
+                        dhcpRelayStore.removeDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()));
+                    }
+                }
+        );
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
new file mode 100644
index 0000000..05cc231
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerUtil.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.DHCP6.MsgType;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
+import org.onlab.packet.dhcp.Dhcp6RelayOption;
+import org.onlab.packet.dhcp.Dhcp6Option;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+
+import org.onlab.util.HexString;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.DeviceId;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import org.onosproject.net.intf.InterfaceService;
+
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.HostLocation;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public final class Dhcp6HandlerUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(Dhcp6HandlerUtil.class);
+
+    private Dhcp6HandlerUtil() {
+    }
+
+    // Returns the first v6 interface ip out of a set of interfaces or null.
+    // Checks all interfaces, and ignores v6 interface ips
+    public static Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
+        for (Interface intf : intfs) {
+            for (InterfaceIpAddress ip : intf.ipAddressesList()) {
+                Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
+                if (relayAgentIp != null) {
+                    return relayAgentIp;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the first interface ip from interface.
+     *
+     * @param iface interface of one connect point
+     * @return the first interface IP; null if not exists an IP address in
+     *         these interfaces
+     */
+    private static Ip6Address getFirstIpFromInterface(Interface iface) {
+        checkNotNull(iface, "Interface can't be null");
+        return iface.ipAddressesList().stream()
+                .map(InterfaceIpAddress::ipAddress)
+                .filter(IpAddress::isIp6)
+                .map(IpAddress::getIp6Address)
+                .findFirst()
+                .orElse(null);
+    }
+    /**
+     *
+     * process the LQ reply packet from dhcp server.
+     *
+     * @param defaultServerInfoList default server list
+     * @param indirectServerInfoList default indirect server list
+     * @param serverInterface server interface
+     * @param interfaceService interface service
+     * @param hostService host service
+     * @param context packet context
+     * @param receivedPacket server ethernet packet
+     * @param recevingInterfaces set of server side interfaces
+     * @return a packet ready to be sent to relevant output interface
+     */
+    public static InternalPacket processLQ6PacketFromServer(
+            List<DhcpServerInfo> defaultServerInfoList,
+            List<DhcpServerInfo> indirectServerInfoList,
+            Interface serverInterface,
+            InterfaceService interfaceService,
+            HostService hostService,
+            PacketContext context,
+            Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
+        // get dhcp6 header.
+        Ethernet etherReply = (Ethernet) receivedPacket.clone();
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        DHCP6 lq6Reply = (DHCP6) udpPacket.getPayload();
+
+        // TODO: refactor
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        DeviceId receivedFromDevice = receivedFrom.deviceId();
+        DhcpServerInfo serverInfo;
+        Ip6Address dhcpServerIp = null;
+        ConnectPoint dhcpServerConnectPoint = null;
+        MacAddress dhcpConnectMac = null;
+        VlanId dhcpConnectVlan = null;
+        Ip6Address dhcpGatewayIp = null;
+
+        // todo: refactor
+        Ip6Address indirectDhcpServerIp = null;
+        ConnectPoint indirectDhcpServerConnectPoint = null;
+        MacAddress indirectDhcpConnectMac = null;
+        VlanId indirectDhcpConnectVlan = null;
+        Ip6Address indirectDhcpGatewayIp = null;
+        Ip6Address indirectRelayAgentIpFromCfg = null;
+
+        if (!defaultServerInfoList.isEmpty()) {
+            serverInfo = defaultServerInfoList.get(0);
+            dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
+            dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
+            dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
+            dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+            dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+        }
+
+        if (!indirectServerInfoList.isEmpty()) {
+            serverInfo = indirectServerInfoList.get(0);
+            indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
+            indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
+            indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
+            indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
+            indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
+            indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
+        }
+
+        Boolean directConnFlag = directlyConnected(lq6Reply);
+        ConnectPoint inPort = context.inPacket().receivedFrom();
+        if ((directConnFlag || indirectDhcpServerIp == null)
+                && !inPort.equals(dhcpServerConnectPoint)) {
+            log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null",
+                    inPort, dhcpServerConnectPoint);
+            return null;
+        }
+
+        if (!directConnFlag && indirectDhcpServerIp != null &&
+                !inPort.equals(indirectDhcpServerConnectPoint)) {
+            log.warn("Receiving port {} is not the same as server connect point {} for indirect",
+                    inPort, indirectDhcpServerConnectPoint);
+            return null;
+        }
+
+
+        Ip6Address nextHopIP =  Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
+        // use hosts store to find out the next hop mac and connection point
+        Set<Host> hosts = hostService.getHostsByIp(nextHopIP);
+        Host host;
+        if (!hosts.isEmpty()) {
+            host = hosts.iterator().next();
+        } else {
+            log.warn("Host {} is not in store", nextHopIP);
+            return null;
+        }
+
+        HostLocation hl = host.location();
+        String clientConnectionPointStr = hl.toString(); // iterator().next());
+        ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
+
+
+        VlanId originalPacketVlanId = VlanId.vlanId(etherReply.getVlanID());
+        Interface iface;
+        iface = interfaceService.getInterfacesByPort(clientConnectionPoint)
+                .stream()
+                .filter(iface1 -> interfaceContainsVlan(iface1, originalPacketVlanId))
+                .findFirst()
+                .orElse(null);
+
+        etherReply.setSourceMACAddress(iface.mac());
+        etherReply.setDestinationMACAddress(host.mac());
+
+        // workaround for a bug where core sends src port as 547 (server)
+        udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
+        udpPacket.setPayload(lq6Reply);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        etherReply.setPayload(ipv6Packet);
+
+        return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
+    }
+
+    /**
+     * extract DHCP6 payload from dhcp6 relay message within relay-forwrd/reply.
+     *
+     * @param dhcp6 dhcp6 relay-reply or relay-foward
+     * @return dhcp6Packet dhcp6 packet extracted from relay-message
+     */
+    public static DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
+
+        // extract the relay message if exist
+        DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
+                .filter(opt -> opt instanceof Dhcp6RelayOption)
+                .map(BasePacket::getPayload)
+                .map(pld -> (DHCP6) pld)
+                .findFirst()
+                .orElse(null);
+        if (dhcp6Payload == null) {
+            // Can't find dhcp payload
+            log.debug("Can't find dhcp6 payload from relay message");
+        } else {
+            log.debug("dhcp6 payload found from relay message {}", dhcp6Payload);
+        }
+        return dhcp6Payload;
+    }
+
+    /**
+     * find the leaf DHCP6 packet from multi-level relay packet.
+     *
+     * @param relayPacket dhcp6 relay packet
+     * @return leafPacket non-relay dhcp6 packet
+     */
+    public static DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
+        DHCP6 dhcp6Parent = relayPacket;
+        DHCP6 dhcp6Child = null;
+
+        log.debug("getDhcp6Leaf entered.");
+        while (dhcp6Parent != null) {
+            dhcp6Child = dhcp6PacketFromRelayPacket(dhcp6Parent);
+            if (dhcp6Child != null) {
+                if (dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
+                        dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
+                    log.debug("leaf dhcp6 packet found.");
+                    break;
+                } else {
+                    // found another relay, go for another loop
+                    dhcp6Parent = dhcp6Child;
+                }
+            } else {
+                log.debug("Expected dhcp6 within relay pkt, but no dhcp6 leaf found.");
+                break;
+            }
+        }
+        return dhcp6Child;
+    }
+
+    /**
+     * Determine DHCP message type (direct DHCPv6 or wrapped into relay messages).
+     *
+     * @param relayPacket {@link DHCP6} packet to be parsed
+     * @return {@link DHCP6.MsgType} contained message type of dhcpv6 packet/relay-message
+     */
+    public static DHCP6.MsgType getDhcp6LeafMessageType(DHCP6 relayPacket) {
+        checkNotNull(relayPacket);
+        DHCP6 dhcp6Child = getDhcp6Leaf(relayPacket);
+        return DHCP6.MsgType.getType(dhcp6Child != null ? dhcp6Child.getMsgType() : relayPacket.getMsgType());
+    }
+
+    /**
+     * check if DHCP6 relay-reply is reply.
+     *
+     * @param relayPacket dhcp6 relay-reply
+     * @return boolean relay-reply contains ack
+     */
+    public static boolean isDhcp6Reply(DHCP6 relayPacket) {
+        DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
+        if (leafDhcp6 != null) {
+            if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
+                log.debug("isDhcp6Reply  true.");
+                return true;  // must be directly connected
+            } else {
+                log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
+            }
+        } else {
+            log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
+        }
+        log.debug("isDhcp6Reply  false.");
+        return false;
+    }
+
+    /**
+     * check if DHCP6 is release or relay-forward contains release.
+     *
+     * @param dhcp6Payload dhcp6 packet
+     * @return boolean dhcp6 contains release
+     */
+    public static  boolean isDhcp6Release(DHCP6 dhcp6Payload) {
+        if (dhcp6Payload.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
+            log.debug("isDhcp6Release  true.");
+            return true;  // must be directly connected
+        } else {
+            DHCP6 dhcp6Leaf = getDhcp6Leaf(dhcp6Payload);
+            if (dhcp6Leaf != null) {
+                if (dhcp6Leaf.getMsgType() ==  DHCP6.MsgType.RELEASE.value()) {
+                    log.debug("isDhcp6Release  true. indirectlry connected");
+                    return true;
+                } else {
+                    log.debug("leaf dhcp6 is not release. MsgType {}",  dhcp6Leaf.getMsgType());
+                    return false;
+                }
+            } else {
+                log.debug("isDhcp6Release  false. dhcp6 is niether relay nor release.");
+                return false;
+            }
+        }
+    }
+
+
+    /**
+     * convert dhcp6 msgType to String.
+     *
+     * @param msgTypeVal msgType byte of dhcp6 packet
+     * @return String string value of dhcp6 msg type
+     */
+    public static String getMsgTypeStr(byte msgTypeVal) {
+        MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
+        return DHCP6.MsgType.getMsgTypeStr(msgType);
+    }
+
+    /**
+     * find the string of dhcp6 leaf packets's msg type.
+     *
+     * @param directConnFlag boolean value indicating direct/indirect connection
+     * @param dhcp6Packet dhcp6 packet
+     * @return String string value of dhcp6 leaf packet msg type
+     */
+    public static String findLeafMsgType(boolean directConnFlag, DHCP6  dhcp6Packet) {
+        if (directConnFlag) {
+            return getMsgTypeStr(dhcp6Packet.getMsgType());
+        } else {
+            DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet);
+            if (leafDhcp != null) {
+                return getMsgTypeStr(leafDhcp.getMsgType());
+            } else {
+                return DhcpRelayCounters.INVALID_PACKET;
+            }
+        }
+    }
+
+    /**
+     * Determind if an Interface contains a vlan id.
+     *
+     * @param iface the Interface
+     * @param vlanId the vlan id
+     * @return true if the Interface contains the vlan id
+     */
+    public static boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
+        if (vlanId.equals(VlanId.NONE)) {
+            // untagged packet, check if vlan untagged or vlan native is not NONE
+            return !iface.vlanUntagged().equals(VlanId.NONE) ||
+                    !iface.vlanNative().equals(VlanId.NONE);
+        }
+        // tagged packet, check if the interface contains the vlan
+        return iface.vlanTagged().contains(vlanId);
+    }
+
+    /**
+     * Check if the host is directly connected to the network or not.
+     *
+     * @param dhcp6Payload the dhcp6 payload
+     * @return true if the host is directly connected to the network; false otherwise
+     */
+    public static boolean directlyConnected(DHCP6 dhcp6Payload) {
+
+        log.debug("directlyConnected enters");
+        if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() ||
+                dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
+            log.debug("directlyConnected false. MsgType {}", dhcp6Payload.getMsgType());
+
+            return false;
+        }
+
+        if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
+                dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
+            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()
+                        && dhcp6Payload2.getMsgType() != MsgType.LEASEQUERY_REPLY.value()) {
+                    log.debug("directlyConnected  true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
+                    return true;  // must be directly connected
+                } else {
+                    log.debug("directlyConnected  false. 1st relay-reply, 2nd relay-reply MsgType {}",
+                            dhcp6Payload2.getMsgType());
+                    return false;  // must be indirectly connected
+                }
+            }
+        } else {
+            log.debug("directlyConnected  true.");
+            return true;
+        }
+    }
+    /**
+     * Check if a given server info has v6 ipaddress.
+     *
+     * @param serverInfo server info to check
+     * @return true if server info has v6 ip address; false otherwise
+     */
+    public static boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
+        if (!serverInfo.getDhcpServerIp6().isPresent()) {
+            log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
+                    HexString.toHexString(serverInfo.getDhcpServerIp6().get().toOctets()));
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean isConnectMacEmpty(DhcpServerInfo serverInfo, Set<Interface> clientInterfaces) {
+        if (!serverInfo.getDhcpConnectMac().isPresent()) {
+            log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
+                            + "packet processing from client on port: {}",
+                    !serverInfo.getDhcpGatewayIp6().isPresent() ? "server IP " + serverInfo.getDhcpServerIp6()
+                            : "gateway IP " + serverInfo.getDhcpGatewayIp6(),
+                    clientInterfaces.iterator().next().connectPoint());
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean isRelayAgentIpFromCfgEmpty(DhcpServerInfo serverInfo, DeviceId receivedFromDevice) {
+        if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
+            log.warn("indirect connection: relayAgentIp NOT availale from config file! Use dynamic.");
+            return true;
+        }
+        return false;
+    }
+
+    private static Dhcp6Option getInterfaceIdIdOption(PacketContext context, Ethernet clientPacket) {
+        String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
+        Dhcp6Option interfaceId = new Dhcp6Option();
+        interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
+        byte[] clientSoureMacBytes = clientPacket.getSourceMACAddress();
+        byte[] inPortStringBytes = inPortString.getBytes();
+        byte[] vlanIdBytes = new byte[2];
+        vlanIdBytes[0] = (byte) (clientPacket.getVlanID() & 0xff);
+        vlanIdBytes[1] = (byte) ((clientPacket.getVlanID() >> 8) & 0xff);
+        byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +
+                inPortStringBytes.length + vlanIdBytes.length];
+        log.debug("Length: interfaceIdBytes  {} clientSoureMacBytes {} inPortStringBytes {} vlan {}",
+                interfaceIdBytes.length, clientSoureMacBytes.length, inPortStringBytes.length,
+                vlanIdBytes.length);
+
+        System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
+        System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length,
+                inPortStringBytes.length);
+        System.arraycopy(vlanIdBytes, 0, interfaceIdBytes,
+                clientSoureMacBytes.length + inPortStringBytes.length,
+                vlanIdBytes.length);
+        interfaceId.setData(interfaceIdBytes);
+        interfaceId.setLength((short) interfaceIdBytes.length);
+        log.debug("interfaceId write srcMac {} portString {}",
+                HexString.toHexString(clientSoureMacBytes, ":"), inPortString);
+        return interfaceId;
+    }
+
+    private static void addDhcp6OptionsFromClient(List<Dhcp6Option> options, byte[] dhcp6PacketByte,
+                                           PacketContext context, Ethernet clientPacket) {
+        Dhcp6Option relayMessage = new Dhcp6Option();
+        relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
+        relayMessage.setLength((short) dhcp6PacketByte.length);
+        relayMessage.setData(dhcp6PacketByte);
+        options.add(relayMessage);
+        // create interfaceId option
+        Dhcp6Option interfaceId = getInterfaceIdIdOption(context, clientPacket);
+        options.add(interfaceId);
+    }
+
+    /**
+     * build the DHCP6 solicit/request packet with gatewayip.
+     *
+     * @param context packet context
+     * @param clientPacket client ethernet packet
+     * @param clientInterfaces set of client side interfaces
+     * @param serverInfo target server which a packet is generated for
+     * @param serverInterface target server interface
+     * @return ethernet packet with dhcp6 packet info
+     */
+    public static Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket,
+                                               Set<Interface> clientInterfaces, DhcpServerInfo serverInfo,
+                                               Interface serverInterface) {
+        ConnectPoint receivedFrom = context.inPacket().receivedFrom();
+        DeviceId receivedFromDevice = receivedFrom.deviceId();
+
+        Ip6Address relayAgentIp = getRelayAgentIPv6Address(clientInterfaces);
+        MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
+        if (relayAgentIp == null || relayAgentMac == null) {
+            log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
+                            + "packet from client on port: {}. Aborting packet processing",
+                    clientInterfaces.iterator().next().connectPoint());
+            return null;
+        }
+        IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
+        UDP clientUdp = (UDP) clientIpv6.getPayload();
+        DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
+        boolean directConnFlag = directlyConnected(clientDhcp6);
+
+        Ip6Address serverIpFacing = getFirstIpFromInterface(serverInterface);
+        if (serverIpFacing == null || serverInterface.mac() == null) {
+            log.warn("No IP v6 address for server Interface {}", serverInterface);
+            return null;
+        }
+
+        Ethernet etherReply = clientPacket.duplicate();
+        etherReply.setSourceMACAddress(serverInterface.mac());
+
+        // set default info and replace with indirect if available later on.
+        if (serverInfo.getDhcpConnectMac().isPresent()) {
+            etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
+        }
+        if (serverInfo.getDhcpConnectVlan().isPresent()) {
+            etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
+        }
+        IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
+        byte[] peerAddress = clientIpv6.getSourceAddress();
+        ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
+        ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
+        UDP udpPacket = (UDP) ipv6Packet.getPayload();
+        udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
+        DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
+        byte[] dhcp6PacketByte = dhcp6Packet.serialize();
+
+        DHCP6 dhcp6Relay = new DHCP6();
+
+        dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
+
+        if (directConnFlag) {
+            dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
+        } else {
+            if (isServerIpEmpty(serverInfo)) {
+                log.warn("indirect DhcpServerIp empty... use default server ");
+            } else {
+                // Indirect case, replace destination to indirect dhcp server if exist
+                // Check if mac is obtained for valid server ip
+                if (isConnectMacEmpty(serverInfo, clientInterfaces)) {
+                    log.warn("indirect Dhcp ConnectMac empty ...");
+                    return null;
+                }
+                etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
+                etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
+                ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
+            }
+            if (isRelayAgentIpFromCfgEmpty(serverInfo, receivedFromDevice)) {
+                log.debug("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}",
+                        HexString.toHexString(relayAgentIp.toOctets(), ":"));
+                serverIpFacing = relayAgentIp;
+            } else {
+                serverIpFacing = serverInfo.getRelayAgentIp6(receivedFromDevice).get();
+            }
+            log.debug("Source IP address set as relay agent IP with value: {}", serverIpFacing);
+            dhcp6Relay.setLinkAddress(serverIpFacing.toOctets());
+            ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
+        }
+        // peer address: address of the client or relay agent from which the message to be relayed was received.
+        dhcp6Relay.setPeerAddress(peerAddress);
+        // directly connected case, hop count is zero; otherwise, hop count + 1
+        if (directConnFlag) {
+            dhcp6Relay.setHopCount((byte) 0);
+        } else {
+            dhcp6Relay.setHopCount((byte) (dhcp6Packet.getHopCount() + 1));
+        }
+
+        List<Dhcp6Option> options = new ArrayList<>();
+        addDhcp6OptionsFromClient(options, dhcp6PacketByte, context, clientPacket);
+        dhcp6Relay.setOptions(options);
+        udpPacket.setPayload(dhcp6Relay);
+        udpPacket.resetChecksum();
+        ipv6Packet.setPayload(udpPacket);
+        ipv6Packet.setHopLimit((byte) 64);
+        etherReply.setPayload(ipv6Packet);
+
+        return etherReply;
+    }
+
+    /**
+     * build the DHCP6 solicit/request packet with gatewayip.
+     *
+     * @param directConnFlag flag indicating if packet is from direct client or not
+     * @param serverInfo server to check its connect point
+     * @return boolean true if serverInfo is found; false otherwise
+     */
+    public static boolean checkDhcpServerConnPt(boolean directConnFlag,
+                                          DhcpServerInfo serverInfo) {
+        if (serverInfo.getDhcpServerConnectPoint() == null) {
+            log.warn("DHCP6 server connect point for {} connPt {}",
+                    directConnFlag ? "direct" : "indirect", serverInfo.getDhcpServerConnectPoint());
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * extract from dhcp6 packet ClientIdOption.
+     *
+     * @param directConnFlag directly connected host
+     * @param dhcp6Payload the dhcp6 payload
+     * @return Dhcp6ClientIdOption clientIdOption, or null if not exists.
+     */
+    static Dhcp6ClientIdOption extractClientId(Boolean directConnFlag, DHCP6 dhcp6Payload) {
+        Dhcp6ClientIdOption clientIdOption;
+
+        if (directConnFlag) {
+            clientIdOption = dhcp6Payload.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6ClientIdOption)
+                    .map(opt -> (Dhcp6ClientIdOption) opt)
+                    .findFirst()
+                    .orElse(null);
+        } else {
+            DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Payload);
+            clientIdOption = leafDhcp.getOptions()
+                    .stream()
+                    .filter(opt -> opt instanceof Dhcp6ClientIdOption)
+                    .map(opt -> (Dhcp6ClientIdOption) opt)
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        return clientIdOption;
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
new file mode 100644
index 0000000..f2ca330
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -0,0 +1,677 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Streams;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+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.ARP;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.IPacket;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Tools;
+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.api.DhcpRelayService;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
+import org.onosproject.dhcprelay.config.EnableDhcpFpmConfig;
+import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
+import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.dhcprelay.store.DhcpFpmPrefixStore;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.net.Device;
+import org.onosproject.net.Host;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import static org.onlab.util.Tools.groupedThreads;
+
+
+import com.google.common.collect.ImmutableSet;
+
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+
+/**
+ * DHCP Relay Agent Application Component.
+ */
+@Component(immediate = true)
+@Service
+public class DhcpRelayManager implements DhcpRelayService {
+    public static final String DHCP_RELAY_APP = "org.onosproject.dhcprelay";
+    public static final String ROUTE_STORE_IMPL =
+            "org.onosproject.routeservice.store.RouteStoreImpl";
+
+    private static final TrafficSelector ARP_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(Ethernet.TYPE_ARP)
+            .build();
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final InternalConfigListener cfgListener = new InternalConfigListener();
+
+    private final Set<ConfigFactory> factories = ImmutableSet.of(
+            new ConfigFactory<ApplicationId, DefaultDhcpRelayConfig>(APP_SUBJECT_FACTORY,
+                    DefaultDhcpRelayConfig.class,
+                    DefaultDhcpRelayConfig.KEY,
+                    true) {
+                @Override
+                public DefaultDhcpRelayConfig createConfig() {
+                    return new DefaultDhcpRelayConfig();
+                }
+            },
+            new ConfigFactory<ApplicationId, IndirectDhcpRelayConfig>(APP_SUBJECT_FACTORY,
+                    IndirectDhcpRelayConfig.class,
+                    IndirectDhcpRelayConfig.KEY,
+                    true) {
+                @Override
+                public IndirectDhcpRelayConfig createConfig() {
+                    return new IndirectDhcpRelayConfig();
+                }
+            },
+            new ConfigFactory<ApplicationId, IgnoreDhcpConfig>(APP_SUBJECT_FACTORY,
+                    IgnoreDhcpConfig.class,
+                    IgnoreDhcpConfig.KEY,
+                    true) {
+                @Override
+                public IgnoreDhcpConfig createConfig() {
+                    return new IgnoreDhcpConfig();
+                }
+            },
+            new ConfigFactory<ApplicationId, EnableDhcpFpmConfig>(APP_SUBJECT_FACTORY,
+                    EnableDhcpFpmConfig.class,
+                    EnableDhcpFpmConfig.KEY,
+                    false) {
+                @Override
+                public EnableDhcpFpmConfig createConfig() {
+                    return new EnableDhcpFpmConfig();
+                }
+            }
+    );
+
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpRelayStore dhcpRelayStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService compCfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpFpmPrefixStore dhcpFpmPrefixStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY,
+            target = "(version=4)")
+    protected DhcpHandler v4Handler;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY,
+            target = "(version=6)")
+    protected DhcpHandler v6Handler;
+
+    @Property(name = "arpEnabled", boolValue = true,
+            label = "Enable Address resolution protocol")
+    protected boolean arpEnabled = true;
+
+    @Property(name = "dhcpPollInterval", intValue = 24 * 3600,
+            label = "dhcp relay poll interval")
+    protected int dhcpPollInterval = 24 * 3600;
+
+    @Property(name = "dhcpFpmEnabled", boolValue = false,
+            label = "Enable DhcpRelay Fpm")
+    protected boolean dhcpFpmEnabled = false;
+
+    private ScheduledExecutorService timerExecutor;
+
+    protected DeviceListener deviceListener = new InternalDeviceListener();
+    private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
+    private ApplicationId appId;
+
+    /**
+     *   One second timer.
+     */
+    class Dhcp6Timer implements Runnable {
+        @Override
+        public void run() {
+            v6Handler.timeTick();
+        }
+    };
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        //start the dhcp relay agent
+        appId = coreService.registerApplication(DHCP_RELAY_APP);
+
+        cfgService.addListener(cfgListener);
+        factories.forEach(cfgService::registerConfigFactory);
+        //update the dhcp server configuration.
+        updateConfig();
+
+        //add the packet processor
+        packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
+
+        timerExecutor = Executors.newScheduledThreadPool(1,
+                groupedThreads("dhcpRelay",
+                        "config-reloader-%d", log));
+        timerExecutor.scheduleAtFixedRate(new Dhcp6Timer(),
+                0,
+                dhcpPollInterval,
+                TimeUnit.SECONDS);
+
+        modified(context);
+
+        // Enable distribute route store
+        compCfgService.preSetProperty(ROUTE_STORE_IMPL,
+                               "distributed", Boolean.TRUE.toString());
+        compCfgService.registerProperties(getClass());
+
+        deviceService.addListener(deviceListener);
+
+
+
+        log.info("DHCP-RELAY Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        cfgService.removeListener(cfgListener);
+        factories.forEach(cfgService::unregisterConfigFactory);
+        packetService.removeProcessor(dhcpRelayPacketProcessor);
+        cancelArpPackets();
+        compCfgService.unregisterProperties(getClass(), false);
+        deviceService.removeListener(deviceListener);
+        timerExecutor.shutdown();
+
+        log.info("DHCP-RELAY Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        Boolean flag;
+
+        flag = Tools.isPropertyEnabled(properties, "arpEnabled");
+        if (flag != null) {
+            arpEnabled = flag;
+            log.info("Address resolution protocol is {}",
+                    arpEnabled ? "enabled" : "disabled");
+        }
+
+        if (arpEnabled) {
+            requestArpPackets();
+        } else {
+            cancelArpPackets();
+        }
+
+        int intervalVal = Tools.getIntegerProperty(properties, "dhcpPollInterval");
+        log.info("DhcpRelay poll interval new {} old {}", intervalVal, dhcpPollInterval);
+        if (intervalVal !=  dhcpPollInterval) {
+            timerExecutor.shutdown();
+            dhcpPollInterval = intervalVal;
+            timerExecutor = Executors.newScheduledThreadPool(1,
+                    groupedThreads("dhcpRelay",
+                            "config-reloader-%d", log));
+            timerExecutor.scheduleAtFixedRate(new Dhcp6Timer(),
+                        0,
+                        dhcpPollInterval > 1 ? dhcpPollInterval : 1,
+                        TimeUnit.SECONDS);
+            v6Handler.setDhcp6PollInterval(dhcpPollInterval);
+        }
+
+        flag = Tools.isPropertyEnabled(properties, "dhcpFpmEnabled");
+        if (flag != null) {
+            boolean oldValue = dhcpFpmEnabled;
+            dhcpFpmEnabled = flag;
+            log.info("DhcpRelay FPM is {}",
+                    dhcpFpmEnabled ? "enabled" : "disabled");
+
+            if (dhcpFpmEnabled && !oldValue) {
+                log.info("Dhcp Fpm is enabled.");
+                processDhcpFpmRoutes(true);
+            }
+            if (!dhcpFpmEnabled && oldValue) {
+                log.info("Dhcp Fpm is disabled.");
+                processDhcpFpmRoutes(false);
+            }
+            v6Handler.setDhcpFpmEnabled(dhcpFpmEnabled);
+        }
+    }
+
+    private static List<TrafficSelector> buildClientDhcpSelectors() {
+        return Streams.concat(Dhcp4HandlerImpl.DHCP_SELECTORS.stream(),
+                              Dhcp6HandlerImpl.DHCP_SELECTORS.stream())
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Updates DHCP relay app configuration.
+     */
+    private void updateConfig() {
+        DefaultDhcpRelayConfig defaultConfig =
+                cfgService.getConfig(appId, DefaultDhcpRelayConfig.class);
+        IndirectDhcpRelayConfig indirectConfig =
+                cfgService.getConfig(appId, IndirectDhcpRelayConfig.class);
+        IgnoreDhcpConfig ignoreDhcpConfig =
+                cfgService.getConfig(appId, IgnoreDhcpConfig.class);
+
+        if (defaultConfig != null) {
+            updateConfig(defaultConfig);
+        }
+        if (indirectConfig != null) {
+            updateConfig(indirectConfig);
+        }
+        if (ignoreDhcpConfig != null) {
+            updateConfig(ignoreDhcpConfig);
+        }
+    }
+
+    /**
+     * Updates DHCP relay app configuration with given configuration.
+     *
+     * @param config the configuration ot update
+     */
+    protected void updateConfig(Config config) {
+        if (config instanceof IndirectDhcpRelayConfig) {
+            IndirectDhcpRelayConfig indirectConfig = (IndirectDhcpRelayConfig) config;
+            v4Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
+            v6Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
+        } else if (config instanceof DefaultDhcpRelayConfig) {
+            DefaultDhcpRelayConfig defaultConfig = (DefaultDhcpRelayConfig) config;
+            v4Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
+            v6Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
+        }
+        if (config instanceof IgnoreDhcpConfig) {
+            v4Handler.updateIgnoreVlanConfig((IgnoreDhcpConfig) config);
+            v6Handler.updateIgnoreVlanConfig((IgnoreDhcpConfig) config);
+        }
+    }
+
+    protected void removeConfig(Config config) {
+        if (config instanceof IndirectDhcpRelayConfig) {
+            v4Handler.setIndirectDhcpServerConfigs(Collections.emptyList());
+            v6Handler.setIndirectDhcpServerConfigs(Collections.emptyList());
+        } else if (config instanceof DefaultDhcpRelayConfig) {
+            v4Handler.setDefaultDhcpServerConfigs(Collections.emptyList());
+            v6Handler.setDefaultDhcpServerConfigs(Collections.emptyList());
+        }
+        if (config instanceof IgnoreDhcpConfig) {
+            v4Handler.updateIgnoreVlanConfig(null);
+            v6Handler.updateIgnoreVlanConfig(null);
+        }
+    }
+
+    private void processDhcpFpmRoutes(Boolean add) {
+        // needs to restore/remove fpm
+    }
+
+    public boolean isDhcpFpmEnabled() {
+        return dhcpFpmEnabled;
+    }
+
+    /**
+     * Request ARP packet in via PacketService.
+     */
+    private void requestArpPackets() {
+        packetService.requestPackets(ARP_SELECTOR, PacketPriority.CONTROL, appId);
+    }
+
+    /**
+     * Cancel requested ARP packets in via packet service.
+     */
+    private void cancelArpPackets() {
+        packetService.cancelPackets(ARP_SELECTOR, PacketPriority.CONTROL, appId);
+    }
+
+    @Override
+    public Optional<DhcpRecord> getDhcpRecord(HostId hostId) {
+        return dhcpRelayStore.getDhcpRecord(hostId);
+    }
+
+    @Override
+    public Collection<DhcpRecord> getDhcpRecords() {
+        return dhcpRelayStore.getDhcpRecords();
+    }
+    @Override
+    public void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord) {
+        dhcpRelayStore.updateDhcpRecord(hostId, dhcpRecord);
+    }
+    @Override
+    public Optional<MacAddress> getDhcpServerMacAddress() {
+        // TODO: depreated it
+        DefaultDhcpRelayConfig config = cfgService.getConfig(appId, DefaultDhcpRelayConfig.class);
+        DhcpServerConfig serverConfig = config.dhcpServerConfigs().get(0);
+        Ip4Address serverip = serverConfig.getDhcpServerIp4().get();
+        return hostService.getHostsByIp(serverip)
+                .stream()
+                .map(Host::mac)
+                .findFirst();
+    }
+
+    @Override
+    public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
+        return ImmutableList.<DhcpServerInfo>builder()
+                .addAll(v4Handler.getDefaultDhcpServerInfoList())
+                .addAll(v6Handler.getDefaultDhcpServerInfoList())
+                .build();
+    }
+
+    @Override
+    public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
+        return ImmutableList.<DhcpServerInfo>builder()
+                .addAll(v4Handler.getIndirectDhcpServerInfoList())
+                .addAll(v6Handler.getIndirectDhcpServerInfoList())
+                .build();
+    }
+
+    /**
+     * Gets DHCP data from a packet.
+     *
+     * @param packet the packet
+     * @return the DHCP data; empty if it is not a DHCP packet
+     */
+    private Optional<DHCP> findDhcp(Ethernet packet) {
+        return Stream.of(packet)
+                .filter(Objects::nonNull)
+                .map(Ethernet::getPayload)
+                .filter(p -> p instanceof IPv4)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof UDP)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof DHCP)
+                .map(p -> (DHCP) p)
+                .findFirst();
+    }
+
+    /**
+     * Gets DHCPv6 data from a packet.
+     *
+     * @param packet the packet
+     * @return the DHCPv6 data; empty if it is not a DHCPv6 packet
+     */
+    private Optional<DHCP6> findDhcp6(Ethernet packet) {
+        return Stream.of(packet)
+                .filter(Objects::nonNull)
+                .map(Ethernet::getPayload)
+                .filter(p -> p instanceof IPv6)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof UDP)
+                .map(IPacket::getPayload)
+                .filter(Objects::nonNull)
+                .filter(p -> p instanceof DHCP6)
+                .map(p -> (DHCP6) p)
+                .findFirst();
+    }
+
+
+    private class DhcpRelayPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+            // process the packet and get the payload
+            Ethernet packet = context.inPacket().parsed();
+            if (packet == null) {
+                return;
+            }
+
+            findDhcp(packet).ifPresent(dhcpPayload -> {
+                v4Handler.processDhcpPacket(context, dhcpPayload);
+            });
+
+            findDhcp6(packet).ifPresent(dhcp6Payload -> {
+                v6Handler.processDhcpPacket(context, dhcp6Payload);
+            });
+
+            if (packet.getEtherType() == Ethernet.TYPE_ARP && arpEnabled) {
+                ARP arpPacket = (ARP) packet.getPayload();
+                VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+                Set<Interface> interfaces = interfaceService.
+                        getInterfacesByPort(context.inPacket().receivedFrom());
+                //ignore the packets if dhcp server interface is not configured on onos.
+                if (interfaces.isEmpty()) {
+                    log.warn("server virtual interface not configured");
+                    return;
+                }
+                if ((arpPacket.getOpCode() != ARP.OP_REQUEST)) {
+                    // handle request only
+                    return;
+                }
+                MacAddress interfaceMac = interfaces.stream()
+                        .filter(iface -> iface.vlan().equals(vlanId))
+                        .map(Interface::mac)
+                        .filter(mac -> !mac.equals(MacAddress.NONE))
+                        .findFirst()
+                        .orElse(MacAddress.ONOS);
+                if (interfaceMac == null) {
+                    // can't find interface mac address
+                    return;
+                }
+                processArpPacket(context, packet, interfaceMac);
+            }
+        }
+
+        /**
+         * Processes the ARP Payload and initiates a reply to the client.
+         *
+         * @param context the packet context
+         * @param packet the ethernet payload
+         * @param replyMac mac address to be replied
+         */
+        private void processArpPacket(PacketContext context, Ethernet packet, MacAddress replyMac) {
+            ARP arpPacket = (ARP) packet.getPayload();
+            ARP arpReply = arpPacket.duplicate();
+            arpReply.setOpCode(ARP.OP_REPLY);
+
+            arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
+            arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress());
+            arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress());
+            arpReply.setSenderHardwareAddress(replyMac.toBytes());
+
+            // Ethernet Frame.
+            Ethernet ethReply = new Ethernet();
+            ethReply.setSourceMACAddress(replyMac.toBytes());
+            ethReply.setDestinationMACAddress(packet.getSourceMAC());
+            ethReply.setEtherType(Ethernet.TYPE_ARP);
+            ethReply.setVlanID(packet.getVlanID());
+            ethReply.setPayload(arpReply);
+
+            ConnectPoint targetPort = context.inPacket().receivedFrom();
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(targetPort.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    targetPort.deviceId(), t, ByteBuffer.wrap(ethReply.serialize()));
+            if (log.isTraceEnabled()) {
+                log.trace("Relaying ARP packet {} to {}", packet, targetPort);
+            }
+            packetService.emit(o);
+        }
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            switch (event.type()) {
+                case CONFIG_UPDATED:
+                case CONFIG_ADDED:
+                    event.config().ifPresent(config -> {
+                        updateConfig(config);
+                        log.info("{} updated", config.getClass().getSimpleName());
+                    });
+                    break;
+                case CONFIG_REMOVED:
+                    event.prevConfig().ifPresent(config -> {
+                        removeConfig(config);
+                        log.info("{} removed", config.getClass().getSimpleName());
+                    });
+                    break;
+                case CONFIG_REGISTERED:
+                case CONFIG_UNREGISTERED:
+                    break;
+                default:
+                    log.warn("Unsupported event type {}", event.type());
+                    break;
+            }
+        }
+
+        @Override
+        public boolean isRelevant(NetworkConfigEvent event) {
+            if (event.configClass().equals(DefaultDhcpRelayConfig.class) ||
+                    event.configClass().equals(IndirectDhcpRelayConfig.class) ||
+                    event.configClass().equals(IgnoreDhcpConfig.class)) {
+                return true;
+            }
+            log.debug("Ignore irrelevant event class {}", event.configClass().getName());
+            return false;
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            Device device = event.subject();
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                    updateIgnoreVlanConfigs();
+                    break;
+                case DEVICE_AVAILABILITY_CHANGED:
+                    deviceAvailabilityChanged(device);
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void deviceAvailabilityChanged(Device device) {
+            if (deviceService.isAvailable(device.id())) {
+                updateIgnoreVlanConfigs();
+            } else {
+                removeIgnoreVlanState();
+            }
+        }
+
+        private void updateIgnoreVlanConfigs() {
+            IgnoreDhcpConfig config = cfgService.getConfig(appId, IgnoreDhcpConfig.class);
+            v4Handler.updateIgnoreVlanConfig(config);
+            v6Handler.updateIgnoreVlanConfig(config);
+        }
+
+        private void removeIgnoreVlanState() {
+            IgnoreDhcpConfig config = cfgService.getConfig(appId, IgnoreDhcpConfig.class);
+            v4Handler.removeIgnoreVlanState(config);
+            v6Handler.removeIgnoreVlanState(config);
+        }
+    }
+
+
+
+    public Optional<FpmRecord> getFpmRecord(IpPrefix prefix) {
+        return dhcpFpmPrefixStore.getFpmRecord(prefix);
+    }
+
+    public Collection<FpmRecord> getFpmRecords() {
+        return dhcpFpmPrefixStore.getFpmRecords();
+    }
+
+    @Override
+    public void addFpmRecord(IpPrefix prefix, FpmRecord fpmRecord) {
+        dhcpFpmPrefixStore.addFpmRecord(prefix, fpmRecord);
+    }
+
+    @Override
+    public Optional<FpmRecord> removeFpmRecord(IpPrefix prefix) {
+        return dhcpFpmPrefixStore.removeFpmRecord(prefix);
+    }
+
+
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/InternalPacket.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/InternalPacket.java
new file mode 100644
index 0000000..70d4ae2
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/InternalPacket.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay;
+
+import org.onlab.packet.Ethernet;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Container for Ethernet packet and destination port.
+ */
+final class InternalPacket {
+    private Ethernet packet;
+    private ConnectPoint destLocation;
+
+    private InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
+        packet = newPacket;
+        destLocation = newLocation;
+    }
+
+    public Ethernet getPacket() {
+        return packet;
+    }
+
+    public ConnectPoint getDestLocation() {
+        return destLocation;
+    }
+
+    /**
+     * Build {@link InternalPacket} object instance.
+     *
+     * @param newPacket {@link Ethernet} packet to be sent
+     * @param newLocation {@link ConnectPoint} packet destination
+     * @return new instance of {@link InternalPacket} class
+     */
+    public static InternalPacket internalPacket(Ethernet newPacket, ConnectPoint newLocation) {
+        return new InternalPacket(newPacket, newLocation);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
new file mode 100644
index 0000000..3de3ced
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.api;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
+import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.packet.PacketContext;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * DHCP relay handler.
+ */
+public interface DhcpHandler {
+    /**
+     * Process the DHCP packet before sending to server or client.
+     *
+     * @param context the packet context
+     * @param dhcpPayload the DHCP payload
+     */
+    void processDhcpPacket(PacketContext context, BasePacket dhcpPayload);
+
+    /**
+     * Gets DHCP server IP.
+     *
+     * @return IP address of DHCP server; empty value if not exist
+     * @deprecated 1.12 get the address from config service
+     */
+    @Deprecated
+    default Optional<IpAddress> getDhcpServerIp() {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Gets DHCP gateway IP.
+     *
+     * @return IP address of DHCP gateway; empty value if not exist
+     * @deprecated 1.12 get the address from config service
+     */
+    @Deprecated
+    default Optional<IpAddress> getDhcpGatewayIp() {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Gets DHCP connect Mac address.
+     *
+     * @return the connect Mac address of server or gateway
+     * @deprecated 1.12 get host mac from host service
+     */
+    @Deprecated
+    default Optional<MacAddress> getDhcpConnectMac() {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Sets DHCP gateway IP.
+     *
+     * @param dhcpGatewayIp the DHCP gateway IP
+     * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
+     */
+    @Deprecated
+    default void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Sets DHCP connect vlan.
+     *
+     * @param dhcpConnectVlan the DHCP connect vlan
+     * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
+     */
+    @Deprecated
+    default void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Sets DHCP connect Mac address.
+     *
+     * @param dhcpConnectMac the connect Mac address
+     * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
+     */
+    @Deprecated
+    default void setDhcpConnectMac(MacAddress dhcpConnectMac) {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Sets DHCP server connect point.
+     *
+     * @param dhcpServerConnectPoint the server connect point
+     * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
+     */
+    @Deprecated
+    default void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Sets DHCP server IP.
+     *
+     * @param dhcpServerIp the DHCP server IP
+     * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
+     */
+    @Deprecated
+    default void setDhcpServerIp(IpAddress dhcpServerIp) {
+        throw new UnsupportedOperationException("Method deprecated");
+    }
+
+    /**
+     * Gets list of default DHCP server information.
+     *
+     * @return list of default DHCP server information
+     */
+    default List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets list of indirect DHCP server information.
+     *
+     * @return list of indirect DHCP server information
+     */
+    default List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Sets DHCP server config for default case.
+     *
+     * @param configs the config
+     */
+    void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs);
+
+    /**
+     * Sets DHCP server config for indirect case.
+     *
+     * @param configs the config
+     */
+    void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs);
+
+    /**
+     * Push IgnoreDhcpConfig to the handler.
+     *
+     * @param config the config
+     */
+    void updateIgnoreVlanConfig(IgnoreDhcpConfig config);
+
+    /**
+     * Remove internal state for IgnoreDhcp.
+     *
+     * @param config the config
+     */
+    void removeIgnoreVlanState(IgnoreDhcpConfig config);
+
+    /**
+     * Hander for Dhcp expiration poll timer.
+     *
+     */
+    default void timeTick() { }
+
+    /**
+     * Update Dhcp expiration poll timer value.
+     *
+     * @param val the timer interval value
+     */
+    default void setDhcp6PollInterval(int val) { }
+
+    /**
+     * Sets DHCP FPM Enable state.
+     *
+     * @param dhcpFpmFlag flag indicating dhcpFpmEnable state
+     */
+    default void setDhcpFpmEnabled(Boolean dhcpFpmFlag) { }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java
new file mode 100644
index 0000000..5eb8d9e
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpRelayService.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.api;
+
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.net.HostId;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+public interface DhcpRelayService {
+    /**
+     * Gets DHCP record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @return the DHCP record of the host
+     */
+    Optional<DhcpRecord> getDhcpRecord(HostId hostId);
+
+    /**
+     * Gets all DHCP records from store.
+     *
+     * @return all DHCP records from store
+     */
+    Collection<DhcpRecord> getDhcpRecords();
+
+    /**
+     * Updates DHCP record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @param dhcpRecord the DHCP record of the host
+     */
+    void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord);
+
+    /**
+     * Gets mac address of DHCP server.
+     *
+     * @return the mac address of DHCP server; empty if not exist
+     * @deprecated 1.12, use get DHCP server configs method
+     */
+    @Deprecated
+    Optional<MacAddress> getDhcpServerMacAddress();
+
+    /**
+     * Gets list of default DHCP server information.
+     *
+     * @return list of default DHCP server information
+     */
+    List<DhcpServerInfo> getDefaultDhcpServerInfoList();
+
+    /**
+     * Gets list of indirect DHCP server information.
+     *
+     * @return list of indirect DHCP server information
+     */
+    List<DhcpServerInfo> getIndirectDhcpServerInfoList();
+
+    /**
+     * Add DHCP FPM record to store.
+     *
+     * @param prefix the prefix
+     * @param fpmRecord the fpmRecord
+     */
+    void addFpmRecord(IpPrefix prefix, FpmRecord fpmRecord);
+
+    /**
+     * Delete DHCP FPM record from store.
+     *
+     * @param prefix the prefix
+     * @return DHCP record from store; empty value if it does not exist.
+     */
+    Optional<FpmRecord> removeFpmRecord(IpPrefix prefix);
+
+    /**
+     * Gets PD route record for specific prefix.
+     *
+     * @param prefix PD prefix
+     * @return the PD route record from store
+     */
+    Optional<FpmRecord> getFpmRecord(IpPrefix prefix);
+
+    /**
+     * Gets all PD route records from store.
+     *
+     * @return all PD records from store
+     */
+    Collection<FpmRecord> getFpmRecords();
+
+    /**
+     * Determine if DHCP FPM feature is enabled or not.
+     *
+     * @return boolean value
+     */
+    public boolean isDhcpFpmEnabled();
+
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpServerInfo.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpServerInfo.java
new file mode 100644
index 0000000..74328ec
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/DhcpServerInfo.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
+
+import java.util.Optional;
+
+/**
+ * class contains DHCP server information.
+ */
+public class DhcpServerInfo extends DhcpServerConfig {
+    public enum Version {
+        DHCP_V4,
+        DHCP_V6
+    }
+    private MacAddress dhcpConnectMac;
+    private VlanId dhcpConnectVlan;
+    private Version version;
+
+    /**
+     * Creates DHCP server information from config.
+     *
+     * @param config DHCP server config
+     * @param version DHCP version for the server
+     */
+    public DhcpServerInfo(DhcpServerConfig config, Version version) {
+        this.relayAgentIps = Maps.newHashMap(config.getRelayAgentIps());
+        this.connectPoint = config.getDhcpServerConnectPoint().orElse(null);
+        this.version = version;
+
+        switch (version) {
+            case DHCP_V4:
+                this.serverIp4Addr = config.getDhcpServerIp4().orElse(null);
+                this.gatewayIp4Addr = config.getDhcpGatewayIp4().orElse(null);
+                break;
+            case DHCP_V6:
+                this.serverIp6Addr = config.getDhcpServerIp6().orElse(null);
+                this.gatewayIp6Addr = config.getDhcpGatewayIp6().orElse(null);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Sets DHCP server or gateway mac address.
+     *
+     * @param dhcpConnectMac the mac address
+     */
+    public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
+        this.dhcpConnectMac = dhcpConnectMac;
+    }
+
+    /**
+     * Sets DHCP server or gateway vlan id.
+     *
+     * @param dhcpConnectVlan the vlan id
+     */
+    public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
+        this.dhcpConnectVlan = dhcpConnectVlan;
+    }
+
+    /**
+     * Gets DHCP server or gateway mac address.
+     *
+     * @return the mac address
+     */
+    public Optional<MacAddress> getDhcpConnectMac() {
+        return Optional.ofNullable(dhcpConnectMac);
+    }
+
+    /**
+     * Gets DHCP server or gateway vlan id.
+     *
+     * @return the vlan id.
+     */
+    public Optional<VlanId> getDhcpConnectVlan() {
+        return Optional.ofNullable(dhcpConnectVlan);
+    }
+
+    /**
+     * Get DHCP version of the DHCP server.
+     *
+     * @return the version; can be DHCP_V4 or DHCP_V6
+     */
+    public Version getVersion() {
+        return version;
+    }
+
+    @Override
+    public String toString() {
+        MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(this);
+        toStringHelper
+                .add("dhcpConnectMac", dhcpConnectMac)
+                .add("dhcpConnectVlan", dhcpConnectVlan)
+                .add("connectPoint", connectPoint)
+                .add("version", version);
+        switch (version) {
+            case DHCP_V4:
+                toStringHelper
+                        .add("serverIp4Addr", serverIp4Addr)
+                        .add("gatewayIp4Addr", gatewayIp4Addr);
+                break;
+            case DHCP_V6:
+                toStringHelper
+                        .add("serverIp6Addr", serverIp6Addr)
+                        .add("gatewayIp6Addr", gatewayIp6Addr);
+                break;
+            default:
+                break;
+        }
+        return toStringHelper.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof DhcpServerInfo)) {
+            return false;
+        }
+        DhcpServerInfo that = (DhcpServerInfo) o;
+        return super.equals(o) &&
+                Objects.equal(dhcpConnectMac, that.dhcpConnectMac) &&
+                Objects.equal(dhcpConnectVlan, that.dhcpConnectVlan) &&
+                version == that.version;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(super.hashCode(), dhcpConnectMac, dhcpConnectVlan, version);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/package-info.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/package-info.java
new file mode 100644
index 0000000..fa239e8
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/api/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ * APIs for DHCP relay application.
+ */
+package org.onosproject.dhcprelay.api;
\ No newline at end of file
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmAddCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmAddCommand.java
new file mode 100644
index 0000000..fd886b9
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmAddCommand.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.cli;
+
+//import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.apache.karaf.shell.commands.Argument;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.IpAddress;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
+
+/**
+ * Prints Dhcp FPM Routes information.
+ */
+@Command(scope = "onos", name = "dhcp-fpm-add",
+         description = "Add DHCP FPM prefix in dhcp-fpm-store.")
+public class DhcpFpmAddCommand extends AbstractShellCommand {
+
+    private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
+
+    @Argument(index = 0, name = "prefix",
+            description = "prefix",
+            required = true, multiValued = false)
+    String prefixString = null;
+
+    @Argument(index = 1, name = "next hop",
+            description = "next hop",
+            required = true, multiValued = false)
+    String nextHopString = null;
+
+    @Override
+    protected void execute() {
+
+        IpPrefix prefix = IpPrefix.valueOf(prefixString);
+        IpAddress nextHop = IpAddress.valueOf(nextHopString);
+        FpmRecord record = new FpmRecord(prefix, nextHop, FpmRecord.Type.DHCP_RELAY);
+
+        DHCP_RELAY_SERVICE.addFpmRecord(prefix, record);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmDeleteCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmDeleteCommand.java
new file mode 100644
index 0000000..244bcf8
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmDeleteCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.apache.karaf.shell.commands.Argument;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
+
+/**
+ * Prints Dhcp FPM Routes information.
+ */
+@Command(scope = "onos", name = "dhcp-fpm-delete",
+         description = "delete DHCP FPM prefix in dhcp-fpm-store")
+public class DhcpFpmDeleteCommand extends AbstractShellCommand {
+
+    private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
+
+    @Argument(index = 0, name = "prefix",
+            description = "prefix",
+            required = true, multiValued = false)
+    String prefixString = null;
+
+    @Override
+    protected void execute() {
+        IpPrefix prefix = IpPrefix.valueOf(prefixString);
+
+        DHCP_RELAY_SERVICE.removeFpmRecord(prefix);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmRoutesCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmRoutesCommand.java
new file mode 100644
index 0000000..9aacac3
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpFpmRoutesCommand.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.cli;
+
+//import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+
+import org.onosproject.dhcprelay.api.DhcpRelayService;
+import org.onosproject.routing.fpm.api.FpmRecord;
+
+import java.util.Collection;
+
+/**
+ * Prints Dhcp FPM Routes information.
+ */
+@Command(scope = "onos", name = "dhcp-fpm-routes",
+         description = "DHCP FPM routes cli.")
+public class DhcpFpmRoutesCommand extends AbstractShellCommand {
+    private static final String NO_RECORDS = "No DHCP FPM Route record found";
+    private static final String HEADER = "DHCP FPM Routes records :";
+    private static final String ROUTE = "prefix=%s, next-hop=%s";
+
+
+    private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
+
+    @Override
+    protected void execute() {
+
+            print("Dhcp Fpm Feature is %s !", DHCP_RELAY_SERVICE.isDhcpFpmEnabled() ? "enabled" : "disabled");
+            print("\n");
+            Collection<FpmRecord> records = DHCP_RELAY_SERVICE.getFpmRecords();
+            if (records.isEmpty()) {
+                print(NO_RECORDS);
+                return;
+            }
+            print(HEADER);
+            records.forEach(record -> print(ROUTE,
+                    record.ipPrefix(),
+                    record.nextHop()));
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayAggCountersCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayAggCountersCommand.java
new file mode 100644
index 0000000..a91a53a
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayAggCountersCommand.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
+import org.onosproject.dhcprelay.store.DhcpRelayCountersStore;
+
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Prints Dhcp FPM Routes information.
+ */
+@Command(scope = "onos", name = "dhcp-relay-agg-counters",
+         description = "DHCP Relay Aggregate Counters cli.")
+public class DhcpRelayAggCountersCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "reset",
+            description = "reset counters or not",
+            required = false, multiValued = false)
+    String reset = null;
+
+    private static final String HEADER = "DHCP Relay Aggregate Counters :";
+    private static final String GCOUNT = "global";
+    private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
+
+    @Override
+    protected void execute() {
+        boolean toResetFlag;
+
+        if (reset != null) {
+            if (reset.equals("reset") || reset.equals("[reset]")) {
+                toResetFlag = true;
+            } else {
+                print("Last parameter is [reset]");
+                return;
+            }
+        } else {
+            toResetFlag = false;
+        }
+
+        print(HEADER);
+
+        DhcpRelayCountersStore counterStore = AbstractShellCommand.get(DhcpRelayCountersStore.class);
+
+        Optional<DhcpRelayCounters> perClassCounters = counterStore.getCounters(GCOUNT);
+
+        if (perClassCounters.isPresent()) {
+            Map<String, Integer> counters = perClassCounters.get().getCounters();
+            if (counters.size() > 0) {
+                counters.forEach((name, value) -> {
+                    print("%-30s  ............................  %-4d packets", name, value);
+                });
+            } else {
+                print("No counter for {}", GCOUNT);
+            }
+
+            if (toResetFlag) {
+                counterStore.resetCounters(GCOUNT);
+
+            }
+        }
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
new file mode 100644
index 0000000..90816b0
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Tools;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
+import org.onosproject.dhcprelay.api.DhcpServerInfo;
+import org.onosproject.dhcprelay.api.DhcpRelayService;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostService;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.Map;
+
+
+/**
+ * Prints DHCP server and DHCP relay status.
+ */
+@Command(scope = "onos", name = "dhcp-relay", description = "DHCP relay app cli.")
+public class DhcpRelayCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "counter",
+            description = "shows counter values",
+            required = false, multiValued = false)
+    String counter = null;
+
+    @Argument(index = 1, name = "reset",
+            description = "reset counters or not",
+            required = false, multiValued = false)
+    String reset = null;
+
+
+
+    private static final String CONUTER_HEADER = "DHCP Relay Counters :";
+    private static final String COUNTER_HOST = "Counters for id=%s/%s, locations=%s%s";
+
+
+    private static final String HEADER = "DHCP relay records ([D]: Directly connected):";
+    private static final String NO_RECORDS = "No DHCP relay record found";
+    private static final String HOST = "id=%s/%s, locations=%s%s, last-seen=%s, IPv4=%s, IPv6=%s";
+    private static final String DHCP_SERVER_GW = "DHCP Server: %s, %s via %s (Mac: %s)";
+    private static final String DHCP_SERVER = "DHCP Server: %s, %s (Mac: %s)";
+    private static final String MISSING_SERVER_CFG = "DHCP Server info not available";
+    private static final String DIRECTLY = "[D]";
+    private static final String EMPTY = "";
+    private static final String NA = "N/A";
+    private static final String STATUS_FMT = "[%s, %s]";
+    private static final String STATUS_FMT_NH = "[%s via %s, %s]";
+    private static final String STATUS_FMT_V6 = "[%s %d, %d ms %s %d %d ms, %s]";
+    private static final String STATUS_FMT_V6_NH = "[%s %d %d ms, %s %d %d ms via %s, %s]";
+    private static final String DEFAULT_SERVERS = "Default DHCP servers:";
+    private static final String INDIRECT_SERVERS = "Indirect DHCP servers:";
+
+    private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
+    private static final HostService HOST_SERVICE = get(HostService.class);
+
+
+    @Override
+    protected void execute() {
+        List<DhcpServerInfo> defaultDhcpServerInfoList = DHCP_RELAY_SERVICE.getDefaultDhcpServerInfoList();
+        List<DhcpServerInfo> indirectDhcpServerInfoList = DHCP_RELAY_SERVICE.getIndirectDhcpServerInfoList();
+
+        if (defaultDhcpServerInfoList.isEmpty() && indirectDhcpServerInfoList.isEmpty()) {
+            print(MISSING_SERVER_CFG);
+            return;
+        }
+
+        if (!defaultDhcpServerInfoList.isEmpty()) {
+            print(DEFAULT_SERVERS);
+            listServers(defaultDhcpServerInfoList);
+        }
+        if (!indirectDhcpServerInfoList.isEmpty()) {
+            print(INDIRECT_SERVERS);
+            listServers(indirectDhcpServerInfoList);
+        }
+
+        // DHCP records
+        Collection<DhcpRecord> records = DHCP_RELAY_SERVICE.getDhcpRecords();
+        if (records.isEmpty()) {
+            print(NO_RECORDS);
+            return;
+        }
+
+        // Handle display of counters
+        boolean toResetFlag;
+
+        if (counter != null) {
+            if (counter.equals("counter") || counter.equals("[counter]")) {
+                print(CONUTER_HEADER);
+            } else {
+                print("first parameter is [counter]");
+                return;
+            }
+            if (reset != null) {
+                if (reset.equals("reset") || reset.equals("[reset]")) {
+                    toResetFlag = true;
+                } else {
+                    print("Last parameter is [reset]");
+                    return;
+                }
+            } else {
+                toResetFlag = false;
+            }
+
+            records.forEach(record -> {
+                print(COUNTER_HOST, record.macAddress(),
+                        record.vlanId(),
+                        record.locations(),
+                        record.directlyConnected() ? DIRECTLY : EMPTY);
+                DhcpRelayCounters v6Counters = record.getV6Counters();
+                Map<String, Integer> countersMap = v6Counters.getCounters();
+                countersMap.forEach((name, value) -> {
+                    print("%-30s  ............................  %-4d packets", name, value);
+                });
+                if (toResetFlag) {
+                    v6Counters.resetCounters();
+                    record.updateLastSeen();
+                    DHCP_RELAY_SERVICE.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
+                }
+            });
+
+
+            return;
+        }
+
+
+        // Handle display of records
+
+        print(HEADER);
+        records.forEach(record -> print(HOST,
+                                        record.macAddress(),
+                                        record.vlanId(),
+                                        record.locations(),
+                                        record.directlyConnected() ? DIRECTLY : EMPTY,
+                                        Tools.timeAgo(record.lastSeen()),
+                                        ip4State(record),
+                                        ip6State(record)));
+    }
+
+    private void listServers(List<DhcpServerInfo> dhcpServerInfoList) {
+        dhcpServerInfoList.forEach(dhcpServerInfo -> {
+            String connectPoint = dhcpServerInfo.getDhcpServerConnectPoint()
+                    .map(Object::toString).orElse(NA);
+            String serverMac = dhcpServerInfo.getDhcpConnectMac()
+                    .map(Object::toString).orElse(NA);
+            String gatewayAddress;
+            String serverIp;
+
+            switch (dhcpServerInfo.getVersion()) {
+                case DHCP_V4:
+                    gatewayAddress = dhcpServerInfo.getDhcpGatewayIp4()
+                            .map(Object::toString).orElse(null);
+                    serverIp = dhcpServerInfo.getDhcpServerIp4()
+                            .map(Object::toString).orElse(NA);
+                    break;
+                case DHCP_V6:
+                    gatewayAddress = dhcpServerInfo.getDhcpGatewayIp6()
+                            .map(Object::toString).orElse(null);
+                    serverIp = dhcpServerInfo.getDhcpServerIp6()
+                            .map(Object::toString).orElse(NA);
+                    break;
+                default:
+                    return;
+            }
+            if (gatewayAddress != null) {
+                print(DHCP_SERVER_GW, connectPoint, serverIp, gatewayAddress, serverMac);
+            } else {
+                print(DHCP_SERVER, connectPoint, serverIp, serverMac);
+            }
+        });
+    }
+
+    private String ip4State(DhcpRecord record) {
+        String nextHopIp = findNextHopIp(IpAddress::isIp4,
+                                         record.nextHop().orElse(null),
+                                         record.vlanId());
+        return ipState(record.ip4Address().map(Object::toString).orElse(NA),
+                       record.ip4Status().map(Object::toString).orElse(NA),
+                       record.directlyConnected(),
+                       nextHopIp);
+    }
+
+    private String ip6State(DhcpRecord record) {
+        String nextHopIp = findNextHopIp6(IpAddress::isIp6,
+                                         record.nextHop().orElse(null),
+                                         record.vlanId());
+
+        if (record.directlyConnected()) {
+            return String.format(STATUS_FMT_V6,
+                    record.ip6Address().map(Object::toString).orElse(NA),
+                    record.addrPrefTime(),
+                    record.getLastIp6Update(),
+                    record.pdPrefix().map(Object::toString).orElse(NA),
+                    record.pdPrefTime(),
+                    record.getLastPdUpdate(),
+                    record.ip6Status().map(Object::toString).orElse(NA));
+        } else {
+            return String.format(STATUS_FMT_V6_NH,
+                    record.ip6Address().map(Object::toString).orElse(NA),
+                    record.addrPrefTime(),
+                    record.getLastIp6Update(),
+                    record.pdPrefix().map(Object::toString).orElse(NA),
+                    record.pdPrefTime(),
+                    record.getLastPdUpdate(),
+                    nextHopIp,
+                    record.ip6Status().map(Object::toString).orElse(NA));
+        }
+    }
+
+    private String ipState(String ipAddress, String status,
+                           boolean directlyConnected,
+                           String nextHopIp) {
+        if (directlyConnected) {
+            return String.format(STATUS_FMT, ipAddress, status);
+        } else {
+            return String.format(STATUS_FMT_NH, ipAddress, nextHopIp, status);
+        }
+    }
+
+    private String findNextHopIp(Predicate<IpAddress> ipFilter, MacAddress nextHopMac, VlanId vlanId) {
+        if (ipFilter == null || nextHopMac == null || vlanId == null) {
+            return NA;
+        }
+
+        Host host = HOST_SERVICE.getHost(HostId.hostId(nextHopMac, vlanId));
+        if (host == null) {
+            return NA;
+        }
+        return host.ipAddresses().stream()
+                .filter(ipFilter)
+                .filter(ip -> !ip.isLinkLocal())
+                .map(Object::toString)
+                .findFirst()
+                .orElse(NA);
+    }
+
+    private String findNextHopIp6(Predicate<IpAddress> ipFilter, MacAddress nextHopMac, VlanId vlanId) {
+        if (ipFilter == null || nextHopMac == null || vlanId == null) {
+            return NA;
+        }
+
+        Host host = HOST_SERVICE.getHost(HostId.hostId(nextHopMac, vlanId));
+        if (host == null) {
+            return NA;
+        }
+        return host.ipAddresses().stream()
+                .filter(ipFilter)
+                .filter(ip -> ip.isLinkLocal())
+                .map(Object::toString)
+                .findFirst()
+                .orElse(NA);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCounterCompleter.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCounterCompleter.java
new file mode 100644
index 0000000..8b024a5
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCounterCompleter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * Dhcp Relay counter completer.
+ */
+public class DhcpRelayCounterCompleter implements Completer {
+
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+        SortedSet<String> strings = delegate.getStrings();
+        strings.add("counter");
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(buffer, cursor, candidates);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayResetCompleter.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayResetCompleter.java
new file mode 100644
index 0000000..3eb4404
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayResetCompleter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * Dhcp Relay reset completer.
+ */
+public class DhcpRelayResetCompleter implements Completer {
+
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+        SortedSet<String> strings = delegate.getStrings();
+        strings.add("reset");
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(buffer, cursor, candidates);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/package-info.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/package-info.java
new file mode 100644
index 0000000..2a983fd
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Command line interface for DHCP relay application.
+ */
+package org.onosproject.dhcprelay.cli;
\ No newline at end of file
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
new file mode 100644
index 0000000..daf97bf
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay.config;
+
+import com.google.common.collect.Lists;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * DHCP Relay Config class for default use case (directly connected hosts).
+ */
+public class DefaultDhcpRelayConfig extends Config<ApplicationId> {
+    public static final String KEY = "default";
+
+    @Override
+    public boolean isValid() {
+        // check if all configs are valid
+        AtomicBoolean valid = new AtomicBoolean(true);
+        array.forEach(config -> valid.compareAndSet(true, DhcpServerConfig.isValid(config)));
+        return valid.get();
+    }
+
+    public List<DhcpServerConfig> dhcpServerConfigs() {
+        List<DhcpServerConfig> configs = Lists.newArrayList();
+        array.forEach(node -> configs.add(new DhcpServerConfig(node)));
+        return configs;
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
new file mode 100644
index 0000000..d60c6b0
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * DHCP server configuration.
+ */
+public class DhcpServerConfig {
+    private final Logger log = getLogger(getClass());
+
+    private static final String DHCP_CONNECT_POINT = "dhcpServerConnectPoint";
+    private static final String DHCP_SERVER_IP = "serverIps";
+    private static final String DHCP_GATEWAY_IP = "gatewayIps";
+    private static final String RELAY_AGENT_IP = "relayAgentIps";
+    private static final String IPV4 = "ipv4";
+    private static final String IPV6 = "ipv6";
+
+    protected ConnectPoint connectPoint;
+    protected Ip4Address serverIp4Addr;
+    protected Ip4Address gatewayIp4Addr;
+    protected Ip6Address serverIp6Addr;
+    protected Ip6Address gatewayIp6Addr;
+    protected Map<DeviceId, Pair<Ip4Address, Ip6Address>> relayAgentIps = Maps.newHashMap();
+
+    protected DhcpServerConfig() {
+        // empty config not allowed here
+    }
+
+    public DhcpServerConfig(JsonNode config) {
+        if (!config.has(DHCP_CONNECT_POINT)) {
+            // connect point doesn't exist
+            throw new IllegalArgumentException("Missing " + DHCP_CONNECT_POINT);
+        }
+        connectPoint = ConnectPoint.deviceConnectPoint(config.path(DHCP_CONNECT_POINT).asText());
+
+        if (!config.has(DHCP_SERVER_IP)) {
+            // server ip doesn't exist
+            throw new IllegalArgumentException("Missing " + DHCP_SERVER_IP);
+        }
+        ArrayNode serverIps = (ArrayNode) config.path(DHCP_SERVER_IP);
+        serverIps.forEach(node -> {
+            if (node.isTextual()) {
+                IpAddress ip = IpAddress.valueOf(node.asText());
+                if (ip.isIp4() && serverIp4Addr == null) {
+                  try {
+                      serverIp4Addr = ip.getIp4Address();
+                  } catch (IllegalArgumentException iae) {
+                      log.warn("Invalid IPv4 address {} found in DHCP server config. Ignored.", ip.toString());
+                  }
+                }
+                if (ip.isIp6() && serverIp6Addr == null) {
+                  try {
+                    serverIp6Addr = ip.getIp6Address();
+                  } catch (IllegalArgumentException iae) {
+                      log.warn("Invalid IPv6 address {} found in DHCP server config. Ignored.", ip.toString());
+                  }
+                }
+            }
+        });
+
+        if (config.has(DHCP_GATEWAY_IP)) {
+            ArrayNode gatewayIps = (ArrayNode) config.path(DHCP_GATEWAY_IP);
+            gatewayIps.forEach(node -> {
+                if (node.isTextual()) {
+                    IpAddress ip = IpAddress.valueOf(node.asText());
+                    if (ip.isIp4() && gatewayIp4Addr == null) {
+                      try {
+                          gatewayIp4Addr = ip.getIp4Address();
+                      } catch (IllegalArgumentException iae) {
+                          log.warn("Invalid IPv4 address {} found in DHCP gateway config. Ignored.", ip.toString());
+                      }
+                    }
+                    if (ip.isIp6() && gatewayIp6Addr == null) {
+                      try {
+                          gatewayIp6Addr = ip.getIp6Address();
+                      } catch (IllegalArgumentException iae) {
+                          log.warn("Invalid IPv6 address {} found in DHCP gateway config. Ignored.", ip.toString());
+                      }
+                    }
+                }
+            });
+        }
+        if (config.has(RELAY_AGENT_IP)) {
+            JsonNode relayAgentIpsNode = config.path(RELAY_AGENT_IP);
+            relayAgentIpsNode.fields().forEachRemaining(e -> {
+                DeviceId deviceId = DeviceId.deviceId(e.getKey());
+                JsonNode ips = e.getValue();
+                Ip4Address ipv4 = null;
+                Ip6Address ipv6 = null;
+                if (ips.has(IPV4)) {
+                    String ipv4Str = ips.get(IPV4).asText();
+                    try {
+                        ipv4 = Ip4Address.valueOf(ipv4Str);
+                    } catch (IllegalArgumentException iae) {
+                        log.warn("Invalid IPv4 address {} found in DHCP relay config. Ignored.", ipv4Str);
+                    }
+                }
+                if (ips.has(IPV6)) {
+                    String ipv6Str = ips.get(IPV6).asText();
+                    try {
+                        ipv6 = Ip6Address.valueOf(ipv6Str);
+                    } catch (IllegalArgumentException iae) {
+                        log.warn("Invalid IPv6 address {} found in DHCP relay config. Ignored.", ipv6Str);
+                    }
+                }
+                relayAgentIps.put(deviceId, Pair.of(ipv4, ipv6));
+            });
+        }
+
+        checkNotNull(connectPoint, "Connect point of DHCP server can't be null");
+        checkState(serverIp4Addr != null || serverIp6Addr != null,
+                   "Should exist at least one server IP for DHCPv4 or DHCPv6");
+
+    }
+
+    /**
+     * Verify a json config is a valid DHCP server config.
+     *
+     * @param jsonConfig the json config
+     * @return true if valid; false otherwise
+     */
+    public static boolean isValid(JsonNode jsonConfig) {
+        return jsonConfig.has(DHCP_CONNECT_POINT) && jsonConfig.has(DHCP_SERVER_IP);
+    }
+
+    /**
+     * Returns the dhcp server connect point.
+     *
+     * @return dhcp server connect point
+     */
+    public Optional<ConnectPoint> getDhcpServerConnectPoint() {
+        return Optional.ofNullable(connectPoint);
+    }
+
+    /**
+     * Returns the IPv4 address of DHCP server.
+     *
+     * @return IPv4 address of server; empty value if not set
+     */
+    public Optional<Ip4Address> getDhcpServerIp4() {
+        return Optional.ofNullable(serverIp4Addr);
+    }
+
+    /**
+     * Returns the optional IPv4 address of dhcp gateway, if configured.
+     * This option is typically used if the dhcp server is not directly attached
+     * to a switch; For example, the dhcp server may be reached via an external
+     * gateway connected to the dhcpserverConnectPoint.
+     *
+     * @return IPv4 address of gateway; empty value if not set
+     */
+    public Optional<Ip4Address> getDhcpGatewayIp4() {
+        return Optional.ofNullable(gatewayIp4Addr);
+    }
+
+    /**
+     * Returns the IPv6 address of DHCP server.
+     *
+     * @return IPv6 address of server ; empty value if not set
+     */
+    public Optional<Ip6Address> getDhcpServerIp6() {
+        return Optional.ofNullable(serverIp6Addr);
+    }
+
+    /**
+     * Returns the optional IPv6 address of dhcp gateway, if configured.
+     * This option is typically used if the dhcp server is not directly attached
+     * to a switch; For example, the dhcp server may be reached via an external
+     * gateway connected to the dhcpserverConnectPoint.
+     *
+     * @return IPv6 address of gateway; empty value if not set
+     */
+    public Optional<Ip6Address> getDhcpGatewayIp6() {
+        return Optional.ofNullable(gatewayIp6Addr);
+    }
+
+    /**
+     * Returns the optional IPv4 address for relay agent for given device,
+     * if configured.
+     * This option is used if we want to replace the giaddr field in DHCPv4
+     * payload.
+     *
+     * @param deviceId the device
+     * @return the giaddr; empty value if not set
+     */
+    public Optional<Ip4Address> getRelayAgentIp4(DeviceId deviceId) {
+        Pair<Ip4Address, Ip6Address> relayAgentIp = relayAgentIps.get(deviceId);
+        if (relayAgentIp == null) {
+            return Optional.empty();
+        }
+        return Optional.ofNullable(relayAgentIp.getLeft());
+    }
+
+    /**
+     * Returns the optional IPv6 address for relay agent for given device,
+     * if configured.
+     * This option is used if we want to replace the link-address field in DHCPv6
+     * payload.
+     *
+     * @param deviceId the device
+     * @return the link-addr; empty value if not set
+     */
+    public Optional<Ip6Address> getRelayAgentIp6(DeviceId deviceId) {
+        Pair<Ip4Address, Ip6Address> relayAgentIp = relayAgentIps.get(deviceId);
+        if (relayAgentIp == null) {
+            return Optional.empty();
+        }
+        return Optional.ofNullable(relayAgentIp.getRight());
+    }
+
+    /**
+     * Gets all relay agent ips and device mapping.
+     *
+     * @return the mapping
+     */
+    public Map<DeviceId, Pair<Ip4Address, Ip6Address>> getRelayAgentIps() {
+        return relayAgentIps;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DhcpServerConfig that = (DhcpServerConfig) o;
+        return Objects.equal(connectPoint, that.connectPoint) &&
+                Objects.equal(serverIp4Addr, that.serverIp4Addr) &&
+                Objects.equal(gatewayIp4Addr, that.gatewayIp4Addr) &&
+                Objects.equal(serverIp6Addr, that.serverIp6Addr) &&
+                Objects.equal(gatewayIp6Addr, that.gatewayIp6Addr) &&
+                Objects.equal(relayAgentIps, that.relayAgentIps);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(connectPoint, serverIp4Addr, gatewayIp4Addr,
+                                serverIp6Addr, gatewayIp6Addr, relayAgentIps);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/EnableDhcpFpmConfig.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/EnableDhcpFpmConfig.java
new file mode 100644
index 0000000..6eb9cf5
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/EnableDhcpFpmConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.config;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+
+/**
+ * Dhcp Fpm Config.
+ */
+public class EnableDhcpFpmConfig extends Config<ApplicationId> {
+    public static final String KEY = "dhcpFpm";
+    private static final String DHCP_FPM_ENABLE = "enabled";
+
+    @Override
+    public boolean isValid() {
+      if (!hasFields(DHCP_FPM_ENABLE)) {
+          return false;
+      }
+      return isBoolean(DHCP_FPM_ENABLE, FieldPresence.OPTIONAL);
+    }
+
+    /**
+     * Returns whether Dhcp Fpm is enabled.
+     *
+     * @return true if enabled, otherwise false
+     */
+    public boolean getDhcpFpmEnable() {
+        return object.path(DHCP_FPM_ENABLE).asBoolean(false);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfig.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfig.java
new file mode 100644
index 0000000..b4b8adb
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfig.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.config;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class IgnoreDhcpConfig extends Config<ApplicationId> {
+    public static final String KEY = "ignoreDhcp";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String VLAN_ID = "vlan";
+
+    @Override
+    public boolean isValid() {
+        AtomicBoolean valid = new AtomicBoolean(true);
+        if (array == null) {
+            return false;
+        }
+        array.forEach(node -> {
+            valid.compareAndSet(true, node.has(DEVICE_ID) && node.has(VLAN_ID));
+        });
+        return valid.get();
+    }
+
+    public Multimap<DeviceId, VlanId> ignoredVlans() {
+        Multimap<DeviceId, VlanId> ignored = ArrayListMultimap.create();
+
+        array.forEach(node -> {
+            DeviceId deviceId = DeviceId.deviceId(node.get(DEVICE_ID).asText());
+            VlanId vlanId = VlanId.vlanId((short) node.get(VLAN_ID).asInt());
+            ignored.put(deviceId, vlanId);
+        });
+
+        return ignored;
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java
new file mode 100644
index 0000000..02e76b2
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.config;
+
+/**
+ * DHCP Relay Config class for indirect use case (indirectly connected hosts).
+ */
+public class IndirectDhcpRelayConfig extends DefaultDhcpRelayConfig {
+    public static final String KEY = "indirect";
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/package-info.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/package-info.java
new file mode 100644
index 0000000..b9ca580
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/config/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ * Configuration utility for DHCP relay app.
+ */
+package org.onosproject.dhcprelay.config;
\ No newline at end of file
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/package-info.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/package-info.java
new file mode 100644
index 0000000..20d1a7a
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-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.
+ */
+
+/**
+ *  DHCP-RELAY application.
+ */
+package org.onosproject.dhcprelay;
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmPrefixStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmPrefixStore.java
new file mode 100644
index 0000000..694b048
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmPrefixStore.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.routing.fpm.api.FpmPrefixStore;
+
+
+
+import org.onlab.packet.IpPrefix;
+import java.util.Optional;
+
+
+
+/**
+ * Interface to store DhcpFpm records.
+ */
+
+public interface DhcpFpmPrefixStore extends FpmPrefixStore {
+
+
+    /**
+     * Add a dhcp fpm record.
+     *
+     * @param prefix the route prefix in the advertisement
+     * @param fpmRecord the route for fpm
+     **/
+    public void addFpmRecord(IpPrefix prefix, FpmRecord fpmRecord);
+
+    /**
+     * Remove a dhcp fpm entry
+     *  and return the removed record; return empty value if not exists.
+     *
+     * @param prefix the route prefix in the advertisement
+     * @return none
+     **/
+    public Optional<FpmRecord> removeFpmRecord(IpPrefix prefix);
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmRecord.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmRecord.java
new file mode 100644
index 0000000..81eadb7
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpFpmRecord.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import java.util.Objects;
+import com.google.common.base.MoreObjects;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A class to define a Dhcp Fpm record.
+ */
+public class DhcpFpmRecord {
+
+    private IpPrefix prefix;
+    private IpAddress nextHop;
+
+    public DhcpFpmRecord(IpPrefix prefix, IpAddress nextHop) {
+        checkNotNull(prefix, "prefix cannot be null");
+        checkNotNull(nextHop, "ipAddress cannot be null");
+
+        this.prefix = prefix;
+        this.nextHop = nextHop;
+    }
+
+    /**
+     * Gets IP prefix of record.
+     *
+     * @return the IP prefix
+     */
+    public IpPrefix ipPrefix() {
+        return prefix;
+    }
+
+    /**
+     * Gets IP address of record.
+     *
+     * @return the IP address
+     */
+    public IpAddress nextHop() {
+        return nextHop;
+    }
+
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(prefix, nextHop);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof DhcpFpmRecord)) {
+            return false;
+        }
+        DhcpFpmRecord that = (DhcpFpmRecord) obj;
+        return Objects.equals(prefix, that.prefix) &&
+                Objects.equals(nextHop, that.nextHop);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("prefix", prefix)
+                .add("ipAddress", nextHop)
+                .toString();
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java
new file mode 100644
index 0000000..f0beff9
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Sets;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A class to record DHCP from DHCP relay application.
+ */
+public class DhcpRecord {
+    private final Set<HostLocation> locations;
+    private final MacAddress macAddress;
+    private final VlanId vlanId;
+    private MacAddress nextHop;
+    // this will hold the potential next hop change in case
+    // of successfull LQ from another NH for a certain IP
+    private MacAddress nextHopTemp;
+
+    private Ip4Address ip4Address;
+    private DHCP.MsgType ip4Status;
+
+    private Ip6Address ip6Address;
+    private IpPrefix pdPrefix;
+    private DHCP6.MsgType ip6Status;
+
+    private long lastSeen;
+    private long lastIp6Update;
+    private long lastPdUpdate;
+
+    private boolean directlyConnected;
+    private long addrPrefTime;
+    private long pdPrefTime;
+    private DhcpRelayCounters v6Counters;
+
+
+    /**
+     * Creates a DHCP record for a host (mac + vlan).
+     *
+     * @param hostId the host id for the host
+     */
+    public DhcpRecord(HostId hostId) {
+        checkNotNull(hostId, "Host id can't be null");
+
+        this.locations = Sets.newHashSet();
+        this.macAddress = hostId.mac();
+        this.vlanId = hostId.vlanId();
+        this.lastSeen = System.currentTimeMillis();
+        this.directlyConnected = false;
+        this.v6Counters = new DhcpRelayCounters();
+    }
+
+    /**
+     * Gets host locations.
+     *
+     * @return the locations of host
+     */
+    public Set<HostLocation> locations() {
+        return locations;
+    }
+
+    /**
+     * Adds a location to record.
+     *
+     * @param location the location
+     * @return the DHCP record
+     */
+    public DhcpRecord addLocation(HostLocation location) {
+        if (locations.contains(location)) {
+            locations.remove(location);
+        }
+        locations.add(location);
+        return this;
+    }
+
+    /**
+     * Removes a location from record.
+     *
+     * @param location the location
+     * @return the DHCP record
+     */
+    public DhcpRecord removeLocation(HostLocation location) {
+        locations.remove(location);
+        return this;
+    }
+
+    /**
+     * Gets host mac address of this record.
+     *
+     * @return the host mac address
+     */
+    public MacAddress macAddress() {
+        return macAddress;
+    }
+
+    /**
+     * Gets host vlan id of this record.
+     *
+     * @return the host id.
+     */
+    public VlanId vlanId() {
+        return vlanId;
+    }
+
+    /**
+     * Gets IPv4 address which assigned to the host.
+     *
+     * @return the IP address assigned to the host
+     */
+    public Optional<Ip4Address> ip4Address() {
+        return Optional.ofNullable(ip4Address);
+    }
+
+    /**
+     * Sets IPv4 address.
+     *
+     * @param ip4Address the IPv4 address
+     * @return the DHCP record
+     */
+    public DhcpRecord ip4Address(Ip4Address ip4Address) {
+        this.ip4Address = ip4Address;
+        return this;
+    }
+
+    /**
+     * Gets IPv6 address which assigned to the host.
+     *
+     * @return the IP address assigned to the host
+     */
+    public Optional<Ip6Address> ip6Address() {
+        return Optional.ofNullable(ip6Address);
+    }
+
+    /**
+     * Sets IPv6 address.
+     *
+     * @param ip6Address the IPv6 address
+     * @return the DHCP record
+     */
+    public DhcpRecord ip6Address(Ip6Address ip6Address) {
+        this.ip6Address = ip6Address;
+        return this;
+    }
+
+    /**
+     * Gets IPv6 PD address which assigned to the host.
+     *
+     * @return the PD IP address assigned to the host
+     */
+    public Optional<IpPrefix> pdPrefix() {
+        return Optional.ofNullable(pdPrefix);
+    }
+
+    /**
+     * Sets IPv6 PD address.
+     *
+     * @param pdPrefix the IPv6 PD address
+     * @return the DHCP record
+     */
+    public DhcpRecord pdPrefix(IpPrefix pdPrefix) {
+        this.pdPrefix = pdPrefix;
+        return this;
+    }
+
+    /**
+     * Gets the latest time this record updated.
+     *
+     * @return the last time host send or receive DHCP packet
+     */
+    public long lastSeen() {
+        return lastSeen;
+    }
+
+    /**
+     * Updates the update time of this record.
+     *
+     * @return the DHCP record
+     */
+    public DhcpRecord updateLastSeen() {
+        lastSeen = System.currentTimeMillis();
+        return this;
+    }
+
+    /**
+     * Gets the latest time this record updated with ip6 Address.
+     *
+     * @return the last time received DHCP packet provide ip6 Address
+     */
+    public long getLastIp6Update() {
+        return lastIp6Update;
+    }
+
+    /**
+     * Updates the update time of this record is given ip6 Address.
+     *
+     * @return the DHCP record
+     */
+    public DhcpRecord updateLastIp6Update() {
+        lastIp6Update = System.currentTimeMillis();
+        return this;
+    }
+
+    /**
+     * Gets the latest time this record updated with pd Prefix.
+     *
+     * @return the last time received DHCP packet provide pd Prefix
+     */
+    public long getLastPdUpdate() {
+        return lastPdUpdate;
+    }
+
+    /**
+     * Updates the update time of this record is given pd Prefix.
+     *
+     * @return the DHCP record
+     */
+    public DhcpRecord updateLastPdUpdate() {
+        lastPdUpdate = System.currentTimeMillis();
+        return this;
+    }
+
+    /**
+     * Gets the IP Address preferred time for this record.
+     *
+     * @return the preferred lease time for this ip address
+     */
+    public long addrPrefTime() {
+        return addrPrefTime;
+    }
+
+    /**
+     * Updates the IP Address preferred time of this record.
+     *
+     * @param prefTime preferred liftme
+     * @return the DHCP record
+     */
+    public DhcpRecord updateAddrPrefTime(long prefTime) {
+        addrPrefTime = prefTime;
+        return this;
+    }
+
+    /**
+     * Gets the PD Prefix preferred time for this record.
+     *
+     * @return the preferred lease time for this PD prefix
+     */
+    public long pdPrefTime() {
+        return pdPrefTime;
+    }
+
+    /**
+     * Updates the PD Prefix preferred time of this record.
+     *
+     * @param prefTime preferred liftme
+     * @return the DHCP record
+     */
+    public DhcpRecord updatePdPrefTime(long prefTime) {
+        pdPrefTime = prefTime;
+        return this;
+    }
+
+    /**
+     * Indicated that the host is direct connected to the network or not.
+     *
+     * @return true if the host is directly connected to the network; false otherwise
+     */
+    public boolean directlyConnected() {
+        return directlyConnected;
+    }
+
+    /**
+     * Sets the flag which indicated that the host is directly connected to the
+     * network.
+     *
+     * @param directlyConnected the flag to set
+     * @return the DHCP record
+     */
+    public DhcpRecord setDirectlyConnected(boolean directlyConnected) {
+        this.directlyConnected = directlyConnected;
+        return this;
+    }
+
+    /**
+     * Gets the DHCPv4 status of this record.
+     *
+     * @return the DHCPv4 status; empty if not exists
+     */
+    public Optional<DHCP.MsgType> ip4Status() {
+        return Optional.ofNullable(ip4Status);
+    }
+
+    /**
+     * Sets status of DHCPv4.
+     *
+     * @param ip4Status the status
+     * @return the DHCP record
+     */
+    public DhcpRecord ip4Status(DHCP.MsgType ip4Status) {
+        this.ip4Status = ip4Status;
+        return this;
+    }
+
+    /**
+     * Gets the DHCPv6 status of this record.
+     *
+     * @return the DHCPv6 status; empty if not exists
+     */
+    public Optional<DHCP6.MsgType> ip6Status() {
+        return Optional.ofNullable(ip6Status);
+    }
+
+    /**
+     * Sets status of DHCPv6.
+     *
+     * @param ip6Status the DHCPv6 status
+     * @return the DHCP record
+     */
+    public DhcpRecord ip6Status(DHCP6.MsgType ip6Status) {
+        this.ip6Status = ip6Status;
+        return this;
+    }
+
+    /**
+     * Gets nextHop mac address.
+     *
+     * @return the IPv4 nextHop mac address; empty if not exists
+     */
+    public Optional<MacAddress> nextHop() {
+        return Optional.ofNullable(nextHop);
+    }
+
+    /**
+     * Sets nextHop mac address.
+     *
+     * @param nextHop the IPv4 nextHop mac address
+     * @return the DHCP record
+     */
+    public DhcpRecord nextHop(MacAddress nextHop) {
+        this.nextHop = nextHop;
+        return this;
+    }
+
+    /**
+     * Gets temporary nextHop mac address.
+     *
+     * @return the IPv4 nextHop mac address; empty if not exists
+     */
+    public Optional<MacAddress> nextHopTemp() {
+        return Optional.ofNullable(nextHopTemp);
+    }
+
+    /**
+     * Sets temporary nextHop mac address.
+     *
+     * @param nextHop the IPv4 nextHop mac address
+     * @return the DHCP record
+     */
+    public DhcpRecord nextHopTemp(MacAddress nextHop) {
+        this.nextHopTemp = nextHop;
+        return this;
+    }
+
+    /**
+     * Gets dhcp relay counters.
+     *
+     * @return the counter object
+     */
+    public DhcpRelayCounters getV6Counters() {
+        return v6Counters;
+    }
+
+    /**
+     * Clone this DHCP record.
+     *
+     * @return the DHCP record which cloned
+     */
+    public DhcpRecord clone() {
+        DhcpRecord newRecord = new DhcpRecord(HostId.hostId(macAddress, vlanId));
+        locations.forEach(newRecord::addLocation);
+        newRecord.directlyConnected = directlyConnected;
+        newRecord.nextHop = nextHop;
+        newRecord.nextHopTemp = nextHopTemp;
+        newRecord.ip4Address = ip4Address;
+        newRecord.ip4Status = ip4Status;
+        newRecord.ip6Address = ip6Address;
+        newRecord.pdPrefix = pdPrefix;
+        newRecord.ip6Status = ip6Status;
+        newRecord.lastSeen = lastSeen;
+        newRecord.lastIp6Update = lastIp6Update;
+        newRecord.lastPdUpdate = lastPdUpdate;
+        newRecord.addrPrefTime = addrPrefTime;
+        newRecord.pdPrefTime = pdPrefTime;
+        newRecord.v6Counters = v6Counters;
+        return newRecord;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(locations, macAddress, vlanId, ip4Address, ip4Status,
+                nextHop, nextHopTemp, ip6Address, pdPrefix, ip6Status, lastSeen,
+                lastIp6Update, lastPdUpdate, addrPrefTime, pdPrefTime, v6Counters);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof DhcpRecord)) {
+            return false;
+        }
+        DhcpRecord that = (DhcpRecord) obj;
+        return Objects.equals(locations, that.locations) &&
+                Objects.equals(macAddress, that.macAddress) &&
+                Objects.equals(vlanId, that.vlanId) &&
+                Objects.equals(ip4Address, that.ip4Address) &&
+                Objects.equals(ip4Status, that.ip4Status) &&
+                Objects.equals(nextHop, that.nextHop) &&
+                Objects.equals(nextHopTemp, that.nextHopTemp) &&
+                Objects.equals(ip6Address, that.ip6Address) &&
+                Objects.equals(pdPrefix, that.pdPrefix) &&
+                Objects.equals(ip6Status, that.ip6Status) &&
+                Objects.equals(lastSeen, that.lastSeen) &&
+                Objects.equals(lastIp6Update, that.lastIp6Update) &&
+                Objects.equals(lastPdUpdate, that.lastPdUpdate) &&
+                Objects.equals(directlyConnected, that.directlyConnected) &&
+                Objects.equals(addrPrefTime, that.addrPrefTime) &&
+                Objects.equals(pdPrefTime, that.pdPrefTime) &&
+                Objects.equals(v6Counters, that.v6Counters);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("locations", locations)
+                .add("macAddress", macAddress)
+                .add("vlanId", vlanId)
+                .add("ip4Address", ip4Address)
+                .add("ip4State", ip4Status)
+                .add("nextHop", nextHop)
+                .add("nextHopTemp", nextHopTemp)
+                .add("ip6Address", ip6Address)
+                .add("pdPrefix", pdPrefix)
+                .add("ip6State", ip6Status)
+                .add("lastSeen", lastSeen)
+                .add("lastIp6Update", lastIp6Update)
+                .add("lastPdUpdate", lastPdUpdate)
+                .add("directlyConnected", directlyConnected)
+                .add("addPrefTime", addrPrefTime)
+                .add("pdPrefTime", pdPrefTime)
+                .add("v6Counters", v6Counters)
+                .toString();
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCounters.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCounters.java
new file mode 100644
index 0000000..2a69c21
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCounters.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.dhcprelay.store;
+
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class DhcpRelayCounters {
+    // common counters
+
+    // IpV6 specific counters
+    public static final String SOLICIT = "SOLICIT";
+    public static final String ADVERTISE = "ADVERTISE";
+    public static final String REQUEST = "REQUEST";
+    public static final String CONFIRM = "CONFIRM";
+    public static final String RENEW = "RENEW";
+    public static final String REBIND = "REBIND";
+    public static final String REPLY = "REPLY";
+    public static final String RELEASE = "RELEASE";
+    public static final String DECLINE = "DECLINE";
+    public static final String RECONFIGURE = "RECONFIGURE";
+    public static final String INFORMATION_REQUEST = "INFORMATION_REQUEST";
+    public static final String RELAY_FORW = "RELAY_FORW";
+    public static final String RELAY_REPL = "RELAY_REPL";
+
+    public static final String NO_LINKLOCAL_GW = "No link-local in Gateway";
+    public static final String NO_LINKLOCAL_FAIL = "No link-local in CLIENT_ID";
+    public static final String NO_CLIENTID_FAIL = "No CLIENT_ID Found";
+    public static final String SVR_CFG_FAIL = "Server Config Error";
+    public static final String OPTION_MISSING_FAIL = "Expected Option missing";
+    public static final String NO_MATCHING_INTF = "No matching Inteface";
+    public static final String NO_CLIENT_INTF_MAC = "No client interface mac";
+    public static final String NO_SERVER_INFO = "No Server info found";
+    public static final String NO_SERVER_IP6ADDR = "No Server ip6 addr found";
+
+    public static final String INVALID_PACKET = "Invalid Packet";
+
+    public static final Set<String> SUPPORTED_COUNTERS =
+            ImmutableSet.of(SOLICIT, ADVERTISE, REQUEST, CONFIRM, RENEW,
+                    REBIND, REPLY, RELEASE, DECLINE, RECONFIGURE,
+                    INFORMATION_REQUEST, RELAY_FORW, RELAY_REPL,
+                    NO_LINKLOCAL_GW, NO_LINKLOCAL_FAIL, NO_CLIENTID_FAIL, SVR_CFG_FAIL, OPTION_MISSING_FAIL,
+                    NO_MATCHING_INTF, NO_CLIENT_INTF_MAC, NO_SERVER_INFO, NO_SERVER_IP6ADDR,
+                    INVALID_PACKET);
+
+    // TODO Use AtomicInteger for the counters
+    private Map<String, Integer> countersMap = new ConcurrentHashMap<>();
+    public long lastUpdate;
+
+    public void resetCounters() {
+        countersMap.forEach((name, value) -> {
+            countersMap.put(name, 0);
+        });
+    }
+    public boolean incrementCounter(String name) {
+        boolean counterValid = false;
+        if (SUPPORTED_COUNTERS.contains(name)) {
+            Integer counter = countersMap.get(name);
+            if (counter != null) {
+                counter = counter + 1;
+                countersMap.put(name, counter);
+            } else {
+                // this is the first time
+                countersMap.put(name, 1);
+            }
+            lastUpdate = System.currentTimeMillis();
+            counterValid = true;
+        }
+        return counterValid;
+    }
+    public Map<String, Integer> getCounters() {
+        return countersMap;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(countersMap, lastUpdate);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof DhcpRelayCounters)) {
+            return false;
+        }
+        DhcpRelayCounters that = (DhcpRelayCounters) obj;
+        return Objects.equals(countersMap, that.countersMap) &&
+                Objects.equals(lastUpdate, that.lastUpdate);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCountersStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCountersStore.java
new file mode 100644
index 0000000..3534871
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayCountersStore.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+
+import java.util.Optional;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Stores DHCP Relay Counters records.
+ */
+public interface DhcpRelayCountersStore {
+
+    /**
+     * Creates or updates DHCP record for specific host id (mac + vlan).
+     *
+     * @param counterClass class of counters (direct, indirect, global)
+     * @param counterName name of counter
+     */
+    void incrementCounter(String counterClass, String counterName);
+
+    /**
+     * Gets the DHCP counter record for a given counter class.
+     *
+     * @param counterClass the class of counters (direct, indirect, global)
+     * @return the DHCP counter record for a given counter class; empty if record not exists
+     */
+    Optional<DhcpRelayCounters> getCounters(String counterClass);
+
+    /**
+     * Gets all classes of DHCP counters record from store.
+     *
+     * @return all classes of DHCP counters records from store
+     */
+    Set<Map.Entry<String, DhcpRelayCounters>> getAllCounters();
+
+    /**
+     * Resets counter value for a given counter class.
+     *
+     * @param counterClass the class of counters (direct, indirect, global)
+     */
+    void resetCounters(String counterClass);
+
+    /**
+     * Resets counter value for a all counter classes.
+     *
+     */
+    void resetAllCounters();
+
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStore.java
new file mode 100644
index 0000000..e26d99e
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStore.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import org.onosproject.net.HostId;
+import org.onosproject.store.Store;
+import org.onosproject.store.StoreDelegate;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Stores DHCP records which relay-ed by DHCP relay application.
+ */
+public interface DhcpRelayStore extends Store<DhcpRelayStoreEvent, StoreDelegate<DhcpRelayStoreEvent>> {
+
+    /**
+     * Creates or updates DHCP record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @param dhcpRecord the DHCP record to update
+     */
+    void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord);
+
+    /**
+     * Gets DHCP record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @return the DHCP record of the host; empty if record not exists
+     */
+    Optional<DhcpRecord> getDhcpRecord(HostId hostId);
+
+    /**
+     * Gets all DHCP records from store.
+     *
+     * @return all DHCP records from store
+     */
+    Collection<DhcpRecord> getDhcpRecords();
+
+    /**
+     * Removes record for specific host id (mac + vlan).
+     *
+     * @param hostId the id of host
+     * @return the DHCP record of the host; empty if record not exists
+     */
+    Optional<DhcpRecord> removeDhcpRecord(HostId hostId);
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java
new file mode 100644
index 0000000..03f8b6a
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DhcpRelayStoreEvent.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Event class for DHCP relay store.
+ */
+public class DhcpRelayStoreEvent extends AbstractEvent<DhcpRelayStoreEvent.Type, DhcpRecord> {
+
+    /**
+     * Types of the event.
+     */
+    public enum Type {
+        /**
+         * A DHCP record has been created or updated.
+         */
+        UPDATED,
+
+        /**
+         * A DHCP record has been removed.
+         */
+        REMOVED
+    }
+
+    /**
+     * Creates a DHCP relay store event by given information.
+     *
+     * @param type the type of event
+     * @param subject the DHCP record of this event
+     */
+    public DhcpRelayStoreEvent(Type type, DhcpRecord subject) {
+        super(type, subject);
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayCountersStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayCountersStore.java
new file mode 100644
index 0000000..4b7b26c
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayCountersStore.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay.store;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.onosproject.store.serializers.KryoNamespaces;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import org.onosproject.store.service.Versioned;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Component(immediate = true)
+@Service
+public class DistributedDhcpRelayCountersStore implements DhcpRelayCountersStore {
+    private static final KryoNamespace.Builder APP_KYRO = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(DhcpRelayCounters.class);
+
+    private Logger log = LoggerFactory.getLogger(getClass());
+    private ConsistentMap<String, DhcpRelayCounters> counters;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+
+    @Activate
+    protected void activated() {
+        ApplicationId appId = coreService.getAppId("org.onosproject.Dhcp6HandlerImpl");
+        counters = storageService.<String, DhcpRelayCounters>consistentMapBuilder()
+                .withSerializer(Serializer.using(APP_KYRO.build()))
+                .withName("Dhcp-Relay-Counters")
+                .withApplicationId(appId)
+                .withPurgeOnUninstall()
+                .build();
+    }
+
+    @Deactivate
+    protected void deactivated() {
+        counters.destroy().join();
+    }
+    @Override
+    public void incrementCounter(String coutnerClass, String counterName) {
+        DhcpRelayCounters countersRecord;
+
+        Versioned<DhcpRelayCounters> vCounters = counters.get(coutnerClass);
+        if (vCounters == null) {
+            countersRecord = new DhcpRelayCounters();
+        } else {
+            countersRecord = vCounters.value();
+        }
+        countersRecord.incrementCounter(counterName);
+        counters.put(coutnerClass, countersRecord);
+    }
+
+    @Override
+    public Set<Map.Entry<String, DhcpRelayCounters>> getAllCounters() {
+        final Set<Map.Entry<String, DhcpRelayCounters>> result =
+                new HashSet<Map.Entry<String, DhcpRelayCounters>>();
+        Set<Map.Entry<String, Versioned<DhcpRelayCounters>>> tmpCounters = counters.entrySet();
+        tmpCounters.forEach(entry -> {
+            String key = entry.getKey();
+            DhcpRelayCounters value = entry.getValue().value();
+            ConcurrentHashMap<String, DhcpRelayCounters> newMap = new ConcurrentHashMap();
+            newMap.put(key, value);
+
+            for (Map.Entry m: newMap.entrySet()) {
+                result.add(m);
+            }
+        });
+        return  result;
+    }
+    @Override
+    public Optional<DhcpRelayCounters> getCounters(String counterClass) {
+        DhcpRelayCounters countersRecord;
+        checkNotNull(counterClass, "counter class can't be null");
+        Versioned<DhcpRelayCounters> vCounters = counters.get(counterClass);
+        if (vCounters == null) {
+            return Optional.empty();
+        }
+        return Optional.of(vCounters.value());
+    }
+    @Override
+    public void resetAllCounters() {
+        counters.clear();
+    }
+
+    @Override
+    public void resetCounters(String counterClass) {
+        checkNotNull(counterClass, "counter class can't be null");
+        DhcpRelayCounters countersRecord = counters.get(counterClass).value();
+        countersRecord.resetCounters();
+        counters.put(counterClass, countersRecord);
+    }
+
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
new file mode 100644
index 0000000..884d9cc
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+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.DHCP;
+import org.onlab.packet.DHCP6;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.HostId;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Distributed DHCP relay store.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedDhcpRelayStore implements DhcpRelayStore {
+    private static final KryoNamespace APP_KRYO = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(DhcpRecord.class)
+            .register(DHCP.MsgType.class)
+            .register(DHCP6.MsgType.class)
+            .register(DhcpRelayCounters.class)
+            .build();
+
+    private Logger log = getLogger(getClass());
+    private StoreDelegate<DhcpRelayStoreEvent> delegate;
+    private EventuallyConsistentMap<HostId, DhcpRecord> dhcpRecords;
+    private EventuallyConsistentMapListener<HostId, DhcpRecord> listener;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Activate
+    protected void activated() {
+        dhcpRecords = storageService.<HostId, DhcpRecord>eventuallyConsistentMapBuilder()
+                .withName("DHCP-Relay-Records")
+                .withTimestampProvider((hostId, record) -> {
+                    if (record != null) {
+                        return new WallClockTimestamp(record.lastSeen());
+                    } else {
+                        return new WallClockTimestamp();
+                    }
+                })
+                .withSerializer(APP_KRYO)
+                .build();
+        listener = new InternalMapListener();
+        dhcpRecords.addListener(listener);
+    }
+
+    @Deactivate
+    protected void deactivated() {
+        dhcpRecords.removeListener(listener);
+        dhcpRecords.destroy().join();
+    }
+
+    @Override
+    public void setDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+        checkNotNull(delegate, "Delegate can't be null");
+        this.delegate = delegate;
+    }
+
+    @Override
+    public void unsetDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+        this.delegate = null;
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return delegate != null;
+    }
+
+    @Override
+    public void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord) {
+        checkNotNull(hostId, "Host id can't be null");
+        checkNotNull(dhcpRecord, "DHCP record can't be null");
+        dhcpRecords.put(hostId, dhcpRecord);
+    }
+
+    @Override
+    public Optional<DhcpRecord> getDhcpRecord(HostId hostId) {
+        checkNotNull(hostId, "Host id can't be null");
+        return Optional.ofNullable(dhcpRecords.get(hostId));
+    }
+
+    @Override
+    public Collection<DhcpRecord> getDhcpRecords() {
+        return dhcpRecords.values();
+    }
+
+    @Override
+    public Optional<DhcpRecord> removeDhcpRecord(HostId hostId) {
+        checkNotNull(hostId, "Host id can't be null");
+        return Optional.ofNullable(dhcpRecords.remove(hostId));
+    }
+
+    /**
+     * Internal map listener for DHCP records map.
+     */
+    private class InternalMapListener implements EventuallyConsistentMapListener<HostId, DhcpRecord> {
+        @Override
+        public void event(EventuallyConsistentMapEvent<HostId, DhcpRecord> event) {
+            DhcpRelayStoreEvent.Type eventType;
+            switch (event.type()) {
+                case PUT:
+                    eventType = DhcpRelayStoreEvent.Type.UPDATED;
+                    break;
+                case REMOVE:
+                    eventType = DhcpRelayStoreEvent.Type.REMOVED;
+                    break;
+                default:
+                    log.warn("Unknown event type {}", event.type());
+                    return;
+            }
+            if (delegate != null) {
+                delegate.notify(new DhcpRelayStoreEvent(eventType, event.value()));
+            }
+        }
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedFpmPrefixStore.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedFpmPrefixStore.java
new file mode 100644
index 0000000..bc95d0b
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/DistributedFpmPrefixStore.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.Property;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.store.StoreDelegate;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.routing.fpm.api.FpmRecord;
+import org.onosproject.routing.fpm.api.FpmPrefixStoreEvent;
+
+
+
+
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Optional;
+
+
+
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Persistent Fpm Prefix Store with Listener.
+ */
+@Component(immediate = true)
+@Property(name = "fpm_type", value = "DHCP")
+@Service
+public class DistributedFpmPrefixStore implements DhcpFpmPrefixStore {
+
+    private static final KryoNamespace APP_KRYO = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(FpmRecord.class)
+            .register(FpmRecord.Type.class)
+            .build();
+
+    private Logger log = getLogger(getClass());
+    private StoreDelegate<FpmPrefixStoreEvent> delegate;
+    private EventuallyConsistentMap<IpPrefix, FpmRecord> dhcpFpmRecords;
+    private EventuallyConsistentMapListener<IpPrefix, FpmRecord> listener;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Activate
+    protected void activated() {
+        dhcpFpmRecords = storageService.<IpPrefix, FpmRecord>eventuallyConsistentMapBuilder()
+                .withName("DHCP-FPM-Records")
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .withSerializer(APP_KRYO)
+                .withPersistence()
+                .build();
+        listener = new InternalMapListener();
+        dhcpFpmRecords.addListener(listener);
+    }
+
+    @Deactivate
+    protected void deactivated() {
+        dhcpFpmRecords.removeListener(listener);
+        dhcpFpmRecords.destroy().join();
+    }
+
+    @Override
+    public void setDelegate(StoreDelegate<FpmPrefixStoreEvent> delegate) {
+        checkNotNull(delegate, "Delegate can't be null");
+        this.delegate = delegate;
+    }
+
+    @Override
+    public void unsetDelegate(StoreDelegate<FpmPrefixStoreEvent> delegate) {
+        this.delegate = null;
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return delegate != null;
+    }
+
+    @Override
+    public Optional<FpmRecord> getFpmRecord(IpPrefix prefix) {
+        checkNotNull(prefix, "Prefix can't be null");
+        return Optional.ofNullable(dhcpFpmRecords.get(prefix));
+    }
+
+    @Override
+    public Collection<FpmRecord> getFpmRecords() {
+        return dhcpFpmRecords.values();
+    }
+
+    /**
+     * Add a dhcp fpm entry.
+     *
+     * @param prefix the route prefix in the advertisement
+     * @param fpmRecord the route for fpm
+     **/
+    @Override
+    public void addFpmRecord(IpPrefix prefix, FpmRecord fpmRecord) {
+        checkNotNull(prefix, "Prefix can't be null");
+        checkNotNull(fpmRecord, "Fpm record can't be null");
+        dhcpFpmRecords.put(prefix, fpmRecord);
+    }
+
+    /**
+     * Remove a dhcp fpm entry.
+     *
+     * @param prefix the route prefix in the advertisement
+     * @return none
+     **/
+    @Override
+    public Optional<FpmRecord> removeFpmRecord(IpPrefix prefix) {
+        checkNotNull(prefix, "Prefix can't be null");
+        return Optional.ofNullable(dhcpFpmRecords.remove(prefix));
+    }
+
+    /**
+     * Internal map listener for Fpm records map.
+     */
+    private class InternalMapListener implements EventuallyConsistentMapListener<IpPrefix, FpmRecord> {
+        @Override
+        public void event(EventuallyConsistentMapEvent<IpPrefix, FpmRecord> event) {
+            FpmPrefixStoreEvent.Type eventType;
+            switch (event.type()) {
+                case PUT:
+                    eventType = FpmPrefixStoreEvent.Type.ADD;
+                    break;
+                case REMOVE:
+                    eventType = FpmPrefixStoreEvent.Type.REMOVE;
+                    break;
+                default:
+                    log.warn("Unknown event type {}", event.type());
+                    return;
+            }
+            if (delegate != null) {
+                delegate.notify(new FpmPrefixStoreEvent(eventType, event.value()));
+            }
+        }
+    }
+}
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/package-info.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/package-info.java
new file mode 100644
index 0000000..105854f
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/store/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Store of DHCP relay application.
+ */
+package org.onosproject.dhcprelay.store;
\ No newline at end of file
diff --git a/apps/dhcprelay/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/dhcprelay/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..c0a4b6f
--- /dev/null
+++ b/apps/dhcprelay/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,44 @@
+<!--
+  ~ Copyright 2014-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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.dhcprelay.cli.DhcpRelayCommand"/>
+            <completers>
+                <ref component-id="dhcpRelayCounterCompleter"/>
+                <ref component-id="dhcpRelayResetCompleter"/>
+            </completers>
+        </command>
+        <command>
+            <action class="org.onosproject.dhcprelay.cli.DhcpFpmRoutesCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.dhcprelay.cli.DhcpFpmAddCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.dhcprelay.cli.DhcpFpmDeleteCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.dhcprelay.cli.DhcpRelayAggCountersCommand"/>
+            <completers>
+                <ref component-id="dhcpRelayResetCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+    <bean id="dhcpRelayCounterCompleter" class="org.onosproject.dhcprelay.cli.DhcpRelayCounterCompleter"/>
+    <bean id="dhcpRelayResetCompleter" class="org.onosproject.dhcprelay.cli.DhcpRelayResetCompleter"/>
+</blueprint>
diff --git a/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
new file mode 100644
index 0000000..9d86606
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/DhcpRelayManagerTest.java
@@ -0,0 +1,1573 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Streams;
+import com.google.common.io.Resources;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.lang3.tuple.Pair;
+import org.easymock.Capture;
+import org.easymock.CaptureType;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.ARP;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DeserializationException;
+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;
+import org.onlab.packet.VlanId;
+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.onlab.packet.dhcp.Dhcp6ClientIdOption;
+import org.onlab.packet.dhcp.Dhcp6Duid;
+import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.dhcprelay.store.DhcpRecord;
+import org.onosproject.dhcprelay.store.DhcpRelayStoreEvent;
+import org.onosproject.dhcprelay.store.DhcpRelayCounters;
+import org.onosproject.dhcprelay.store.DhcpRelayCountersStore;
+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.config.DefaultDhcpRelayConfig;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
+import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
+import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceServiceAdapter;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteStoreAdapter;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketContextAdapter;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.store.StoreDelegate;
+
+
+
+
+import org.osgi.service.component.ComponentContext;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.IPv6;
+
+import java.io.IOException;
+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;
+import java.util.stream.Collectors;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+import static org.onosproject.dhcprelay.DhcpRelayManager.DHCP_RELAY_APP;
+
+public class DhcpRelayManagerTest {
+    private static final short VLAN_LEN = 2;
+    private static final short SEPARATOR_LEN = 1;
+    private static final String CONFIG_FILE_PATH = "dhcp-relay.json";
+    private static final DeviceId DEV_1_ID = DeviceId.deviceId("of:0000000000000001");
+    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 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");
+    private static final MacAddress CLIENT_IFACE_MAC = MacAddress.valueOf("00:00:00:00:11:01");
+    private static final HostLocation CLIENT_LOCATION = new HostLocation(CLIENT_CP, 0);
+    private static final HostId CLIENT_HOST_ID = HostId.hostId(CLIENT_MAC, CLIENT_VLAN);
+    private static final Ip6Address CLIENT_LL_IP_V6 = Ip6Address.valueOf("fe80::200:00ff:fe00:0001");
+    private static final Host EXISTS_HOST = new DefaultHost(Dhcp4HandlerImpl.PROVIDER_ID,
+                                                            CLIENT_HOST_ID, CLIENT_MAC, CLIENT_VLAN,
+                                                            CLIENT_LOCATION, ImmutableSet.of(CLIENT_LL_IP_V6));
+    private static final Interface CLIENT_INTERFACE = createInterface("C1",
+                                                                      CLIENT_CP,
+                                                                      INTERFACE_IPS,
+                                                                      CLIENT_IFACE_MAC,
+                                                                      CLIENT_VLAN,
+                                                                      null);
+
+
+
+    // Dual homing test
+    private static final ConnectPoint CLIENT_DH_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/3");
+    private static final HostLocation CLIENT_DH_LOCATION = new HostLocation(CLIENT_DH_CP, 0);
+    private static final Interface CLIENT_DH_INTERFACE = createInterface("C1-DH",
+                                                                         CLIENT_DH_CP,
+                                                                         INTERFACE_IPS,
+                                                                         CLIENT_IFACE_MAC,
+                                                                         CLIENT_VLAN,
+                                                                         null);
+
+
+    // DHCP client 2 (will send with option 82, so the vlan should equals to vlan from server)
+    private static final MacAddress CLIENT2_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId CLIENT2_VLAN = VlanId.NONE;
+    private static final VlanId CLIENT2_VLAN_NATIVE = VlanId.vlanId("20");
+    private static final ConnectPoint CLIENT2_CP = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+    private static final MacAddress CLIENT2_IFACE_MAC = MacAddress.valueOf("00:00:00:00:11:01");
+    private static final Interface CLIENT2_INTERFACE = createInterface("C2",
+                                                                       CLIENT2_CP,
+                                                                       INTERFACE_IPS,
+                                                                       CLIENT2_IFACE_MAC,
+                                                                       CLIENT2_VLAN,
+                                                                       CLIENT2_VLAN_NATIVE);
+    private static final VlanId CLIENT_BOGUS_VLAN = VlanId.vlanId("108");
+
+    // Outer relay information
+    private static final Ip4Address OUTER_RELAY_IP = Ip4Address.valueOf("10.0.6.253");
+    private static final Ip6Address OUTER_RELAY_IP_V6 = Ip6Address.valueOf("2001:db8:1::4");
+    private static final Ip6Address OUTER_RELAY_LL_IP_V6 = Ip6Address.valueOf("fe80::200:0102:0304:0501");
+    private static final Set<IpAddress> OUTER_RELAY_IPS = ImmutableSet.of(OUTER_RELAY_IP,
+            OUTER_RELAY_IP_V6,
+            OUTER_RELAY_LL_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");
+    private static final HostLocation OUTER_REPLAY_HL = new HostLocation(OUTER_RELAY_CP, 0);
+    private static final HostId OUTER_RELAY_HOST_ID = HostId.hostId(OUTER_RELAY_MAC, OUTER_RELAY_VLAN);
+    private static final Host OUTER_RELAY_HOST = new DefaultHost(Dhcp4HandlerImpl.PROVIDER_ID,
+                                                                 OUTER_RELAY_HOST_ID,
+                                                                 OUTER_RELAY_MAC,
+                                                                 OUTER_RELAY_VLAN,
+                                                                 OUTER_REPLAY_HL,
+                                                                 OUTER_RELAY_IPS);
+
+    // DHCP Server
+    private static final MacAddress SERVER_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId SERVER_VLAN = VlanId.NONE;
+    private static final VlanId SERVER_VLAN_NATIVE = VlanId.vlanId("10");
+    private static final ConnectPoint SERVER_CONNECT_POINT =
+            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 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(Dhcp4HandlerImpl.PROVIDER_ID,
+                                                            SERVER_HOST_ID,
+                                                            SERVER_MAC,
+                                                            SERVER_VLAN,
+                                                            SERVER_LOCATION,
+                                                            DHCP_SERVER_IPS);
+    private static final MacAddress SERVER_IFACE_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final Interface SERVER_INTERFACE = createInterface("SERVER",
+                                                                      SERVER_CONNECT_POINT,
+                                                                      INTERFACE_IPS,
+                                                                      SERVER_IFACE_MAC,
+                                                                      SERVER_VLAN,
+                                                                      SERVER_VLAN_NATIVE);
+
+    // Relay agent config
+    private static final Ip4Address RELAY_AGENT_IP = Ip4Address.valueOf("10.0.4.254");
+
+    private static final List<TrafficSelector> DHCP_SELECTORS = buildClientDhcpSelectors();
+
+    // 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,
+            SERVER_INTERFACE,
+            CLIENT_DH_INTERFACE
+    );
+    private static final String NON_ONOS_CID = "Non-ONOS circuit ID";
+    private static final VlanId IGNORED_VLAN = VlanId.vlanId("100");
+    private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
+
+    private DhcpRelayManager manager;
+    private MockPacketService packetService;
+    private MockRouteStore mockRouteStore;
+    private MockDhcpRelayStore mockDhcpRelayStore;
+    private MockDhcpRelayCountersStore mockDhcpRelayCountersStore;
+    private HostProviderService mockHostProviderService;
+    private FlowObjectiveService flowObjectiveService;
+    private DeviceService deviceService;
+    private Dhcp4HandlerImpl v4Handler;
+    private Dhcp6HandlerImpl v6Handler;
+
+    private static Interface createInterface(String name, ConnectPoint connectPoint,
+                                             List<InterfaceIpAddress> interfaceIps,
+                                             MacAddress macAddress,
+                                             VlanId vlanId,
+                                             VlanId vlanNative) {
+
+        if (vlanId.equals(VlanId.NONE)) {
+            return new Interface(name, connectPoint, interfaceIps, macAddress, vlanId,
+                                 null, null, vlanNative);
+        } else {
+            return new Interface(name, connectPoint, interfaceIps, macAddress, vlanId,
+                                 null, ImmutableSet.of(vlanId), null);
+        }
+    }
+
+    @Before
+    public void setup() {
+        manager = new DhcpRelayManager();
+        manager.cfgService = createNiceMock(NetworkConfigRegistry.class);
+
+        expect(manager.cfgService.getConfig(APP_ID, DefaultDhcpRelayConfig.class))
+                .andReturn(CONFIG)
+                .anyTimes();
+
+        expect(manager.cfgService.getConfig(APP_ID, IndirectDhcpRelayConfig.class))
+                .andReturn(CONFIG_INDIRECT)
+                .anyTimes();
+
+        manager.coreService = createNiceMock(CoreService.class);
+        expect(manager.coreService.registerApplication(anyString()))
+                .andReturn(APP_ID).anyTimes();
+
+        manager.hostService = createNiceMock(HostService.class);
+
+        expect(manager.hostService.getHostsByIp(OUTER_RELAY_IP_V6))
+                .andReturn(ImmutableSet.of(OUTER_RELAY_HOST)).anyTimes();
+        expect(manager.hostService.getHostsByIp(SERVER_IP))
+                .andReturn(ImmutableSet.of(SERVER_HOST)).anyTimes();
+        expect(manager.hostService.getHostsByIp(SERVER_IP_V6))
+                .andReturn(ImmutableSet.of(SERVER_HOST)).anyTimes();
+        expect(manager.hostService.getHostsByIp(GATEWAY_IP))
+                .andReturn(ImmutableSet.of(SERVER_HOST)).anyTimes();
+        expect(manager.hostService.getHostsByIp(GATEWAY_IP_V6))
+                .andReturn(ImmutableSet.of(SERVER_HOST)).anyTimes();
+        expect(manager.hostService.getHostsByIp(CLIENT_LL_IP_V6))
+                .andReturn(ImmutableSet.of(EXISTS_HOST)).anyTimes();
+
+        expect(manager.hostService.getHost(OUTER_RELAY_HOST_ID)).andReturn(OUTER_RELAY_HOST).anyTimes();
+
+        packetService = new MockPacketService();
+        manager.packetService = packetService;
+        manager.compCfgService = createNiceMock(ComponentConfigService.class);
+        deviceService = createNiceMock(DeviceService.class);
+
+        Device device = createNiceMock(Device.class);
+        expect(device.is(Pipeliner.class)).andReturn(true).anyTimes();
+
+        expect(deviceService.getDevice(DEV_1_ID)).andReturn(device).anyTimes();
+        expect(deviceService.getDevice(DEV_2_ID)).andReturn(device).anyTimes();
+        replay(deviceService, device);
+
+        mockRouteStore = new MockRouteStore();
+        mockDhcpRelayStore = new MockDhcpRelayStore();
+        mockDhcpRelayCountersStore = new MockDhcpRelayCountersStore();
+
+        manager.dhcpRelayStore = mockDhcpRelayStore;
+
+        manager.deviceService = deviceService;
+
+        manager.interfaceService = new MockInterfaceService();
+        flowObjectiveService = EasyMock.niceMock(FlowObjectiveService.class);
+        mockHostProviderService = createNiceMock(HostProviderService.class);
+        v4Handler = new Dhcp4HandlerImpl();
+        v4Handler.providerService = mockHostProviderService;
+        v4Handler.dhcpRelayStore = mockDhcpRelayStore;
+        v4Handler.hostService = manager.hostService;
+        v4Handler.interfaceService = manager.interfaceService;
+        v4Handler.packetService = manager.packetService;
+        v4Handler.routeStore = mockRouteStore;
+        v4Handler.coreService = createNiceMock(CoreService.class);
+        v4Handler.flowObjectiveService = flowObjectiveService;
+        v4Handler.appId = TestApplicationId.create(Dhcp4HandlerImpl.DHCP_V4_RELAY_APP);
+        v4Handler.deviceService = deviceService;
+        manager.v4Handler = v4Handler;
+
+        v6Handler = new Dhcp6HandlerImpl();
+        v6Handler.dhcpRelayStore = mockDhcpRelayStore;
+        v6Handler.dhcpRelayCountersStore = mockDhcpRelayCountersStore;
+        v6Handler.hostService = manager.hostService;
+        v6Handler.interfaceService = manager.interfaceService;
+        v6Handler.packetService = manager.packetService;
+        v6Handler.routeStore = mockRouteStore;
+        v6Handler.providerService = mockHostProviderService;
+        v6Handler.coreService = createNiceMock(CoreService.class);
+        v6Handler.flowObjectiveService = flowObjectiveService;
+        v6Handler.appId = TestApplicationId.create(Dhcp6HandlerImpl.DHCP_V6_RELAY_APP);
+        v6Handler.deviceService = deviceService;
+        manager.v6Handler = v6Handler;
+
+        // properties
+        Dictionary<String, Object> dictionary = createNiceMock(Dictionary.class);
+        expect(dictionary.get("arpEnabled")).andReturn(true).anyTimes();
+        expect(dictionary.get("dhcpPollInterval")).andReturn(120).anyTimes();
+        ComponentContext context = createNiceMock(ComponentContext.class);
+        expect(context.getProperties()).andReturn(dictionary).anyTimes();
+
+        replay(manager.cfgService, manager.coreService, manager.hostService,
+               manager.compCfgService, dictionary, context);
+        manager.activate(context);
+    }
+
+    @After
+    public void tearDown() {
+        manager.deactivate();
+    }
+
+    /**
+     * Relay a DHCP packet without option 82.
+     * Should add new host to host store after dhcp ack.
+     */
+    @Test
+    public void relayDhcpWithoutAgentInfo() {
+        replay(mockHostProviderService);
+        // send request
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT_MAC,
+                                                                     CLIENT_VLAN,
+                                                                     CLIENT_CP,
+                                                                     INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                     false));
+        // won't trigger the host provider service
+        verify(mockHostProviderService);
+        reset(mockHostProviderService);
+
+        assertEquals(0, mockRouteStore.routes.size());
+
+        HostId expectHostId = HostId.hostId(CLIENT_MAC, CLIENT_VLAN);
+        Capture<HostDescription> capturedHostDesc = newCapture();
+        mockHostProviderService.hostDetected(eq(expectHostId), capture(capturedHostDesc), eq(false));
+        replay(mockHostProviderService);
+        // send ack
+        packetService.processPacket(new TestDhcpAckPacketContext(CLIENT_CP, CLIENT_MAC,
+                                                                 CLIENT_VLAN, INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                 false));
+        verify(mockHostProviderService);
+        assertEquals(0, mockRouteStore.routes.size());
+
+        HostDescription host = capturedHostDesc.getValue();
+        assertEquals(false, host.configured());
+        assertEquals(CLIENT_CP.deviceId(), host.location().elementId());
+        assertEquals(CLIENT_CP.port(), host.location().port());
+        assertEquals(1, host.ipAddress().size());
+        assertEquals(IP_FOR_CLIENT, host.ipAddress().iterator().next());
+    }
+
+    /**
+     * Relay a DHCP packet with option 82 (Indirectly connected host).
+     */
+    @Test
+    public void relayDhcpWithAgentInfo() {
+        replay(mockHostProviderService);
+        // Assume outer dhcp relay agent exists in store already
+        // send request
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT2_MAC,
+                                                                     CLIENT2_VLAN,
+                                                                     CLIENT2_CP,
+                                                                     INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                     true));
+        // No routes
+        assertEquals(0, mockRouteStore.routes.size());
+        // send ack
+        packetService.processPacket(new TestDhcpAckPacketContext(CLIENT2_CP,
+                                                                 CLIENT2_MAC,
+                                                                 CLIENT2_VLAN,
+                                                                 INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                 true));
+
+        // won't trigger the host provider service
+        verify(mockHostProviderService);
+        reset(mockHostProviderService);
+
+        assertEquals(1, mockRouteStore.routes.size());
+
+        Route route = mockRouteStore.routes.get(0);
+        assertEquals(OUTER_RELAY_IP, route.nextHop());
+        assertEquals(IP_FOR_CLIENT.toIpPrefix(), route.prefix());
+        assertEquals(Route.Source.DHCP, route.source());
+    }
+
+    @Test
+    public void testWithRelayAgentConfig() throws DeserializationException {
+        manager.v4Handler
+                .setDefaultDhcpServerConfigs(ImmutableList.of(new MockDhcpServerConfig(RELAY_AGENT_IP)));
+        manager.v4Handler
+                .setIndirectDhcpServerConfigs(ImmutableList.of(new MockDhcpServerConfig(RELAY_AGENT_IP)));
+        packetService.processPacket(new TestDhcpRequestPacketContext(CLIENT2_MAC,
+                                                                     CLIENT2_VLAN,
+                                                                     CLIENT2_CP,
+                                                                     INTERFACE_IP.ipAddress().getIp4Address(),
+                                                                     true));
+        OutboundPacket outPacket = packetService.emittedPacket;
+        byte[] outData = outPacket.data().array();
+        Ethernet eth = Ethernet.deserializer().deserialize(outData, 0, outData.length);
+        IPv4 ip = (IPv4) eth.getPayload();
+        UDP udp = (UDP) ip.getPayload();
+        DHCP dhcp = (DHCP) udp.getPayload();
+        assertEquals(RELAY_AGENT_IP.toInt(), dhcp.getGatewayIPAddress());
+    }
+
+    @Test
+    public void testArpRequest() throws Exception {
+        packetService.processPacket(new TestArpRequestPacketContext(CLIENT_INTERFACE));
+        OutboundPacket outboundPacket = packetService.emittedPacket;
+        byte[] outPacketData = outboundPacket.data().array();
+        Ethernet eth = Ethernet.deserializer().deserialize(outPacketData, 0, outPacketData.length);
+
+        assertEquals(eth.getEtherType(), Ethernet.TYPE_ARP);
+        ARP arp = (ARP) eth.getPayload();
+        assertArrayEquals(arp.getSenderHardwareAddress(), CLIENT_INTERFACE.mac().toBytes());
+    }
+
+    /**
+     * Ignores specific vlans from specific devices if config.
+     *
+     * @throws Exception the exception from this test
+     */
+    @Test
+    public void testIgnoreVlan() throws Exception {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        IgnoreDhcpConfig config = new IgnoreDhcpConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(IgnoreDhcpConfig.KEY);
+        config.init(APP_ID, IgnoreDhcpConfig.KEY, json, om, null);
+
+        Capture<Objective> capturedFromDev1 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_1_ID), capture(capturedFromDev1));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        Capture<Objective> capturedFromDev2 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_2_ID), capture(capturedFromDev2));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        replay(flowObjectiveService);
+        manager.updateConfig(config);
+        verify(flowObjectiveService);
+
+        List<Objective> objectivesFromDev1 = capturedFromDev1.getValues();
+        List<Objective> objectivesFromDev2 = capturedFromDev2.getValues();
+
+        assertTrue(objectivesFromDev1.containsAll(objectivesFromDev2));
+        assertTrue(objectivesFromDev2.containsAll(objectivesFromDev1));
+
+        for (int index = 0; index < objectivesFromDev1.size(); index++) {
+            TrafficSelector selector =
+                    DefaultTrafficSelector.builder(DHCP_SELECTORS.get(index))
+                    .matchVlanId(IGNORED_VLAN)
+                    .build();
+            ForwardingObjective fwd = (ForwardingObjective) objectivesFromDev1.get(index);
+            assertEquals(selector, fwd.selector());
+            assertEquals(DefaultTrafficTreatment.emptyTreatment(), fwd.treatment());
+            assertEquals(IGNORE_CONTROL_PRIORITY, fwd.priority());
+            assertEquals(ForwardingObjective.Flag.VERSATILE, fwd.flag());
+            assertEquals(Objective.Operation.ADD, fwd.op());
+            fwd.context().ifPresent(ctx -> {
+                ctx.onSuccess(fwd);
+            });
+        }
+        objectivesFromDev2.forEach(obj -> obj.context().ifPresent(ctx -> ctx.onSuccess(obj)));
+        assertEquals(2, v4Handler.ignoredVlans.size());
+        assertEquals(2, v6Handler.ignoredVlans.size());
+    }
+
+    /**
+     * "IgnoreVlan" policy should be removed when the config removed.
+     */
+    @Test
+    public void testRemoveIgnoreVlan() {
+        v4Handler.ignoredVlans.put(DEV_1_ID, IGNORED_VLAN);
+        v4Handler.ignoredVlans.put(DEV_2_ID, IGNORED_VLAN);
+        v6Handler.ignoredVlans.put(DEV_1_ID, IGNORED_VLAN);
+        v6Handler.ignoredVlans.put(DEV_2_ID, IGNORED_VLAN);
+        IgnoreDhcpConfig config = new IgnoreDhcpConfig();
+
+        Capture<Objective> capturedFromDev1 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_1_ID), capture(capturedFromDev1));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        Capture<Objective> capturedFromDev2 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_2_ID), capture(capturedFromDev2));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        replay(flowObjectiveService);
+        manager.removeConfig(config);
+        verify(flowObjectiveService);
+
+        List<Objective> objectivesFromDev1 = capturedFromDev1.getValues();
+        List<Objective> objectivesFromDev2 = capturedFromDev2.getValues();
+
+        assertTrue(objectivesFromDev1.containsAll(objectivesFromDev2));
+        assertTrue(objectivesFromDev2.containsAll(objectivesFromDev1));
+
+        for (int index = 0; index < objectivesFromDev1.size(); index++) {
+            TrafficSelector selector =
+                    DefaultTrafficSelector.builder(DHCP_SELECTORS.get(index))
+                    .matchVlanId(IGNORED_VLAN)
+                    .build();
+            ForwardingObjective fwd = (ForwardingObjective) objectivesFromDev1.get(index);
+            assertEquals(selector, fwd.selector());
+            assertEquals(DefaultTrafficTreatment.emptyTreatment(), fwd.treatment());
+            assertEquals(IGNORE_CONTROL_PRIORITY, fwd.priority());
+            assertEquals(ForwardingObjective.Flag.VERSATILE, fwd.flag());
+            assertEquals(Objective.Operation.REMOVE, fwd.op());
+            fwd.context().ifPresent(ctx -> {
+                ctx.onSuccess(fwd);
+            });
+        }
+        objectivesFromDev2.forEach(obj -> obj.context().ifPresent(ctx -> ctx.onSuccess(obj)));
+        assertEquals(0, v4Handler.ignoredVlans.size());
+        assertEquals(0, v6Handler.ignoredVlans.size());
+    }
+
+    /**
+     * Should ignore ignore rules installation when device not available.
+     */
+    @Test
+    public void testIgnoreUnknownDevice() throws IOException {
+        reset(manager.deviceService);
+        Device device = createNiceMock(Device.class);
+        expect(device.is(Pipeliner.class)).andReturn(true).anyTimes();
+
+        expect(manager.deviceService.getDevice(DEV_1_ID)).andReturn(device).anyTimes();
+        expect(manager.deviceService.getDevice(DEV_2_ID)).andReturn(null).anyTimes();
+
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        IgnoreDhcpConfig config = new IgnoreDhcpConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(IgnoreDhcpConfig.KEY);
+        config.init(APP_ID, IgnoreDhcpConfig.KEY, json, om, null);
+
+        Capture<Objective> capturedFromDev1 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_1_ID), capture(capturedFromDev1));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        replay(flowObjectiveService, manager.deviceService, device);
+
+        manager.updateConfig(config);
+        capturedFromDev1.getValues().forEach(obj -> obj.context().ifPresent(ctx -> ctx.onSuccess(obj)));
+
+        assertEquals(1, v4Handler.ignoredVlans.size());
+        assertEquals(1, v6Handler.ignoredVlans.size());
+    }
+
+    /**
+     * Should try install ignore rules when device comes up.
+     */
+    @Test
+    public void testInstallIgnoreRuleWhenDeviceComesUp() throws IOException {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        IgnoreDhcpConfig config = new IgnoreDhcpConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(IgnoreDhcpConfig.KEY);
+        config.init(APP_ID, IgnoreDhcpConfig.KEY, json, om, null);
+
+        reset(manager.cfgService, flowObjectiveService, manager.deviceService);
+        expect(manager.cfgService.getConfig(APP_ID, IgnoreDhcpConfig.class))
+                .andReturn(config).anyTimes();
+
+        Device device = createNiceMock(Device.class);
+        expect(device.is(Pipeliner.class)).andReturn(true).anyTimes();
+        expect(device.id()).andReturn(DEV_1_ID).anyTimes();
+        expect(manager.deviceService.getDevice(DEV_1_ID)).andReturn(device).anyTimes();
+        DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
+        Capture<Objective> capturedFromDev1 = newCapture(CaptureType.ALL);
+        flowObjectiveService.apply(eq(DEV_1_ID), capture(capturedFromDev1));
+        expectLastCall().times(DHCP_SELECTORS.size());
+        replay(manager.cfgService, flowObjectiveService, manager.deviceService, device);
+        manager.deviceListener.event(event);
+        capturedFromDev1.getValues().forEach(obj -> obj.context().ifPresent(ctx -> ctx.onSuccess(obj)));
+        assertEquals(1, v4Handler.ignoredVlans.size());
+        assertEquals(1, v6Handler.ignoredVlans.size());
+    }
+
+    /**
+     * Relay a DHCP6 packet without relay option
+     * Note: Should add new host to host store after dhcp ack.
+     */
+    @Test
+    public void relayDhcp6WithoutAgentInfo() {
+        replay(mockHostProviderService);
+        // send request
+        packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.REQUEST.value(),
+                                                                     CLIENT_MAC,
+                                                                     CLIENT_VLAN,
+                                                                     CLIENT_CP,
+                                                                     INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                                                                     0));
+
+        verify(mockHostProviderService);
+        reset(mockHostProviderService);
+        assertEquals(0, mockRouteStore.routes.size());
+
+        Capture<HostDescription> capturedHostDesc = newCapture();
+        mockHostProviderService.hostDetected(eq(HostId.hostId(CLIENT_MAC, CLIENT_VLAN)),
+                                             capture(capturedHostDesc), eq(false));
+        replay(mockHostProviderService);
+        // send reply
+        packetService.processPacket(new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(),
+                                                                    CLIENT_CP, CLIENT_MAC,
+                                                                    CLIENT_VLAN,
+                                                                    INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                                                                    0, false, CLIENT_VLAN));
+        verify(mockHostProviderService);
+        assertEquals(0, mockRouteStore.routes.size());
+
+        HostDescription host = capturedHostDesc.getValue();
+        assertEquals(CLIENT_VLAN, host.vlan());
+        assertEquals(CLIENT_CP.deviceId(), host.location().elementId());
+        assertEquals(CLIENT_CP.port(), host.location().port());
+        assertEquals(1, host.ipAddress().size());
+        assertEquals(IP_FOR_CLIENT_V6, host.ipAddress().iterator().next());
+
+        // send release
+        packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.RELEASE.value(),
+                CLIENT_MAC,
+                CLIENT_VLAN,
+                CLIENT_CP,
+                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                0));
+
+        assertEquals(null, manager.hostService.getHost(HostId.hostId(CLIENT_MAC, CLIENT_VLAN)));
+    }
+
+    /**
+     * Relay a DHCP6 packet with Relay Message opion (Indirectly connected host).
+     */
+    @Test
+    public void relayDhcp6WithAgentInfo() {
+        replay(mockHostProviderService);
+        // Assume outer dhcp6 relay agent exists in store already
+        // send request
+        packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.REQUEST.value(),
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                CLIENT2_CP,
+                OUTER_RELAY_IP_V6,
+                1));
+
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send reply
+        packetService.processPacket(new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(), CLIENT2_CP,
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                OUTER_RELAY_IP_V6,
+                1, false, CLIENT2_VLAN));
+
+        // won't trigger the host provider service
+        verify(mockHostProviderService);
+        reset(mockHostProviderService);
+        assertEquals(2, mockRouteStore.routes.size()); // ipAddress and prefix
+
+        Route aRoute = mockRouteStore.routes.stream()
+                             .filter(rt -> rt.prefix().contains(IP_FOR_CLIENT_V6))
+                             .findFirst()
+                             .orElse(null);
+        assertNotEquals(null, aRoute);
+
+        aRoute = mockRouteStore.routes.stream()
+                .filter(rt -> rt.prefix().contains(PREFIX_FOR_CLIENT_V6))
+                .findFirst()
+                .orElse(null);
+        assertNotEquals(null, aRoute);
+
+        // send release msg
+        packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.RELEASE.value(),
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                CLIENT2_CP,
+                OUTER_RELAY_IP_V6,
+                1));
+
+        aRoute = mockRouteStore.routes.stream()
+                .filter(rt -> rt.prefix().contains(IP_FOR_CLIENT_V6))
+                .findFirst()
+                .orElse(null);
+        assertEquals(null, aRoute);
+
+        aRoute = mockRouteStore.routes.stream()
+                .filter(rt -> rt.prefix().contains(PREFIX_FOR_CLIENT_V6))
+                .findFirst()
+                .orElse(null);
+        assertEquals(null, aRoute);
+
+        assertEquals(0, mockRouteStore.routes.size());
+
+    }
+
+    /**
+     * Relay a DHCP6 packet with Relay Message opion (Indirectly connected host) and server responded
+     * with vlan differnt from client interface vlan.
+     */
+    @Test
+    public void relayDhcp6WithAgentInfoWrongVlan() {
+        replay(mockHostProviderService);
+        // Assume outer dhcp6 relay agent exists in store already
+        // send request
+        packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.REQUEST.value(),
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                CLIENT2_CP,
+                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                1));
+
+        assertEquals(0, mockRouteStore.routes.size());
+
+        // send reply
+        packetService.processPacket(new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(),
+                CLIENT2_CP,
+                CLIENT2_MAC,
+                CLIENT2_VLAN,
+                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                1, true,
+                CLIENT_BOGUS_VLAN // mismatch
+        ));
+
+        // won't trigger the host provider service
+        verify(mockHostProviderService);
+        reset(mockHostProviderService);
+        assertEquals(0, mockRouteStore.routes.size()); // ipAddress and prefix
+
+    }
+
+
+    @Test
+    public void testDhcp4DualHome() {
+        PacketContext packetContext =
+                new TestDhcpAckPacketContext(CLIENT_DH_CP, CLIENT_MAC, CLIENT_VLAN,
+                                             INTERFACE_IP.ipAddress().getIp4Address(),
+                                             false);
+        reset(manager.hostService);
+        expect(manager.hostService.getHost(CLIENT_HOST_ID)).andReturn(EXISTS_HOST).anyTimes();
+        Capture<HostDescription> capturedHostDesc = newCapture();
+        mockHostProviderService.hostDetected(eq(CLIENT_HOST_ID), capture(capturedHostDesc), eq(false));
+        replay(mockHostProviderService, manager.hostService);
+        packetService.processPacket(packetContext);
+        verify(mockHostProviderService);
+
+        HostDescription hostDesc = capturedHostDesc.getValue();
+        Set<HostLocation> hostLocations = hostDesc.locations();
+        assertEquals(2, hostLocations.size());
+        assertTrue(hostLocations.contains(CLIENT_LOCATION));
+        assertTrue(hostLocations.contains(CLIENT_DH_LOCATION));
+    }
+
+    @Test
+    public void testDhcp6DualHome() {
+        PacketContext packetContext =
+                new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(),
+                                                CLIENT_DH_CP, CLIENT_MAC, CLIENT_VLAN,
+                                                INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                                                0, false, CLIENT_VLAN);
+        reset(manager.hostService);
+        expect(manager.hostService.getHostsByIp(CLIENT_LL_IP_V6)).andReturn(ImmutableSet.of(EXISTS_HOST)).anyTimes();
+
+        // FIXME: currently DHCPv6 has a bug, we can't get correct vlan of client......
+        // XXX: The vlan relied from DHCP6 handler might be wrong, do hack here
+        HostId hostId = HostId.hostId(CLIENT_MAC, VlanId.NONE);
+        expect(manager.hostService.getHost(hostId)).andReturn(EXISTS_HOST).anyTimes();
+
+        // XXX: sometimes this will work, sometimes not
+         expect(manager.hostService.getHost(CLIENT_HOST_ID)).andReturn(EXISTS_HOST).anyTimes();
+
+        Capture<HostDescription> capturedHostDesc = newCapture();
+
+        // XXX: also a hack here
+        mockHostProviderService.hostDetected(eq(hostId), capture(capturedHostDesc), eq(false));
+        expectLastCall().anyTimes();
+
+        mockHostProviderService.hostDetected(eq(CLIENT_HOST_ID), capture(capturedHostDesc), eq(false));
+        expectLastCall().anyTimes();
+        replay(mockHostProviderService, manager.hostService);
+        packetService.processPacket(packetContext);
+        verify(mockHostProviderService);
+
+        HostDescription hostDesc = capturedHostDesc.getValue();
+        Set<HostLocation> hostLocations = hostDesc.locations();
+        assertEquals(2, hostLocations.size());
+        assertTrue(hostLocations.contains(CLIENT_LOCATION));
+        assertTrue(hostLocations.contains(CLIENT_DH_LOCATION));
+    }
+
+    private static class MockDefaultDhcpRelayConfig extends DefaultDhcpRelayConfig {
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        public List<DhcpServerConfig> dhcpServerConfigs() {
+            return ImmutableList.of(new MockDhcpServerConfig(null));
+        }
+    }
+
+    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;
+
+        /**
+         * Create mocked version DHCP server config.
+         *
+         * @param relayAgentIp the relay agent Ip config; null if we don't need it
+         */
+        public MockDhcpServerConfig(Ip4Address relayAgentIp) {
+            this.relayAgentIp = relayAgentIp;
+            this.relayAgentIps.put(DEV_1_ID, Pair.of(relayAgentIp, null));
+            this.relayAgentIps.put(DEV_2_ID, Pair.of(relayAgentIp, null));
+        }
+
+        @Override
+        public Optional<Ip4Address> getRelayAgentIp4(DeviceId deviceId) {
+            return Optional.ofNullable(this.relayAgentIps.get(deviceId).getLeft());
+        }
+
+        @Override
+        public Optional<ConnectPoint> getDhcpServerConnectPoint() {
+            return Optional.of(SERVER_CONNECT_POINT);
+        }
+
+        @Override
+        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 MockRouteStore extends RouteStoreAdapter {
+        private List<Route> routes = Lists.newArrayList();
+
+        @Override
+        public void updateRoute(Route route) {
+            routes.add(route);
+        }
+
+        @Override
+        public void removeRoute(Route route) {
+            routes.remove(route);
+        }
+
+        public void replaceRoute(Route route) {
+            routes.remove(route);
+            routes.add(route);
+        }
+    }
+
+    private class MockInterfaceService extends InterfaceServiceAdapter {
+
+        @Override
+        public Set<Interface> getInterfaces() {
+            return INTERFACES;
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByIp(IpAddress ip) {
+            return INTERFACES.stream()
+                    .filter(iface -> {
+                        return iface.ipAddressesList().stream()
+                                .anyMatch(ifaceIp -> ifaceIp.ipAddress().equals(ip));
+                    })
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            return INTERFACES.stream()
+                    .filter(iface -> iface.connectPoint().equals(port))
+                    .collect(Collectors.toSet());
+        }
+    }
+
+    private class MockDhcpRelayStore implements DhcpRelayStore {
+        StoreDelegate<DhcpRelayStoreEvent> delegate;
+        private Map<HostId, DhcpRecord> records = Maps.newHashMap();
+
+        @Override
+        public void updateDhcpRecord(HostId hostId, DhcpRecord dhcpRecord) {
+            records.put(hostId, dhcpRecord);
+            DhcpRelayStoreEvent event = new DhcpRelayStoreEvent(DhcpRelayStoreEvent.Type.UPDATED,
+                                                                dhcpRecord);
+            if (delegate != null) {
+                delegate.notify(event);
+            }
+        }
+
+        @Override
+        public Optional<DhcpRecord> getDhcpRecord(HostId hostId) {
+            return Optional.ofNullable(records.get(hostId));
+        }
+
+        @Override
+        public Collection<DhcpRecord> getDhcpRecords() {
+            return records.values();
+        }
+
+        @Override
+        public Optional<DhcpRecord> removeDhcpRecord(HostId hostId) {
+            DhcpRecord dhcpRecord = records.remove(hostId);
+            if (dhcpRecord != null) {
+                DhcpRelayStoreEvent event = new DhcpRelayStoreEvent(DhcpRelayStoreEvent.Type.REMOVED,
+                                                                    dhcpRecord);
+                if (delegate != null) {
+                    delegate.notify(event);
+                }
+            }
+            return Optional.ofNullable(dhcpRecord);
+        }
+
+        @Override
+        public void setDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public void unsetDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
+            this.delegate = null;
+        }
+
+        @Override
+        public boolean hasDelegate() {
+            return this.delegate != null;
+        }
+    }
+
+    private class MockDhcpRelayCountersStore implements DhcpRelayCountersStore {
+        private Map<String, DhcpRelayCounters> counters = Maps.newHashMap();
+
+        public void incrementCounter(String coutnerClass, String counterName) {
+            DhcpRelayCounters countersRecord;
+
+            DhcpRelayCounters classCounters = counters.get(coutnerClass);
+            if (classCounters == null) {
+                classCounters = new DhcpRelayCounters();
+            }
+            classCounters.incrementCounter(counterName);
+            counters.put(coutnerClass, classCounters);
+        }
+
+        @Override
+        public Set<Map.Entry<String, DhcpRelayCounters>> getAllCounters() {
+            return counters.entrySet();
+        }
+
+        @Override
+        public Optional<DhcpRelayCounters> getCounters(String counterClass) {
+            DhcpRelayCounters classCounters = counters.get(counterClass);
+            if (classCounters == null) {
+                return Optional.empty();
+            }
+            return Optional.of(classCounters);
+        }
+
+        @Override
+        public void resetAllCounters() {
+            counters.clear();
+        }
+
+        @Override
+        public void resetCounters(String counterClass) {
+            DhcpRelayCounters classCounters = counters.get(counterClass);
+            classCounters.resetCounters();
+            counters.put(counterClass, classCounters);
+        }
+    }
+
+
+    private class MockPacketService extends PacketServiceAdapter {
+        Set<PacketProcessor> packetProcessors = Sets.newHashSet();
+        OutboundPacket emittedPacket;
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessors.add(processor);
+        }
+
+        public void processPacket(PacketContext packetContext) {
+            packetProcessors.forEach(p -> p.process(packetContext));
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            this.emittedPacket = packet;
+        }
+    }
+
+
+
+    /**
+     * Generates DHCP REQUEST packet.
+     */
+    private class TestDhcpRequestPacketContext extends PacketContextAdapter {
+
+
+        private InboundPacket inPacket;
+
+        public TestDhcpRequestPacketContext(MacAddress clientMac, VlanId vlanId,
+                                            ConnectPoint clientCp,
+                                            Ip4Address clientGwAddr,
+                                            boolean withNonOnosRelayInfo) {
+            super(0, null, null, false);
+            byte[] dhcpMsgType = new byte[1];
+            dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
+
+            DhcpOption dhcpOption = new DhcpOption();
+            dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+            dhcpOption.setData(dhcpMsgType);
+            dhcpOption.setLength((byte) 1);
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+
+            DHCP dhcp = new DHCP();
+            dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
+            dhcp.setHardwareAddressLength((byte) 6);
+            dhcp.setClientHardwareAddress(clientMac.toBytes());
+            if (withNonOnosRelayInfo) {
+                DhcpRelayAgentOption relayOption = new DhcpRelayAgentOption();
+                DhcpOption circuitIdOption = new DhcpOption();
+                CircuitId circuitId = new CircuitId("Custom option", VlanId.NONE);
+                byte[] cid = circuitId.serialize();
+                circuitIdOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdOption.setLength((byte) cid.length);
+                circuitIdOption.setData(cid);
+                relayOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayOption.addSubOption(circuitIdOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayOption, endOption));
+                dhcp.setGatewayIPAddress(OUTER_RELAY_IP.getIp4Address().toInt());
+            } else {
+                dhcp.setOptions(ImmutableList.of(dhcpOption, endOption));
+            }
+
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp);
+            udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
+            udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
+
+            IPv4 ipv4 = new IPv4();
+            ipv4.setPayload(udp);
+            ipv4.setDestinationAddress(SERVER_IP.toInt());
+            ipv4.setSourceAddress(clientGwAddr.toInt());
+
+            Ethernet eth = new Ethernet();
+            if (withNonOnosRelayInfo) {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(OUTER_RELAY_MAC)
+                        .setDestinationMACAddress(MacAddress.BROADCAST)
+                        .setPayload(ipv4);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(vlanId.toShort())
+                        .setSourceMACAddress(clientMac)
+                        .setDestinationMACAddress(MacAddress.BROADCAST)
+                        .setPayload(ipv4);
+            }
+
+            this.inPacket = new DefaultInboundPacket(clientCp, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+    /**
+     * Generates DHCP ACK packet.
+     */
+    private class TestDhcpAckPacketContext extends PacketContextAdapter {
+        private InboundPacket inPacket;
+
+        public TestDhcpAckPacketContext(ConnectPoint clientCp, MacAddress clientMac,
+                                        VlanId clientVlan, Ip4Address clientGwAddr,
+                                        boolean withNonOnosRelayInfo) {
+            super(0, null, null, false);
+
+            byte[] dhcpMsgType = new byte[1];
+            dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPACK.getValue();
+
+            DhcpOption dhcpOption = new DhcpOption();
+            dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+            dhcpOption.setData(dhcpMsgType);
+            dhcpOption.setLength((byte) 1);
+
+            DhcpOption endOption = new DhcpOption();
+            endOption.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
+
+            DHCP dhcp = new DHCP();
+            if (withNonOnosRelayInfo) {
+                DhcpRelayAgentOption relayOption = new DhcpRelayAgentOption();
+                DhcpOption circuitIdOption = new DhcpOption();
+                String circuitId = NON_ONOS_CID;
+                byte[] cid = circuitId.getBytes(Charsets.US_ASCII);
+                circuitIdOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdOption.setLength((byte) cid.length);
+                circuitIdOption.setData(cid);
+                relayOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayOption.addSubOption(circuitIdOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayOption, endOption));
+                dhcp.setGatewayIPAddress(OUTER_RELAY_IP.getIp4Address().toInt());
+            } else {
+                CircuitId cid = new CircuitId(clientCp.toString(), clientVlan);
+                byte[] circuitId = cid.serialize();
+                DhcpOption circuitIdSubOption = new DhcpOption();
+                circuitIdSubOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
+                circuitIdSubOption.setData(circuitId);
+                circuitIdSubOption.setLength((byte) circuitId.length);
+
+                DhcpRelayAgentOption relayInfoOption = new DhcpRelayAgentOption();
+                relayInfoOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
+                relayInfoOption.addSubOption(circuitIdSubOption);
+                dhcp.setOptions(ImmutableList.of(dhcpOption, relayInfoOption, endOption));
+                dhcp.setGatewayIPAddress(clientGwAddr.toInt());
+            }
+            dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
+            dhcp.setHardwareAddressLength((byte) 6);
+            dhcp.setClientHardwareAddress(clientMac.toBytes());
+            dhcp.setYourIPAddress(IP_FOR_CLIENT.toInt());
+
+            UDP udp = new UDP();
+            udp.setPayload(dhcp);
+            udp.setSourcePort(UDP.DHCP_SERVER_PORT);
+            udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
+            IPv4 ipv4 = new IPv4();
+            ipv4.setPayload(udp);
+            ipv4.setDestinationAddress(IP_FOR_CLIENT.toString());
+            ipv4.setSourceAddress(SERVER_IP.toString());
+            Ethernet eth = new Ethernet();
+            if (withNonOnosRelayInfo) {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(OUTER_RELAY_MAC)
+                        .setPayload(ipv4);
+            } else {
+                eth.setEtherType(Ethernet.TYPE_IPV4)
+                        .setVlanID(SERVER_VLAN.toShort())
+                        .setSourceMACAddress(SERVER_MAC)
+                        .setDestinationMACAddress(CLIENT_MAC)
+                        .setPayload(ipv4);
+            }
+
+            this.inPacket = new DefaultInboundPacket(SERVER_CONNECT_POINT, eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            return this.inPacket;
+        }
+    }
+
+    private class TestArpRequestPacketContext extends PacketContextAdapter {
+        private InboundPacket inPacket;
+
+        public TestArpRequestPacketContext(Interface fromInterface) {
+            super(0, null, null, false);
+            ARP arp = new ARP();
+            arp.setOpCode(ARP.OP_REQUEST);
+
+            IpAddress targetIp = fromInterface.ipAddressesList().get(0).ipAddress();
+            arp.setTargetProtocolAddress(targetIp.toOctets());
+            arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
+            arp.setSenderHardwareAddress(MacAddress.NONE.toBytes());
+            arp.setSenderProtocolAddress(Ip4Address.valueOf(0).toOctets());
+            arp.setHardwareAddressLength((byte) MacAddress.MAC_ADDRESS_LENGTH);
+            Ethernet eth = new Ethernet();
+            eth.setEtherType(Ethernet.TYPE_ARP);
+            eth.setSourceMACAddress(MacAddress.NONE);
+            eth.setDestinationMACAddress(MacAddress.BROADCAST);
+            eth.setVlanID(fromInterface.vlan().toShort());
+            eth.setPayload(arp);
+
+            this.inPacket = new DefaultInboundPacket(fromInterface.connectPoint(), eth,
+                                                     ByteBuffer.wrap(eth.serialize()));
+        }
+
+        @Override
+        public InboundPacket inPacket() {
+            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);
+
+        Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
+        Dhcp6Duid dhcp6Duip = new Dhcp6Duid();
+        dhcp6Duip.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
+        dhcp6Duip.setHardwareType((short) 0x01);   // Ethernet
+        dhcp6Duip.setDuidTime(1234);
+        dhcp6Duip.setLinkLayerAddress(CLIENT_MAC.toBytes());
+        clientIdOption.setDuid(dhcp6Duip);
+
+        Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
+        iaNaOption.setCode(DHCP6.OptionCode.IA_NA.value());
+        iaNaOption.setIaId(0);
+        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(clientIdOption);
+        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);
+        byte[] optionData = interfaceIdOption.getData();
+        ByteBuffer bb = ByteBuffer.wrap(interfaceIdBytes);
+
+        byte[] macAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
+        byte[] port =  new byte[optionData.length - MacAddress.MAC_ADDRESS_LENGTH -
+                                VLAN_LEN - SEPARATOR_LEN * 2];
+        short vlan;
+        bb.get(macAddr);
+        bb.get();  // separator
+        bb.get(port);
+        bb.get();  // separator
+        vlan = bb.getShort();
+        interfaceIdOption.setMacAddress(MacAddress.valueOf(macAddr));
+        interfaceIdOption.setInPort(port);
+        interfaceIdOption.setVlanId(vlan);
+
+        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, short vlanId, ConnectPoint clientCp) {
+        String inPortString = "-" + clientCp.toString() + ":";
+        byte[] clientSoureMacBytes = clientMac.toBytes();
+        byte[] inPortStringBytes = inPortString.getBytes();
+        byte[] vlanIdBytes = new byte[2];
+        vlanIdBytes[0] = (byte) ((vlanId >> 8) & 0xff);  // high-order byte first
+        vlanIdBytes[1] = (byte) (vlanId & 0xff);
+        byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +  inPortStringBytes.length + vlanIdBytes.length];
+
+        System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
+        System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length, inPortStringBytes.length);
+        System.arraycopy(vlanIdBytes, 0, interfaceIdBytes, clientSoureMacBytes.length + inPortStringBytes.length,
+                vlanIdBytes.length);
+
+        return interfaceIdBytes;
+    }
+
+    private static List<TrafficSelector> buildClientDhcpSelectors() {
+        return Streams.concat(Dhcp4HandlerImpl.DHCP_SELECTORS.stream(),
+                              Dhcp6HandlerImpl.DHCP_SELECTORS.stream())
+                .collect(Collectors.toList());
+    }
+
+    private class TestDhcp6RequestPacketContext extends PacketContextAdapter {
+
+
+        private InboundPacket inPacket;
+
+
+        public TestDhcp6RequestPacketContext(byte msgType, 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, msgType,
+                                 IP_FOR_CLIENT_V6,
+                        msgType == DHCP6.MsgType.REQUEST.value() ? PREFIX_FOR_ZERO : PREFIX_FOR_CLIENT_V6);
+                DHCP6 dhcp6Parent = null;
+                DHCP6 dhcp6Child = dhcp6Payload;
+                for (int i = 0; i < relayLevel; i++) {
+                    dhcp6Parent = new DHCP6();
+                    byte[] interfaceId = buildInterfaceId(clientMac, vlanId.toShort(), 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, msgType,
+                                        IP_FOR_CLIENT_V6,
+                        msgType == DHCP6.MsgType.REQUEST.value() ? PREFIX_FOR_ZERO : PREFIX_FOR_CLIENT_V6);
+            }
+
+            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(OUTER_RELAY_VLAN.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(byte msgType, ConnectPoint clientCp, MacAddress clientMac,
+                                        VlanId clientVlan, Ip6Address clientGwAddr,
+                                        int relayLevel, boolean overWriteFlag, VlanId overWriteVlan) {
+            super(0, null, null, false);
+
+
+            DHCP6 dhcp6Payload = new DHCP6();
+            buildDhcp6Packet(dhcp6Payload, msgType,
+                    IP_FOR_CLIENT_V6,
+                    PREFIX_FOR_CLIENT_V6);
+            byte[] interfaceId = null;
+            if (relayLevel > 0) {
+                interfaceId = buildInterfaceId(OUTER_RELAY_MAC,
+                                               overWriteFlag ? overWriteVlan.toShort() : OUTER_RELAY_VLAN.toShort(),
+                                                OUTER_RELAY_CP);
+            } else {
+                interfaceId = buildInterfaceId(clientMac, clientVlan.toShort(), clientCp);
+            }
+            DHCP6 dhcp6 = new DHCP6();
+            buildRelayMsg(dhcp6, DHCP6.MsgType.RELAY_REPL.value(),
+                          INTERFACE_IP_V6.ipAddress().getIp6Address(),
+                          CLIENT_LL_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/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/DhcpRelayConfigTest.java b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/DhcpRelayConfigTest.java
new file mode 100644
index 0000000..c743247
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/DhcpRelayConfigTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.dhcprelay.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.io.Resources;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+import static org.onosproject.dhcprelay.DhcpRelayManager.DHCP_RELAY_APP;
+
+/**
+ * Tests for DHCP relay app configuration.
+ */
+public class DhcpRelayConfigTest {
+    private static final String CONFIG_FILE_PATH = "dhcp-relay.json";
+    private static final String INVALID_CONFIG_FILE_PATH = "invalid-dhcp-relay.json";
+    private static final ApplicationId APP_ID = new TestApplicationId("DhcpRelayTest");
+    private static final ConnectPoint DEFAULT_CONNECT_POINT = ConnectPoint.deviceConnectPoint("of:0000000000000002/2");
+    private static final Ip4Address DEFAULT_SERVER_IP = Ip4Address.valueOf("172.168.10.2");
+    private static final Ip4Address DEFAULT_GATEWAY_IP = Ip4Address.valueOf("192.168.10.254");
+    private static final Ip6Address DEFAULT_SERVER_IP_V6 = Ip6Address.valueOf("2000::200:1");
+    private static final Ip6Address DEFAULT_GATEWAY_IP_V6 = Ip6Address.valueOf("1000::100:1");
+    private static final ConnectPoint INDIRECT_CONNECT_POINT = ConnectPoint.deviceConnectPoint("of:0000000000000002/3");
+    private static final Ip4Address INDIRECT_SERVER_IP = Ip4Address.valueOf("172.168.10.3");
+
+    @Test
+    public void testDefaultConfig() throws IOException {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        DefaultDhcpRelayConfig config = new DefaultDhcpRelayConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(DefaultDhcpRelayConfig.KEY);
+        config.init(APP_ID, DefaultDhcpRelayConfig.KEY, json, om, null);
+
+        assertEquals(1, config.dhcpServerConfigs().size());
+        DhcpServerConfig serverConfig = config.dhcpServerConfigs().get(0);
+        assertEquals(DEFAULT_CONNECT_POINT, serverConfig.getDhcpServerConnectPoint().orElse(null));
+        assertEquals(DEFAULT_SERVER_IP, serverConfig.getDhcpServerIp4().orElse(null));
+        assertEquals(DEFAULT_GATEWAY_IP, serverConfig.getDhcpGatewayIp4().orElse(null));
+        assertEquals(DEFAULT_SERVER_IP_V6, serverConfig.getDhcpServerIp6().orElse(null));
+        assertEquals(DEFAULT_GATEWAY_IP_V6, serverConfig.getDhcpGatewayIp6().orElse(null));
+    }
+
+    @Test
+    public void testIndirectConfig() throws IOException {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        IndirectDhcpRelayConfig config = new IndirectDhcpRelayConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(IndirectDhcpRelayConfig.KEY);
+        config.init(APP_ID, IndirectDhcpRelayConfig.KEY, json, om, null);
+
+        assertEquals(1, config.dhcpServerConfigs().size());
+        DhcpServerConfig serverConfig = config.dhcpServerConfigs().get(0);
+        assertEquals(INDIRECT_CONNECT_POINT, serverConfig.getDhcpServerConnectPoint().orElse(null));
+        assertEquals(INDIRECT_SERVER_IP, serverConfig.getDhcpServerIp4().orElse(null));
+        assertNull(serverConfig.getDhcpGatewayIp4().orElse(null));
+        assertNull(serverConfig.getDhcpServerIp6().orElse(null));
+        assertNull(serverConfig.getDhcpGatewayIp6().orElse(null));
+    }
+
+    @Test
+    public void testInvalidConfig() throws IOException {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(INVALID_CONFIG_FILE_PATH));
+        DefaultDhcpRelayConfig config = new DefaultDhcpRelayConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(DefaultDhcpRelayConfig.KEY);
+        config.init(APP_ID, DefaultDhcpRelayConfig.KEY, json, om, null);
+        assertFalse(config.isValid());
+    }
+}
diff --git a/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfigTest.java b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfigTest.java
new file mode 100644
index 0000000..3712c06
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/config/IgnoreDhcpConfigTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.io.Resources;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.dhcprelay.DhcpRelayManager.DHCP_RELAY_APP;
+
+public class IgnoreDhcpConfigTest {
+    private static final String CONFIG_FILE_PATH = "dhcp-relay.json";
+    private static final ApplicationId APP_ID = new TestApplicationId("DhcpRelayTest");
+    private static final DeviceId DEV_1_ID = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV_2_ID = DeviceId.deviceId("of:0000000000000002");
+    private static final VlanId IGNORED_VLAN = VlanId.vlanId("100");
+    @Test
+    public void testIgnoredDhcpConfig() throws IOException {
+        ObjectMapper om = new ObjectMapper();
+        JsonNode json = om.readTree(Resources.getResource(CONFIG_FILE_PATH));
+        IgnoreDhcpConfig config = new IgnoreDhcpConfig();
+        json = json.path("apps").path(DHCP_RELAY_APP).path(IgnoreDhcpConfig.KEY);
+        config.init(APP_ID, IgnoreDhcpConfig.KEY, json, om, null);
+
+        assertEquals(2, config.ignoredVlans().size());
+        Collection<VlanId> vlanForDev1 = config.ignoredVlans().get(DEV_1_ID);
+        Collection<VlanId> vlanForDev2 = config.ignoredVlans().get(DEV_2_ID);
+
+        assertEquals(1, vlanForDev1.size());
+        assertEquals(1, vlanForDev2.size());
+
+        assertTrue(vlanForDev1.contains(IGNORED_VLAN));
+        assertTrue(vlanForDev2.contains(IGNORED_VLAN));
+    }
+}
diff --git a/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DhcpRecordTest.java b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DhcpRecordTest.java
new file mode 100644
index 0000000..7aaf65b
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DhcpRecordTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.dhcprelay.store;
+
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.DHCP;
+import org.onlab.packet.DHCP6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+
+import java.util.Optional;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit test for DHCP record.
+ */
+public class DhcpRecordTest {
+    private static final MacAddress MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+    private static final VlanId VLAN = VlanId.vlanId("100");
+    private static final HostId HOST_ID = HostId.hostId(MAC, VLAN);
+    private static final HostLocation HL1 =
+            new HostLocation(ConnectPoint.deviceConnectPoint("of:0000000000000001/1"), 0);
+    private static final HostLocation HL2 =
+            new HostLocation(ConnectPoint.deviceConnectPoint("of:0000000000000001/2"), 0);
+    private static final Ip4Address IP4ADDR = Ip4Address.valueOf("10.0.2.1");
+    private static final MacAddress GW_MAC = MacAddress.valueOf("00:00:00:00:04:01");
+    private static final Ip6Address IP6ADDR = Ip6Address.valueOf("2001::1");
+
+    /**
+     * Test creating a DHCP relay record.
+     */
+    @Test
+    public void testCreateRecord() {
+        DhcpRecord record = new DhcpRecord(HOST_ID)
+                .addLocation(HL1)
+                .addLocation(HL2)
+                .ip4Address(IP4ADDR)
+                .nextHop(GW_MAC)
+                .ip4Status(DHCP.MsgType.DHCPACK)
+                .ip6Address(IP6ADDR)
+                .ip6Status(DHCP6.MsgType.REPLY)
+                .setDirectlyConnected(true);
+
+        assertThat(record.locations().size(), is(2));
+        assertThat(record.locations(), containsInAnyOrder(HL1, HL2));
+        assertThat(record.ip4Address(), is(Optional.of(IP4ADDR)));
+        assertThat(record.nextHop(), is(Optional.of(GW_MAC)));
+        assertThat(record.ip4Status(), is(Optional.of(DHCP.MsgType.DHCPACK)));
+        assertThat(record.ip6Address(), is(Optional.of(IP6ADDR)));
+        assertThat(record.ip6Status(), is(Optional.of(DHCP6.MsgType.REPLY)));
+        assertThat(record.directlyConnected(), is(true));
+
+        DhcpRecord record2 = new DhcpRecord(HOST_ID)
+                .nextHop(GW_MAC)
+                .addLocation(HL2)
+                .ip6Address(IP6ADDR)
+                .addLocation(HL1)
+                .ip6Status(DHCP6.MsgType.REPLY)
+                .ip4Address(IP4ADDR)
+                .ip4Status(DHCP.MsgType.DHCPACK)
+                .setDirectlyConnected(true);
+
+        TestUtils.setField(record, "lastSeen", 0);
+        TestUtils.setField(record2, "lastSeen", 0);
+        TestUtils.setField(record, "addrPrefTime", 0);
+        TestUtils.setField(record2, "addrPrefTime", 0);
+        TestUtils.setField(record, "pdPrefTime", 0);
+        TestUtils.setField(record2, "pdPrefTime", 0);
+        TestUtils.setField(record, "v6Counter", null);
+        TestUtils.setField(record2, "v6Counter", null);
+
+        assertThat(record, equalTo(record2));
+        assertThat(record.hashCode(), equalTo(record2.hashCode()));
+    }
+
+    /**
+     * Test clone a DHCP record.
+     */
+    @Test
+    public void testCloneRecord() {
+        DhcpRecord record = new DhcpRecord(HOST_ID)
+                .addLocation(HL1)
+                .addLocation(HL2)
+                .ip4Address(IP4ADDR)
+                .nextHop(GW_MAC)
+                .ip4Status(DHCP.MsgType.DHCPACK)
+                .ip6Address(IP6ADDR)
+                .ip6Status(DHCP6.MsgType.REPLY)
+                .setDirectlyConnected(true);
+        DhcpRecord clonedRecord = record.clone();
+        assertEquals(record, clonedRecord);
+    }
+}
diff --git a/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStoreTest.java b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStoreTest.java
new file mode 100644
index 0000000..81491d0
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStoreTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.dhcprelay.store;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.onlab.packet.DHCP.MsgType.DHCPREQUEST;
+
+public class DistributedDhcpRelayStoreTest {
+    private static final ConnectPoint CP = ConnectPoint.deviceConnectPoint("of:1/1");
+    private static final MacAddress MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final VlanId VLAN_ID = VlanId.vlanId("100");
+    private static final HostId HOST_ID = HostId.hostId(MAC, VLAN_ID);
+    private static final Ip4Address IP = Ip4Address.valueOf("192.168.1.10");
+    private static final MacAddress GW_MAC = MacAddress.valueOf("00:00:00:00:01:01");
+    private DistributedDhcpRelayStore store;
+
+    @Before
+    public void setup() {
+        store = new DistributedDhcpRelayStore();
+        store.storageService = new TestStorageService();
+        store.activated();
+    }
+
+    @After
+    public void teerDown() {
+        store.deactivated();
+    }
+
+    /**
+     * Puts and removes a record, should received UPDATED and REMOVED event.
+     */
+    @Test
+    public void testPutAndRemoveRecord() {
+        // dhcp request, no IP
+        HostId hostId = HostId.hostId(MAC, VLAN_ID);
+        DhcpRecord record = new DhcpRecord(hostId);
+        record.addLocation(new HostLocation(CP, System.currentTimeMillis()));
+        record.setDirectlyConnected(true);
+        record.nextHop(GW_MAC);
+        record.ip4Status(DHCPREQUEST);
+
+        CompletableFuture<DhcpRelayStoreEvent> recordComplete = new CompletableFuture<>();
+        store.setDelegate(recordComplete::complete);
+        store.updateDhcpRecord(HOST_ID, record);
+        DhcpRelayStoreEvent event = recordComplete.join();
+        assertEquals(record, event.subject());
+        assertEquals(DhcpRelayStoreEvent.Type.UPDATED, event.type());
+        DhcpRecord recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
+        assertNotNull(recordInStore);
+        assertEquals(record, recordInStore);
+        Collection<DhcpRecord> recordsInStore = store.getDhcpRecords();
+        assertEquals(1, recordsInStore.size());
+        assertEquals(record, recordsInStore.iterator().next());
+
+        // dhcp request, with IP
+        record = new DhcpRecord(hostId);
+        record.addLocation(new HostLocation(CP, System.currentTimeMillis()));
+        record.setDirectlyConnected(true);
+        record.ip4Address(IP);
+        record.nextHop(GW_MAC);
+        record.ip4Status(DHCPREQUEST);
+
+        recordComplete = new CompletableFuture<>();
+        store.setDelegate(recordComplete::complete);
+        store.updateDhcpRecord(HOST_ID, record);
+        event = recordComplete.join();
+        DhcpRecord subject = event.subject();
+        assertEquals(record.locations(), subject.locations());
+        assertEquals(record.vlanId(), subject.vlanId());
+        assertEquals(record.macAddress(), subject.macAddress());
+        assertEquals(record.ip4Address(), subject.ip4Address());
+        assertEquals(record.nextHop(), subject.nextHop());
+        assertEquals(record.ip4Status(), subject.ip4Status());
+        assertEquals(record.ip6Address(), subject.ip6Address());
+        assertEquals(record.ip6Status(), subject.ip6Status());
+        assertEquals(record.directlyConnected(), subject.directlyConnected());
+
+        assertEquals(DhcpRelayStoreEvent.Type.UPDATED, event.type());
+        recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
+        assertNotNull(recordInStore);
+        assertEquals(record.locations(), recordInStore.locations());
+        assertEquals(record.vlanId(), recordInStore.vlanId());
+        assertEquals(record.macAddress(), recordInStore.macAddress());
+        assertEquals(record.ip4Address(), recordInStore.ip4Address());
+        assertEquals(record.nextHop(), recordInStore.nextHop());
+        assertEquals(record.ip4Status(), recordInStore.ip4Status());
+        assertEquals(record.ip6Address(), recordInStore.ip6Address());
+        assertEquals(record.ip6Status(), recordInStore.ip6Status());
+        assertEquals(record.directlyConnected(), recordInStore.directlyConnected());
+        recordsInStore = store.getDhcpRecords();
+        assertEquals(1, recordsInStore.size());
+
+        // removes record
+        recordComplete = new CompletableFuture<>();
+        store.setDelegate(recordComplete::complete);
+        DhcpRecord removedRecord = store.removeDhcpRecord(HOST_ID).orElse(null);
+        assertEquals(record.locations(), removedRecord.locations());
+        assertEquals(record.vlanId(), removedRecord.vlanId());
+        assertEquals(record.macAddress(), removedRecord.macAddress());
+        assertEquals(record.ip4Address(), removedRecord.ip4Address());
+        assertEquals(record.nextHop(), removedRecord.nextHop());
+        assertEquals(record.ip4Status(), removedRecord.ip4Status());
+        assertEquals(record.ip6Address(), removedRecord.ip6Address());
+        assertEquals(record.ip6Status(), removedRecord.ip6Status());
+        assertEquals(record.directlyConnected(), removedRecord.directlyConnected());
+        event = recordComplete.join();
+        assertEquals(record, event.subject());
+        assertEquals(DhcpRelayStoreEvent.Type.REMOVED, event.type());
+        recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
+        assertNull(recordInStore);
+        recordsInStore = store.getDhcpRecords();
+        assertEquals(0, recordsInStore.size());
+    }
+}
diff --git a/apps/dhcprelay/app/src/test/resources/dhcp-relay.json b/apps/dhcprelay/app/src/test/resources/dhcp-relay.json
new file mode 100644
index 0000000..fe5da9c
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/resources/dhcp-relay.json
@@ -0,0 +1,39 @@
+{
+  "apps": {
+    "org.onosproject.dhcprelay" : {
+      "default": [
+        {
+          "dhcpServerConnectPoint": "of:0000000000000002/2",
+          "serverIps": ["172.168.10.2", "2000::200:1"],
+          "gatewayIps": ["192.168.10.254", "1000::100:1"],
+          "relayAgentIps": {
+            "of:0000000000000001": {
+              "ipv4": "10.0.0.10",
+              "ipv6": "2000::10"
+            },
+            "of:0000000000000002": {
+              "ipv4": "10.0.1.10",
+              "ipv6": "2000::1:10"
+            }
+          }
+        }
+      ],
+      "indirect": [
+        {
+          "dhcpServerConnectPoint": "of:0000000000000002/3",
+          "serverIps": ["172.168.10.3"],
+          "relayAgentIps": {
+            "of:0000000000000001": {
+              "ipv4": "10.0.0.10",
+              "ipv6": "2000::10"
+            }
+          }
+        }
+      ],
+      "ignoreDhcp": [
+        {"deviceId": "of:0000000000000001", "vlan": 100},
+        {"deviceId": "of:0000000000000002", "vlan": 100}
+      ]
+    }
+  }
+}
diff --git a/apps/dhcprelay/app/src/test/resources/invalid-dhcp-relay.json b/apps/dhcprelay/app/src/test/resources/invalid-dhcp-relay.json
new file mode 100644
index 0000000..2c67eaa
--- /dev/null
+++ b/apps/dhcprelay/app/src/test/resources/invalid-dhcp-relay.json
@@ -0,0 +1,12 @@
+{
+  "apps": {
+    "org.onosproject.dhcprelay" : {
+      "default": [
+        {
+          "dhcpServerConnectPoint": "of:0000000000000002/2",
+          "gatewayIps": ["192.168.10.254", "1000::100:1"]
+        }
+      ]
+    }
+  }
+}
