samanwita pal
Committed by Gerrit Code Review

ONOS-2926 Remove IP instead of host when the IP mapping is released

Change-Id: Ifea3366ce8a18ea068e615636b3069e769221c0e
...@@ -65,7 +65,7 @@ public interface DhcpStore { ...@@ -65,7 +65,7 @@ public interface DhcpStore {
65 * 65 *
66 * @param hostId the host ID for which the mapping needs to be changed 66 * @param hostId the host ID for which the mapping needs to be changed
67 */ 67 */
68 - void releaseIP(HostId hostId); 68 + Ip4Address releaseIP(HostId hostId);
69 69
70 /** 70 /**
71 * Returns a collection of all the MacAddress to IPAddress mapping assigned to the hosts. 71 * Returns a collection of all the MacAddress to IPAddress mapping assigned to the hosts.
......
...@@ -481,7 +481,10 @@ public class DhcpManager implements DhcpService { ...@@ -481,7 +481,10 @@ public class DhcpManager implements DhcpService {
481 } 481 }
482 } 482 }
483 } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) { 483 } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) {
484 - dhcpStore.releaseIP(hostId); 484 + Ip4Address ip4Address = dhcpStore.releaseIP(hostId);
485 + if (ip4Address != null) {
486 + hostProviderService.removeIpFromHost(hostId, ip4Address);
487 + }
485 } 488 }
486 } 489 }
487 } 490 }
...@@ -666,9 +669,10 @@ public class DhcpManager implements DhcpService { ...@@ -666,9 +669,10 @@ public class DhcpManager implements DhcpService {
666 if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) && 669 if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) &&
667 (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { 670 (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) {
668 671
669 - dhcpStore.releaseIP(entry.getKey()); 672 + Ip4Address ip4Address = dhcpStore.releaseIP(entry.getKey());
670 - // TODO remove only the IP from the host entry when the API is in place. 673 + if (ip4Address != null) {
671 - hostProviderService.hostVanished(entry.getKey()); 674 + hostProviderService.removeIpFromHost(entry.getKey(), ipAssignment.ipAddress());
675 + }
672 } 676 }
673 } 677 }
674 timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); 678 timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
......
...@@ -212,7 +212,7 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -212,7 +212,7 @@ public class DistributedDhcpStore implements DhcpStore {
212 } 212 }
213 213
214 @Override 214 @Override
215 - public void releaseIP(HostId hostId) { 215 + public Ip4Address releaseIP(HostId hostId) {
216 if (allocationMap.containsKey(hostId)) { 216 if (allocationMap.containsKey(hostId)) {
217 IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value()) 217 IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value())
218 .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) 218 .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
...@@ -222,7 +222,9 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -222,7 +222,9 @@ public class DistributedDhcpStore implements DhcpStore {
222 if (ipWithinRange(freeIP)) { 222 if (ipWithinRange(freeIP)) {
223 freeIPPool.add(freeIP); 223 freeIPPool.add(freeIP);
224 } 224 }
225 + return freeIP;
225 } 226 }
227 + return null;
226 } 228 }
227 229
228 @Override 230 @Override
......
...@@ -25,6 +25,7 @@ import org.onlab.packet.DHCPPacketType; ...@@ -25,6 +25,7 @@ import org.onlab.packet.DHCPPacketType;
25 import org.onlab.packet.Ethernet; 25 import org.onlab.packet.Ethernet;
26 import org.onlab.packet.IPv4; 26 import org.onlab.packet.IPv4;
27 import org.onlab.packet.Ip4Address; 27 import org.onlab.packet.Ip4Address;
28 +import org.onlab.packet.IpAddress;
28 import org.onlab.packet.MacAddress; 29 import org.onlab.packet.MacAddress;
29 import org.onlab.packet.UDP; 30 import org.onlab.packet.UDP;
30 import org.onosproject.core.CoreServiceAdapter; 31 import org.onosproject.core.CoreServiceAdapter;
...@@ -234,7 +235,8 @@ public class DhcpManagerTest { ...@@ -234,7 +235,8 @@ public class DhcpManagerTest {
234 public void setDefaultTimeoutForPurge(int timeInSeconds) { 235 public void setDefaultTimeoutForPurge(int timeInSeconds) {
235 } 236 }
236 237
237 - public void releaseIP(HostId hostId) { 238 + public Ip4Address releaseIP(HostId hostId) {
239 + return null;
238 } 240 }
239 241
240 public Map<HostId, IpAssignment> listAssignedMapping() { 242 public Map<HostId, IpAssignment> listAssignedMapping() {
...@@ -338,6 +340,11 @@ public class DhcpManagerTest { ...@@ -338,6 +340,11 @@ public class DhcpManagerTest {
338 public void hostVanished(HostId hostId) { 340 public void hostVanished(HostId hostId) {
339 } 341 }
340 342
343 + @Override
344 + public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
345 +
346 + }
347 +
341 } 348 }
342 349
343 /** 350 /**
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.host; 16 package org.onosproject.net.host;
17 17
18 +import org.onlab.packet.IpAddress;
18 import org.onosproject.net.HostId; 19 import org.onosproject.net.HostId;
19 import org.onosproject.net.provider.ProviderService; 20 import org.onosproject.net.provider.ProviderService;
20 21
...@@ -52,4 +53,11 @@ public interface HostProviderService extends ProviderService<HostProvider> { ...@@ -52,4 +53,11 @@ public interface HostProviderService extends ProviderService<HostProvider> {
52 */ 53 */
53 void hostVanished(HostId hostId); 54 void hostVanished(HostId hostId);
54 55
56 + /**
57 + * Notifies the core when a host is no longer detected on a network.
58 + *
59 + * @param hostId id of the host that vanished
60 + */
61 + void removeIpFromHost(HostId hostId, IpAddress ipAddress);
62 +
55 } 63 }
......
...@@ -55,6 +55,15 @@ public interface HostStore extends Store<HostEvent, HostStoreDelegate> { ...@@ -55,6 +55,15 @@ public interface HostStore extends Store<HostEvent, HostStoreDelegate> {
55 HostEvent removeHost(HostId hostId); 55 HostEvent removeHost(HostId hostId);
56 56
57 /** 57 /**
58 + * Removes the specified ip from the host entry.
59 + *
60 + * @param hostId host identification
61 + * @param ipAddress ipAddress to be removed
62 + * @return remove event or null if host was not found
63 + */
64 + HostEvent removeIp(HostId hostId, IpAddress ipAddress);
65 +
66 + /**
58 * Returns the number of hosts in the store. 67 * Returns the number of hosts in the store.
59 * 68 *
60 * @return host count 69 * @return host count
......
...@@ -160,6 +160,11 @@ public class SimpleHostStore ...@@ -160,6 +160,11 @@ public class SimpleHostStore
160 } 160 }
161 161
162 @Override 162 @Override
163 + public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
164 + return null;
165 + }
166 +
167 + @Override
163 public int getHostCount() { 168 public int getHostCount() {
164 return hosts.size(); 169 return hosts.size();
165 } 170 }
......
...@@ -236,6 +236,16 @@ public class HostManager ...@@ -236,6 +236,16 @@ public class HostManager
236 post(event); 236 post(event);
237 } 237 }
238 } 238 }
239 +
240 + @Override
241 + public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
242 + checkNotNull(hostId, HOST_ID_NULL);
243 + checkValidity();
244 + HostEvent event = store.removeIp(hostId, ipAddress);
245 + if (event != null) {
246 + post(event);
247 + }
248 + }
239 } 249 }
240 250
241 // Store delegate to re-post events emitted from the store. 251 // Store delegate to re-post events emitted from the store.
......
...@@ -27,6 +27,7 @@ import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.RE ...@@ -27,6 +27,7 @@ import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.RE
27 import static org.slf4j.LoggerFactory.getLogger; 27 import static org.slf4j.LoggerFactory.getLogger;
28 28
29 import java.util.Collection; 29 import java.util.Collection;
30 +import java.util.HashSet;
30 import java.util.Objects; 31 import java.util.Objects;
31 import java.util.Set; 32 import java.util.Set;
32 import java.util.concurrent.atomic.AtomicReference; 33 import java.util.concurrent.atomic.AtomicReference;
...@@ -197,6 +198,34 @@ public class ECHostStore ...@@ -197,6 +198,34 @@ public class ECHostStore
197 } 198 }
198 199
199 @Override 200 @Override
201 + public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
202 + DefaultHost host = hosts.compute(hostId, (id, existingHost) -> {
203 + if (existingHost != null) {
204 + checkState(Objects.equals(hostId.mac(), existingHost.mac()),
205 + "Existing and new MAC addresses differ.");
206 + checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
207 + "Existing and new VLANs differ.");
208 +
209 + Set<IpAddress> addresses = new HashSet<>(existingHost.ipAddresses());
210 + if (addresses != null && addresses.contains(ipAddress)) {
211 + addresses.remove(ipAddress);
212 + return new DefaultHost(existingHost.providerId(),
213 + hostId,
214 + existingHost.mac(),
215 + existingHost.vlan(),
216 + existingHost.location(),
217 + ImmutableSet.copyOf(addresses),
218 + existingHost.annotations());
219 + } else {
220 + return existingHost;
221 + }
222 + }
223 + return null;
224 + });
225 + return host != null ? new HostEvent(HOST_UPDATED, host) : null;
226 + }
227 +
228 + @Override
200 public int getHostCount() { 229 public int getHostCount() {
201 return hosts.size(); 230 return hosts.size();
202 } 231 }
......
...@@ -259,6 +259,10 @@ public class HostLocationProviderTest { ...@@ -259,6 +259,10 @@ public class HostLocationProviderTest {
259 removeCount++; 259 removeCount++;
260 } 260 }
261 261
262 + @Override
263 + public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
264 + }
265 +
262 } 266 }
263 267
264 private class TestPacketService extends PacketServiceAdapter { 268 private class TestPacketService extends PacketServiceAdapter {
......
...@@ -24,6 +24,7 @@ import java.util.Set; ...@@ -24,6 +24,7 @@ import java.util.Set;
24 import org.junit.After; 24 import org.junit.After;
25 import org.junit.Before; 25 import org.junit.Before;
26 import org.junit.Test; 26 import org.junit.Test;
27 +import org.onlab.packet.IpAddress;
27 import org.onlab.packet.MacAddress; 28 import org.onlab.packet.MacAddress;
28 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
29 import org.onosproject.net.HostId; 30 import org.onosproject.net.HostId;
...@@ -159,6 +160,11 @@ public class OvsdbHostProviderTest { ...@@ -159,6 +160,11 @@ public class OvsdbHostProviderTest {
159 removeCount++; 160 removeCount++;
160 } 161 }
161 162
163 + @Override
164 + public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
165 +
166 + }
167 +
162 } 168 }
163 169
164 private class OvsdbControllerTest implements OvsdbController { 170 private class OvsdbControllerTest implements OvsdbController {
......