DHCP Config changes + null pointer checks + ONOS-2881

Change-Id: Ice391f539ae816329fde7970d762380a36fd7661
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java
index 20e1c61..7c2127f 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java
@@ -17,6 +17,7 @@
 
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
+import org.onosproject.net.HostId;
 
 import java.util.Map;
 
@@ -30,7 +31,7 @@
      *
      * @return collection of mappings.
      */
-    Map<MacAddress, IpAssignment> listMapping();
+    Map<HostId, IpAssignment> listMapping();
 
     /**
      * Returns the default lease time granted by the DHCP Server.
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java
index 4e2d67d..1637cf7 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java
@@ -17,6 +17,7 @@
 
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
+import org.onosproject.net.HostId;
 
 import java.util.Map;
 
@@ -36,21 +37,21 @@
     /**
      * Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message.
      *
-     * @param macID Mac ID of the client requesting an IP
+     * @param hostId Host ID of the client requesting an IP
      * @param requestedIP requested IP address
      * @return IP address assigned to the Mac ID
      */
-    Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP);
+    Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
 
     /**
      * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
      *
-     * @param macID Mac Id of the client requesting an IP
+     * @param hostId Host Id of the client requesting an IP
      * @param ipAddr IP Address being requested
      * @param leaseTime Lease time offered by the server for this mapping
      * @return returns true if the assignment was successful, false otherwise
      */
-    boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime);
+    boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime);
 
     /**
      * Sets the default time for which suggested IP mappings are valid.
@@ -60,25 +61,18 @@
     void setDefaultTimeoutForPurge(int timeInSeconds);
 
     /**
-     * Sets the delay after which the dhcp server will purge expired entries.
-     *
-     * @param timeInSeconds default time
-     */
-    void setTimerDelay(int timeInSeconds);
-
-    /**
      * Releases the IP assigned to a Mac ID into the free pool.
      *
-     * @param macID the macID for which the mapping needs to be changed
+     * @param hostId the host ID for which the mapping needs to be changed
      */
-    void releaseIP(MacAddress macID);
+    void releaseIP(HostId hostId);
 
     /**
      * Returns a collection of all the MacAddress to IPAddress mapping.
      *
      * @return the collection of the mappings
      */
-    Map<MacAddress, IpAssignment> listMapping();
+    Map<HostId, IpAssignment> listMapping();
 
     /**
      * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time.
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java
index ec6ade5..9b3aa68 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java
@@ -100,10 +100,19 @@
     /**
      * Returns the lease period of the IP assignment.
      *
-     * @return the lease period
+     * @return the lease period in seconds
      */
     public int leasePeriod() {
-        return (int) this.leasePeriod / 1000;
+        return (int) this.leasePeriod;
+    }
+
+    /**
+     * Returns the lease period of the IP assignment.
+     *
+     * @return the lease period in milliseconds
+     */
+    public int leasePeriodMs() {
+        return (int) this.leasePeriod * 1000;
     }
 
     @Override
@@ -155,7 +164,7 @@
         private Builder(IpAssignment ipAssignment) {
             ipAddress = ipAssignment.ipAddress();
             timeStamp = ipAssignment.timestamp();
-            leasePeriod = ipAssignment.leasePeriod() * 1000;
+            leasePeriod = ipAssignment.leasePeriod();
             assignmentStatus = ipAssignment.assignmentStatus();
         }
 
@@ -178,7 +187,7 @@
         }
 
         public Builder leasePeriod(int leasePeriodinSeconds) {
-            leasePeriod = leasePeriodinSeconds * 1000;
+            leasePeriod = leasePeriodinSeconds;
             return this;
         }
 
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
index fc470ce..209ba68 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
@@ -16,10 +16,10 @@
 package org.onosproject.dhcp.cli;
 
 import org.apache.karaf.shell.commands.Command;
-import org.onlab.packet.MacAddress;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.dhcp.DhcpService;
 import org.onosproject.dhcp.IpAssignment;
+import org.onosproject.net.HostId;
 
 import java.util.Map;
 
@@ -35,9 +35,9 @@
     protected void execute() {
 
         DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class);
-        Map<MacAddress, IpAssignment> allocationMap = dhcpService.listMapping();
+        Map<HostId, IpAssignment> allocationMap = dhcpService.listMapping();
 
-        for (Map.Entry<MacAddress, IpAssignment> entry : allocationMap.entrySet()) {
+        for (Map.Entry<HostId, IpAssignment> entry : allocationMap.entrySet()) {
             print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().ipAddress().toString());
         }
     }
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
index f8d5e63..85ea47b 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
@@ -15,6 +15,8 @@
  */
 package org.onosproject.dhcp.impl;
 
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.config.Config;
 import org.onosproject.net.config.basics.BasicElementConfig;
@@ -34,14 +36,19 @@
     public static final String LEASE_TIME = "lease";
     public static final String RENEW_TIME = "renew";
     public static final String REBIND_TIME = "rebind";
+    public static final String TIMER_DELAY = "delay";
+    public static final String DEFAULT_TIMEOUT = "timeout";
+    public static final String START_IP = "startip";
+    public static final String END_IP = "endip";
 
     /**
      * Returns the dhcp server ip.
      *
      * @return ip address or null if not set
      */
-    public String ip() {
-        return get(MY_IP, null);
+    public Ip4Address ip() {
+        String ip = get(MY_IP, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
     }
 
     /**
@@ -59,8 +66,9 @@
      *
      * @return server mac or null if not set
      */
-    public String mac() {
-        return get(MY_MAC, null);
+    public MacAddress mac() {
+        String mac = get(MY_MAC, null);
+        return mac != null ? MacAddress.valueOf(mac) : null;
     }
 
     /**
@@ -78,8 +86,9 @@
      *
      * @return subnet mask or null if not set
      */
-    public String subnetMask() {
-        return get(SUBNET_MASK, null);
+    public Ip4Address subnetMask() {
+        String ip = get(SUBNET_MASK, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
     }
 
     /**
@@ -97,8 +106,9 @@
      *
      * @return broadcast address or null if not set
      */
-    public String broadcastAddress() {
-        return get(BROADCAST_ADDRESS, null);
+    public Ip4Address broadcastAddress() {
+        String ip = get(BROADCAST_ADDRESS, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
     }
 
     /**
@@ -116,8 +126,8 @@
      *
      * @return ttl or null if not set
      */
-    public String ttl() {
-        return get(TTL, null);
+    public int ttl() {
+        return get(TTL, 0);
     }
 
     /**
@@ -126,7 +136,7 @@
      * @param ttl new ttl; null to clear
      * @return self
      */
-    public BasicElementConfig ttl(String ttl) {
+    public BasicElementConfig ttl(int ttl) {
         return (BasicElementConfig) setOrClear(TTL, ttl);
     }
 
@@ -135,8 +145,8 @@
      *
      * @return lease time or null if not set
      */
-    public String leaseTime() {
-        return get(LEASE_TIME, null);
+    public int leaseTime() {
+        return get(LEASE_TIME, 0);
     }
 
     /**
@@ -145,7 +155,7 @@
      * @param lease new lease time; null to clear
      * @return self
      */
-    public BasicElementConfig leaseTime(String lease) {
+    public BasicElementConfig leaseTime(int lease) {
         return (BasicElementConfig) setOrClear(LEASE_TIME, lease);
     }
 
@@ -154,8 +164,8 @@
      *
      * @return renew time or null if not set
      */
-    public String renewTime() {
-        return get(RENEW_TIME, null);
+    public int renewTime() {
+        return get(RENEW_TIME, 0);
     }
 
     /**
@@ -164,7 +174,7 @@
      * @param renew new renew time; null to clear
      * @return self
      */
-    public BasicElementConfig renewTime(String renew) {
+    public BasicElementConfig renewTime(int renew) {
         return (BasicElementConfig) setOrClear(RENEW_TIME, renew);
     }
 
@@ -173,8 +183,8 @@
      *
      * @return rebind time or null if not set
      */
-    public String rebindTime() {
-        return get(REBIND_TIME, null);
+    public int rebindTime() {
+        return get(REBIND_TIME, 0);
     }
 
     /**
@@ -183,7 +193,7 @@
      * @param rebind new rebind time; null to clear
      * @return self
      */
-    public BasicElementConfig rebindTime(String rebind) {
+    public BasicElementConfig rebindTime(int rebind) {
         return (BasicElementConfig) setOrClear(REBIND_TIME, rebind);
     }
 
@@ -192,8 +202,9 @@
      *
      * @return router address or null if not set
      */
-    public String routerAddress() {
-        return get(ROUTER_ADDRESS, null);
+    public Ip4Address routerAddress() {
+        String ip = get(ROUTER_ADDRESS, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
     }
 
     /**
@@ -211,8 +222,9 @@
      *
      * @return domain server address or null if not set
      */
-    public String domainServer() {
-        return get(DOMAIN_SERVER, null);
+    public Ip4Address domainServer() {
+        String ip = get(DOMAIN_SERVER, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
     }
 
     /**
@@ -224,4 +236,82 @@
     public BasicElementConfig domainServer(String domain) {
         return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain);
     }
+
+    /**
+     * Returns the delay after which the dhcp server will purge expired entries.
+     *
+     * @return time delay or null if not set
+     */
+    public int timerDelay() {
+        return get(TIMER_DELAY, 0);
+    }
+
+    /**
+     * Sets the delay after which the dhcp server will purge expired entries.
+     *
+     * @param delay new time delay; null to clear
+     * @return self
+     */
+    public BasicElementConfig timerDelay(int delay) {
+        return (BasicElementConfig) setOrClear(TIMER_DELAY, delay);
+    }
+
+    /**
+     * Returns the default timeout for pending assignments.
+     *
+     * @return default timeout or null if not set
+     */
+    public int defaultTimeout() {
+        return get(DEFAULT_TIMEOUT, 0);
+    }
+
+    /**
+     * Sets the default timeout for pending assignments.
+     *
+     * @param defaultTimeout new default timeout; null to clear
+     * @return self
+     */
+    public BasicElementConfig defaultTimeout(int defaultTimeout) {
+        return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout);
+    }
+
+    /**
+     * Returns the start IP for the available IP Range.
+     *
+     * @return start IP or null if not set
+     */
+    public Ip4Address startIp() {
+        String ip = get(START_IP, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
+    }
+
+    /**
+     * Sets the start IP for the available IP Range.
+     *
+     * @param startIp new start IP; null to clear
+     * @return self
+     */
+    public BasicElementConfig startIp(String startIp) {
+        return (BasicElementConfig) setOrClear(START_IP, startIp);
+    }
+
+    /**
+     * Returns the end IP for the available IP Range.
+     *
+     * @return end IP or null if not set
+     */
+    public Ip4Address endIp() {
+        String ip = get(END_IP, null);
+        return ip != null ? Ip4Address.valueOf(ip) : null;
+    }
+
+    /**
+     * Sets the end IP for the available IP Range.
+     *
+     * @param endIp new end IP; null to clear
+     * @return self
+     */
+    public BasicElementConfig endIp(String endIp) {
+        return (BasicElementConfig) setOrClear(END_IP, endIp);
+    }
 }
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
index bbb2dda..f3f2cee 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
@@ -22,6 +22,8 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.TimerTask;
 import org.onlab.packet.ARP;
 import org.onlab.packet.DHCP;
 import org.onlab.packet.DHCPOption;
@@ -34,20 +36,20 @@
 import org.onlab.packet.TpPort;
 import org.onlab.packet.UDP;
 import org.onlab.packet.VlanId;
+import org.onlab.util.Timer;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.dhcp.DhcpService;
 import org.onosproject.dhcp.DhcpStore;
 import org.onosproject.dhcp.IpAssignment;
-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.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
 import org.onosproject.net.HostLocation;
+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;
@@ -68,10 +70,12 @@
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import static org.onlab.packet.MacAddress.valueOf;
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
@@ -96,14 +100,6 @@
                 public DhcpConfig createConfig() {
                     return new DhcpConfig();
                 }
-            },
-            new ConfigFactory<ApplicationId, DhcpStoreConfig>(APP_SUBJECT_FACTORY,
-                    DhcpStoreConfig.class,
-                    "dhcpstore") {
-                @Override
-                public DhcpStoreConfig createConfig() {
-                    return new DhcpStoreConfig();
-                }
             }
     );
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -125,11 +121,13 @@
 
     protected HostProviderService hostProviderService;
 
+    private final HostProvider hostProvider = new InternalHostProvider();
+
     private ApplicationId appId;
 
     // Hardcoded values are default values.
 
-    private static String myIP = "10.0.0.2";
+    private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2");
 
     private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
 
@@ -147,14 +145,17 @@
 
     private static byte packetTTL = (byte) 127;
 
-    private static String subnetMask = "255.0.0.0";
+    private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0");
 
-    private static String broadcastAddress = "10.255.255.255";
+    private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255");
 
-    private static String routerAddress = "10.0.0.2";
+    private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2");
 
-    private static String domainServer = "10.0.0.2";
-    private final HostProvider hostProvider = new InternalHostProvider();
+    private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2");
+
+    protected Timeout timeout;
+
+    protected static int timerDelay = 2;
 
     @Activate
     protected void activate() {
@@ -164,11 +165,11 @@
         cfgService.addListener(cfgListener);
         factories.forEach(cfgService::registerConfigFactory);
         cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class));
-        cfgListener.reconfigureStore(cfgService.getConfig(appId, DhcpStoreConfig.class));
 
         hostProviderService = hostProviderRegistry.register(hostProvider);
         packetService.addProcessor(processor, PacketProcessor.director(0));
         requestPackets();
+        timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
         log.info("Started");
     }
 
@@ -180,6 +181,7 @@
         hostProviderRegistry.unregister(hostProvider);
         hostProviderService = null;
         cancelPackets();
+        timeout.cancel();
         log.info("Stopped");
     }
 
@@ -217,7 +219,7 @@
     }
 
     @Override
-    public Map<MacAddress, IpAssignment> listMapping() {
+    public Map<HostId, IpAssignment> listMapping() {
         return dhcpStore.listMapping();
     }
 
@@ -261,9 +263,7 @@
          * @param outgoingMessageType the message type of the outgoing packet
          * @return the Ethernet reply frame
          */
-        private Ethernet buildReply(Ethernet packet, String ipOffered, byte outgoingMessageType) {
-            Ip4Address myIPAddress = Ip4Address.valueOf(myIP);
-            Ip4Address ipAddress;
+        private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) {
 
             // Ethernet Frame.
             Ethernet ethReply = new Ethernet();
@@ -275,9 +275,8 @@
             // IP Packet
             IPv4 ipv4Packet = (IPv4) packet.getPayload();
             IPv4 ipv4Reply = new IPv4();
-            ipv4Reply.setSourceAddress(myIPAddress.toInt());
-            ipAddress = Ip4Address.valueOf(ipOffered);
-            ipv4Reply.setDestinationAddress(ipAddress.toInt());
+            ipv4Reply.setSourceAddress(myIP.toInt());
+            ipv4Reply.setDestinationAddress(ipOffered.toInt());
             ipv4Reply.setTtl(packetTTL);
 
             // UDP Datagram.
@@ -291,9 +290,8 @@
             DHCP dhcpReply = new DHCP();
             dhcpReply.setOpCode(DHCP.OPCODE_REPLY);
 
-            ipAddress = Ip4Address.valueOf(ipOffered);
-            dhcpReply.setYourIPAddress(ipAddress.toInt());
-            dhcpReply.setServerIPAddress(myIPAddress.toInt());
+            dhcpReply.setYourIPAddress(ipOffered.toInt());
+            dhcpReply.setServerIPAddress(myIP.toInt());
 
             dhcpReply.setTransactionId(dhcpPacket.getTransactionId());
             dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress());
@@ -315,7 +313,7 @@
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue());
             option.setLength((byte) 4);
-            option.setData(myIPAddress.toOctets());
+            option.setData(myIP.toOctets());
             optionList.add(option);
 
             // IP Address Lease Time.
@@ -343,32 +341,28 @@
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue());
             option.setLength((byte) 4);
-            ipAddress = Ip4Address.valueOf(subnetMask);
-            option.setData(ipAddress.toOctets());
+            option.setData(subnetMask.toOctets());
             optionList.add(option);
 
             // Broadcast Address.
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue());
             option.setLength((byte) 4);
-            ipAddress = Ip4Address.valueOf(broadcastAddress);
-            option.setData(ipAddress.toOctets());
+            option.setData(broadcastAddress.toOctets());
             optionList.add(option);
 
             // Router Address.
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
             option.setLength((byte) 4);
-            ipAddress = Ip4Address.valueOf(routerAddress);
-            option.setData(ipAddress.toOctets());
+            option.setData(routerAddress.toOctets());
             optionList.add(option);
 
             // DNS Server Address.
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
             option.setLength((byte) 4);
-            ipAddress = Ip4Address.valueOf(domainServer);
-            option.setData(ipAddress.toOctets());
+            option.setData(domainServer.toOctets());
             optionList.add(option);
 
             // End Option.
@@ -418,12 +412,11 @@
 
             if (dhcpPayload != null) {
 
-                // TODO Convert this to enum value.
-                byte incomingPacketType = 0;
+                DHCPPacketType incomingPacketType = DHCPPacketType.getType(0);
                 for (DHCPOption option : dhcpPayload.getOptions()) {
                     if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) {
                         byte[] data = option.getData();
-                        incomingPacketType = data[0];
+                        incomingPacketType = DHCPPacketType.getType(data[0]);
                     }
                     if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) {
                         byte[] data = option.getData();
@@ -436,37 +429,39 @@
                         flagIfServerIP = true;
                     }
                 }
-
-                String ipOffered = "";
                 DHCPPacketType outgoingPacketType;
                 MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress());
+                VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+                HostId hostId = HostId.hostId(clientMAC, vlanId);
 
-                if (incomingPacketType == DHCPPacketType.DHCPDISCOVER.getValue()) {
+                if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) {
 
                     outgoingPacketType = DHCPPacketType.DHCPOFFER;
-                    ipOffered = dhcpStore.suggestIP(clientMAC, requestedIP).toString();
+                    Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
+                    if (ipOffered != null) {
+                        Ethernet ethReply = buildReply(packet, ipOffered,
+                                (byte) outgoingPacketType.getValue());
+                        sendReply(context, ethReply);
+                    }
 
-                    Ethernet ethReply = buildReply(packet, ipOffered, (byte) outgoingPacketType.getValue());
-                    sendReply(context, ethReply);
-
-                } else if (incomingPacketType == DHCPPacketType.DHCPREQUEST.getValue()) {
+                } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) {
 
                     outgoingPacketType = DHCPPacketType.DHCPACK;
 
                     if (flagIfServerIP && flagIfRequestedIP) {
                         // SELECTING state
-                        if (myIP.equals(serverIP.toString()) &&
-                                dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) {
+                        if (myIP.equals(serverIP) &&
+                                dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
 
-                            Ethernet ethReply = buildReply(packet, requestedIP.toString(),
+                            Ethernet ethReply = buildReply(packet, requestedIP,
                                     (byte) outgoingPacketType.getValue());
                             sendReply(context, ethReply);
                             discoverHost(context, requestedIP);
                         }
                     } else if (flagIfRequestedIP) {
                         // INIT-REBOOT state
-                        if (dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) {
-                            Ethernet ethReply = buildReply(packet, requestedIP.toString(),
+                        if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
+                            Ethernet ethReply = buildReply(packet, requestedIP,
                                     (byte) outgoingPacketType.getValue());
                             sendReply(context, ethReply);
                             discoverHost(context, requestedIP);
@@ -476,16 +471,16 @@
                         int ciaadr = dhcpPayload.getClientIPAddress();
                         if (ciaadr != 0) {
                             Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr);
-                            if (dhcpStore.assignIP(clientMAC, clientIaddr, leaseTime)) {
-                                Ethernet ethReply = buildReply(packet, clientIaddr.toString(),
+                            if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) {
+                                Ethernet ethReply = buildReply(packet, clientIaddr,
                                         (byte) outgoingPacketType.getValue());
                                 sendReply(context, ethReply);
                                 discoverHost(context, clientIaddr);
                             }
                         }
                     }
-                } else if (incomingPacketType == DHCPPacketType.DHCPRELEASE.getValue()) {
-                    dhcpStore.releaseIP(clientMAC);
+                } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) {
+                    dhcpStore.releaseIP(hostId);
                 }
             }
         }
@@ -564,7 +559,7 @@
                 ARP arpPacket = (ARP) packet.getPayload();
 
                 if ((arpPacket.getOpCode() == ARP.OP_REQUEST) &&
-                        (Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()).toString().equals(myIP))) {
+                        (myIP).equals(Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) {
 
                     processARPPacket(context, packet);
 
@@ -588,7 +583,7 @@
                 myIP = cfg.ip();
             }
             if (cfg.mac() != null) {
-                myMAC = MacAddress.valueOf(cfg.mac());
+                myMAC = cfg.mac();
             }
             if (cfg.subnetMask() != null) {
                 subnetMask = cfg.subnetMask();
@@ -602,57 +597,40 @@
             if (cfg.domainServer() != null) {
                 domainServer = cfg.domainServer();
             }
-            if (cfg.ttl() != null) {
-                packetTTL = Byte.valueOf(cfg.ttl());
+            if (cfg.ttl() != 0) {
+                packetTTL = (byte) cfg.ttl();
             }
-            if (cfg.leaseTime() != null) {
-                leaseTime = Integer.valueOf(cfg.leaseTime());
+            if (cfg.leaseTime() != 0) {
+                leaseTime = cfg.leaseTime();
             }
-            if (cfg.renewTime() != null) {
-                renewalTime = Integer.valueOf(cfg.renewTime());
+            if (cfg.renewTime() != 0) {
+                renewalTime = cfg.renewTime();
             }
-            if (cfg.rebindTime() != null) {
-                rebindingTime = Integer.valueOf(cfg.rebindTime());
+            if (cfg.rebindTime() != 0) {
+                rebindingTime = cfg.rebindTime();
+            }
+            if (cfg.defaultTimeout() != 0) {
+                dhcpStore.setDefaultTimeoutForPurge(cfg.defaultTimeout());
+            }
+            if (cfg.timerDelay() != 0) {
+                timerDelay = cfg.timerDelay();
+            }
+            if ((cfg.startIp() != null) && (cfg.endIp() != null)) {
+                dhcpStore.populateIPPoolfromRange(cfg.startIp(), cfg.endIp());
             }
         }
 
-        /**
-         * Reconfigures the DHCP Store according to the configuration parameters passed.
-         *
-         * @param cfg configuration object
-         */
-        private void reconfigureStore(DhcpStoreConfig cfg) {
-            if (cfg == null) {
-                return;
-            }
-
-            if (cfg.defaultTimeout() != null) {
-                dhcpStore.setDefaultTimeoutForPurge(Integer.valueOf(cfg.defaultTimeout()));
-            }
-            if (cfg.timerDelay() != null) {
-                dhcpStore.setTimerDelay(Integer.valueOf(cfg.defaultTimeout()));
-            }
-            if ((cfg.startIP() != null) && (cfg.endIP() != null)) {
-                dhcpStore.populateIPPoolfromRange(Ip4Address.valueOf(cfg.startIP()),
-                        Ip4Address.valueOf(cfg.endIP()));
-            }
-        }
 
         @Override
         public void event(NetworkConfigEvent event) {
 
             if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
-                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) {
-                if (event.configClass().equals(DhcpConfig.class)) {
-                    DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class);
-                    reconfigureNetwork(cfg);
-                    log.info("Reconfigured Manager");
-                }
-                if (event.configClass().equals(DhcpStoreConfig.class)) {
-                    DhcpStoreConfig cfg = cfgService.getConfig(appId, DhcpStoreConfig.class);
-                    reconfigureStore(cfg);
-                    log.info("Reconfigured Store");
-                }
+                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
+                    event.configClass().equals(DhcpConfig.class)) {
+
+                DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class);
+                reconfigureNetwork(cfg);
+                log.info("Reconfigured");
             }
         }
     }
@@ -671,4 +649,27 @@
             // nothing to do
         }
     }
+
+    private class PurgeListTask implements TimerTask {
+
+        @Override
+        public void run(Timeout to) {
+            IpAssignment ipAssignment;
+            Date dateNow = new Date();
+
+            Map<HostId, IpAssignment> ipAssignmentMap = dhcpStore.listMapping();
+            for (Map.Entry<HostId, IpAssignment> entry: ipAssignmentMap.entrySet()) {
+                ipAssignment = entry.getValue();
+
+                long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime();
+                if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) &&
+                        (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) {
+
+                    dhcpStore.releaseIP(entry.getKey());
+                    hostProviderService.hostVanished(entry.getKey());
+                }
+            }
+            timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
+        }
+    }
 }
\ No newline at end of file
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpStoreConfig.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpStoreConfig.java
deleted file mode 100644
index db4672d..0000000
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpStoreConfig.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2014 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.dhcp.impl;
-
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.Config;
-import org.onosproject.net.config.basics.BasicElementConfig;
-
-/**
- * DHCP Store Config class.
- */
-public class DhcpStoreConfig extends Config<ApplicationId> {
-
-    // FIXME: combine with the other config and properly type the values
-
-    public static final String TIMER_DELAY = "delay";
-    public static final String DEFAULT_TIMEOUT = "timeout";
-    public static final String START_IP = "startip";
-    public static final String END_IP = "endip";
-
-    /**
-     * Returns the delay after which the dhcp server will purge expired entries.
-     *
-     * @return time delay or null if not set
-     */
-    public String timerDelay() {
-        return get(TIMER_DELAY, null);
-    }
-
-    /**
-     * Sets the delay after which the dhcp server will purge expired entries.
-     *
-     * @param delay new time delay; null to clear
-     * @return self
-     */
-    public BasicElementConfig timerDelay(String delay) {
-        return (BasicElementConfig) setOrClear(TIMER_DELAY, delay);
-    }
-
-    /**
-     * Returns the default timeout for pending assignments.
-     *
-     * @return default timeout or null if not set
-     */
-    public String defaultTimeout() {
-        return get(DEFAULT_TIMEOUT, null);
-    }
-
-    /**
-     * Sets the default timeout for pending assignments.
-     *
-     * @param defaultTimeout new default timeout; null to clear
-     * @return self
-     */
-    public BasicElementConfig defaultTimeout(String defaultTimeout) {
-        return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout);
-    }
-
-    /**
-     * Returns the start IP for the available IP Range.
-     *
-     * @return start IP or null if not set
-     */
-    public String startIP() {
-        return get(START_IP, null);
-    }
-
-    /**
-     * Sets the start IP for the available IP Range.
-     *
-     * @param startIP new start IP; null to clear
-     * @return self
-     */
-    public BasicElementConfig startIP(String startIP) {
-        return (BasicElementConfig) setOrClear(START_IP, startIP);
-    }
-
-    /**
-     * Returns the end IP for the available IP Range.
-     *
-     * @return end IP or null if not set
-     */
-    public String endIP() {
-        return get(END_IP, null);
-    }
-
-    /**
-     * Sets the end IP for the available IP Range.
-     *
-     * @param endIP new end IP; null to clear
-     * @return self
-     */
-    public BasicElementConfig endIP(String endIP) {
-        return (BasicElementConfig) setOrClear(END_IP, endIP);
-    }
-}
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
index 2b3bfd5..9ce65d5 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
@@ -17,10 +17,10 @@
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.ImmutableSet;
-import org.onlab.packet.MacAddress;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.dhcp.DhcpService;
 import org.onosproject.dhcp.IpAssignment;
+import org.onosproject.net.HostId;
 import org.onosproject.ui.RequestHandler;
 import org.onosproject.ui.UiMessageHandler;
 import org.onosproject.ui.table.TableModel;
@@ -39,12 +39,12 @@
     private static final String DHCP_DATA_RESP = "dhcpDataResponse";
     private static final String DHCP = "dhcps";
 
-    private static final String MAC = "mac";
+    private static final String HOST = "host";
     private static final String IP = "ip";
     private static final String LEASE = "lease";
 
     private static final String[] COL_IDS = {
-            MAC, IP, LEASE
+            HOST, IP, LEASE
     };
 
     @Override
@@ -63,7 +63,7 @@
 
         @Override
         protected String defaultColumnId() {
-            return MAC;
+            return HOST;
         }
 
         @Override
@@ -74,21 +74,21 @@
         @Override
         protected void populateTable(TableModel tm, ObjectNode payload) {
             DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class);
-            Map<MacAddress, IpAssignment> allocationMap = dhcpService.listMapping();
+            Map<HostId, IpAssignment> allocationMap = dhcpService.listMapping();
 
-            for (Map.Entry<MacAddress, IpAssignment> entry : allocationMap.entrySet()) {
+            for (Map.Entry<HostId, IpAssignment> entry : allocationMap.entrySet()) {
                 populateRow(tm.addRow(), entry);
             }
         }
 
-        private void populateRow(TableModel.Row row, Map.Entry<MacAddress, IpAssignment> entry) {
+        private void populateRow(TableModel.Row row, Map.Entry<HostId, IpAssignment> entry) {
             if (entry.getValue().leasePeriod() > 0) {
                 Date now = new Date(entry.getValue().timestamp().getTime() + entry.getValue().leasePeriod());
-                row.cell(MAC, entry.getKey())
+                row.cell(HOST, entry.getKey())
                         .cell(IP, entry.getValue().ipAddress())
                         .cell(LEASE, now.toString());
             } else {
-                row.cell(MAC, entry.getKey())
+                row.cell(HOST, entry.getKey())
                         .cell(IP, entry.getValue().ipAddress())
                         .cell(LEASE, "Infinite Static Lease");
             }
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
index 6a74cf5..96013b6 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
@@ -22,14 +22,12 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
 import org.onlab.util.KryoNamespace;
-import org.onlab.util.Timer;
 import org.onosproject.dhcp.DhcpStore;
 import org.onosproject.dhcp.IpAssignment;
+import org.onosproject.net.HostId;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.DistributedSet;
@@ -42,7 +40,6 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Manages the pool of available IP Addresses in the network and
@@ -58,25 +55,21 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected StorageService storageService;
 
-    private ConsistentMap<MacAddress, IpAssignment> allocationMap;
+    private ConsistentMap<HostId, IpAssignment> allocationMap;
 
     private DistributedSet<Ip4Address> freeIPPool;
 
-    private Timeout timeout;
-
     private static Ip4Address startIPRange;
 
     private static Ip4Address endIPRange;
 
     // Hardcoded values are default values.
 
-    private static int timerDelay = 2;
-
     private static int timeoutForPendingAssignments = 60;
 
     @Activate
     protected void activate() {
-        allocationMap = storageService.<MacAddress, IpAssignment>consistentMapBuilder()
+        allocationMap = storageService.<HostId, IpAssignment>consistentMapBuilder()
                 .withName("onos-dhcp-assignedIP")
                 .withSerializer(Serializer.using(
                         new KryoNamespace.Builder()
@@ -94,23 +87,20 @@
                 .withSerializer(Serializer.using(KryoNamespaces.API))
                 .build();
 
-        timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
-
         log.info("Started");
     }
 
     @Deactivate
     protected void deactivate() {
-        timeout.cancel();
         log.info("Stopped");
     }
 
     @Override
-    public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) {
+    public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) {
 
         IpAssignment assignmentInfo;
-        if (allocationMap.containsKey(macID)) {
-            assignmentInfo = allocationMap.get(macID).value();
+        if (allocationMap.containsKey(hostId)) {
+            assignmentInfo = allocationMap.get(hostId).value();
             IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
             Ip4Address ipAddr = assignmentInfo.ipAddress();
 
@@ -131,7 +121,7 @@
                             .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
                             .build();
                     if (freeIPPool.remove(ipAddr)) {
-                        allocationMap.put(macID, assignmentInfo);
+                        allocationMap.put(hostId, assignmentInfo);
                         return ipAddr;
                     }
                 }
@@ -148,7 +138,7 @@
                         .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
                         .build();
                 if (freeIPPool.remove(requestedIP)) {
-                    allocationMap.put(macID, assignmentInfo);
+                    allocationMap.put(hostId, assignmentInfo);
                     return requestedIP;
                 }
             }
@@ -156,24 +146,26 @@
 
         // Allocate a new IP from the server's pool of available IP.
         Ip4Address nextIPAddr = fetchNextIP();
-        assignmentInfo = IpAssignment.builder()
-                                    .ipAddress(nextIPAddr)
-                                    .timestamp(new Date())
-                                    .leasePeriod(timeoutForPendingAssignments)
-                                    .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
-                                    .build();
+        if (nextIPAddr != null) {
+            assignmentInfo = IpAssignment.builder()
+                    .ipAddress(nextIPAddr)
+                    .timestamp(new Date())
+                    .leasePeriod(timeoutForPendingAssignments)
+                    .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
+                    .build();
 
-        allocationMap.put(macID, assignmentInfo);
+            allocationMap.put(hostId, assignmentInfo);
+        }
         return nextIPAddr;
 
     }
 
     @Override
-    public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) {
+    public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
 
         IpAssignment assignmentInfo;
-        if (allocationMap.containsKey(macID)) {
-            assignmentInfo = allocationMap.get(macID).value();
+        if (allocationMap.containsKey(hostId)) {
+            assignmentInfo = allocationMap.get(hostId).value();
             if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) &&
                     (ipAddr.toInt() >= startIPRange.toInt()) && (ipAddr.toInt() <= endIPRange.toInt())) {
 
@@ -183,7 +175,7 @@
                         .leasePeriod(leaseTime)
                         .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
                         .build();
-                allocationMap.put(macID, assignmentInfo);
+                allocationMap.put(hostId, assignmentInfo);
                 return true;
             }
         } else if (freeIPPool.contains(ipAddr)) {
@@ -194,7 +186,7 @@
                                     .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
                                     .build();
             if (freeIPPool.remove(ipAddr)) {
-                allocationMap.put(macID, assignmentInfo);
+                allocationMap.put(hostId, assignmentInfo);
                 return true;
             }
         }
@@ -202,14 +194,16 @@
     }
 
     @Override
-    public void releaseIP(MacAddress macID) {
-        if (allocationMap.containsKey(macID)) {
-            IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(macID).value())
+    public void releaseIP(HostId hostId) {
+        if (allocationMap.containsKey(hostId)) {
+            IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value())
                                                     .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
                                                     .build();
             Ip4Address freeIP = newAssignment.ipAddress();
-            allocationMap.put(macID, newAssignment);
-            freeIPPool.add(freeIP);
+            allocationMap.put(hostId, newAssignment);
+            if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
+                freeIPPool.add(freeIP);
+            }
         }
     }
 
@@ -219,15 +213,10 @@
     }
 
     @Override
-    public void setTimerDelay(int timeInSeconds) {
-        timerDelay = timeInSeconds;
-    }
+    public Map<HostId, IpAssignment> listMapping() {
 
-    @Override
-    public Map<MacAddress, IpAssignment> listMapping() {
-
-        Map<MacAddress, IpAssignment> allMapping = new HashMap<>();
-        for (Map.Entry<MacAddress, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
+        Map<HostId, IpAssignment> allMapping = new HashMap<>();
+        for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
             IpAssignment assignment = entry.getValue().value();
             if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) {
                 allMapping.put(entry.getKey(), assignment);
@@ -239,17 +228,21 @@
 
     @Override
     public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) {
-        return assignIP(macID, ipAddr, -1);
+        HostId host = HostId.hostId(macID);
+        return assignIP(host, ipAddr, -1);
     }
 
     @Override
     public boolean removeStaticIP(MacAddress macID) {
-        if (allocationMap.containsKey(macID)) {
-            IpAssignment assignment = allocationMap.get(macID).value();
+        HostId host = HostId.hostId(macID);
+        if (allocationMap.containsKey(host)) {
+            IpAssignment assignment = allocationMap.get(host).value();
             Ip4Address freeIP = assignment.ipAddress();
             if (assignment.leasePeriod() < 0) {
-                allocationMap.remove(macID);
-                freeIPPool.add(freeIP);
+                allocationMap.remove(host);
+                if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
+                    freeIPPool.add(freeIP);
+                }
                 return true;
             }
         }
@@ -289,36 +282,4 @@
         }
         return null;
     }
-
-    /**
-     * Purges the IP allocation map to remove expired entries and returns the freed IPs to the free pool.
-     */
-    private class PurgeListTask implements TimerTask {
-
-        @Override
-        public void run(Timeout to) {
-            IpAssignment ipAssignment, newAssignment;
-            Date dateNow = new Date();
-            for (Map.Entry<MacAddress, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
-                ipAssignment = entry.getValue().value();
-                long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime();
-                if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) &&
-                        (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriod()))) {
-                    Ip4Address freeIP = ipAssignment.ipAddress();
-
-                    newAssignment = IpAssignment.builder(ipAssignment)
-                            .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
-                            .build();
-                    allocationMap.put(entry.getKey(), newAssignment);
-
-                    if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
-                        freeIPPool.add(freeIP);
-                    }
-                }
-            }
-            timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
-        }
-
-    }
-
 }
diff --git a/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java b/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
index bfa2767..646ab7e 100644
--- a/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
+++ b/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
@@ -22,6 +22,7 @@
 import org.onlab.packet.MacAddress;
 import org.onosproject.dhcp.DhcpService;
 import org.onosproject.dhcp.IpAssignment;
+import org.onosproject.net.HostId;
 import org.onosproject.rest.AbstractWebResource;
 
 import javax.ws.rs.Consumes;
@@ -72,10 +73,10 @@
     public Response listMappings() {
         ObjectNode root = mapper().createObjectNode();
 
-        final Map<MacAddress, IpAssignment> intents = service.listMapping();
+        final Map<HostId, IpAssignment> intents = service.listMapping();
         ArrayNode arrayNode = root.putArray("mappings");
         intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
-                .put("mac", i.getKey().toString())
+                .put("host", i.getKey().toString())
                 .put("ip", i.getValue().ipAddress().toString())));
 
         return ok(root.toString()).build();
@@ -125,10 +126,10 @@
                 }
             }
 
-            final Map<MacAddress, IpAssignment> intents = service.listMapping();
+            final Map<HostId, IpAssignment> intents = service.listMapping();
             ArrayNode arrayNode = root.putArray("mappings");
             intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
-                    .put("mac", i.getKey().toString())
+                    .put("host", i.getKey().toString())
                     .put("ip", i.getValue().ipAddress().toString())));
         } catch (IOException e) {
             throw new IllegalArgumentException(e.getMessage());
@@ -152,10 +153,10 @@
         if (!service.removeStaticMapping(MacAddress.valueOf(macID))) {
             throw new IllegalArgumentException("Static Mapping Removal Failed.");
         }
-        final Map<MacAddress, IpAssignment> intents = service.listMapping();
+        final Map<HostId, IpAssignment> intents = service.listMapping();
         ArrayNode arrayNode = root.putArray("mappings");
         intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
-                .put("mac", i.getKey().toString())
+                .put("host", i.getKey().toString())
                 .put("ip", i.getValue().ipAddress().toString())));
 
         return ok(root.toString()).build();
diff --git a/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html b/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html
index 3e14570..5782bad 100644
--- a/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html
+++ b/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html
@@ -17,7 +17,7 @@
     <div class="table-header" onos-sortable-header>
       <table>
         <tr>
-          <td colId="mac" sortable>MAC Address</td>
+          <td colId="host" sortable>Host ID</td>
           <td colId="ip" sortable>IP Address</td>
           <td colId="lease" sortable>Lease Expiry</td>
         </tr>
@@ -25,7 +25,7 @@
     </div>
 
     <div class="table-body">
-      <table onos-flash-changes id-prop="mac">
+      <table onos-flash-changes id-prop="host">
         <tr ng-if="!tableData.length" class="no-data">
           <td colspan="2">
             No mappings found
@@ -34,8 +34,8 @@
 
         <tr ng-repeat="dhcp in tableData track by $index"
             ng-click="selectCallback($event, dhcp)"
-            ng-repeat-complete row-id="{{dhcp.mac}}">
-          <td>{{dhcp.mac}}</td>
+            ng-repeat-complete row-id="{{dhcp.host}}">
+          <td>{{dhcp.host}}</td>
           <td>{{dhcp.ip}}</td>
           <td>{{dhcp.lease}}</td>
         </tr>
diff --git a/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
index 42ac73d..85c9d5c 100644
--- a/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
+++ b/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
@@ -72,7 +72,7 @@
 
     protected HostProviderService hostProviderService;
 
-    private static final MacAddress CLIENT1_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+    private static final HostId CLIENT1_HOST = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
 
     private static final String EXPECTED_IP = "10.2.0.2";
 
@@ -141,7 +141,7 @@
 
         // Ethernet Frame.
         Ethernet ethReply = new Ethernet();
-        ethReply.setSourceMACAddress(CLIENT1_MAC);
+        ethReply.setSourceMACAddress(CLIENT1_HOST.mac());
         ethReply.setDestinationMACAddress(MacAddress.BROADCAST);
         ethReply.setEtherType(Ethernet.TYPE_IPV4);
         ethReply.setVlanID((short) 2);
@@ -165,7 +165,7 @@
         dhcpReply.setServerIPAddress(0);
 
         dhcpReply.setTransactionId(TRANSACTION_ID);
-        dhcpReply.setClientHardwareAddress(CLIENT1_MAC.toBytes());
+        dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes());
         dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
         dhcpReply.setHardwareAddressLength((byte) 6);
 
@@ -209,7 +209,7 @@
      */
     private void validatePacket(Ethernet packet) {
         DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
-        assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_MAC);
+        assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac());
         assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
         assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);
     }
@@ -223,32 +223,29 @@
         public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) {
         }
 
-        public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) {
+        public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) {
             return Ip4Address.valueOf(EXPECTED_IP);
         }
 
-        public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) {
+        public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
             return true;
         }
 
         public void setDefaultTimeoutForPurge(int timeInSeconds) {
         }
 
-        public void setTimerDelay(int timeInSeconds) {
+        public void releaseIP(HostId hostId) {
         }
 
-        public void releaseIP(MacAddress macID) {
-        }
-
-        public Map<MacAddress, IpAssignment> listMapping() {
-            Map<MacAddress, IpAssignment> map = new HashMap<>();
+        public Map<HostId, IpAssignment> listMapping() {
+            Map<HostId, IpAssignment> map = new HashMap<>();
             IpAssignment assignment = IpAssignment.builder()
                                         .ipAddress(Ip4Address.valueOf(EXPECTED_IP))
                                         .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
                                         .leasePeriod(300)
                                         .timestamp(new Date())
                                         .build();
-            map.put(CLIENT1_MAC, assignment);
+            map.put(CLIENT1_HOST, assignment);
             return map;
         }
 
diff --git a/apps/dhcp/src/test/resources/dhcp-cfg.json b/apps/dhcp/src/test/resources/dhcp-cfg.json
index 8ce5486..abc48a8 100644
--- a/apps/dhcp/src/test/resources/dhcp-cfg.json
+++ b/apps/dhcp/src/test/resources/dhcp-cfg.json
@@ -11,9 +11,7 @@
         "ttl": "63",
         "lease": "300",
         "renew": "150",
-        "rebind": "200"
-      },
-      "dhcpstore" : {
+        "rebind": "200",
         "delay": "3",
         "timeout": "150",
         "startip": "10.0.0.110",