Refactored the HostStore to allow multiple MAC addresses bound to a single port
Change-Id: Icd3b2e483b15486251ac1cca107478a012d1a3e7
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostToInterfaceAdaptor.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostToInterfaceAdaptor.java
index f9d6951..604d12d 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostToInterfaceAdaptor.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/HostToInterfaceAdaptor.java
@@ -53,11 +53,13 @@
public Interface getInterface(ConnectPoint connectPoint) {
checkNotNull(connectPoint);
- PortAddresses portAddresses =
+ Set<PortAddresses> portAddresses =
hostService.getAddressBindingsForPort(connectPoint);
- if (!portAddresses.ipAddresses().isEmpty()) {
- return new Interface(portAddresses);
+ for (PortAddresses addresses : portAddresses) {
+ if (addresses.connectPoint().equals(connectPoint)) {
+ return new Interface(addresses);
+ }
}
return null;
diff --git a/apps/sdnip/src/test/java/org/onlab/onos/sdnip/HostToInterfaceAdaptorTest.java b/apps/sdnip/src/test/java/org/onlab/onos/sdnip/HostToInterfaceAdaptorTest.java
index 2a65616..9e31389 100644
--- a/apps/sdnip/src/test/java/org/onlab/onos/sdnip/HostToInterfaceAdaptorTest.java
+++ b/apps/sdnip/src/test/java/org/onlab/onos/sdnip/HostToInterfaceAdaptorTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -63,10 +64,6 @@
private static final ConnectPoint NON_EXISTENT_CP = new ConnectPoint(
DeviceId.deviceId("doesnotexist"), PortNumber.portNumber(1));
- private static final PortAddresses DEFAULT_PA = new PortAddresses(
- NON_EXISTENT_CP, null, null);
-
-
@Before
public void setUp() throws Exception {
hostService = createMock(HostService.class);
@@ -123,7 +120,8 @@
MacAddress mac) {
PortAddresses pa = new PortAddresses(cp, ipAddresses, mac);
portAddresses.add(pa);
- expect(hostService.getAddressBindingsForPort(cp)).andReturn(pa).anyTimes();
+ expect(hostService.getAddressBindingsForPort(cp)).andReturn(
+ Collections.singleton(pa)).anyTimes();
Interface intf = new Interface(cp, ipAddresses, mac);
interfaces.put(cp, intf);
@@ -158,7 +156,7 @@
// Try and get an interface for a connect point with no addresses
reset(hostService);
expect(hostService.getAddressBindingsForPort(NON_EXISTENT_CP))
- .andReturn(DEFAULT_PA).anyTimes();
+ .andReturn(Collections.<PortAddresses>emptySet()).anyTimes();
replay(hostService);
assertNull(adaptor.getInterface(NON_EXISTENT_CP));
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java b/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
index f421fd8..c51a847 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
@@ -34,11 +34,7 @@
* Binds IP and MAC addresses to the given connection point.
* <p>
* The addresses are added to the set of addresses already bound to the
- * connection point. If any of the fields in addresses is null, no change
- * is made to the corresponding addresses in the store.
- * {@link #unbindAddressesFromPort(PortAddresses)} must be use to unbind
- * addresses that have previously been bound.
- * </p>
+ * connection point.
*
* @param addresses address object containing addresses to add and the port
* to add them to
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostService.java b/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
index aa31459..7f7be50 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
@@ -135,7 +135,7 @@
* @param connectPoint the connection point to retrieve address bindings for
* @return addresses bound to the port
*/
- PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
+ Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint);
/**
* Adds the specified host listener.
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java b/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
index a6bf96d..0316dcf 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.host;
+import java.util.Set;
+
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
@@ -25,8 +27,6 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import java.util.Set;
-
/**
* Manages inventory of end-station hosts; not intended for direct use.
*/
@@ -153,5 +153,5 @@
* for
* @return address information for the connection point
*/
- PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
+ Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint);
}
diff --git a/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java b/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
index a0a0e36..03a8a43 100644
--- a/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
+++ b/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
@@ -95,7 +95,7 @@
}
@Override
- public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
+ public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
return null;
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
index 762bae0..5b5e5b7 100644
--- a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
@@ -207,7 +207,7 @@
}
@Override
- public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
+ public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
return store.getAddressBindingsForPort(connectPoint);
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostMonitor.java b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostMonitor.java
index a6af018..d7299e8 100644
--- a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostMonitor.java
+++ b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostMonitor.java
@@ -175,13 +175,15 @@
for (Device device : deviceService.getDevices()) {
for (Port port : deviceService.getPorts(device.id())) {
ConnectPoint cp = new ConnectPoint(device.id(), port.number());
- PortAddresses portAddresses =
+ Set<PortAddresses> portAddressSet =
hostManager.getAddressBindingsForPort(cp);
- for (InterfaceIpAddress ia : portAddresses.ipAddresses()) {
- if (ia.subnetAddress().contains(targetIp)) {
- sendProbe(device.id(), port, targetIp,
- ia.ipAddress(), portAddresses.mac());
+ for (PortAddresses portAddresses : portAddressSet) {
+ for (InterfaceIpAddress ia : portAddresses.ipAddresses()) {
+ if (ia.subnetAddress().contains(targetIp)) {
+ sendProbe(device.id(), port, targetIp,
+ ia.ipAddress(), portAddresses.mac());
+ }
}
}
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
index 0aae62d..49528d0 100644
--- a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
@@ -134,14 +134,16 @@
IpAddress target =
IpAddress.valueOf(IpAddress.Version.INET,
arp.getTargetProtocolAddress());
- PortAddresses addresses =
+ Set<PortAddresses> addressSet =
hostService.getAddressBindingsForPort(inPort);
- for (InterfaceIpAddress ia : addresses.ipAddresses()) {
- if (ia.ipAddress().equals(target)) {
- Ethernet arpReply =
- buildArpReply(ia.ipAddress(), addresses.mac(), eth);
- sendTo(arpReply, inPort);
+ for (PortAddresses addresses : addressSet) {
+ for (InterfaceIpAddress ia : addresses.ipAddresses()) {
+ if (ia.ipAddress().equals(target)) {
+ Ethernet arpReply =
+ buildArpReply(ia.ipAddress(), addresses.mac(), eth);
+ sendTo(arpReply, inPort);
+ }
}
}
return;
@@ -244,7 +246,7 @@
// TODO: Is this sufficient to identify outside-facing ports: just
// having IP addresses on a port?
//
- return !hostService.getAddressBindingsForPort(port).ipAddresses().isEmpty();
+ return !hostService.getAddressBindingsForPort(port).isEmpty();
}
@Override
diff --git a/core/net/src/test/java/org/onlab/onos/net/host/impl/HostManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/host/impl/HostManagerTest.java
index cbc9cf1..6a058ab 100644
--- a/core/net/src/test/java/org/onlab/onos/net/host/impl/HostManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/host/impl/HostManagerTest.java
@@ -234,10 +234,10 @@
new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
mgr.bindAddressesToPort(add1);
- PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
+ Set<PortAddresses> storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(add1.ipAddresses().equals(storedAddresses.ipAddresses()));
- assertTrue(add1.mac().equals(storedAddresses.mac()));
+ assertEquals(1, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
// Add some more addresses and check that they're added correctly
PortAddresses add2 =
@@ -246,18 +246,19 @@
mgr.bindAddressesToPort(add2);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().equals(
- Sets.newHashSet(IA1, IA2, IA3)));
- assertTrue(storedAddresses.mac().equals(MAC1));
+ assertEquals(2, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
+ assertTrue(storedAddresses.contains(add2));
PortAddresses add3 = new PortAddresses(CP1, null, MAC2);
mgr.bindAddressesToPort(add3);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().equals(
- Sets.newHashSet(IA1, IA2, IA3)));
- assertTrue(storedAddresses.mac().equals(MAC2));
+ assertEquals(3, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
+ assertTrue(storedAddresses.contains(add2));
+ assertTrue(storedAddresses.contains(add3));
}
@Test
@@ -266,10 +267,10 @@
new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
mgr.bindAddressesToPort(add1);
- PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
+ Set<PortAddresses> storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().size() == 2);
- assertNotNull(storedAddresses.mac());
+ assertEquals(1, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
PortAddresses rem1 =
new PortAddresses(CP1, Sets.newHashSet(IA1), null);
@@ -277,25 +278,15 @@
mgr.unbindAddressesFromPort(rem1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().equals(Sets.newHashSet(IA2)));
- assertTrue(storedAddresses.mac().equals(MAC1));
+ // It shouldn't have been removed because it didn't match the originally
+ // submitted address object
+ assertEquals(1, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
- PortAddresses rem2 = new PortAddresses(CP1, null, MAC1);
-
- mgr.unbindAddressesFromPort(rem2);
+ mgr.unbindAddressesFromPort(add1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().equals(Sets.newHashSet(IA2)));
- assertNull(storedAddresses.mac());
-
- PortAddresses rem3 =
- new PortAddresses(CP1, Sets.newHashSet(IA2), MAC1);
-
- mgr.unbindAddressesFromPort(rem3);
- storedAddresses = mgr.getAddressBindingsForPort(CP1);
-
- assertTrue(storedAddresses.ipAddresses().isEmpty());
- assertNull(storedAddresses.mac());
+ assertTrue(storedAddresses.isEmpty());
}
@Test
@@ -304,16 +295,15 @@
new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
mgr.bindAddressesToPort(add1);
- PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
+ Set<PortAddresses> storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().size() == 2);
- assertNotNull(storedAddresses.mac());
+ assertEquals(1, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
mgr.clearAddresses(CP1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.ipAddresses().isEmpty());
- assertNull(storedAddresses.mac());
+ assertTrue(storedAddresses.isEmpty());
}
@Test
@@ -322,12 +312,10 @@
new PortAddresses(CP1, Sets.newHashSet(IA1, IA2), MAC1);
mgr.bindAddressesToPort(add1);
- PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
+ Set<PortAddresses> storedAddresses = mgr.getAddressBindingsForPort(CP1);
- assertTrue(storedAddresses.connectPoint().equals(CP1));
- assertTrue(storedAddresses.ipAddresses().equals(
- Sets.newHashSet(IA1, IA2)));
- assertTrue(storedAddresses.mac().equals(MAC1));
+ assertEquals(1, storedAddresses.size());
+ assertTrue(storedAddresses.contains(add1));
}
@Test
diff --git a/core/net/src/test/java/org/onlab/onos/net/host/impl/HostMonitorTest.java b/core/net/src/test/java/org/onlab/onos/net/host/impl/HostMonitorTest.java
index 654cab1..a8febd7 100644
--- a/core/net/src/test/java/org/onlab/onos/net/host/impl/HostMonitorTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/host/impl/HostMonitorTest.java
@@ -20,7 +20,9 @@
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
@@ -130,7 +132,7 @@
expect(hostManager.getHostsByIp(TARGET_IP_ADDR))
.andReturn(Collections.<Host>emptySet()).anyTimes();
expect(hostManager.getAddressBindingsForPort(cp))
- .andReturn(pa).anyTimes();
+ .andReturn(Collections.singleton(pa)).anyTimes();
replay(hostManager);
TestPacketService packetService = new TestPacketService();
diff --git a/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
index e82151e..8beac4a 100644
--- a/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
@@ -19,7 +19,10 @@
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
@@ -207,13 +210,18 @@
IpAddress addr2 = IpAddress.valueOf("10.0." + (2 * i) + ".1");
InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1);
InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2);
- PortAddresses pa =
- new PortAddresses(cp, Sets.newHashSet(ia1, ia2),
- MacAddress.valueOf(i));
- addresses.add(pa);
+ PortAddresses pa1 =
+ new PortAddresses(cp, Sets.newHashSet(ia1),
+ MacAddress.valueOf(2 * i - 1));
+ PortAddresses pa2 =
+ new PortAddresses(cp, Sets.newHashSet(ia2),
+ MacAddress.valueOf(2 * i));
+
+ addresses.add(pa1);
+ addresses.add(pa2);
expect(hostService.getAddressBindingsForPort(cp))
- .andReturn(pa).anyTimes();
+ .andReturn(Sets.newHashSet(pa1, pa2)).anyTimes();
}
expect(hostService.getAddressBindings()).andReturn(addresses).anyTimes();
@@ -222,7 +230,7 @@
ConnectPoint cp = new ConnectPoint(getDeviceId(i + NUM_ADDRESS_PORTS),
P1);
expect(hostService.getAddressBindingsForPort(cp))
- .andReturn(new PortAddresses(cp, null, null)).anyTimes();
+ .andReturn(Collections.<PortAddresses>emptySet()).anyTimes();
}
}
@@ -339,7 +347,8 @@
IpAddress theirIp = IpAddress.valueOf("10.0.1.254");
IpAddress ourFirstIp = IpAddress.valueOf("10.0.1.1");
IpAddress ourSecondIp = IpAddress.valueOf("10.0.2.1");
- MacAddress ourMac = MacAddress.valueOf(1L);
+ MacAddress firstMac = MacAddress.valueOf(1L);
+ MacAddress secondMac = MacAddress.valueOf(2L);
Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
Collections.singleton(theirIp));
@@ -352,7 +361,7 @@
proxyArp.reply(arpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- Ethernet arpReply = buildArp(ARP.OP_REPLY, ourMac, MAC2, ourFirstIp, theirIp);
+ Ethernet arpReply = buildArp(ARP.OP_REPLY, firstMac, MAC2, ourFirstIp, theirIp);
verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
// Test a request for the second address on that port
@@ -362,7 +371,7 @@
proxyArp.reply(arpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- arpReply = buildArp(ARP.OP_REPLY, ourMac, MAC2, ourSecondIp, theirIp);
+ arpReply = buildArp(ARP.OP_REPLY, secondMac, MAC2, ourSecondIp, theirIp);
verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
}
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
index 8029e27..30a73e0 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
@@ -15,12 +15,25 @@
*/
package org.onlab.onos.store.host.impl;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
+import static org.onlab.util.Tools.namedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.RandomUtils;
import org.apache.felix.scr.annotations.Activate;
@@ -45,7 +58,6 @@
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostStore;
import org.onlab.onos.net.host.HostStoreDelegate;
-import org.onlab.onos.net.host.InterfaceIpAddress;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.store.AbstractStore;
@@ -63,21 +75,13 @@
import org.onlab.util.KryoNamespace;
import org.slf4j.Logger;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.onos.cluster.ControllerNodeToNodeId.toNodeId;
-import static org.onlab.onos.net.host.HostEvent.Type.*;
-import static org.onlab.util.Tools.namedThreads;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
//TODO: multi-provider, annotation not supported.
/**
@@ -100,8 +104,9 @@
// Hosts tracked by their location
private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
- private final Map<ConnectPoint, PortAddresses> portAddresses =
- new ConcurrentHashMap<>();
+ private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
+ Multimaps.synchronizedSetMultimap(
+ HashMultimap.<ConnectPoint, PortAddresses>create());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostClockService hostClockService;
@@ -343,77 +348,37 @@
@Override
public void updateAddressBindings(PortAddresses addresses) {
- synchronized (portAddresses) {
- PortAddresses existing = portAddresses.get(addresses.connectPoint());
- if (existing == null) {
- portAddresses.put(addresses.connectPoint(), addresses);
- } else {
- Set<InterfaceIpAddress> union =
- Sets.union(existing.ipAddresses(),
- addresses.ipAddresses()).immutableCopy();
-
- MacAddress newMac = (addresses.mac() == null) ? existing.mac()
- : addresses.mac();
-
- PortAddresses newAddresses =
- new PortAddresses(addresses.connectPoint(), union, newMac);
-
- portAddresses.put(newAddresses.connectPoint(), newAddresses);
- }
- }
+ portAddresses.put(addresses.connectPoint(), addresses);
}
@Override
public void removeAddressBindings(PortAddresses addresses) {
- synchronized (portAddresses) {
- PortAddresses existing = portAddresses.get(addresses.connectPoint());
- if (existing != null) {
- Set<InterfaceIpAddress> difference =
- Sets.difference(existing.ipAddresses(),
- addresses.ipAddresses()).immutableCopy();
-
- // If they removed the existing mac, set the new mac to null.
- // Otherwise, keep the existing mac.
- MacAddress newMac = existing.mac();
- if (addresses.mac() != null && addresses.mac().equals(existing.mac())) {
- newMac = null;
- }
-
- PortAddresses newAddresses =
- new PortAddresses(addresses.connectPoint(), difference, newMac);
-
- portAddresses.put(newAddresses.connectPoint(), newAddresses);
- }
- }
+ portAddresses.remove(addresses.connectPoint(), addresses);
}
@Override
public void clearAddressBindings(ConnectPoint connectPoint) {
- synchronized (portAddresses) {
- portAddresses.remove(connectPoint);
- }
+ portAddresses.removeAll(connectPoint);
}
@Override
public Set<PortAddresses> getAddressBindings() {
synchronized (portAddresses) {
- return new HashSet<>(portAddresses.values());
+ return ImmutableSet.copyOf(portAddresses.values());
}
}
@Override
- public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
- PortAddresses addresses;
-
+ public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
synchronized (portAddresses) {
- addresses = portAddresses.get(connectPoint);
- }
+ Set<PortAddresses> addresses = portAddresses.get(connectPoint);
- if (addresses == null) {
- addresses = new PortAddresses(connectPoint, null, null);
+ if (addresses == null) {
+ return Collections.emptySet();
+ } else {
+ return ImmutableSet.copyOf(addresses);
+ }
}
-
- return addresses;
}
// Auxiliary extension to allow location to mutate.
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java
index 6c27ea8..2f8fbd2 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java
@@ -15,10 +15,18 @@
*/
package org.onlab.onos.store.trivial.impl;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
+import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -34,7 +42,6 @@
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostStore;
import org.onlab.onos.net.host.HostStoreDelegate;
-import org.onlab.onos.net.host.InterfaceIpAddress;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.store.AbstractStore;
@@ -43,13 +50,11 @@
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.onlab.onos.net.host.HostEvent.Type.*;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
// TODO: multi-provider, annotation not supported.
/**
@@ -70,8 +75,9 @@
// Hosts tracked by their location
private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
- private final Map<ConnectPoint, PortAddresses> portAddresses =
- new ConcurrentHashMap<>();
+ private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
+ Multimaps.synchronizedSetMultimap(
+ HashMultimap.<ConnectPoint, PortAddresses>create());
@Activate
public void activate() {
@@ -213,77 +219,37 @@
@Override
public void updateAddressBindings(PortAddresses addresses) {
- synchronized (portAddresses) {
- PortAddresses existing = portAddresses.get(addresses.connectPoint());
- if (existing == null) {
- portAddresses.put(addresses.connectPoint(), addresses);
- } else {
- Set<InterfaceIpAddress> union =
- Sets.union(existing.ipAddresses(),
- addresses.ipAddresses()).immutableCopy();
-
- MacAddress newMac = (addresses.mac() == null) ? existing.mac()
- : addresses.mac();
-
- PortAddresses newAddresses =
- new PortAddresses(addresses.connectPoint(), union, newMac);
-
- portAddresses.put(newAddresses.connectPoint(), newAddresses);
- }
- }
+ portAddresses.put(addresses.connectPoint(), addresses);
}
@Override
public void removeAddressBindings(PortAddresses addresses) {
- synchronized (portAddresses) {
- PortAddresses existing = portAddresses.get(addresses.connectPoint());
- if (existing != null) {
- Set<InterfaceIpAddress> difference =
- Sets.difference(existing.ipAddresses(),
- addresses.ipAddresses()).immutableCopy();
-
- // If they removed the existing mac, set the new mac to null.
- // Otherwise, keep the existing mac.
- MacAddress newMac = existing.mac();
- if (addresses.mac() != null && addresses.mac().equals(existing.mac())) {
- newMac = null;
- }
-
- PortAddresses newAddresses =
- new PortAddresses(addresses.connectPoint(), difference, newMac);
-
- portAddresses.put(newAddresses.connectPoint(), newAddresses);
- }
- }
+ portAddresses.remove(addresses.connectPoint(), addresses);
}
@Override
public void clearAddressBindings(ConnectPoint connectPoint) {
- synchronized (portAddresses) {
- portAddresses.remove(connectPoint);
- }
+ portAddresses.removeAll(connectPoint);
}
@Override
public Set<PortAddresses> getAddressBindings() {
synchronized (portAddresses) {
- return new HashSet<>(portAddresses.values());
+ return ImmutableSet.copyOf(portAddresses.values());
}
}
@Override
- public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
- PortAddresses addresses;
-
+ public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
synchronized (portAddresses) {
- addresses = portAddresses.get(connectPoint);
- }
+ Set<PortAddresses> addresses = portAddresses.get(connectPoint);
- if (addresses == null) {
- addresses = new PortAddresses(connectPoint, null, null);
+ if (addresses == null) {
+ return Collections.emptySet();
+ } else {
+ return ImmutableSet.copyOf(addresses);
+ }
}
-
- return addresses;
}
// Auxiliary extension to allow location to mutate.