ONOS-2197 Adding some logic to keep track of expired IP Lease Assignments
Change-Id: I330e5fbf790f0a4fe72f1fbce272617837225e64
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 b6c60a2..29cb277 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
@@ -31,7 +31,7 @@
* @param macID Mac ID of the client requesting an IP
* @return IP address assigned to the Mac ID
*/
- Ip4Address suggestIP(MacAddress macID);
+ Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP);
/**
* Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/IPAssignment.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/IPAssignment.java
index 56cf3da..1129d2a 100644
--- a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/IPAssignment.java
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/IPAssignment.java
@@ -126,6 +126,15 @@
}
/**
+ * Creates and returns a new builder instance that clones an existing IPAssignment.
+ *
+ * @return new builder
+ */
+ public static Builder builder(IPAssignment assignment) {
+ return new Builder(assignment);
+ }
+
+ /**
* IPAssignment Builder.
*/
public static final class Builder {
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 3190a54..ee995d0 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
@@ -365,7 +365,7 @@
if (incomingPacketType == DHCP.DHCPMessageType.MessageType_Discover.getValue()) {
outgoingPacketType = DHCP.DHCPMessageType.MessageType_Offer;
- ipOffered = dhcpStore.suggestIP(clientMAC).toString();
+ ipOffered = dhcpStore.suggestIP(clientMAC, requestedIP).toString();
Ethernet ethReply = buildReply(packet, ipOffered, outgoingPacketType.getValue());
sendReply(context, ethReply);
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 1ad4bc5..7344e6c 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
@@ -107,26 +107,64 @@
}
@Override
- public Ip4Address suggestIP(MacAddress macID) {
+ public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) {
IPAssignment assignmentInfo;
if (allocationMap.containsKey(macID)) {
assignmentInfo = allocationMap.get(macID).value();
+ IPAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
+ Ip4Address ipAddr = assignmentInfo.ipAddress();
+
+ if (status == IPAssignment.AssignmentStatus.Option_Assigned ||
+ status == IPAssignment.AssignmentStatus.Option_Requested) {
+ // Client has a currently Active Binding.
+ return ipAddr;
+
+ } else if (status == IPAssignment.AssignmentStatus.Option_Expired) {
+ // Client has a Released or Expired Binding.
+ if (freeIPPool.contains(ipAddr)) {
+ assignmentInfo = IPAssignment.builder()
+ .ipAddress(ipAddr)
+ .timestamp(new Date())
+ .leasePeriod(timeoutForPendingAssignments)
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested)
+ .build();
+ if (freeIPPool.remove(ipAddr)) {
+ allocationMap.put(macID, assignmentInfo);
+ return ipAddr;
+ }
+ }
+ }
return assignmentInfo.ipAddress();
- } else {
- Ip4Address nextIPAddr = fetchNextIP();
-
- assignmentInfo = IPAssignment.builder()
- .ipAddress(nextIPAddr)
- .timestamp(new Date())
- .leasePeriod(timeoutForPendingAssignments)
- .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested)
- .build();
-
- allocationMap.put(macID, assignmentInfo);
- return nextIPAddr;
+ } else if (requestedIP.toInt() != 0) {
+ // Client has requested an IP.
+ if (freeIPPool.contains(requestedIP)) {
+ assignmentInfo = IPAssignment.builder()
+ .ipAddress(requestedIP)
+ .timestamp(new Date())
+ .leasePeriod(timeoutForPendingAssignments)
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested)
+ .build();
+ if (freeIPPool.remove(requestedIP)) {
+ allocationMap.put(macID, assignmentInfo);
+ return requestedIP;
+ }
+ }
}
+
+ // 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();
+
+ allocationMap.put(macID, assignmentInfo);
+ return nextIPAddr;
+
}
@Override
@@ -164,8 +202,11 @@
@Override
public void releaseIP(MacAddress macID) {
if (allocationMap.containsKey(macID)) {
- Ip4Address freeIP = allocationMap.get(macID).value().ipAddress();
- allocationMap.remove(macID);
+ IPAssignment newAssignment = IPAssignment.builder(allocationMap.get(macID).value())
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired)
+ .build();
+ Ip4Address freeIP = newAssignment.ipAddress();
+ allocationMap.put(macID, newAssignment);
freeIPPool.add(freeIP);
}
}
@@ -249,14 +290,19 @@
@Override
public void run(Timeout to) {
- IPAssignment ipAssignment;
+ 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.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriod()))) {
+ if ((ipAssignment.assignmentStatus() != IPAssignment.AssignmentStatus.Option_Expired) &&
+ (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriod()))) {
Ip4Address freeIP = ipAssignment.ipAddress();
- allocationMap.remove(entry.getKey());
+
+ newAssignment = IPAssignment.builder(ipAssignment)
+ .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired)
+ .build();
+ allocationMap.put(entry.getKey(), newAssignment);
freeIPPool.add(freeIP);
}
}