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; ...@@ -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);
247 + }
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 + });
213 } 261 }
214 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();
......