Merge remote-tracking branch 'origin/master'
diff --git a/apps/ifwd/src/main/java/org/onlab/onos/ifwd/IntentReactiveForwarding.java b/apps/ifwd/src/main/java/org/onlab/onos/ifwd/IntentReactiveForwarding.java
index 15c7bc3..2cbfcc4 100644
--- a/apps/ifwd/src/main/java/org/onlab/onos/ifwd/IntentReactiveForwarding.java
+++ b/apps/ifwd/src/main/java/org/onlab/onos/ifwd/IntentReactiveForwarding.java
@@ -14,6 +14,7 @@
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.intent.HostToHostIntent;
+import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.packet.DefaultOutboundPacket;
@@ -26,6 +27,9 @@
import org.onlab.packet.Ethernet;
import org.slf4j.Logger;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -52,6 +56,8 @@
private static long intentId = 1;
+ private Map<HostIdPair, IntentId> intents = new ConcurrentHashMap<>();
+
@Activate
public void activate() {
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
@@ -91,8 +97,12 @@
return;
}
- // Otherwise forward and be done with it.
- setUpConnectivity(context, srcId, dstId);
+ // Install a new intent only if we have not installed one already
+ HostIdPair key = new HostIdPair(srcId, dstId);
+ if (!intents.containsKey(key)) {
+ // Otherwise forward and be done with it.
+ intents.put(key, setUpConnectivity(context, srcId, dstId).getId());
+ }
forwardPacketToDst(context, dst);
}
}
@@ -122,15 +132,26 @@
}
// Install a rule forwarding the packet to the specified port.
- private void setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) {
+ private Intent setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) {
TrafficSelector selector = DefaultTrafficSelector.builder().build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
HostToHostIntent intent =
new HostToHostIntent(new IntentId(intentId++), srcId, dstId,
selector, treatment);
-
intentService.submit(intent);
+ return intent;
}
+
+ private class HostIdPair {
+ HostId one;
+ HostId two;
+
+ HostIdPair(HostId one, HostId two) {
+ boolean oneFirst = one.hashCode() < two.hashCode();
+ this.one = oneFirst ? one : two;
+ this.two = oneFirst ? two : one;
+ }
+ }
}
diff --git a/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
new file mode 100644
index 0000000..592b737
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
@@ -0,0 +1,32 @@
+package org.onlab.onos.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.cluster.ClusterService;
+import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.flow.FlowRuleService;
+import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.intent.IntentService;
+import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.topology.TopologyService;
+
+/**
+ * Provides summary of ONOS model.
+ */
+@Command(scope = "onos", name = "summary",
+ description = "Provides summary of ONOS model")
+public class SummaryCommand extends AbstractShellCommand {
+
+ @Override
+ protected void execute() {
+ TopologyService topologyService = get(TopologyService.class);
+ print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, flows=%d, intents=%d",
+ get(ClusterService.class).getNodes().size(),
+ get(DeviceService.class).getDeviceCount(),
+ get(LinkService.class).getLinkCount(),
+ get(HostService.class).getHostCount(),
+ topologyService.getClusters(topologyService.currentTopology()).size(),
+ get(FlowRuleService.class).getFlowRuleCount(),
+ get(IntentService.class).getIntentCount());
+ }
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 9ed8a47..96f974a 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -2,6 +2,9 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
+ <action class="org.onlab.onos.cli.SummaryCommand"/>
+ </command>
+ <command>
<action class="org.onlab.onos.cli.NodesListCommand"/>
</command>
<command>
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
index 2ebc5a25..ccbb33b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -13,6 +13,13 @@
public interface FlowRuleService {
/**
+ * Returns the number of flow rules in the system.
+ *
+ * @return flow rule count
+ */
+ int getFlowRuleCount();
+
+ /**
* Returns the collection of flow entries applied on the specified device.
* This will include flow rules which may not yet have been applied to
* the device.
@@ -72,7 +79,4 @@
* @param listener flow rule listener
*/
void removeListener(FlowRuleListener listener);
-
-
-
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
index 4d68e74..5ce7eb1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
@@ -10,7 +10,15 @@
public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> {
/**
+ * Returns the number of flow rule in the store.
+ *
+ * @return number of flow rules
+ */
+ int getFlowRuleCount();
+
+ /**
* Returns the stored flow.
+ *
* @param rule the rule to look for
* @return a flow rule
*/
@@ -60,5 +68,4 @@
* @return flow_removed event, or null if nothing removed
*/
FlowRuleEvent removeFlowRule(FlowEntry rule);
-
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index 385e300..27a86a3 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -40,14 +40,14 @@
@Component(immediate = true)
@Service
public class FlowRuleManager
-extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
-implements FlowRuleService, FlowRuleProviderRegistry {
+ extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
+ implements FlowRuleService, FlowRuleProviderRegistry {
public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
private final Logger log = getLogger(getClass());
private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
- listenerRegistry = new AbstractListenerRegistry<>();
+ listenerRegistry = new AbstractListenerRegistry<>();
private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate();
@@ -75,6 +75,11 @@
}
@Override
+ public int getFlowRuleCount() {
+ return store.getFlowRuleCount();
+ }
+
+ @Override
public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
return store.getFlowEntries(deviceId);
}
@@ -106,7 +111,7 @@
@Override
public void removeFlowRulesById(ApplicationId id) {
- Iterable<FlowRule> rules = getFlowRulesById(id);
+ Iterable<FlowRule> rules = getFlowRulesById(id);
FlowRuleProvider frp;
Device device;
@@ -140,8 +145,8 @@
}
private class InternalFlowRuleProviderService
- extends AbstractProviderService<FlowRuleProvider>
- implements FlowRuleProviderService {
+ extends AbstractProviderService<FlowRuleProvider>
+ implements FlowRuleProviderService {
protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
super(provider);
@@ -160,16 +165,16 @@
FlowRuleProvider frp = getProvider(device.providerId());
FlowRuleEvent event = null;
switch (stored.state()) {
- case ADDED:
- case PENDING_ADD:
+ case ADDED:
+ case PENDING_ADD:
frp.applyFlowRule(stored);
- break;
- case PENDING_REMOVE:
- case REMOVED:
- event = store.removeFlowRule(stored);
- break;
- default:
- break;
+ break;
+ case PENDING_REMOVE:
+ case REMOVED:
+ event = store.removeFlowRule(stored);
+ break;
+ default:
+ break;
}
if (event != null) {
@@ -186,17 +191,17 @@
FlowRuleProvider frp = getProvider(device.providerId());
FlowRuleEvent event = null;
switch (flowRule.state()) {
- case PENDING_REMOVE:
- case REMOVED:
- event = store.removeFlowRule(flowRule);
- frp.removeFlowRule(flowRule);
- break;
- case ADDED:
- case PENDING_ADD:
- frp.applyFlowRule(flowRule);
- break;
- default:
- log.debug("Flow {} has not been installed.", flowRule);
+ case PENDING_REMOVE:
+ case REMOVED:
+ event = store.removeFlowRule(flowRule);
+ frp.removeFlowRule(flowRule);
+ break;
+ case ADDED:
+ case PENDING_ADD:
+ frp.applyFlowRule(flowRule);
+ break;
+ default:
+ log.debug("Flow {} has not been installed.", flowRule);
}
if (event != null) {
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index f3c8f34..d49e00b 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -58,6 +58,11 @@
@Override
+ public int getFlowRuleCount() {
+ return flowEntries.size();
+ }
+
+ @Override
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
diff --git a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index f3c8f34..d49e00b 100644
--- a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -58,6 +58,11 @@
@Override
+ public int getFlowRuleCount() {
+ return flowEntries.size();
+ }
+
+ @Override
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
index 5fa92f3..833d6a6 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
@@ -57,6 +57,11 @@
@Override
+ public int getFlowRuleCount() {
+ return flowEntries.size();
+ }
+
+ @Override
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {