From 3e6f05e0bc2124cc0fab2bcb9c883f44a8cb4990 Mon Sep 17 00:00:00 2001 From: soumya Date: Fri, 5 Aug 2016 15:11:11 -0700 Subject: [PATCH] Code changes to ensure ONOS has each IP address attached to only one host at a time Change-Id: I1b4de39175d5bfd5ddf04c9087f4f3beff264594 --- .../net/host/impl/HostManager.java | 55 ++++++++++++++++++- .../net/host/impl/HostManagerTest.java | 18 +++++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java index 01d943e821..bdb5e438cd 100644 --- a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java +++ b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java @@ -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 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) { diff --git a/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java b/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java index bd5d68f17b..1eb014fab0 100644 --- a/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java +++ b/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java @@ -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 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();