ONOS-2888 Bug fix to avaoid DHCP Server assigning two hosts the same IP
Change-Id: I75dd4bdca43b9b3a0194d9742d84e088eeddac4e
Showing
4 changed files
with
70 additions
and
17 deletions
... | @@ -68,11 +68,18 @@ public interface DhcpStore { | ... | @@ -68,11 +68,18 @@ public interface DhcpStore { |
68 | void releaseIP(HostId hostId); | 68 | void releaseIP(HostId hostId); |
69 | 69 | ||
70 | /** | 70 | /** |
71 | + * Returns a collection of all the MacAddress to IPAddress mapping assigned to the hosts. | ||
72 | + * | ||
73 | + * @return the collection of the mappings | ||
74 | + */ | ||
75 | + Map<HostId, IpAssignment> listAssignedMapping(); | ||
76 | + | ||
77 | + /** | ||
71 | * Returns a collection of all the MacAddress to IPAddress mapping. | 78 | * Returns a collection of all the MacAddress to IPAddress mapping. |
72 | * | 79 | * |
73 | * @return the collection of the mappings | 80 | * @return the collection of the mappings |
74 | */ | 81 | */ |
75 | - Map<HostId, IpAssignment> listMapping(); | 82 | + Map<HostId, IpAssignment> listAllMapping(); |
76 | 83 | ||
77 | /** | 84 | /** |
78 | * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. | 85 | * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. | ... | ... |
... | @@ -221,7 +221,7 @@ public class DhcpManager implements DhcpService { | ... | @@ -221,7 +221,7 @@ public class DhcpManager implements DhcpService { |
221 | 221 | ||
222 | @Override | 222 | @Override |
223 | public Map<HostId, IpAssignment> listMapping() { | 223 | public Map<HostId, IpAssignment> listMapping() { |
224 | - return dhcpStore.listMapping(); | 224 | + return dhcpStore.listAssignedMapping(); |
225 | } | 225 | } |
226 | 226 | ||
227 | @Override | 227 | @Override |
... | @@ -658,7 +658,7 @@ public class DhcpManager implements DhcpService { | ... | @@ -658,7 +658,7 @@ public class DhcpManager implements DhcpService { |
658 | IpAssignment ipAssignment; | 658 | IpAssignment ipAssignment; |
659 | Date dateNow = new Date(); | 659 | Date dateNow = new Date(); |
660 | 660 | ||
661 | - Map<HostId, IpAssignment> ipAssignmentMap = dhcpStore.listMapping(); | 661 | + Map<HostId, IpAssignment> ipAssignmentMap = dhcpStore.listAllMapping(); |
662 | for (Map.Entry<HostId, IpAssignment> entry: ipAssignmentMap.entrySet()) { | 662 | for (Map.Entry<HostId, IpAssignment> entry: ipAssignmentMap.entrySet()) { |
663 | ipAssignment = entry.getValue(); | 663 | ipAssignment = entry.getValue(); |
664 | 664 | ||
... | @@ -667,6 +667,7 @@ public class DhcpManager implements DhcpService { | ... | @@ -667,6 +667,7 @@ public class DhcpManager implements DhcpService { |
667 | (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { | 667 | (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { |
668 | 668 | ||
669 | dhcpStore.releaseIP(entry.getKey()); | 669 | dhcpStore.releaseIP(entry.getKey()); |
670 | + // TODO remove only the IP from the host entry when the API is in place. | ||
670 | hostProviderService.hostVanished(entry.getKey()); | 671 | hostProviderService.hostVanished(entry.getKey()); |
671 | } | 672 | } |
672 | } | 673 | } | ... | ... |
... | @@ -40,6 +40,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -40,6 +40,7 @@ import org.slf4j.LoggerFactory; |
40 | import java.util.Date; | 40 | import java.util.Date; |
41 | import java.util.HashMap; | 41 | import java.util.HashMap; |
42 | import java.util.Map; | 42 | import java.util.Map; |
43 | +import java.util.Objects; | ||
43 | 44 | ||
44 | /** | 45 | /** |
45 | * Manages the pool of available IP Addresses in the network and | 46 | * Manages the pool of available IP Addresses in the network and |
... | @@ -107,7 +108,7 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -107,7 +108,7 @@ public class DistributedDhcpStore implements DhcpStore { |
107 | if (status == IpAssignment.AssignmentStatus.Option_Assigned || | 108 | if (status == IpAssignment.AssignmentStatus.Option_Assigned || |
108 | status == IpAssignment.AssignmentStatus.Option_Requested) { | 109 | status == IpAssignment.AssignmentStatus.Option_Requested) { |
109 | // Client has a currently Active Binding. | 110 | // Client has a currently Active Binding. |
110 | - if ((ipAddr.toInt() > startIPRange.toInt()) && (ipAddr.toInt() < endIPRange.toInt())) { | 111 | + if (ipWithinRange(ipAddr)) { |
111 | return ipAddr; | 112 | return ipAddr; |
112 | } | 113 | } |
113 | 114 | ||
... | @@ -126,8 +127,6 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -126,8 +127,6 @@ public class DistributedDhcpStore implements DhcpStore { |
126 | } | 127 | } |
127 | } | 128 | } |
128 | } | 129 | } |
129 | - return assignmentInfo.ipAddress(); | ||
130 | - | ||
131 | } else if (requestedIP.toInt() != 0) { | 130 | } else if (requestedIP.toInt() != 0) { |
132 | // Client has requested an IP. | 131 | // Client has requested an IP. |
133 | if (freeIPPool.contains(requestedIP)) { | 132 | if (freeIPPool.contains(requestedIP)) { |
... | @@ -166,9 +165,13 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -166,9 +165,13 @@ public class DistributedDhcpStore implements DhcpStore { |
166 | IpAssignment assignmentInfo; | 165 | IpAssignment assignmentInfo; |
167 | if (allocationMap.containsKey(hostId)) { | 166 | if (allocationMap.containsKey(hostId)) { |
168 | assignmentInfo = allocationMap.get(hostId).value(); | 167 | assignmentInfo = allocationMap.get(hostId).value(); |
169 | - if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) && | 168 | + IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); |
170 | - (ipAddr.toInt() >= startIPRange.toInt()) && (ipAddr.toInt() <= endIPRange.toInt())) { | 169 | + |
170 | + if (Objects.equals(assignmentInfo.ipAddress(), ipAddr) && ipWithinRange(ipAddr)) { | ||
171 | 171 | ||
172 | + if (status == IpAssignment.AssignmentStatus.Option_Assigned || | ||
173 | + status == IpAssignment.AssignmentStatus.Option_Requested) { | ||
174 | + // Client has a currently active binding with the server. | ||
172 | assignmentInfo = IpAssignment.builder() | 175 | assignmentInfo = IpAssignment.builder() |
173 | .ipAddress(ipAddr) | 176 | .ipAddress(ipAddr) |
174 | .timestamp(new Date()) | 177 | .timestamp(new Date()) |
... | @@ -177,6 +180,21 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -177,6 +180,21 @@ public class DistributedDhcpStore implements DhcpStore { |
177 | .build(); | 180 | .build(); |
178 | allocationMap.put(hostId, assignmentInfo); | 181 | allocationMap.put(hostId, assignmentInfo); |
179 | return true; | 182 | return true; |
183 | + } else if (status == IpAssignment.AssignmentStatus.Option_Expired) { | ||
184 | + // Client has an expired binding with the server. | ||
185 | + if (freeIPPool.contains(ipAddr)) { | ||
186 | + assignmentInfo = IpAssignment.builder() | ||
187 | + .ipAddress(ipAddr) | ||
188 | + .timestamp(new Date()) | ||
189 | + .leasePeriod(leaseTime) | ||
190 | + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) | ||
191 | + .build(); | ||
192 | + if (freeIPPool.remove(ipAddr)) { | ||
193 | + allocationMap.put(hostId, assignmentInfo); | ||
194 | + return true; | ||
195 | + } | ||
196 | + } | ||
197 | + } | ||
180 | } | 198 | } |
181 | } else if (freeIPPool.contains(ipAddr)) { | 199 | } else if (freeIPPool.contains(ipAddr)) { |
182 | assignmentInfo = IpAssignment.builder() | 200 | assignmentInfo = IpAssignment.builder() |
... | @@ -201,7 +219,7 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -201,7 +219,7 @@ public class DistributedDhcpStore implements DhcpStore { |
201 | .build(); | 219 | .build(); |
202 | Ip4Address freeIP = newAssignment.ipAddress(); | 220 | Ip4Address freeIP = newAssignment.ipAddress(); |
203 | allocationMap.put(hostId, newAssignment); | 221 | allocationMap.put(hostId, newAssignment); |
204 | - if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) { | 222 | + if (ipWithinRange(freeIP)) { |
205 | freeIPPool.add(freeIP); | 223 | freeIPPool.add(freeIP); |
206 | } | 224 | } |
207 | } | 225 | } |
... | @@ -213,17 +231,26 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -213,17 +231,26 @@ public class DistributedDhcpStore implements DhcpStore { |
213 | } | 231 | } |
214 | 232 | ||
215 | @Override | 233 | @Override |
216 | - public Map<HostId, IpAssignment> listMapping() { | 234 | + public Map<HostId, IpAssignment> listAssignedMapping() { |
217 | 235 | ||
218 | - Map<HostId, IpAssignment> allMapping = new HashMap<>(); | 236 | + Map<HostId, IpAssignment> validMapping = new HashMap<>(); |
237 | + IpAssignment assignment; | ||
219 | for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) { | 238 | for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) { |
220 | - IpAssignment assignment = entry.getValue().value(); | 239 | + assignment = entry.getValue().value(); |
221 | if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { | 240 | if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { |
222 | - allMapping.put(entry.getKey(), assignment); | 241 | + validMapping.put(entry.getKey(), assignment); |
223 | } | 242 | } |
224 | } | 243 | } |
225 | - return allMapping; | 244 | + return validMapping; |
245 | + } | ||
226 | 246 | ||
247 | + @Override | ||
248 | + public Map<HostId, IpAssignment> listAllMapping() { | ||
249 | + Map<HostId, IpAssignment> validMapping = new HashMap<>(); | ||
250 | + for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) { | ||
251 | + validMapping.put(entry.getKey(), entry.getValue().value()); | ||
252 | + } | ||
253 | + return validMapping; | ||
227 | } | 254 | } |
228 | 255 | ||
229 | @Override | 256 | @Override |
... | @@ -240,7 +267,7 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -240,7 +267,7 @@ public class DistributedDhcpStore implements DhcpStore { |
240 | Ip4Address freeIP = assignment.ipAddress(); | 267 | Ip4Address freeIP = assignment.ipAddress(); |
241 | if (assignment.leasePeriod() < 0) { | 268 | if (assignment.leasePeriod() < 0) { |
242 | allocationMap.remove(host); | 269 | allocationMap.remove(host); |
243 | - if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) { | 270 | + if (ipWithinRange(freeIP)) { |
244 | freeIPPool.add(freeIP); | 271 | freeIPPool.add(freeIP); |
245 | } | 272 | } |
246 | return true; | 273 | return true; |
... | @@ -257,9 +284,10 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -257,9 +284,10 @@ public class DistributedDhcpStore implements DhcpStore { |
257 | @Override | 284 | @Override |
258 | public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { | 285 | public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { |
259 | // Clear all entries from previous range. | 286 | // Clear all entries from previous range. |
287 | + allocationMap.clear(); | ||
288 | + freeIPPool.clear(); | ||
260 | startIPRange = startIP; | 289 | startIPRange = startIP; |
261 | endIPRange = endIP; | 290 | endIPRange = endIP; |
262 | - freeIPPool.clear(); | ||
263 | 291 | ||
264 | int lastIP = endIP.toInt(); | 292 | int lastIP = endIP.toInt(); |
265 | Ip4Address nextIP; | 293 | Ip4Address nextIP; |
... | @@ -282,4 +310,17 @@ public class DistributedDhcpStore implements DhcpStore { | ... | @@ -282,4 +310,17 @@ public class DistributedDhcpStore implements DhcpStore { |
282 | } | 310 | } |
283 | return null; | 311 | return null; |
284 | } | 312 | } |
313 | + | ||
314 | + /** | ||
315 | + * Returns true if the given ip is within the range of available IPs. | ||
316 | + * | ||
317 | + * @param ip given ip address | ||
318 | + * @return true if within range, false otherwise | ||
319 | + */ | ||
320 | + private boolean ipWithinRange(Ip4Address ip) { | ||
321 | + if ((ip.toInt() >= startIPRange.toInt()) && (ip.toInt() <= endIPRange.toInt())) { | ||
322 | + return true; | ||
323 | + } | ||
324 | + return false; | ||
325 | + } | ||
285 | } | 326 | } | ... | ... |
... | @@ -237,7 +237,11 @@ public class DhcpManagerTest { | ... | @@ -237,7 +237,11 @@ public class DhcpManagerTest { |
237 | public void releaseIP(HostId hostId) { | 237 | public void releaseIP(HostId hostId) { |
238 | } | 238 | } |
239 | 239 | ||
240 | - public Map<HostId, IpAssignment> listMapping() { | 240 | + public Map<HostId, IpAssignment> listAssignedMapping() { |
241 | + return listAllMapping(); | ||
242 | + } | ||
243 | + | ||
244 | + public Map<HostId, IpAssignment> listAllMapping() { | ||
241 | Map<HostId, IpAssignment> map = new HashMap<>(); | 245 | Map<HostId, IpAssignment> map = new HashMap<>(); |
242 | IpAssignment assignment = IpAssignment.builder() | 246 | IpAssignment assignment = IpAssignment.builder() |
243 | .ipAddress(Ip4Address.valueOf(EXPECTED_IP)) | 247 | .ipAddress(Ip4Address.valueOf(EXPECTED_IP)) | ... | ... |
-
Please register or login to post a comment