Added FatTree simulator, extended NullProviders.java and cli null control command
Change-Id: Ibfae78306fa8663af13770abe51d202453dd1474
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/FatTreeTopologySimulator.java b/providers/null/src/main/java/org/onosproject/provider/nil/FatTreeTopologySimulator.java
new file mode 100644
index 0000000..9a97c62
--- /dev/null
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/FatTreeTopologySimulator.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.nil;
+import java.util.Arrays;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Fat-tree topology simulator.
+ */
+public class FatTreeTopologySimulator extends TopologySimulator {
+
+ private static final int DEFAULT_NUMBER_OF_PORTS_PER_SWITCH = 4;
+ protected int kPorts;
+ protected int numberOfPods;
+ protected int numberOfAggLayerSwitches;
+ protected int numberOfCoreLayerSwitches;
+ protected int numberOfEdgeLayerSwitches;
+
+ @Override
+ protected void processTopoShape(String shape) {
+ super.processTopoShape(shape);
+
+ // If switch ports are not provided use a default value
+ int k = (topoShape.length == 1) ?
+ DEFAULT_NUMBER_OF_PORTS_PER_SWITCH :
+ Integer.parseInt(topoShape[1]);
+
+ // A fat-tree is parametrized by the total number of ports per switch.
+ // check top of page 4 of http://web.eecs.umich.edu/~mosharaf/Readings/Fat-Tree.pdf
+ kPorts = k;
+ numberOfPods = k;
+ numberOfCoreLayerSwitches = (k / 2) * (k / 2);
+ numberOfAggLayerSwitches = k * k / 2;
+ numberOfEdgeLayerSwitches = k * k / 2;
+
+ // need to also change hostCount variable of TopologySimulator
+ hostCount = kPorts / 2;
+ }
+
+
+ @Override
+ public void setUpTopology() {
+
+ checkArgument(kPorts > 1, "Fat Tree switches must " +
+ "have at **least** 2 ports each!");
+
+ // this is the total number of **Switches**
+ // in a fat-tree topology
+ deviceCount = numberOfAggLayerSwitches +
+ numberOfCoreLayerSwitches +
+ numberOfEdgeLayerSwitches;
+
+ log.info("Booting a {} with {}-ports, {} switches in total {} pods",
+ topoShape[0], kPorts, deviceCount, numberOfPods);
+
+
+ prepareForDeviceEvents(deviceCount);
+ createDevices();
+ waitForDeviceEvents();
+
+ createLinks();
+ createHosts();
+ }
+
+ @Override
+ protected void createLinks() {
+
+ // For each switch keep a count of used ports
+ int[] portList = new int[deviceCount];
+ Arrays.fill(portList, 0);
+
+ // we assume that deviceIds stores all the fat tree switches in a flat list
+ int end = numberOfPods / 2;
+ // from [ 0, (k/2)^2 - 1] we store (k/2)^2 core switces
+ int startOfCore = 0;
+ // from [ (k/2)^2, (k/2)^2 + (k^2)/2 - 1] we store (k^2)/2 aggregation switches
+ int startOfAgg = (numberOfPods / 2) * (numberOfPods / 2);
+ // from [ (k/2)^2 + (k^2)/2, (k/2)^2 + (k^2)/2 + (k^2)/2 -1] we store (k^2)/2 edge switches
+ int startOfEdge = startOfAgg + (numberOfPods * numberOfPods) / 2;
+
+ log.debug("startOfCore = {}, startOfAgg = {}, startOfEdge = {}",
+ startOfCore, startOfAgg, startOfEdge);
+
+ // Create links between core and aggregation switches
+ for (int x = 0; x < numberOfAggLayerSwitches; x += end) {
+
+ // each agg.switch will handle a group of k/2 core consecutive switches
+ for (int i = 0; i < end; i += 1) {
+ for (int j = 0; j < end; j += 1) {
+ int coreSwitch = i * end + j;
+ int aggSwitch = startOfAgg + x + i;
+
+ createLink(coreSwitch,
+ aggSwitch,
+ portList[coreSwitch]++,
+ portList[aggSwitch]++);
+ }
+ }
+ }
+
+ // Create links between aggregation and edge switches
+ for (int x = 0; x < numberOfAggLayerSwitches; x += end) {
+ for (int i = 0; i < end; i += 1) {
+ for (int j = 0; j < end; j += 1) {
+ int aggSwitch = startOfAgg + x + i;
+ int edgeSwitch = startOfEdge + x + j;
+
+ createLink(aggSwitch,
+ edgeSwitch,
+ portList[aggSwitch]++,
+ portList[edgeSwitch]++);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void createHosts() {
+
+ int firstEdgeSwitch = (numberOfPods / 2) * (numberOfPods / 2) +
+ (numberOfPods * numberOfPods) / 2;
+
+ // hosts connect **only** to edge switches, each edge switch has k/2 ports free for hosts
+ for (int edgeSwitch = firstEdgeSwitch; edgeSwitch < deviceCount; edgeSwitch++) {
+
+ createHosts(deviceIds.get(edgeSwitch), kPorts / 2);
+ }
+ }
+}
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java b/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
index b0ccf15..5d65caf 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
@@ -365,6 +365,8 @@
return new MeshTopologySimulator();
} else if (topoShape.matches("grid([,].*|$)")) {
return new GridTopologySimulator();
+ } else if (topoShape.matches("fattree([,].*|$)")) {
+ return new FatTreeTopologySimulator();
} else if (topoShape.matches("custom([,].*|$)")) {
return new CustomTopologySimulator();
} else {
diff --git a/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullControlCommand.java b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullControlCommand.java
index 74fbbb1..6edf6e5 100644
--- a/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullControlCommand.java
+++ b/providers/null/src/main/java/org/onosproject/provider/nil/cli/NullControlCommand.java
@@ -35,7 +35,8 @@
String cmd = null;
@Argument(index = 1, name = "topoShape",
- description = "Topology shape: e.g. configured, linear, reroute, centipede, tree, spineleaf, mesh",
+ description = "Topology shape: e.g. configured, linear, reroute, centipede, tree, spineleaf, " +
+ ", mesh, fattree",
required = false, multiValued = false)
String topoShape = null;