ONOS-2197 Enabling configuration using a json file for the DHCP server
Change-Id: I2e2998eec134d8e230a806c898e8f15d5cd1b559
diff --git a/onos-app-dhcpserver/pom.xml b/onos-app-dhcpserver/pom.xml
index 8f9000e..33a1f42 100644
--- a/onos-app-dhcpserver/pom.xml
+++ b/onos-app-dhcpserver/pom.xml
@@ -63,6 +63,12 @@
<artifactId>onos-core-serializers</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/DHCPStore.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/DHCPStore.java
index 29cb277..e2cabbd 100644
--- a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/DHCPStore.java
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/DHCPStore.java
@@ -26,6 +26,14 @@
public interface DHCPStore {
/**
+ * Appends all the IPs in a given range to the free pool of IPs.
+ *
+ * @param startIP Start IP for the range
+ * @param endIP End IP for the range
+ */
+ void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP);
+
+ /**
* 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
@@ -51,6 +59,13 @@
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
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPConfig.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPConfig.java
new file mode 100644
index 0000000..4b678f1
--- /dev/null
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPConfig.java
@@ -0,0 +1,187 @@
+/*
+ * 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.dhcpserver.impl;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.Config;
+import org.onosproject.incubator.net.config.basics.BasicElementConfig;
+
+/**
+ * DHCP Config class.
+ */
+public class DHCPConfig extends Config<ApplicationId> {
+
+ public static final String MY_IP = "ip";
+ public static final String MY_MAC = "mac";
+ public static final String SUBNET_MASK = "subnet";
+ public static final String BROADCAST_ADDRESS = "broadcast";
+ public static final String TTL = "ttl";
+ public static final String LEASE_TIME = "lease";
+ public static final String RENEW_TIME = "renew";
+ public static final String REBIND_TIME = "rebind";
+
+ /**
+ * Returns the dhcp server ip.
+ *
+ * @return ip address or null if not set
+ */
+ public String ip() {
+ return get(MY_IP, null);
+ }
+
+ /**
+ * Sets the dhcp server ip.
+ *
+ * @param ip new ip address; null to clear
+ * @return self
+ */
+ public BasicElementConfig ip(String ip) {
+ return (BasicElementConfig) setOrClear(MY_IP, ip);
+ }
+
+ /**
+ * Returns the dhcp server mac.
+ *
+ * @return server mac or null if not set
+ */
+ public String mac() {
+ return get(MY_MAC, null);
+ }
+
+ /**
+ * Sets the dhcp server mac.
+ *
+ * @param mac new mac address; null to clear
+ * @return self
+ */
+ public BasicElementConfig mac(String mac) {
+ return (BasicElementConfig) setOrClear(MY_MAC, mac);
+ }
+
+ /**
+ * Returns the subnet mask.
+ *
+ * @return subnet mask or null if not set
+ */
+ public String subnetMask() {
+ return get(SUBNET_MASK, null);
+ }
+
+ /**
+ * Sets the subnet mask.
+ *
+ * @param subnet new subnet mask; null to clear
+ * @return self
+ */
+ public BasicElementConfig subnetMask(String subnet) {
+ return (BasicElementConfig) setOrClear(SUBNET_MASK, subnet);
+ }
+
+ /**
+ * Returns the broadcast address.
+ *
+ * @return broadcast address or null if not set
+ */
+ public String broadcastAddress() {
+ return get(BROADCAST_ADDRESS, null);
+ }
+
+ /**
+ * Sets the broadcast address.
+ *
+ * @param broadcast new broadcast address; null to clear
+ * @return self
+ */
+ public BasicElementConfig broadcastAddress(String broadcast) {
+ return (BasicElementConfig) setOrClear(BROADCAST_ADDRESS, broadcast);
+ }
+
+ /**
+ * Returns the Time To Live for the reply packets.
+ *
+ * @return ttl or null if not set
+ */
+ public String ttl() {
+ return get(TTL, null);
+ }
+
+ /**
+ * Sets the Time To Live for the reply packets.
+ *
+ * @param ttl new ttl; null to clear
+ * @return self
+ */
+ public BasicElementConfig ttl(String ttl) {
+ return (BasicElementConfig) setOrClear(TTL, ttl);
+ }
+
+ /**
+ * Returns the Lease Time offered by the DHCP Server.
+ *
+ * @return lease time or null if not set
+ */
+ public String leaseTime() {
+ return get(LEASE_TIME, null);
+ }
+
+ /**
+ * Sets the Lease Time offered by the DHCP Server.
+ *
+ * @param lease new lease time; null to clear
+ * @return self
+ */
+ public BasicElementConfig leaseTime(String lease) {
+ return (BasicElementConfig) setOrClear(LEASE_TIME, lease);
+ }
+
+ /**
+ * Returns the Renew Time offered by the DHCP Server.
+ *
+ * @return renew time or null if not set
+ */
+ public String renewTime() {
+ return get(RENEW_TIME, null);
+ }
+
+ /**
+ * Sets the Renew Time offered by the DHCP Server.
+ *
+ * @param renew new renew time; null to clear
+ * @return self
+ */
+ public BasicElementConfig renewTime(String renew) {
+ return (BasicElementConfig) setOrClear(RENEW_TIME, renew);
+ }
+
+ /**
+ * Returns the Rebind Time offered by the DHCP Server.
+ *
+ * @return rebind time or null if not set
+ */
+ public String rebindTime() {
+ return get(REBIND_TIME, null);
+ }
+
+ /**
+ * Sets the Rebind Time offered by the DHCP Server.
+ *
+ * @param rebind new rebind time; null to clear
+ * @return self
+ */
+ public BasicElementConfig rebindTime(String rebind) {
+ return (BasicElementConfig) setOrClear(REBIND_TIME, rebind);
+ }
+}
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
index ee995d0..39cf17d 100644
--- a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.dhcpserver.impl;
+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;
@@ -32,6 +33,10 @@
import org.onosproject.core.CoreService;
import org.onosproject.dhcpserver.DHCPService;
import org.onosproject.dhcpserver.DHCPStore;
+import org.onosproject.incubator.net.config.ConfigFactory;
+import org.onosproject.incubator.net.config.NetworkConfigEvent;
+import org.onosproject.incubator.net.config.NetworkConfigListener;
+import org.onosproject.incubator.net.config.NetworkConfigRegistry;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -49,8 +54,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.onlab.packet.MacAddress.valueOf;
+import static org.onosproject.incubator.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
/**
* Skeletal ONOS DHCP Server application.
@@ -61,6 +68,29 @@
private final Logger log = LoggerFactory.getLogger(getClass());
+ private final NetworkConfigListener cfgListener = new InternalConfigListener();
+
+ private final Set<ConfigFactory> factories = ImmutableSet.of(
+ new ConfigFactory<ApplicationId, DHCPConfig>(APP_SUBJECT_FACTORY,
+ DHCPConfig.class,
+ "dhcp") {
+ @Override
+ 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)
+ protected NetworkConfigRegistry cfgService;
+
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
@@ -74,11 +104,11 @@
private ApplicationId appId;
- // TODO Make the hardcoded values configurable.
+ // Hardcoded values are default values.
- private static final String MY_IP = "10.0.0.2";
+ private static String myIP = "10.0.0.2";
- private static final MacAddress MY_MAC = valueOf("4f:4f:4f:4f:4f:4f");
+ private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
/**
* leaseTime - 10 mins or 600s.
@@ -98,18 +128,27 @@
private static String broadcastAddress = "10.255.255.255";
+ private static Ip4Address startIPRange = Ip4Address.valueOf("10.1.0.140");
+
+ private static Ip4Address endIPRange = Ip4Address.valueOf("10.1.0.160");
+
@Activate
protected void activate() {
// start the dhcp server
appId = coreService.registerApplication("org.onosproject.dhcpserver");
+ cfgService.addListener(cfgListener);
+ factories.forEach(cfgService::registerConfigFactory);
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 10);
requestPackets();
+ dhcpStore.populateIPPoolfromRange(startIPRange, endIPRange);
log.info("Started");
}
@Deactivate
protected void deactivate() {
+ cfgService.removeListener(cfgListener);
+ factories.forEach(cfgService::unregisterConfigFactory);
packetService.removeProcessor(processor);
TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
@@ -184,12 +223,12 @@
* @return the Ethernet reply frame
*/
private Ethernet buildReply(Ethernet packet, String ipOffered, byte outgoingMessageType) {
- Ip4Address myIPAddress = Ip4Address.valueOf(MY_IP);
+ Ip4Address myIPAddress = Ip4Address.valueOf(myIP);
Ip4Address ipAddress;
// Ethernet Frame.
Ethernet ethReply = new Ethernet();
- ethReply.setSourceMACAddress(MY_MAC);
+ ethReply.setSourceMACAddress(myMAC);
ethReply.setDestinationMACAddress(packet.getSourceMAC());
ethReply.setEtherType(Ethernet.TYPE_IPV4);
ethReply.setVlanID(packet.getVlanID());
@@ -376,7 +415,7 @@
if (flagIfServerIP && flagIfRequestedIP) {
// SELECTING state
- if (MY_IP.equals(serverIP.toString()) &&
+ if (myIP.equals(serverIP.toString()) &&
dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) {
Ethernet ethReply = buildReply(packet, requestedIP.toString(),
@@ -440,4 +479,80 @@
}
}
}
+
+ private class InternalConfigListener implements NetworkConfigListener {
+
+ /**
+ * Reconfigures the DHCP Server according to the configuration parameters passed.
+ *
+ * @param cfg configuration object
+ */
+ private void reconfigureNetwork(DHCPConfig cfg) {
+
+ if (cfg.ip() != null) {
+ myIP = cfg.ip();
+ }
+ if (cfg.mac() != null) {
+ myMAC = MacAddress.valueOf(cfg.mac());
+ }
+ if (cfg.subnetMask() != null) {
+ subnetMask = cfg.subnetMask();
+ }
+ if (cfg.broadcastAddress() != null) {
+ broadcastAddress = cfg.broadcastAddress();
+ }
+ if (cfg.ttl() != null) {
+ packetTTL = Byte.valueOf(cfg.ttl());
+ }
+ if (cfg.leaseTime() != null) {
+ leaseTime = Integer.valueOf(cfg.leaseTime());
+ }
+ if (cfg.renewTime() != null) {
+ renewalTime = Integer.valueOf(cfg.renewTime());
+ }
+ if (cfg.rebindTime() != null) {
+ rebindingTime = Integer.valueOf(cfg.rebindTime());
+ }
+ }
+
+ /**
+ * Reconfigures the DHCP Store according to the configuration parameters passed.
+ *
+ * @param cfg configuration object
+ */
+ private void reconfigureStore(DHCPStoreConfig cfg) {
+
+ 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)) {
+ startIPRange = Ip4Address.valueOf(cfg.startIP());
+ endIPRange = Ip4Address.valueOf(cfg.endIP());
+ dhcpStore.populateIPPoolfromRange(startIPRange, endIPRange);
+ }
+ }
+
+ @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");
+ }
+
+ }
+ log.info("Reconfigured");
+ }
+ }
}
\ No newline at end of file
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPStoreConfig.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPStoreConfig.java
new file mode 100644
index 0000000..edc389c
--- /dev/null
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPStoreConfig.java
@@ -0,0 +1,107 @@
+/*
+ * 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.dhcpserver.impl;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.Config;
+import org.onosproject.incubator.net.config.basics.BasicElementConfig;
+
+/**
+ * DHCP Store Config class.
+ */
+public class DHCPStoreConfig extends Config<ApplicationId> {
+
+ 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/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DistributedDHCPStore.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DistributedDHCPStore.java
index 7344e6c..d072b58 100644
--- a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DistributedDHCPStore.java
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DistributedDHCPStore.java
@@ -64,16 +64,16 @@
private Timeout timeout;
- // TODO Make the hardcoded values configurable.
+ private static Ip4Address startIPRange;
- private static final int INITIAL_DELAY = 2;
+ private static Ip4Address endIPRange;
+
+ // Hardcoded values are default values.
+
+ private static int timerDelay = 2;
private static int timeoutForPendingAssignments = 60;
- private static final Ip4Address START_IP = Ip4Address.valueOf("10.1.0.140");
-
- private static final Ip4Address END_IP = Ip4Address.valueOf("10.1.0.160");
-
@Activate
protected void activate() {
allocationMap = storageService.<MacAddress, IPAssignment>consistentMapBuilder()
@@ -94,8 +94,7 @@
.withSerializer(Serializer.using(KryoNamespaces.API))
.build();
- populateIPPoolfromRange(START_IP, END_IP);
- timeout = Timer.getTimer().newTimeout(new PurgeListTask(), INITIAL_DELAY, TimeUnit.MINUTES);
+ timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
log.info("Started");
}
@@ -118,7 +117,9 @@
if (status == IPAssignment.AssignmentStatus.Option_Assigned ||
status == IPAssignment.AssignmentStatus.Option_Requested) {
// Client has a currently Active Binding.
- return ipAddr;
+ if ((ipAddr.toInt() > startIPRange.toInt()) && (ipAddr.toInt() < endIPRange.toInt())) {
+ return ipAddr;
+ }
} else if (status == IPAssignment.AssignmentStatus.Option_Expired) {
// Client has a Released or Expired Binding.
@@ -173,14 +174,15 @@
IPAssignment assignmentInfo;
if (allocationMap.containsKey(macID)) {
assignmentInfo = allocationMap.get(macID).value();
- if (assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) {
+ if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) &&
+ (ipAddr.toInt() > startIPRange.toInt()) && (ipAddr.toInt() < endIPRange.toInt())) {
assignmentInfo = IPAssignment.builder()
- .ipAddress(ipAddr)
- .timestamp(new Date())
- .leasePeriod(leaseTime)
- .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned)
- .build();
+ .ipAddress(ipAddr)
+ .timestamp(new Date())
+ .leasePeriod(leaseTime)
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned)
+ .build();
allocationMap.put(macID, assignmentInfo);
return true;
}
@@ -217,6 +219,11 @@
}
@Override
+ public void setTimerDelay(int timeInSeconds) {
+ timerDelay = timeInSeconds;
+ }
+
+ @Override
public Map<MacAddress, Ip4Address> listMapping() {
Map<MacAddress, Ip4Address> allMapping = new HashMap<>();
@@ -254,13 +261,13 @@
return ImmutableSet.<Ip4Address>copyOf(freeIPPool);
}
- /**
- * Appends all the IPs in a given range to the free pool of IPs.
- *
- * @param startIP Start IP for the range
- * @param endIP End IP for the range
- */
+ @Override
public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) {
+ // Clear all entries from previous range.
+ startIPRange = startIP;
+ endIPRange = endIP;
+ freeIPPool.clear();
+
int lastIP = endIP.toInt();
Ip4Address nextIP;
for (int loopCounter = startIP.toInt(); loopCounter <= lastIP; loopCounter++) {
@@ -300,13 +307,16 @@
Ip4Address freeIP = ipAssignment.ipAddress();
newAssignment = IPAssignment.builder(ipAssignment)
- .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired)
- .build();
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired)
+ .build();
allocationMap.put(entry.getKey(), newAssignment);
- freeIPPool.add(freeIP);
+
+ if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
+ freeIPPool.add(freeIP);
+ }
}
}
- timeout = Timer.getTimer().newTimeout(new PurgeListTask(), INITIAL_DELAY, TimeUnit.MINUTES);
+ timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
}
}
diff --git a/onos-app-dhcpserver/src/test/resources/dhcp-cfg.json b/onos-app-dhcpserver/src/test/resources/dhcp-cfg.json
new file mode 100644
index 0000000..c4aefff
--- /dev/null
+++ b/onos-app-dhcpserver/src/test/resources/dhcp-cfg.json
@@ -0,0 +1,22 @@
+{
+ "apps": {
+ "org.onosproject.dhcpserver" : {
+ "dhcp" : {
+ "ip": "10.0.0.1",
+ "mac": "1f:2f:3f:4f:5f:6f",
+ "subnet": "255.0.0.0",
+ "broadcast": "10.255.255.255",
+ "ttl": "63",
+ "lease": "300",
+ "renew": "150",
+ "rebind": "200"
+ },
+ "dhcpstore" : {
+ "delay": "3",
+ "timeout": "150",
+ "startip": "10.0.0.110",
+ "endip": "10.0.0.130"
+ }
+ }
+ }
+}
\ No newline at end of file