soumya
Committed by Gerrit Code Review

Code changes to ensure ONOS has each IP address attached to only one host at a time

Change-Id: I1b4de39175d5bfd5ddf04c9087f4f3beff264594
......@@ -18,12 +18,16 @@ package org.onosproject.net.host.impl;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
......@@ -48,8 +52,10 @@ import org.onosproject.net.host.HostStore;
import org.onosproject.net.host.HostStoreDelegate;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProviderService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import java.util.Dictionary;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -93,18 +99,42 @@ public class HostManager
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EdgePortService edgePortService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
@Property(name = "allowDuplicateIps", boolValue = true,
label = "Enable removal of duplicate ip address")
private boolean allowDuplicateIps = true;
private HostMonitor monitor;
@Activate
public void activate() {
public void activate(ComponentContext context) {
store.setDelegate(delegate);
eventDispatcher.addSink(HostEvent.class, listenerRegistry);
cfgService.registerProperties(getClass());
modified(context);
networkConfigService.addListener(networkConfigListener);
monitor = new HostMonitor(packetService, this, interfaceService, edgePortService);
monitor.start();
log.info("Started");
}
@Modified
public void modified(ComponentContext context) {
Dictionary<?, ?> properties = context.getProperties();
Boolean flag;
flag = Tools.isPropertyEnabled(properties, "allowDuplicateIps");
if (flag == null) {
log.info("Removal of duplicate ip address is not configured");
} else {
allowDuplicateIps = flag;
log.info("Removal of duplicate ip address is {}",
allowDuplicateIps ? "disabled" : "enabled");
}
}
@Deactivate
public void deactivate() {
store.unsetDelegate(delegate);
......@@ -208,10 +238,31 @@ public class HostManager
checkNotNull(hostId, HOST_ID_NULL);
checkValidity();
hostDescription = validateHost(hostDescription, hostId);
if (!allowDuplicateIps) {
removeDuplicates(hostId, hostDescription);
}
store.createOrUpdateHost(provider().id(), hostId,
hostDescription, replaceIps);
hostDescription, replaceIps);
}
// When a new IP is detected, remove that IP on other hosts if it exists
public void removeDuplicates(HostId hostId, HostDescription desc) {
desc.ipAddress().forEach(ip -> {
Set<Host> allHosts = store.getHosts(ip);
allHosts.forEach(eachHost -> {
if (!(eachHost.id().equals(hostId))) {
log.info("Duplicate ip {} found on host {} and {}", ip,
hostId.toString(), eachHost.id().toString());
store.removeIp(eachHost.id(), ip);
}
});
});
}
// returns a HostDescription made from the union of the BasicHostConfig
// annotations if it exists
private HostDescription validateHost(HostDescription hostDescription, HostId hostId) {
......
......@@ -21,9 +21,11 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestTools;
import org.onlab.osgi.ComponentContextAdapter;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.event.Event;
import org.onosproject.net.DeviceId;
......@@ -43,6 +45,8 @@ import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.trivial.SimpleHostStore;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
......@@ -94,6 +98,16 @@ public class HostManagerTest {
protected TestHostProvider provider;
protected HostProviderService providerService;
private static final ComponentContextAdapter REMOVE_DUPS =
new ComponentContextAdapter() {
@Override
public Dictionary getProperties() {
Hashtable<String, String> props = new Hashtable<>();
props.put("allowDuplicateIps", "true");
return props;
}
};
@Before
public void setUp() {
mgr = new HostManager();
......@@ -101,8 +115,8 @@ public class HostManagerTest {
injectEventDispatcher(mgr, new TestEventDispatcher());
registry = mgr;
mgr.networkConfigService = new TestNetworkConfigService();
mgr.activate();
mgr.cfgService = new ComponentConfigAdapter();
mgr.activate(REMOVE_DUPS);
mgr.addListener(listener);
provider = new TestHostProvider();
......