blob: 9a97c622259fee6f45a068197ec2c1cb825da156 [file] [log] [blame]
Andreas Pantelopoulos620d3d72016-11-08 22:18:59 +01001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.provider.nil;
17import java.util.Arrays;
18import static com.google.common.base.Preconditions.checkArgument;
19
20/**
21 * Fat-tree topology simulator.
22 */
23public class FatTreeTopologySimulator extends TopologySimulator {
24
25 private static final int DEFAULT_NUMBER_OF_PORTS_PER_SWITCH = 4;
26 protected int kPorts;
27 protected int numberOfPods;
28 protected int numberOfAggLayerSwitches;
29 protected int numberOfCoreLayerSwitches;
30 protected int numberOfEdgeLayerSwitches;
31
32 @Override
33 protected void processTopoShape(String shape) {
34 super.processTopoShape(shape);
35
36 // If switch ports are not provided use a default value
37 int k = (topoShape.length == 1) ?
38 DEFAULT_NUMBER_OF_PORTS_PER_SWITCH :
39 Integer.parseInt(topoShape[1]);
40
41 // A fat-tree is parametrized by the total number of ports per switch.
42 // check top of page 4 of http://web.eecs.umich.edu/~mosharaf/Readings/Fat-Tree.pdf
43 kPorts = k;
44 numberOfPods = k;
45 numberOfCoreLayerSwitches = (k / 2) * (k / 2);
46 numberOfAggLayerSwitches = k * k / 2;
47 numberOfEdgeLayerSwitches = k * k / 2;
48
49 // need to also change hostCount variable of TopologySimulator
50 hostCount = kPorts / 2;
51 }
52
53
54 @Override
55 public void setUpTopology() {
56
57 checkArgument(kPorts > 1, "Fat Tree switches must " +
58 "have at **least** 2 ports each!");
59
60 // this is the total number of **Switches**
61 // in a fat-tree topology
62 deviceCount = numberOfAggLayerSwitches +
63 numberOfCoreLayerSwitches +
64 numberOfEdgeLayerSwitches;
65
66 log.info("Booting a {} with {}-ports, {} switches in total {} pods",
67 topoShape[0], kPorts, deviceCount, numberOfPods);
68
69
70 prepareForDeviceEvents(deviceCount);
71 createDevices();
72 waitForDeviceEvents();
73
74 createLinks();
75 createHosts();
76 }
77
78 @Override
79 protected void createLinks() {
80
81 // For each switch keep a count of used ports
82 int[] portList = new int[deviceCount];
83 Arrays.fill(portList, 0);
84
85 // we assume that deviceIds stores all the fat tree switches in a flat list
86 int end = numberOfPods / 2;
87 // from [ 0, (k/2)^2 - 1] we store (k/2)^2 core switces
88 int startOfCore = 0;
89 // from [ (k/2)^2, (k/2)^2 + (k^2)/2 - 1] we store (k^2)/2 aggregation switches
90 int startOfAgg = (numberOfPods / 2) * (numberOfPods / 2);
91 // from [ (k/2)^2 + (k^2)/2, (k/2)^2 + (k^2)/2 + (k^2)/2 -1] we store (k^2)/2 edge switches
92 int startOfEdge = startOfAgg + (numberOfPods * numberOfPods) / 2;
93
94 log.debug("startOfCore = {}, startOfAgg = {}, startOfEdge = {}",
95 startOfCore, startOfAgg, startOfEdge);
96
97 // Create links between core and aggregation switches
98 for (int x = 0; x < numberOfAggLayerSwitches; x += end) {
99
100 // each agg.switch will handle a group of k/2 core consecutive switches
101 for (int i = 0; i < end; i += 1) {
102 for (int j = 0; j < end; j += 1) {
103 int coreSwitch = i * end + j;
104 int aggSwitch = startOfAgg + x + i;
105
106 createLink(coreSwitch,
107 aggSwitch,
108 portList[coreSwitch]++,
109 portList[aggSwitch]++);
110 }
111 }
112 }
113
114 // Create links between aggregation and edge switches
115 for (int x = 0; x < numberOfAggLayerSwitches; x += end) {
116 for (int i = 0; i < end; i += 1) {
117 for (int j = 0; j < end; j += 1) {
118 int aggSwitch = startOfAgg + x + i;
119 int edgeSwitch = startOfEdge + x + j;
120
121 createLink(aggSwitch,
122 edgeSwitch,
123 portList[aggSwitch]++,
124 portList[edgeSwitch]++);
125 }
126 }
127 }
128 }
129
130 @Override
131 protected void createHosts() {
132
133 int firstEdgeSwitch = (numberOfPods / 2) * (numberOfPods / 2) +
134 (numberOfPods * numberOfPods) / 2;
135
136 // hosts connect **only** to edge switches, each edge switch has k/2 ports free for hosts
137 for (int edgeSwitch = firstEdgeSwitch; edgeSwitch < deviceCount; edgeSwitch++) {
138
139 createHosts(deviceIds.get(edgeSwitch), kPorts / 2);
140 }
141 }
142}