Speeding up stuff.
HostDescription now passes up just a single IpAddress.
diff --git a/apps/tvue/src/main/java/org/onlab/onos/tvue/package-info.java b/apps/tvue/src/main/java/org/onlab/onos/tvue/package-info.java
index bfd46a6..c3a6d857 100644
--- a/apps/tvue/src/main/java/org/onlab/onos/tvue/package-info.java
+++ b/apps/tvue/src/main/java/org/onlab/onos/tvue/package-info.java
@@ -1,4 +1,4 @@
/**
- * REST resources for the sample topology viewer application.
+ * Sample topology viewer application.
*/
package org.onlab.onos.tvue;
diff --git a/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
index e843770..1597b55 100644
--- a/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
@@ -22,8 +22,10 @@
protected void execute() {
TopologyService topologyService = get(TopologyService.class);
Topology topology = topologyService.currentTopology();
- print("version=%s, nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d",
- get(CoreService.class).version().toString(),
+ print("node=%s, version=%s",
+ get(ClusterService.class).getLocalNode().ip(),
+ get(CoreService.class).version().toString());
+ print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d",
get(ClusterService.class).getNodes().size(),
get(DeviceService.class).getDeviceCount(),
get(LinkService.class).getLinkCount(),
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java b/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
index bc6e3e5..2e92dad 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
@@ -1,6 +1,5 @@
package org.onlab.onos.net.host;
-import com.google.common.collect.ImmutableSet;
import org.onlab.onos.net.AbstractDescription;
import org.onlab.onos.net.HostLocation;
import org.onlab.onos.net.SparseAnnotations;
@@ -8,9 +7,6 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import java.util.HashSet;
-import java.util.Set;
-
import static com.google.common.base.MoreObjects.toStringHelper;
/**
@@ -22,7 +18,7 @@
private final MacAddress mac;
private final VlanId vlan;
private final HostLocation location;
- private final Set<IpPrefix> ips;
+ private final IpPrefix ip;
/**
* Creates a host description using the supplied information.
@@ -35,7 +31,7 @@
public DefaultHostDescription(MacAddress mac, VlanId vlan,
HostLocation location,
SparseAnnotations... annotations) {
- this(mac, vlan, location, new HashSet<IpPrefix>(), annotations);
+ this(mac, vlan, location, null, annotations);
}
/**
@@ -44,17 +40,17 @@
* @param mac host MAC address
* @param vlan host VLAN identifier
* @param location host location
- * @param ips of host IP addresses
+ * @param ip host IP address
* @param annotations optional key/value annotations map
*/
public DefaultHostDescription(MacAddress mac, VlanId vlan,
- HostLocation location, Set<IpPrefix> ips,
+ HostLocation location, IpPrefix ip,
SparseAnnotations... annotations) {
super(annotations);
this.mac = mac;
this.vlan = vlan;
this.location = location;
- this.ips = new HashSet<>(ips);
+ this.ip = ip;
}
@Override
@@ -73,8 +69,8 @@
}
@Override
- public Set<IpPrefix> ipAddresses() {
- return ImmutableSet.copyOf(ips);
+ public IpPrefix ipAddress() {
+ return ip;
}
@Override
@@ -83,7 +79,7 @@
.add("mac", mac)
.add("vlan", vlan)
.add("location", location)
- .add("ipAddresses", ips)
+ .add("ipAddress", ip)
.toString();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostDescription.java b/core/api/src/main/java/org/onlab/onos/net/host/HostDescription.java
index 27014b6..f45a383 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostDescription.java
@@ -1,7 +1,5 @@
package org.onlab.onos.net.host;
-import java.util.Set;
-
import org.onlab.onos.net.Description;
import org.onlab.onos.net.HostLocation;
import org.onlab.packet.IpPrefix;
@@ -35,10 +33,10 @@
HostLocation location();
/**
- * Returns zero or more IP address(es) associated with this host's MAC.
+ * Returns the IP address associated with this host's MAC.
*
- * @return a set of IP addresses.
+ * @return host IP address
*/
- Set<IpPrefix> ipAddresses();
+ IpPrefix ipAddress();
}
diff --git a/core/api/src/test/java/org/onlab/onos/event/AbstractEventAccumulatorTest.java b/core/api/src/test/java/org/onlab/onos/event/AbstractEventAccumulatorTest.java
index 9e561bf..ed18195 100644
--- a/core/api/src/test/java/org/onlab/onos/event/AbstractEventAccumulatorTest.java
+++ b/core/api/src/test/java/org/onlab/onos/event/AbstractEventAccumulatorTest.java
@@ -45,15 +45,18 @@
public void timeTrigger() {
TestAccumulator accumulator = new TestAccumulator();
accumulator.add(new TestEvent(FOO, "a"));
- delay(40);
+ delay(30);
assertTrue("should not have fired yet", accumulator.batch.isEmpty());
accumulator.add(new TestEvent(FOO, "b"));
- delay(40);
+ delay(30);
assertTrue("should not have fired yet", accumulator.batch.isEmpty());
accumulator.add(new TestEvent(FOO, "c"));
- delay(40);
+ delay(30);
+ assertTrue("should not have fired yet", accumulator.batch.isEmpty());
+ accumulator.add(new TestEvent(FOO, "d"));
+ delay(30);
assertFalse("should have fired", accumulator.batch.isEmpty());
- assertEquals("incorrect batch", "abc", accumulator.batch);
+ assertEquals("incorrect batch", "abcd", accumulator.batch);
}
@Test
diff --git a/core/api/src/test/java/org/onlab/onos/net/host/DefualtHostDecriptionTest.java b/core/api/src/test/java/org/onlab/onos/net/host/DefualtHostDecriptionTest.java
index 1b00be7..5ae7c27 100644
--- a/core/api/src/test/java/org/onlab/onos/net/host/DefualtHostDecriptionTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/host/DefualtHostDecriptionTest.java
@@ -1,10 +1,5 @@
package org.onlab.onos.net.host;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Set;
-
import org.junit.Test;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.HostLocation;
@@ -13,7 +8,8 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
-import com.google.common.collect.Sets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* Test for the default host description.
@@ -22,24 +18,22 @@
private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
private static final VlanId VLAN = VlanId.vlanId((short) 10);
+ private static final IpPrefix IP = IpPrefix.valueOf("10.0.0.1");
+
private static final HostLocation LOC = new HostLocation(
- DeviceId.deviceId("of:foo"),
- PortNumber.portNumber(100),
- 123L
- );
- private static final Set<IpPrefix> IPS = Sets.newHashSet(
- IpPrefix.valueOf("10.0.0.1"),
- IpPrefix.valueOf("10.0.0.2")
- );
+ DeviceId.deviceId("of:foo"),
+ PortNumber.portNumber(100),
+ 123L
+ );
@Test
public void basics() {
HostDescription host =
- new DefaultHostDescription(MAC, VLAN, LOC, IPS);
+ new DefaultHostDescription(MAC, VLAN, LOC, IP);
assertEquals("incorrect mac", MAC, host.hwAddress());
assertEquals("incorrect vlan", VLAN, host.vlan());
assertEquals("incorrect location", LOC, host.location());
- assertTrue("incorrect ip's", IPS.equals(host.ipAddresses()));
+ assertEquals("incorrect ip's", IP, host.ipAddress());
assertTrue("incorrect toString", host.toString().contains("vlan=10"));
}
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 29a0f18..4f9bcbb 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
@@ -168,7 +168,6 @@
checkNotNull(hostId, HOST_ID_NULL);
HostEvent event = store.removeHost(hostId);
if (event != null) {
- log.info("Host {} administratively removed", hostId);
post(event);
}
}
@@ -214,7 +213,6 @@
HostEvent event = store.createOrUpdateHost(provider().id(), hostId,
hostDescription);
if (event != null) {
- log.debug("Host {} detected", hostId);
post(event);
}
}
@@ -225,7 +223,6 @@
checkValidity();
HostEvent event = store.removeHost(hostId);
if (event != null) {
- log.debug("Host {} vanished", hostId);
post(event);
}
}
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 0b07380..6864fd7 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
@@ -58,8 +58,6 @@
private static final IpPrefix IP1 = IpPrefix.valueOf("10.0.0.1");
private static final IpPrefix IP2 = IpPrefix.valueOf("10.0.0.2");
- private static final Set<IpPrefix> IPSET1 = Sets.newHashSet(IP1);
- private static final Set<IpPrefix> IPSET2 = Sets.newHashSet(IP2);
private static final DeviceId DID1 = DeviceId.deviceId("of:001");
private static final DeviceId DID2 = DeviceId.deviceId("of:002");
@@ -94,14 +92,14 @@
provider = new TestHostProvider();
providerService = registry.register(provider);
assertTrue("provider should be registered",
- registry.getProviders().contains(provider.id()));
+ registry.getProviders().contains(provider.id()));
}
@After
public void tearDown() {
registry.unregister(provider);
assertFalse("provider should not be registered",
- registry.getProviders().contains(provider.id()));
+ registry.getProviders().contains(provider.id()));
mgr.removeListener(listener);
mgr.deactivate();
@@ -109,8 +107,8 @@
}
private void detect(HostId hid, MacAddress mac, VlanId vlan,
- HostLocation loc, Set<IpPrefix> ips) {
- HostDescription descr = new DefaultHostDescription(mac, vlan, loc, ips);
+ HostLocation loc, IpPrefix ip) {
+ HostDescription descr = new DefaultHostDescription(mac, vlan, loc, ip);
providerService.hostDetected(hid, descr);
assertNotNull("host should be found", mgr.getHost(hid));
}
@@ -130,26 +128,26 @@
assertNull("host shouldn't be found", mgr.getHost(HID1));
// host addition
- detect(HID1, MAC1, VLAN1, LOC1, IPSET1);
+ detect(HID1, MAC1, VLAN1, LOC1, IP1);
assertEquals("exactly one should be found", 1, mgr.getHostCount());
- detect(HID2, MAC2, VLAN2, LOC2, IPSET1);
+ detect(HID2, MAC2, VLAN2, LOC2, IP1);
assertEquals("two hosts should be found", 2, mgr.getHostCount());
validateEvents(HOST_ADDED, HOST_ADDED);
// host motion
- detect(HID1, MAC1, VLAN1, LOC2, IPSET1);
+ detect(HID1, MAC1, VLAN1, LOC2, IP1);
validateEvents(HOST_MOVED);
assertEquals("only two hosts should be found", 2, mgr.getHostCount());
// host update
- detect(HID1, MAC1, VLAN1, LOC2, IPSET2);
+ detect(HID1, MAC1, VLAN1, LOC2, IP2);
validateEvents(HOST_UPDATED);
assertEquals("only two hosts should be found", 2, mgr.getHostCount());
}
@Test
public void hostVanished() {
- detect(HID1, MAC1, VLAN1, LOC1, IPSET1);
+ detect(HID1, MAC1, VLAN1, LOC1, IP1);
providerService.hostVanished(HID1);
validateEvents(HOST_ADDED, HOST_REMOVED);
@@ -157,7 +155,7 @@
}
private void validateHosts(
- String msg, Iterable<Host> hosts, HostId ... ids) {
+ String msg, Iterable<Host> hosts, HostId... ids) {
Set<HostId> hids = Sets.newHashSet(ids);
for (Host h : hosts) {
assertTrue(msg, hids.remove(h.id()));
@@ -167,8 +165,8 @@
@Test
public void getHosts() {
- detect(HID1, MAC1, VLAN1, LOC1, IPSET1);
- detect(HID2, MAC2, VLAN1, LOC2, IPSET2);
+ detect(HID1, MAC1, VLAN1, LOC1, IP1);
+ detect(HID2, MAC2, VLAN1, LOC2, IP2);
validateHosts("host not properly stored", mgr.getHosts(), HID1, HID2);
validateHosts("can't get hosts by VLAN", mgr.getHostsByVlan(VLAN1), HID1, HID2);
@@ -210,7 +208,7 @@
@Test
public void bindAddressesToPort() {
PortAddresses add1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -241,7 +239,7 @@
@Test
public void unbindAddressesFromPort() {
PortAddresses add1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -250,7 +248,7 @@
assertNotNull(storedAddresses.mac());
PortAddresses rem1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1), null);
+ Sets.newHashSet(PREFIX1), null);
mgr.unbindAddressesFromPort(rem1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -267,7 +265,7 @@
assertNull(storedAddresses.mac());
PortAddresses rem3 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX2), MAC1);
mgr.unbindAddressesFromPort(rem3);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -279,7 +277,7 @@
@Test
public void clearAddresses() {
PortAddresses add1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -297,7 +295,7 @@
@Test
public void getAddressBindingsForPort() {
PortAddresses add1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
@@ -314,7 +312,7 @@
assertTrue(storedAddresses.isEmpty());
PortAddresses add1 = new PortAddresses(CP1,
- Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
+ Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
@@ -323,7 +321,7 @@
assertTrue(storedAddresses.size() == 1);
PortAddresses add2 = new PortAddresses(CP2,
- Sets.newHashSet(PREFIX3), MAC2);
+ Sets.newHashSet(PREFIX3), MAC2);
mgr.bindAddressesToPort(add2);
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
index 09820f4..9362156 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
@@ -1,26 +1,20 @@
package org.onlab.onos.store.host.impl;
-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 com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
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.Service;
+import org.onlab.onos.net.Annotations;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultHost;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.HostLocation;
import org.onlab.onos.net.host.HostDescription;
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostStore;
@@ -33,10 +27,13 @@
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
-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 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;
/**
* Manages inventory of end-station hosts using trivial in-memory
@@ -46,13 +43,13 @@
@Component(immediate = true)
@Service
public class DistributedHostStore
-extends AbstractStore<HostEvent, HostStoreDelegate>
-implements HostStore {
+ extends AbstractStore<HostEvent, HostStoreDelegate>
+ implements HostStore {
private final Logger log = getLogger(getClass());
// Host inventory
- private final Map<HostId, Host> hosts = new ConcurrentHashMap<>();
+ private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(2000000, 0.75f, 16);
// Hosts tracked by their location
private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
@@ -72,8 +69,8 @@
@Override
public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
- HostDescription hostDescription) {
- Host host = hosts.get(hostId);
+ HostDescription hostDescription) {
+ StoredHost host = hosts.get(hostId);
if (host == null) {
return createHost(providerId, hostId, hostDescription);
}
@@ -82,12 +79,12 @@
// creates a new host and sends HOST_ADDED
private HostEvent createHost(ProviderId providerId, HostId hostId,
- HostDescription descr) {
- DefaultHost newhost = new DefaultHost(providerId, hostId,
- descr.hwAddress(),
- descr.vlan(),
- descr.location(),
- descr.ipAddresses());
+ HostDescription descr) {
+ StoredHost newhost = new StoredHost(providerId, hostId,
+ descr.hwAddress(),
+ descr.vlan(),
+ descr.location(),
+ ImmutableSet.of(descr.ipAddress()));
synchronized (this) {
hosts.put(hostId, newhost);
locations.put(descr.location(), newhost);
@@ -96,28 +93,24 @@
}
// checks for type of update to host, sends appropriate event
- private HostEvent updateHost(ProviderId providerId, Host host,
- HostDescription descr) {
- DefaultHost updated;
+ private HostEvent updateHost(ProviderId providerId, StoredHost host,
+ HostDescription descr) {
HostEvent event;
if (!host.location().equals(descr.location())) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- host.ipAddresses());
- event = new HostEvent(HOST_MOVED, updated);
+ host.setLocation(descr.location());
+ return new HostEvent(HOST_MOVED, host);
+ }
- } else if (!(host.ipAddresses().equals(descr.ipAddresses()))) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- descr.ipAddresses());
- event = new HostEvent(HOST_UPDATED, updated);
- } else {
+ if (host.ipAddresses().contains(descr.ipAddress())) {
return null;
}
+
+ Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
+ addresses.add(descr.ipAddress());
+ StoredHost updated = new StoredHost(providerId, host.id(),
+ host.mac(), host.vlan(),
+ descr.location(), addresses);
+ event = new HostEvent(HOST_UPDATED, updated);
synchronized (this) {
hosts.put(host.id(), updated);
locations.remove(host.location(), host);
@@ -145,7 +138,7 @@
@Override
public Iterable<Host> getHosts() {
- return Collections.unmodifiableSet(new HashSet<>(hosts.values()));
+ return ImmutableSet.<Host>copyOf(hosts.values());
}
@Override
@@ -275,4 +268,35 @@
return addresses;
}
+ // Auxiliary extension to allow location to mutate.
+ private class StoredHost extends DefaultHost {
+ private HostLocation location;
+
+ /**
+ * Creates an end-station host using the supplied information.
+ *
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param location host location
+ * @param ips host IP addresses
+ * @param annotations optional key/value annotations
+ */
+ public StoredHost(ProviderId providerId, HostId id,
+ MacAddress mac, VlanId vlan, HostLocation location,
+ Set<IpPrefix> ips, Annotations... annotations) {
+ super(providerId, id, mac, vlan, location, ips, annotations);
+ this.location = location;
+ }
+
+ void setLocation(HostLocation location) {
+ this.location = location;
+ }
+
+ @Override
+ public HostLocation location() {
+ return location;
+ }
+ }
}
diff --git a/core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java b/core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
index 5c706e6..0ca4ae2 100644
--- a/core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
+++ b/core/store/hz/net/src/main/java/org/onlab/onos/store/host/impl/DistributedHostStore.java
@@ -1,26 +1,20 @@
package org.onlab.onos.store.host.impl;
-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 com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
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.Service;
+import org.onlab.onos.net.Annotations;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultHost;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.HostLocation;
import org.onlab.onos.net.host.HostDescription;
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostStore;
@@ -33,10 +27,13 @@
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
-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 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;
/**
* TEMPORARY: Manages inventory of end-station hosts using distributed
@@ -46,13 +43,13 @@
@Component(immediate = true)
@Service
public class DistributedHostStore
-extends AbstractStore<HostEvent, HostStoreDelegate>
-implements HostStore {
+ extends AbstractStore<HostEvent, HostStoreDelegate>
+ implements HostStore {
private final Logger log = getLogger(getClass());
// Host inventory
- private final Map<HostId, Host> hosts = new ConcurrentHashMap<>();
+ private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(2000000, 0.75f, 16);
// Hosts tracked by their location
private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
@@ -72,8 +69,8 @@
@Override
public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
- HostDescription hostDescription) {
- Host host = hosts.get(hostId);
+ HostDescription hostDescription) {
+ StoredHost host = hosts.get(hostId);
if (host == null) {
return createHost(providerId, hostId, hostDescription);
}
@@ -82,12 +79,12 @@
// creates a new host and sends HOST_ADDED
private HostEvent createHost(ProviderId providerId, HostId hostId,
- HostDescription descr) {
- DefaultHost newhost = new DefaultHost(providerId, hostId,
- descr.hwAddress(),
- descr.vlan(),
- descr.location(),
- descr.ipAddresses());
+ HostDescription descr) {
+ StoredHost newhost = new StoredHost(providerId, hostId,
+ descr.hwAddress(),
+ descr.vlan(),
+ descr.location(),
+ ImmutableSet.of(descr.ipAddress()));
synchronized (this) {
hosts.put(hostId, newhost);
locations.put(descr.location(), newhost);
@@ -96,28 +93,24 @@
}
// checks for type of update to host, sends appropriate event
- private HostEvent updateHost(ProviderId providerId, Host host,
- HostDescription descr) {
- DefaultHost updated;
+ private HostEvent updateHost(ProviderId providerId, StoredHost host,
+ HostDescription descr) {
HostEvent event;
if (!host.location().equals(descr.location())) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- host.ipAddresses());
- event = new HostEvent(HOST_MOVED, updated);
+ host.setLocation(descr.location());
+ return new HostEvent(HOST_MOVED, host);
+ }
- } else if (!(host.ipAddresses().equals(descr.ipAddresses()))) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- descr.ipAddresses());
- event = new HostEvent(HOST_UPDATED, updated);
- } else {
+ if (host.ipAddresses().contains(descr.ipAddress())) {
return null;
}
+
+ Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
+ addresses.add(descr.ipAddress());
+ StoredHost updated = new StoredHost(providerId, host.id(),
+ host.mac(), host.vlan(),
+ descr.location(), addresses);
+ event = new HostEvent(HOST_UPDATED, updated);
synchronized (this) {
hosts.put(host.id(), updated);
locations.remove(host.location(), host);
@@ -145,7 +138,7 @@
@Override
public Iterable<Host> getHosts() {
- return Collections.unmodifiableSet(new HashSet<>(hosts.values()));
+ return ImmutableSet.<Host>copyOf(hosts.values());
}
@Override
@@ -275,4 +268,35 @@
return addresses;
}
+ // Auxiliary extension to allow location to mutate.
+ private class StoredHost extends DefaultHost {
+ private HostLocation location;
+
+ /**
+ * Creates an end-station host using the supplied information.
+ *
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param location host location
+ * @param ips host IP addresses
+ * @param annotations optional key/value annotations
+ */
+ public StoredHost(ProviderId providerId, HostId id,
+ MacAddress mac, VlanId vlan, HostLocation location,
+ Set<IpPrefix> ips, Annotations... annotations) {
+ super(providerId, id, mac, vlan, location, ips, annotations);
+ this.location = location;
+ }
+
+ void setLocation(HostLocation location) {
+ this.location = location;
+ }
+
+ @Override
+ public HostLocation location() {
+ return location;
+ }
+ }
}
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 92d6a22..67ed050 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
@@ -1,26 +1,20 @@
package org.onlab.onos.store.trivial.impl;
-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 com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
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.Service;
+import org.onlab.onos.net.Annotations;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultHost;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.HostLocation;
import org.onlab.onos.net.host.HostDescription;
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostStore;
@@ -33,10 +27,13 @@
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
-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 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;
/**
* Manages inventory of end-station hosts using trivial in-memory
@@ -51,7 +48,7 @@
private final Logger log = getLogger(getClass());
// Host inventory
- private final Map<HostId, Host> hosts = new ConcurrentHashMap<>();
+ private final Map<HostId, StoredHost> hosts = new ConcurrentHashMap<>(2000000, 0.75f, 16);
// Hosts tracked by their location
private final Multimap<ConnectPoint, Host> locations = HashMultimap.create();
@@ -72,7 +69,7 @@
@Override
public HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId,
HostDescription hostDescription) {
- Host host = hosts.get(hostId);
+ StoredHost host = hosts.get(hostId);
if (host == null) {
return createHost(providerId, hostId, hostDescription);
}
@@ -82,11 +79,11 @@
// creates a new host and sends HOST_ADDED
private HostEvent createHost(ProviderId providerId, HostId hostId,
HostDescription descr) {
- DefaultHost newhost = new DefaultHost(providerId, hostId,
- descr.hwAddress(),
- descr.vlan(),
- descr.location(),
- descr.ipAddresses());
+ StoredHost newhost = new StoredHost(providerId, hostId,
+ descr.hwAddress(),
+ descr.vlan(),
+ descr.location(),
+ ImmutableSet.of(descr.ipAddress()));
synchronized (this) {
hosts.put(hostId, newhost);
locations.put(descr.location(), newhost);
@@ -95,28 +92,24 @@
}
// checks for type of update to host, sends appropriate event
- private HostEvent updateHost(ProviderId providerId, Host host,
+ private HostEvent updateHost(ProviderId providerId, StoredHost host,
HostDescription descr) {
- DefaultHost updated;
HostEvent event;
if (!host.location().equals(descr.location())) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- host.ipAddresses());
- event = new HostEvent(HOST_MOVED, updated);
+ host.setLocation(descr.location());
+ return new HostEvent(HOST_MOVED, host);
+ }
- } else if (!(host.ipAddresses().equals(descr.ipAddresses()))) {
- updated = new DefaultHost(providerId, host.id(),
- host.mac(),
- host.vlan(),
- descr.location(),
- descr.ipAddresses());
- event = new HostEvent(HOST_UPDATED, updated);
- } else {
+ if (host.ipAddresses().contains(descr.ipAddress())) {
return null;
}
+
+ Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
+ addresses.add(descr.ipAddress());
+ StoredHost updated = new StoredHost(providerId, host.id(),
+ host.mac(), host.vlan(),
+ descr.location(), addresses);
+ event = new HostEvent(HOST_UPDATED, updated);
synchronized (this) {
hosts.put(host.id(), updated);
locations.remove(host.location(), host);
@@ -144,7 +137,7 @@
@Override
public Iterable<Host> getHosts() {
- return Collections.unmodifiableSet(new HashSet<>(hosts.values()));
+ return ImmutableSet.<Host>copyOf(hosts.values());
}
@Override
@@ -274,4 +267,35 @@
return addresses;
}
+ // Auxiliary extension to allow location to mutate.
+ private class StoredHost extends DefaultHost {
+ private HostLocation location;
+
+ /**
+ * Creates an end-station host using the supplied information.
+ *
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param location host location
+ * @param ips host IP addresses
+ * @param annotations optional key/value annotations
+ */
+ public StoredHost(ProviderId providerId, HostId id,
+ MacAddress mac, VlanId vlan, HostLocation location,
+ Set<IpPrefix> ips, Annotations... annotations) {
+ super(providerId, id, mac, vlan, location, ips, annotations);
+ this.location = location;
+ }
+
+ void setLocation(HostLocation location) {
+ this.location = location;
+ }
+
+ @Override
+ public HostLocation location() {
+ return location;
+ }
+ }
}
diff --git a/pom.xml b/pom.xml
index ad4ddcb..bf5e1f0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -493,7 +493,7 @@
<group>
<title>Core Subsystems</title>
<packages>
- org.onlab.onos.cluster.impl:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.store.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.event.impl:org.onlab.onos.store.*:org.onlab.onos.net.intent.impl
+ org.onlab.onos.impl:org.onlab.onos.cluster.impl:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.store.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.event.impl:org.onlab.onos.store.*:org.onlab.onos.net.intent.impl:org.onlab.onos.net.proxyarp.impl
</packages>
</group>
<group>
@@ -518,7 +518,7 @@
<group>
<title>Sample Applications</title>
<packages>
- org.onlab.onos.tvue:org.onlab.onos.fwd:org.onlab.onos.foo
+ org.onlab.onos.tvue:org.onlab.onos.fwd:org.onlab.onos.ifwd:org.onlab.onos.mobility:org.onlab.onos.proxyarp:org.onlab.onos.foo
</packages>
</group>
</groups>
diff --git a/providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java b/providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
index 4f5bb81..45a7bd8 100644
--- a/providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
+++ b/providers/openflow/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
@@ -1,12 +1,5 @@
package org.onlab.onos.provider.of.host.impl;
-import static com.google.common.collect.Sets.newHashSet;
-import static org.onlab.onos.net.DeviceId.deviceId;
-import static org.onlab.onos.net.PortNumber.portNumber;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Set;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -36,6 +29,10 @@
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.PortNumber.portNumber;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Provider which uses an OpenFlow controller to detect network
* end-station hosts.
@@ -58,6 +55,8 @@
private final InternalHostProvider listener = new InternalHostProvider();
+ private boolean ipLearn = true;
+
/**
* Creates an OpenFlow host provider.
*/
@@ -69,7 +68,6 @@
public void activate() {
providerService = providerRegistry.register(this);
controller.addPacketListener(10, listener);
-
log.info("Started");
}
@@ -78,7 +76,6 @@
providerRegistry.unregister(this);
controller.removePacketListener(listener);
providerService = null;
-
log.info("Stopped");
}
@@ -95,33 +92,33 @@
VlanId vlan = VlanId.vlanId(eth.getVlanID());
ConnectPoint heardOn = new ConnectPoint(deviceId(Dpid.uri(pktCtx.dpid())),
- portNumber(pktCtx.inPort()));
+ portNumber(pktCtx.inPort()));
- // If this is not an edge port, bail out.
+ // If this is not an edge port, bail out.
Topology topology = topologyService.currentTopology();
if (topologyService.isInfrastructure(topology, heardOn)) {
return;
}
HostLocation hloc = new HostLocation(deviceId(Dpid.uri(pktCtx.dpid())),
- portNumber(pktCtx.inPort()),
- System.currentTimeMillis());
+ portNumber(pktCtx.inPort()),
+ System.currentTimeMillis());
+
HostId hid = HostId.hostId(eth.getSourceMAC(), vlan);
+
// Potentially a new or moved host
if (eth.getEtherType() == Ethernet.TYPE_ARP) {
-
-
ARP arp = (ARP) eth.getPayload();
- Set<IpPrefix> ips = newHashSet(IpPrefix.valueOf(arp.getSenderProtocolAddress()));
+ IpPrefix ip = IpPrefix.valueOf(arp.getSenderProtocolAddress());
HostDescription hdescr =
- new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ips);
+ new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
providerService.hostDetected(hid, hdescr);
- } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
- IPv4 ip = (IPv4) eth.getPayload();
- Set<IpPrefix> ips = newHashSet(IpPrefix.valueOf(ip.getSourceAddress()));
+ } else if (ipLearn && eth.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 pip = (IPv4) eth.getPayload();
+ IpPrefix ip = IpPrefix.valueOf(pip.getSourceAddress());
HostDescription hdescr =
- new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ips);
+ new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
providerService.hostDetected(hid, hdescr);
}