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
Showing
2 changed files
with
68 additions
and
3 deletions
| ... | @@ -18,12 +18,16 @@ package org.onosproject.net.host.impl; | ... | @@ -18,12 +18,16 @@ package org.onosproject.net.host.impl; |
| 18 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
| 19 | import org.apache.felix.scr.annotations.Component; | 19 | import org.apache.felix.scr.annotations.Component; |
| 20 | import org.apache.felix.scr.annotations.Deactivate; | 20 | import org.apache.felix.scr.annotations.Deactivate; |
| 21 | +import org.apache.felix.scr.annotations.Modified; | ||
| 22 | +import org.apache.felix.scr.annotations.Property; | ||
| 21 | import org.apache.felix.scr.annotations.Reference; | 23 | import org.apache.felix.scr.annotations.Reference; |
| 22 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 23 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
| 24 | import org.onlab.packet.IpAddress; | 26 | import org.onlab.packet.IpAddress; |
| 25 | import org.onlab.packet.MacAddress; | 27 | import org.onlab.packet.MacAddress; |
| 26 | import org.onlab.packet.VlanId; | 28 | import org.onlab.packet.VlanId; |
| 29 | +import org.onlab.util.Tools; | ||
| 30 | +import org.onosproject.cfg.ComponentConfigService; | ||
| 27 | import org.onosproject.incubator.net.intf.InterfaceService; | 31 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 28 | import org.onosproject.net.edge.EdgePortService; | 32 | import org.onosproject.net.edge.EdgePortService; |
| 29 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; | 33 | import org.onosproject.net.provider.AbstractListenerProviderRegistry; |
| ... | @@ -48,8 +52,10 @@ import org.onosproject.net.host.HostStore; | ... | @@ -48,8 +52,10 @@ import org.onosproject.net.host.HostStore; |
| 48 | import org.onosproject.net.host.HostStoreDelegate; | 52 | import org.onosproject.net.host.HostStoreDelegate; |
| 49 | import org.onosproject.net.packet.PacketService; | 53 | import org.onosproject.net.packet.PacketService; |
| 50 | import org.onosproject.net.provider.AbstractProviderService; | 54 | import org.onosproject.net.provider.AbstractProviderService; |
| 55 | +import org.osgi.service.component.ComponentContext; | ||
| 51 | import org.slf4j.Logger; | 56 | import org.slf4j.Logger; |
| 52 | 57 | ||
| 58 | +import java.util.Dictionary; | ||
| 53 | import java.util.Set; | 59 | import java.util.Set; |
| 54 | 60 | ||
| 55 | import static com.google.common.base.Preconditions.checkNotNull; | 61 | import static com.google.common.base.Preconditions.checkNotNull; |
| ... | @@ -93,18 +99,42 @@ public class HostManager | ... | @@ -93,18 +99,42 @@ public class HostManager |
| 93 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 99 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 94 | protected EdgePortService edgePortService; | 100 | protected EdgePortService edgePortService; |
| 95 | 101 | ||
| 102 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 103 | + protected ComponentConfigService cfgService; | ||
| 104 | + | ||
| 105 | + @Property(name = "allowDuplicateIps", boolValue = true, | ||
| 106 | + label = "Enable removal of duplicate ip address") | ||
| 107 | + | ||
| 108 | + private boolean allowDuplicateIps = true; | ||
| 96 | private HostMonitor monitor; | 109 | private HostMonitor monitor; |
| 97 | 110 | ||
| 111 | + | ||
| 98 | @Activate | 112 | @Activate |
| 99 | - public void activate() { | 113 | + public void activate(ComponentContext context) { |
| 100 | store.setDelegate(delegate); | 114 | store.setDelegate(delegate); |
| 101 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); | 115 | eventDispatcher.addSink(HostEvent.class, listenerRegistry); |
| 116 | + cfgService.registerProperties(getClass()); | ||
| 117 | + modified(context); | ||
| 102 | networkConfigService.addListener(networkConfigListener); | 118 | networkConfigService.addListener(networkConfigListener); |
| 103 | monitor = new HostMonitor(packetService, this, interfaceService, edgePortService); | 119 | monitor = new HostMonitor(packetService, this, interfaceService, edgePortService); |
| 104 | monitor.start(); | 120 | monitor.start(); |
| 105 | log.info("Started"); | 121 | log.info("Started"); |
| 106 | } | 122 | } |
| 107 | 123 | ||
| 124 | + @Modified | ||
| 125 | + public void modified(ComponentContext context) { | ||
| 126 | + Dictionary<?, ?> properties = context.getProperties(); | ||
| 127 | + Boolean flag; | ||
| 128 | + flag = Tools.isPropertyEnabled(properties, "allowDuplicateIps"); | ||
| 129 | + if (flag == null) { | ||
| 130 | + log.info("Removal of duplicate ip address is not configured"); | ||
| 131 | + } else { | ||
| 132 | + allowDuplicateIps = flag; | ||
| 133 | + log.info("Removal of duplicate ip address is {}", | ||
| 134 | + allowDuplicateIps ? "disabled" : "enabled"); | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + | ||
| 108 | @Deactivate | 138 | @Deactivate |
| 109 | public void deactivate() { | 139 | public void deactivate() { |
| 110 | store.unsetDelegate(delegate); | 140 | store.unsetDelegate(delegate); |
| ... | @@ -208,10 +238,31 @@ public class HostManager | ... | @@ -208,10 +238,31 @@ public class HostManager |
| 208 | checkNotNull(hostId, HOST_ID_NULL); | 238 | checkNotNull(hostId, HOST_ID_NULL); |
| 209 | checkValidity(); | 239 | checkValidity(); |
| 210 | hostDescription = validateHost(hostDescription, hostId); | 240 | hostDescription = validateHost(hostDescription, hostId); |
| 241 | + | ||
| 242 | + if (!allowDuplicateIps) { | ||
| 243 | + removeDuplicates(hostId, hostDescription); | ||
| 244 | + } | ||
| 211 | store.createOrUpdateHost(provider().id(), hostId, | 245 | store.createOrUpdateHost(provider().id(), hostId, |
| 212 | hostDescription, replaceIps); | 246 | hostDescription, replaceIps); |
| 213 | } | 247 | } |
| 214 | 248 | ||
| 249 | + // When a new IP is detected, remove that IP on other hosts if it exists | ||
| 250 | + public void removeDuplicates(HostId hostId, HostDescription desc) { | ||
| 251 | + desc.ipAddress().forEach(ip -> { | ||
| 252 | + Set<Host> allHosts = store.getHosts(ip); | ||
| 253 | + allHosts.forEach(eachHost -> { | ||
| 254 | + if (!(eachHost.id().equals(hostId))) { | ||
| 255 | + log.info("Duplicate ip {} found on host {} and {}", ip, | ||
| 256 | + hostId.toString(), eachHost.id().toString()); | ||
| 257 | + store.removeIp(eachHost.id(), ip); | ||
| 258 | + } | ||
| 259 | + }); | ||
| 260 | + }); | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + | ||
| 264 | + | ||
| 265 | + | ||
| 215 | // returns a HostDescription made from the union of the BasicHostConfig | 266 | // returns a HostDescription made from the union of the BasicHostConfig |
| 216 | // annotations if it exists | 267 | // annotations if it exists |
| 217 | private HostDescription validateHost(HostDescription hostDescription, HostId hostId) { | 268 | private HostDescription validateHost(HostDescription hostDescription, HostId hostId) { | ... | ... |
| ... | @@ -21,9 +21,11 @@ import org.junit.After; | ... | @@ -21,9 +21,11 @@ import org.junit.After; |
| 21 | import org.junit.Before; | 21 | import org.junit.Before; |
| 22 | import org.junit.Test; | 22 | import org.junit.Test; |
| 23 | import org.onlab.junit.TestTools; | 23 | import org.onlab.junit.TestTools; |
| 24 | +import org.onlab.osgi.ComponentContextAdapter; | ||
| 24 | import org.onlab.packet.IpAddress; | 25 | import org.onlab.packet.IpAddress; |
| 25 | import org.onlab.packet.MacAddress; | 26 | import org.onlab.packet.MacAddress; |
| 26 | import org.onlab.packet.VlanId; | 27 | import org.onlab.packet.VlanId; |
| 28 | +import org.onosproject.cfg.ComponentConfigAdapter; | ||
| 27 | import org.onosproject.common.event.impl.TestEventDispatcher; | 29 | import org.onosproject.common.event.impl.TestEventDispatcher; |
| 28 | import org.onosproject.event.Event; | 30 | import org.onosproject.event.Event; |
| 29 | import org.onosproject.net.DeviceId; | 31 | import org.onosproject.net.DeviceId; |
| ... | @@ -43,6 +45,8 @@ import org.onosproject.net.provider.AbstractProvider; | ... | @@ -43,6 +45,8 @@ import org.onosproject.net.provider.AbstractProvider; |
| 43 | import org.onosproject.net.provider.ProviderId; | 45 | import org.onosproject.net.provider.ProviderId; |
| 44 | import org.onosproject.store.trivial.SimpleHostStore; | 46 | import org.onosproject.store.trivial.SimpleHostStore; |
| 45 | 47 | ||
| 48 | +import java.util.Dictionary; | ||
| 49 | +import java.util.Hashtable; | ||
| 46 | import java.util.List; | 50 | import java.util.List; |
| 47 | import java.util.Set; | 51 | import java.util.Set; |
| 48 | 52 | ||
| ... | @@ -94,6 +98,16 @@ public class HostManagerTest { | ... | @@ -94,6 +98,16 @@ public class HostManagerTest { |
| 94 | protected TestHostProvider provider; | 98 | protected TestHostProvider provider; |
| 95 | protected HostProviderService providerService; | 99 | protected HostProviderService providerService; |
| 96 | 100 | ||
| 101 | + private static final ComponentContextAdapter REMOVE_DUPS = | ||
| 102 | + new ComponentContextAdapter() { | ||
| 103 | + @Override | ||
| 104 | + public Dictionary getProperties() { | ||
| 105 | + Hashtable<String, String> props = new Hashtable<>(); | ||
| 106 | + props.put("allowDuplicateIps", "true"); | ||
| 107 | + return props; | ||
| 108 | + } | ||
| 109 | + }; | ||
| 110 | + | ||
| 97 | @Before | 111 | @Before |
| 98 | public void setUp() { | 112 | public void setUp() { |
| 99 | mgr = new HostManager(); | 113 | mgr = new HostManager(); |
| ... | @@ -101,8 +115,8 @@ public class HostManagerTest { | ... | @@ -101,8 +115,8 @@ public class HostManagerTest { |
| 101 | injectEventDispatcher(mgr, new TestEventDispatcher()); | 115 | injectEventDispatcher(mgr, new TestEventDispatcher()); |
| 102 | registry = mgr; | 116 | registry = mgr; |
| 103 | mgr.networkConfigService = new TestNetworkConfigService(); | 117 | mgr.networkConfigService = new TestNetworkConfigService(); |
| 104 | - mgr.activate(); | 118 | + mgr.cfgService = new ComponentConfigAdapter(); |
| 105 | - | 119 | + mgr.activate(REMOVE_DUPS); |
| 106 | mgr.addListener(listener); | 120 | mgr.addListener(listener); |
| 107 | 121 | ||
| 108 | provider = new TestHostProvider(); | 122 | provider = new TestHostProvider(); | ... | ... |
-
Please register or login to post a comment