Nikhil Cheerla
Committed by Gerrit Code Review

OECF removed working

Change-Id: I178a227fedacb4efc8669c839042d952f4efd670
1 -<?xml version="1.0" encoding="UTF-8"?>
2 -<!--
3 - ~ Copyright 2014 Open Networking Laboratory
4 - ~
5 - ~ Licensed under the Apache License, Version 2.0 (the "License");
6 - ~ you may not use this file except in compliance with the License.
7 - ~ You may obtain a copy of the License at
8 - ~
9 - ~ http://www.apache.org/licenses/LICENSE-2.0
10 - ~
11 - ~ Unless required by applicable law or agreed to in writing, software
12 - ~ distributed under the License is distributed on an "AS IS" BASIS,
13 - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 - ~ See the License for the specific language governing permissions and
15 - ~ limitations under the License.
16 - -->
17 -<project xmlns="http://maven.apache.org/POM/4.0.0"
18 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20 - <modelVersion>4.0.0</modelVersion>
21 -
22 - <parent>
23 - <groupId>org.onosproject</groupId>
24 - <artifactId>onos-apps</artifactId>
25 - <version>1.3.0-SNAPSHOT</version>
26 - <relativePath>../pom.xml</relativePath>
27 - </parent>
28 -
29 - <artifactId>onos-app-oecfg</artifactId>
30 - <packaging>jar</packaging>
31 -
32 - <description>Standalone utility for converting ONOS JSON config to OE-Linc JSON config</description>
33 -
34 - <dependencies>
35 - <dependency>
36 - <groupId>com.fasterxml.jackson.core</groupId>
37 - <artifactId>jackson-databind</artifactId>
38 - <scope>compile</scope>
39 - </dependency>
40 - <dependency>
41 - <groupId>com.fasterxml.jackson.core</groupId>
42 - <artifactId>jackson-annotations</artifactId>
43 - <scope>compile</scope>
44 - </dependency>
45 - </dependencies>
46 -
47 - <build>
48 - <plugins>
49 - <plugin>
50 - <groupId>org.apache.maven.plugins</groupId>
51 - <artifactId>maven-shade-plugin</artifactId>
52 - <executions>
53 - <execution>
54 - <phase>package</phase>
55 - <goals>
56 - <goal>shade</goal>
57 - </goals>
58 - <configuration>
59 - <transformers>
60 - <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
61 - <manifestEntries>
62 - <Main-Class>org.onosproject.oecfg.OELinkConfig</Main-Class>
63 - </manifestEntries>
64 - </transformer>
65 - </transformers>
66 - </configuration>
67 - </execution>
68 - </executions>
69 - </plugin>
70 - </plugins>
71 - </build>
72 -
73 -</project>
1 -/*
2 - * Copyright 2014 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 - */
16 -package org.onosproject.oecfg;
17 -
18 -import com.fasterxml.jackson.databind.JsonNode;
19 -import com.fasterxml.jackson.databind.ObjectMapper;
20 -import com.fasterxml.jackson.databind.node.ArrayNode;
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 -
23 -import java.io.IOException;
24 -import java.io.InputStream;
25 -import java.util.HashMap;
26 -import java.util.Map;
27 -
28 -/**
29 - * Utility program to convert standard ONOS config JSON to format expected
30 - * by the OE Link switch.
31 - */
32 -public final class OELinkConfig {
33 -
34 - private ObjectMapper mapper = new ObjectMapper();
35 - private Map<String, String> dpidToName = new HashMap<>();
36 -
37 - public static void main(String[] args) {
38 - try {
39 - OELinkConfig config = new OELinkConfig();
40 - JsonNode json = config.convert(System.in);
41 - System.out.println(json.toString());
42 - } catch (IOException e) {
43 - System.err.println("Unable to convert JSON due to: " + e.getMessage());
44 - e.printStackTrace();
45 - }
46 - }
47 -
48 - private OELinkConfig() {
49 - }
50 -
51 - private JsonNode convert(InputStream input) throws IOException {
52 - JsonNode json = mapper.readTree(input);
53 - ObjectNode result = mapper.createObjectNode();
54 - result.set("switchConfig", opticalSwitches(json));
55 - result.set("linkConfig", opticalLinks(json));
56 - return result;
57 - }
58 -
59 - private JsonNode opticalSwitches(JsonNode json) {
60 - ArrayNode result = mapper.createArrayNode();
61 - for (JsonNode node : json.get("devices")) {
62 - String dpid = dpid(node.path("uri"));
63 - String name = node.path("name").asText("none");
64 - dpidToName.put(dpid, name);
65 - if (node.path("type").asText("none").equals("ROADM")) {
66 - result.add(opticalSwitch(dpid, name, (ObjectNode) node));
67 - }
68 - }
69 - return result;
70 - }
71 -
72 - private ObjectNode opticalSwitch(String dpid, String name, ObjectNode node) {
73 - ObjectNode result = mapper.createObjectNode();
74 - ObjectNode annot = (ObjectNode) node.path("annotations");
75 - result.put("allowed", true).put("type", "Roadm")
76 - .put("name", name).put("nodeDpid", dpid)
77 - .put("latitude", annot.path("latitude").asDouble(0.0))
78 - .put("longitude", annot.path("longitude").asDouble(0.0))
79 - .set("params", switchParams(annot));
80 - return result;
81 - }
82 -
83 - private ObjectNode switchParams(ObjectNode annot) {
84 - return mapper.createObjectNode()
85 - .put("numRegen", annot.path("optical.regens").asInt(0));
86 - }
87 -
88 - private JsonNode opticalLinks(JsonNode json) {
89 - ArrayNode result = mapper.createArrayNode();
90 - for (JsonNode node : json.get("links")) {
91 - if (node.path("type").asText("none").equals("OPTICAL")) {
92 - result.add(opticalLink((ObjectNode) node));
93 - }
94 - }
95 - return result;
96 - }
97 -
98 - private ObjectNode opticalLink(ObjectNode node) {
99 - ObjectNode result = mapper.createObjectNode();
100 - ObjectNode annot = (ObjectNode) node.path("annotations");
101 - String src = dpid(node.path("src"));
102 - String dst = dpid(node.path("dst"));
103 - result.put("allowed", true).put("type", linkType(annot))
104 - .put("nodeDpid1", src).put("nodeDpid2", dst)
105 - .set("params", linkParams(src, dst, node, annot));
106 - return result;
107 - }
108 -
109 - private String linkType(ObjectNode annot) {
110 - return annot.path("optical.type").asText("cross-connect").equals("WDM") ?
111 - "wdmLink" : "pktOptLink";
112 - }
113 -
114 - private ObjectNode linkParams(String src, String dst,
115 - ObjectNode node, ObjectNode annot) {
116 - ObjectNode result = mapper.createObjectNode()
117 - .put("nodeName1", dpidToName.get(src))
118 - .put("nodeName2", dpidToName.get(dst))
119 - .put("port1", port(node.path("src")))
120 - .put("port2", port(node.path("dst")));
121 - if (annot.has("bandwidth")) {
122 - result.put("bandwidth", annot.path("bandwidth").asInt());
123 - }
124 - if (annot.has("optical.waves")) {
125 - result.put("numWaves", annot.path("optical.waves").asInt());
126 - }
127 - return result;
128 - }
129 -
130 - private String dpid(JsonNode node) {
131 - String s = node.asText("of:0000000000000000").substring(3);
132 - return s.substring(0, 2) + ":" + s.substring(2, 4) + ":" +
133 - s.substring(4, 6) + ":" + s.substring(6, 8) + ":" +
134 - s.substring(8, 10) + ":" + s.substring(10, 12) + ":" +
135 - s.substring(12, 14) + ":" + s.substring(14, 16);
136 - }
137 -
138 - private int port(JsonNode node) {
139 - return Integer.parseInt(node.asText("of:0000000000000000/0").substring(20));
140 - }
141 -
142 -}
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
40 <module>sdnip</module> 40 <module>sdnip</module>
41 <module>optical</module> 41 <module>optical</module>
42 <module>metrics</module> 42 <module>metrics</module>
43 - <module>oecfg</module>
44 <module>routing</module> 43 <module>routing</module>
45 <module>routing-api</module> 44 <module>routing-api</module>
46 <module>reactive-routing</module> 45 <module>reactive-routing</module>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 Notes: 4 Notes:
5 5
6 This file contains classes and methods useful for integrating LincOE with Mininet, 6 This file contains classes and methods useful for integrating LincOE with Mininet,
7 -such as startOE, stopOE, LINCLink, and OpticalSwitch 7 +such as startOE, stopOE, OpticalLink, and OpticalSwitch
8 8
9 - $ONOS_ROOT ust be set 9 - $ONOS_ROOT ust be set
10 - Need to run with sudo -E to preserve ONOS_ROOT env var 10 - Need to run with sudo -E to preserve ONOS_ROOT env var
...@@ -22,10 +22,10 @@ such as startOE, stopOE, LINCLink, and OpticalSwitch ...@@ -22,10 +22,10 @@ such as startOE, stopOE, LINCLink, and OpticalSwitch
22 22
23 Usage: 23 Usage:
24 ------------ 24 ------------
25 - - import LINCLink and OpticalSwitch from this module 25 + - import OpticalLink and OpticalSwitch from this module
26 - import startOE and stopOE from this module 26 - import startOE and stopOE from this module
27 - create topology as you would a normal topology. when 27 - create topology as you would a normal topology. when
28 - to an optical switch with topo.addLink, always specify cls=LINCLink 28 + to an optical switch with topo.addLink, always specify cls=OpticalLink
29 - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch 29 - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch
30 - for annotations on links and switches, a dictionary must be passed in as 30 - for annotations on links and switches, a dictionary must be passed in as
31 the annotations argument 31 the annotations argument
...@@ -51,12 +51,11 @@ switches have been started, the new Mininet start() method should also push the ...@@ -51,12 +51,11 @@ switches have been started, the new Mininet start() method should also push the
51 Topology configuration file to ONOS. 51 Topology configuration file to ONOS.
52 52
53 ''' 53 '''
54 -import sys 54 +
55 import re 55 import re
56 import json 56 import json
57 import os 57 import os
58 from time import sleep 58 from time import sleep
59 -import urllib2
60 59
61 from mininet.node import Switch, RemoteController 60 from mininet.node import Switch, RemoteController
62 from mininet.topo import Topo 61 from mininet.topo import Topo
...@@ -66,127 +65,25 @@ from mininet.log import setLogLevel, info, error, warn ...@@ -66,127 +65,25 @@ from mininet.log import setLogLevel, info, error, warn
66 from mininet.link import Link, Intf 65 from mininet.link import Link, Intf
67 from mininet.cli import CLI 66 from mininet.cli import CLI
68 67
69 -# Sleep time and timeout values in seconds 68 +class OpticalSwitch( Switch ):
70 -SLEEP_TIME = 2
71 -TIMEOUT = 60
72 -
73 -class OpticalSwitch(Switch):
74 - """
75 - For now, same as Switch class.
76 - """
77 - pass
78 -
79 -class OpticalIntf(Intf):
80 - """
81 - For now,same as Intf class.
82 - """
83 - pass
84 -
85 -class OpticalLink(Link):
86 - """
87 - For now, same as Link.
88 - """
89 - pass
90 69
91 -class LINCSwitch(OpticalSwitch): 70 + def __init__( self, name, dpid=None, allowed=True,
92 - """ 71 + switchType='ROADM', annotations={}, **params ):
93 - LINCSwitch class
94 - """
95 - # FIXME:Sometimes LINC doesn't remove pipes and on restart increase the pipe
96 - # number from erlang.pipe.1.* to erlang.pipe.2.*, so should read and write
97 - # from latest pipe files. For now we are removing all the pipes before
98 - # starting LINC.
99 - ### User Name ###
100 - user = os.getlogin()
101 - ### pipes ###
102 - readPipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.r".format(user)
103 - writePipe = "/tmp/home/{}/linc-oe/rel/linc/erlang.pipe.1.w".format(user)
104 - ### sys.config path ###
105 - sysConfig = "/home/{}/linc-oe/rel/linc/releases/1.0/sys.config".format(user)
106 - ### method, mapping dpid to LINC switchId ###
107 - @staticmethod
108 - def dpids_to_ids(sysConfig):
109 - '''
110 - return the dict containing switch dpids as key and LINC switch id as values
111 - '''
112 - dpids_to_ids = {}
113 - fd = None
114 - try:
115 - with open(sysConfig, 'r', 0) as fd:
116 - switch_id = 1
117 - for line in fd:
118 - dpid = re.search(r'([0-9A-Fa-f]{2}[:-]){7}([0-9A-Fa-f]{2})+', line, re.I)
119 - if dpid:
120 - dpids_to_ids[dpid.group().replace(':', '')] = switch_id
121 - switch_id += 1
122 - return dpids_to_ids
123 - except:
124 - print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info())
125 - fd.close()
126 - return None
127 - ### dict of containing dpids as key and corresponding LINC switchId as values ###
128 - dpidsToLINCSwitchId = dpids_to_ids.__func__(sysConfig)
129 - @staticmethod
130 - def findDir(directory, userName):
131 - "finds and returns the path of any directory in the user's home directory"
132 - homeDir = '/home/' + userName
133 - Dir = quietRun('find %s -maxdepth 1 -name %s -type d' % (homeDir, directory)).strip('\n')
134 - DirList = Dir.split('\n')
135 - if not Dir:
136 - return None
137 - elif len(DirList) > 1 :
138 - warn('***WARNING: Found multiple instances of %s; using %s\n'
139 - % (directory, DirList[ 0 ]))
140 - return DirList[ 0 ]
141 - else:
142 - return Dir
143 - ### ONOS Directory ###
144 - try:
145 - onosDir = os.environ[ 'ONOS_ROOT' ]
146 - except:
147 - onosDir = findDir('onos', user)
148 - if not onosDir:
149 - error('Please set ONOS_ROOT environment variable!\n')
150 - else:
151 - os.environ[ 'ONOS_ROOT' ] = onosDir
152 - ### LINC-directory
153 - lincDir = findDir.__func__('linc-oe', user)
154 - if not lincDir:
155 - error("***ERROR: Could not find linc-oe in user's home directory\n")
156 - ### LINC config generator directory###
157 - configGen = findDir.__func__('LINC-config-generator', user)
158 - if not configGen:
159 - error("***ERROR: Could not find LINC-config-generator in user's home directory\n")
160 - # list of all the controllers
161 - controllers = None
162 - def __init__(self, name, dpid=None, allowed=True,
163 - switchType='ROADM', topo=None, annotations={}, controller=None, **params):
164 params[ 'inNamespace' ] = False 72 params[ 'inNamespace' ] = False
165 - Switch.__init__(self, name, dpid=dpid, **params) 73 + Switch.__init__( self, name, dpid=dpid, **params )
166 self.name = name 74 self.name = name
167 self.annotations = annotations 75 self.annotations = annotations
168 self.allowed = allowed 76 self.allowed = allowed
169 self.switchType = switchType 77 self.switchType = switchType
170 self.configDict = {} # dictionary that holds all of the JSON configuration data 78 self.configDict = {} # dictionary that holds all of the JSON configuration data
171 - self.crossConnects = []
172 - self.deletedCrossConnects = []
173 - self.controller = controller
174 - self.lincId = self._get_linc_id() # use to communicate with LINC
175 - self.lincStarted = False
176 79
177 - def start(self, *opts, **params): 80 + def start( self, *opts, **params ):
178 '''Instead of starting a virtual switch, we build the JSON 81 '''Instead of starting a virtual switch, we build the JSON
179 dictionary for the emulated optical switch''' 82 dictionary for the emulated optical switch'''
180 - # TODO:Once LINC has the ability to spawn network element dynamically
181 - # we need to use this method to spawn new logical LINC switch rather then
182 - # bulding JSON.
183 - # if LINC is started then we can start and stop logical switches else create JSON
184 - if self.lincStarted:
185 - return self.start_oe()
186 self.configDict[ 'uri' ] = 'of:' + self.dpid 83 self.configDict[ 'uri' ] = 'of:' + self.dpid
187 self.configDict[ 'annotations' ] = self.annotations 84 self.configDict[ 'annotations' ] = self.annotations
188 - self.configDict[ 'annotations' ].setdefault('name', self.name) 85 + self.configDict[ 'annotations' ].setdefault( 'name', self.name )
189 - self.configDict[ 'hw' ] = 'LINC-OE' 86 + self.configDict[ 'hw' ] = 'OE'
190 self.configDict[ 'mfr' ] = 'Linc' 87 self.configDict[ 'mfr' ] = 'Linc'
191 self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1] 88 self.configDict[ 'mac' ] = 'ffffffffffff' + self.dpid[-2] + self.dpid[-1]
192 self.configDict[ 'type' ] = self.switchType 89 self.configDict[ 'type' ] = self.switchType
...@@ -195,137 +92,95 @@ class LINCSwitch(OpticalSwitch): ...@@ -195,137 +92,95 @@ class LINCSwitch(OpticalSwitch):
195 if intf.name == 'lo': 92 if intf.name == 'lo':
196 continue 93 continue
197 else: 94 else:
198 - self.configDict[ 'ports' ].append(intf.json()) 95 + self.configDict[ 'ports' ].append( intf.json() )
199 - self.lincStarted = True 96 +
200 - 97 +
201 - def stop(self, deleteIntfs=False): 98 + def json( self ):
202 - ''' 99 + "return json configuration dictionary for switch"
203 - stop the existing switch 100 + return self.configDict
204 - ''' 101 +
205 - # TODO:Add support for deleteIntf 102 + def terminate( self ):
206 - self.stop_oe()
207 -
208 - def dpctl( self, *args ):
209 - "Run dpctl command: ignore for now"
210 pass 103 pass
211 104
212 - def write_to_cli(self, command): 105 +class OpticalLink( Link ):
213 - ''' 106 +
214 - send command to LINC 107 + def __init__( self, node1, node2, port1=None, port2=None, allowed=True,
215 - ''' 108 + intfName1=None, intfName2=None, linkType='OPTICAL',
216 - fd = None 109 + annotations={}, speed1=0, speed2=0, **params ):
217 - try: 110 + "Creates a dummy link without a virtual ethernet pair."
218 - fd = open(self.writePipe, 'w', 0) 111 + self.allowed = allowed
219 - fd.write(command) 112 + self.annotations = annotations
220 - fd.close() 113 + self.linkType = linkType
221 - except: 114 + params1 = { 'speed': speed1 }
222 - print "Error working with {}\nError: {}\n".format(self.writePipe, sys.exc_info()) 115 + params2 = { 'speed': speed2 }
223 - if fd: 116 +
224 - fd.close() 117 + if isinstance( node1, OpticalSwitch ):
225 - 118 + cls1 = OpticalIntf
226 - def read_from_cli(self):
227 - '''
228 - read the output from the LINC CLI
229 - '''
230 - response = None
231 - fd = None
232 - try:
233 - fd = open(self.readPipe, 'r', 0)
234 - fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) # for non-blocking read
235 - # FIXME:Due to non-blocking read most for the time we read nothing
236 - response = fd.read()
237 - fd.close()
238 - except :
239 - # print "Error working with {}\nError: {}\n".format(self.readPipe, sys.exc_info())
240 - if fd:
241 - fd.close()
242 - return response
243 -
244 - def _get_linc_id(self):
245 - '''
246 - return the corresponding LINC switchId.
247 - '''
248 - return LINCSwitch.dpidsToLINCSwitchId.get(self.dpid)
249 - #--------------------------------------------------------------------------
250 - # LINC CLI commands
251 - #--------------------------------------------------------------------------
252 - def start_oe(self):
253 - '''
254 - start the existing LINC switch
255 - '''
256 - #starting Switch
257 - cmd = "linc:start_switch({}).\r\n".format(self.lincId)
258 - self.write_to_cli(cmd)
259 - #hanlding taps interfaces related to the switch
260 - crossConnectJSON = {}
261 - linkConfig = []
262 - for i in range(0,len(self.deletedCrossConnects)):
263 - crossConnect = self.deletedCrossConnects.pop()
264 - tap = None
265 - if isinstance(crossConnect.intf1.node, LINCSwitch):
266 - intf = crossConnect.intf2
267 - tapPort = crossConnect.intf1.port
268 else: 119 else:
269 - intf = crossConnect.intf1 120 + cls1 = Intf
270 - tapPort = crossConnect.intf2.port 121 + # bad hack to stop error message from appearing when we try to set up intf in a packet switch,
271 - tap = LINCSwitch.findTap(self, tapPort) 122 + # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up
272 - if tap: 123 + intfName1 = 'lo'
273 - LINCSwitch.setupInts([tap]) 124 + if isinstance( node2, OpticalSwitch ):
274 - intf.node.attach(tap) 125 + cls2 = OpticalIntf
275 - self.crossConnects.append(crossConnect)
276 - linkConfig.append(crossConnect.json())
277 - #Sending crossConnect info to the ONOS.
278 - crossConnectJSON['links'] = linkConfig
279 - with open("crossConnect.json", 'w') as fd:
280 - json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': '))
281 - info('*** Pushing crossConnect.json to ONOS\n')
282 - output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\
283 - Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
284 -
285 - def stop_oe(self):
286 - '''
287 - stop the existing LINC switch
288 - '''
289 - cmd = "linc:stop_switch({}).\r\n".format(self.lincId)
290 - self.write_to_cli(cmd)
291 - #handling taps if any
292 - for i in range(0, len(self.crossConnects)):
293 - crossConnect = self.crossConnects.pop()
294 - if isinstance(crossConnect.intf1.node, LINCSwitch):
295 - intf = crossConnect.intf2
296 - tapPort = crossConnect.intf1.port
297 else: 126 else:
298 - intf = crossConnect.intf1 127 + cls2 = Intf
299 - tapPort = crossConnect.intf2.port 128 + intfName2 = 'lo'
300 - intf.node.detach(LINCSwitch.findTap(self, tapPort)) 129 + Link.__init__( self, node1, node2, port1=port1, port2=port2,
301 - self.deletedCrossConnects.append(crossConnect) 130 + intfName1=intfName1, intfName2=intfName2, cls1=cls1,
302 - 131 + cls2=cls2, params1=params1, params2=params2 )
303 - def w_port_up(self, port): 132 +
304 - ''' 133 +
305 - port_up 134 + @classmethod
306 - ''' 135 + def makeIntfPair( _cls, intfName1, intfName2, *args, **kwargs ):
307 - cmd = "linc:port_up({},{}).\r\n".format(self.lincId, port) 136 + pass
308 - self.write_to_cli(cmd) 137 +
309 - 138 + def json( self ):
310 - def w_port_down(self, port): 139 + "build and return the json configuration dictionary for this link"
311 - ''' 140 + configData = {}
312 - port_down 141 + configData[ 'src' ] = ( 'of:' + self.intf1.node.dpid +
313 - ''' 142 + '/%s' % self.intf1.node.ports[ self.intf1 ] )
314 - cmd = "linc:port_down({},{}).\r\n".format(self.lincId, port) 143 + configData[ 'dst' ] = ( 'of:' + self.intf2.node.dpid +
315 - self.write_to_cli(cmd) 144 + '/%s' % self.intf2.node.ports[ self.intf2 ] )
316 - 145 + configData[ 'type' ] = self.linkType
317 - # helper functions 146 + configData[ 'annotations' ] = self.annotations
318 - @staticmethod 147 + return configData
319 - def switchJSON(switch): 148 +
149 +class OpticalIntf( Intf ):
150 +
151 + def __init__( self, name=None, node=None, speed=0,
152 + port=None, link=None, **params ):
153 + self.node = node
154 + self.speed = speed
155 + self.port = port
156 + self.link = link
157 + self.name = name
158 + node.addIntf( self, port=port )
159 + self.params = params
160 + self.ip = None
161 +
162 + def json( self ):
163 + "build and return the JSON information for this interface( not used right now )"
164 + configDict = {}
165 + configDict[ 'port' ] = self.port
166 + configDict[ 'speed' ] = self.speed
167 + configDict[ 'type' ] = 'FIBER'
168 + return configDict
169 +
170 + def config( self, *args, **kwargs ):
171 + "dont configure a dummy interface"
172 + pass
173 +
174 +def switchJSON( switch ):
320 "Returns the json configuration for a packet switch" 175 "Returns the json configuration for a packet switch"
321 configDict = {} 176 configDict = {}
322 configDict[ 'uri' ] = 'of:' + switch.dpid 177 configDict[ 'uri' ] = 'of:' + switch.dpid
323 - configDict[ 'mac' ] = quietRun('cat /sys/class/net/%s/address' % switch.name).strip('\n').translate(None, ':') 178 + configDict[ 'mac' ] = quietRun( 'cat /sys/class/net/%s/address' % switch.name ).strip( '\n' ).translate( None, ':' )
324 configDict[ 'hw' ] = 'PK' # FIXME what about OVS? 179 configDict[ 'hw' ] = 'PK' # FIXME what about OVS?
325 configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS? 180 configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS?
326 configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS? 181 configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS?
327 - annotations = switch.params.get('annotations', {}) 182 + annotations = switch.params.get( 'annotations', {} )
328 - annotations.setdefault('name', switch.name) 183 + annotations.setdefault( 'name', switch.name )
329 configDict[ 'annotations' ] = annotations 184 configDict[ 'annotations' ] = annotations
330 ports = [] 185 ports = []
331 for port, intf in switch.intfs.items(): 186 for port, intf in switch.intfs.items():
...@@ -333,176 +188,234 @@ class LINCSwitch(OpticalSwitch): ...@@ -333,176 +188,234 @@ class LINCSwitch(OpticalSwitch):
333 continue 188 continue
334 portDict = {} 189 portDict = {}
335 portDict[ 'port' ] = port 190 portDict[ 'port' ] = port
336 - portDict[ 'type' ] = 'FIBER' if isinstance(intf.link, LINCLink) else 'COPPER' 191 + portDict[ 'type' ] = 'FIBER' if isinstance( intf.link, OpticalLink ) else 'COPPER'
337 intfList = [ intf.link.intf1, intf.link.intf2 ] 192 intfList = [ intf.link.intf1, intf.link.intf2 ]
338 - intfList.remove(intf) 193 + intfList.remove( intf )
339 - portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0 194 + portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance( intf.link, OpticalLink ) else 0
340 - ports.append(portDict) 195 + ports.append( portDict )
341 configDict[ 'ports' ] = ports 196 configDict[ 'ports' ] = ports
342 return configDict 197 return configDict
343 198
344 - @staticmethod 199 +
345 - def bootOE(net): 200 +def startOE( net ):
346 "Start the LINC optical emulator within a mininet instance" 201 "Start the LINC optical emulator within a mininet instance"
347 opticalJSON = {} 202 opticalJSON = {}
348 linkConfig = [] 203 linkConfig = []
349 devices = [] 204 devices = []
350 - #setting up the controllers for LINCSwitch class
351 - LINCSwitch.controllers = net.controllers
352 205
353 for switch in net.switches: 206 for switch in net.switches:
354 - if isinstance(switch, OpticalSwitch): 207 + if isinstance( switch, OpticalSwitch ):
355 - devices.append(switch.json()) 208 + devices.append( switch.json() )
356 else: 209 else:
357 - devices.append(LINCSwitch.switchJSON(switch)) 210 + devices.append( switchJSON( switch ) )
358 opticalJSON[ 'devices' ] = devices 211 opticalJSON[ 'devices' ] = devices
359 212
360 for link in net.links: 213 for link in net.links:
361 - if isinstance(link, LINCLink) : 214 + if isinstance( link, OpticalLink ) :
362 - linkConfig.append(link.json()) 215 + linkConfig.append( link.json() )
363 - opticalJSON[ 'links' ] = linkConfig
364 216
365 - info('*** Writing Topology.json file\n') 217 + opticalJSON[ 'links' ] = linkConfig
366 - with open('Topology.json', 'w') as outfile:
367 - json.dump(opticalJSON, outfile, indent=4, separators=(',', ': '))
368 218
369 - info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file\n') 219 + try:
370 - output = quietRun('%s/tools/test/bin/onos-oecfg ./Topology.json > TopoConfig.json' % LINCSwitch.onosDir, shell=True) 220 + onosDir = os.environ[ 'ONOS_ROOT' ]
371 - if output: 221 + except:
372 - error('***ERROR: Error creating topology file: %s ' % output + '\n') 222 + onosDir = findDir( 'onos' )
223 + if not onosDir:
224 + error( 'Please set ONOS_ROOT environment variable!\n' )
373 return False 225 return False
226 + else:
227 + os.environ[ 'ONOS_ROOT' ] = onosDir
228 +
229 + info( '*** Writing Topology.json file\n' )
230 + with open( 'Topology.json', 'w' ) as outfile:
231 + json.dump( opticalJSON, outfile, indent=4, separators=(',', ': ') )
232 +
233 + info( '*** Converting Topology.json to linc-oe format (TopoConfig.json) file (not using oecfg) \n' )
234 +
235 + topoConfigJson = {};
236 + newLinkConfig = [];
237 + switchConfig = [];
238 + dpIdToName = {};
239 +
240 + #Iterate through all switches and convert the ROADM switches to linc-oe format
241 + for switch in opticalJSON["devices"]:
242 + if switch["type"] == "ROADM":
243 + builtSwitch = {}
244 +
245 + #set basic switch params based on annotations
246 + builtSwitch["allowed"] = True;
247 + builtSwitch["latitude"] = switch["annotations"]["latitude"];
248 + builtSwitch["longitude"] = switch["annotations"]["longitude"];
249 +
250 + nodeId = switch["uri"]
251 +
252 + #convert the nodeId to linc-oe format
253 + nodeDpid = dpId(nodeId);
254 +
255 + if "name" in switch:
256 + builtSwitch["name"] = switch["name"]
257 + else:
258 + builtSwitch["name"] = "none"
259 +
260 + #keep track of the name corresponding to each switch dpid
261 + dpIdToName[nodeDpid] = builtSwitch["name"];
262 +
263 + builtSwitch["nodeDpid"] = nodeDpid
264 +
265 + #set switch params and type
266 + builtSwitch["params"] = {};
267 + builtSwitch["params"]["numregens"] = switch["annotations"]["optical.regens"];
268 + builtSwitch["type"] = "Roadm"
269 +
270 + #append to list of switches
271 + switchConfig.append(builtSwitch);
272 +
273 + topoConfigJson["switchConfig"] = switchConfig;
274 +
275 + #Iterate through all optical links and convert them to linc-oe format
276 + for link in opticalJSON["links"]:
277 + if link["type"] == "OPTICAL":
278 + builtLink = {}
279 +
280 + #set basic link params for src and dst
281 + builtLink["allowed"] = True;
282 + builtLink["nodeDpid1"] = dpId(link["src"])
283 + builtLink["nodeDpid2"] = dpId(link["dst"])
284 +
285 + #set more params such as name/bandwidth/port/waves if they exist
286 + params = {}
287 + params["nodeName1"] = dpIdToName.get(builtLink["nodeDpid1"], "none")
288 + params["nodeName2"] = dpIdToName.get(builtLink["nodeDpid2"], "none")
289 + if "bandwidth" in link["annotations"]:
290 + params["bandwidth"] = link["annotations"]["bandwidth"]
291 + params["port1"] = int(link["src"].split("/")[1])
292 + params["port2"] = int(link["dst"].split("/")[1])
293 +
294 + if "optical.waves" in link["annotations"]:
295 + params["numWaves"] = link["annotations"]["optical.waves"]
296 + builtLink["params"] = params
297 +
298 + #set type of link (WDM or pktOpt)
299 + if link["annotations"]["optical.type"] == "WDM":
300 + builtLink["type"] = "wdmLink"
301 + else:
302 + builtLink["type"] = "pktOptLink"
303 +
304 + newLinkConfig.append(builtLink);
374 305
375 - info('*** Creating sys.config...\n') 306 + topoConfigJson["linkConfig"] = newLinkConfig;
376 - output = quietRun('%s/config_generator TopoConfig.json %s/sys.config.template %s %s' 307 +
377 - % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[ 0 ].ip, LINCSwitch.controllers[ 0 ].port), shell=True) 308 + #Writing to TopoConfig.json
309 + with open( 'TopoConfig.json', 'w' ) as outfile:
310 + json.dump( topoConfigJson, outfile, indent=4, separators=(',', ': ') )
311 +
312 + info( '*** Creating sys.config...\n' )
313 + configGen = findDir( 'LINC-config-generator' )
314 + if not configGen:
315 + error( "***ERROR: Could not find LINC-config-generator in user's home directory\n" )
316 + return False
317 + output = quietRun( '%s/config_generator TopoConfig.json %s/sys.config.template %s %s'
318 + % ( configGen, configGen, net.controllers[ 0 ].ip, net.controllers[ 0 ].port ), shell=True )
378 if output: 319 if output:
379 - error('***ERROR: Error creating sys.config file: %s\n' % output) 320 + error( '***ERROR: Error creating sys.config file: %s\n' % output )
380 return False 321 return False
381 322
382 - info ('*** Setting multiple controllers in sys.config...\n') 323 + info ('*** Setting multiple controllers in sys.config...\n' )
383 - searchStr = '\[{"Switch.*$' 324 + searchStr = '{controllers,.*$'
384 ctrlStr = '' 325 ctrlStr = ''
385 - for index in range(len(LINCSwitch.controllers)): 326 + for index in range(len(net.controllers)):
386 ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port) 327 ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % (index, net.controllers[index].ip, net.controllers[index].port)
387 - replaceStr = '[%s]},' % ctrlStr[:-1] # Cut off last comma 328 + replaceStr = '{controllers,[%s]},' % ctrlStr[:-1] # Cut off last comma
388 sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr) 329 sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr)
389 - output = quietRun(sedCmd, shell=True) 330 + output = quietRun( sedCmd, shell=True )
390 -
391 - info('*** Copying sys.config to linc-oe directory: ', output + '\n')
392 - output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n')
393 - info(output + '\n')
394 -
395 - info('*** Adding taps and bringing them up...\n')
396 - LINCSwitch.setupInts(LINCSwitch.getTaps())
397 331
398 - info('*** removing pipes if any \n') 332 + info( '*** Copying sys.config to linc-oe directory: ', output + '\n' )
399 - quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True) 333 + lincDir = findDir( 'linc-oe' )
334 + if not lincDir:
335 + error( "***ERROR: Could not find linc-oe in user's home directory\n" )
336 + return False
337 + output = quietRun( 'cp -v sys.config %s/rel/linc/releases/1.0/' % lincDir, shell=True ).strip( '\n' )
338 + info( output + '\n' )
400 339
401 - info('*** Starting linc OE...\n') 340 + info( '*** Starting linc OE...\n' )
402 - output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True) 341 + output = quietRun( '%s/rel/linc/bin/linc start' % lincDir, shell=True )
403 if output: 342 if output:
404 - error('***ERROR: LINC-OE: %s' % output + '\n') 343 + error( '***ERROR: LINC-OE: %s' % output + '\n' )
405 - quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) 344 + quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )
406 return False 345 return False
407 346
408 - info('*** Waiting for linc-oe to start...\n') 347 + info( '*** Waiting for linc-oe to start...\n' )
409 - LINCSwitch.waitStarted(net) 348 + waitStarted( net )
410 349
411 - info('*** Adding cross-connect (tap) interfaces to packet switches...\n') 350 + info( '*** Adding cross-connect (tap) interfaces to packet switches...\n' )
412 for link in net.links: 351 for link in net.links:
413 - if isinstance(link, LINCLink): 352 + if isinstance( link, OpticalLink ):
414 if link.annotations[ 'optical.type' ] == 'cross-connect': 353 if link.annotations[ 'optical.type' ] == 'cross-connect':
415 for intf in [ link.intf1, link.intf2 ]: 354 for intf in [ link.intf1, link.intf2 ]:
416 - if not isinstance(intf, LINCIntf): 355 + if not isinstance( intf, OpticalIntf ):
417 intfList = [ intf.link.intf1, intf.link.intf2 ] 356 intfList = [ intf.link.intf1, intf.link.intf2 ]
418 - intfList.remove(intf) 357 + intfList.remove( intf )
419 intf2 = intfList[ 0 ] 358 intf2 = intfList[ 0 ]
420 - intf.node.attach(LINCSwitch.findTap(intf2.node, intf2.node.ports[ intf2 ])) 359 + intf.node.attach( findTap( intf2.node, intf2.node.ports[ intf2 ] ) )
421 -
422 - info('*** Waiting for all devices to be available in ONOS...\n')
423 - url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip
424 - time = 0
425 - while True:
426 - response = json.load(urllib2.urlopen(url))
427 - devs = response.get('devices')
428 360
429 - # Wait for all devices to be registered 361 + info( '*** Press ENTER to push Topology.json to onos...\n' )
430 - if (len(devices) != len(devs)): 362 + raw_input() # FIXME... we should eventually remove this
431 - continue 363 + info( '*** Pushing Topology.json to ONOS\n' )
432 - 364 + output = quietRun( '%s/tools/test/bin/onos-topo-cfg %s Topology.json' % ( onosDir, net.controllers[ 0 ].ip ), shell=True )
433 - # Wait for all devices to available
434 - available = True
435 - for d in devs:
436 - available &= d['available']
437 - if available:
438 - break
439 -
440 - if (time >= TIMEOUT):
441 - error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT)
442 - break
443 -
444 - time += SLEEP_TIME
445 - sleep(SLEEP_TIME)
446 -
447 - info('*** Pushing Topology.json to ONOS\n')
448 - for index in range(len(LINCSwitch.controllers)):
449 - output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json &' % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True)
450 # successful output contains the two characters '{}' 365 # successful output contains the two characters '{}'
451 # if there is more output than this, there is an issue 366 # if there is more output than this, there is an issue
452 - if output.strip('{}'): 367 + if output.strip( '{}' ):
453 - warn('***WARNING: Could not push topology file to ONOS: %s\n' % output) 368 + warn( '***WARNING: Could not push topology file to ONOS: %s' % output )
454 - 369 +
455 - @staticmethod 370 +#converts node ids to linc-oe format, with colons every two chars
456 - def waitStarted(net, timeout=TIMEOUT): 371 +def dpId(id):
372 + nodeDpid = ""
373 + id = id.split("/", 1)[0]
374 + for i in range(3, len(id) - 1, 2):
375 + nodeDpid += (id[i:(i + 2):]) + ":"
376 + return nodeDpid[0:(len(nodeDpid) - 1)];
377 +
378 +def waitStarted( net, timeout=None ):
457 "wait until all tap interfaces are available" 379 "wait until all tap interfaces are available"
458 tapCount = 0 380 tapCount = 0
459 time = 0 381 time = 0
460 for link in net.links: 382 for link in net.links:
461 - if isinstance(link, LINCLink): 383 + if isinstance( link, OpticalLink ):
462 if link.annotations[ 'optical.type' ] == 'cross-connect': 384 if link.annotations[ 'optical.type' ] == 'cross-connect':
463 tapCount += 1 385 tapCount += 1
464 386
465 while True: 387 while True:
466 - if str(tapCount) == quietRun('ip addr | grep tap | wc -l', shell=True).strip('\n'): 388 + if str( tapCount ) == quietRun( 'ip addr | grep tap | wc -l', shell=True ).strip( '\n' ):
467 return True 389 return True
468 if timeout: 390 if timeout:
469 - if time >= TIMEOUT: 391 + if time >= timeout:
470 - error('***ERROR: LINC OE did not start within %s seconds\n' % TIMEOUT) 392 + error( '***ERROR: Linc OE did not start within %s seconds' % timeout )
471 return False 393 return False
472 - time += SLEEP_TIME 394 + time += .5
473 - sleep(SLEEP_TIME) 395 + sleep( .5 )
474 396
475 - @staticmethod 397 +def stopOE():
476 - def shutdownOE():
477 "stop the optical emulator" 398 "stop the optical emulator"
478 - info('*** Stopping linc OE...\n') 399 + info( '*** Stopping linc OE...\n' )
479 - quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) 400 + lincDir = findDir( 'linc-oe' )
480 - 401 + quietRun( '%s/rel/linc/bin/linc stop' % lincDir, shell=True )
481 - @staticmethod 402 +
482 - def setupInts(intfs): 403 +def findDir( directory ):
483 - ''' 404 + "finds and returns the path of any directory in the user's home directory"
484 - add taps and bring them up. 405 + user = findUser()
485 - ''' 406 + homeDir = '/home/' + user
486 - for i in intfs: 407 + Dir = quietRun( 'find %s -maxdepth 1 -name %s -type d' % ( homeDir, directory ) ).strip( '\n' )
487 - quietRun('ip tuntap add dev %s mode tap' % i) 408 + DirList = Dir.split( '\n' )
488 - quietRun('ip link set dev %s up' % i) 409 + if not Dir:
489 - info('*** Intf %s set\n' % i) 410 + return None
490 - 411 + elif len( DirList ) > 1 :
491 - @staticmethod 412 + warn( '***WARNING: Found multiple instances of %s; using %s\n'
492 - def getTaps(path=None): 413 + % ( directory, DirList[ 0 ] ) )
493 - ''' 414 + return DirList[ 0 ]
494 - return list of all the tops in sys.config 415 + else:
495 - ''' 416 + return Dir
496 - if path is None: 417 +
497 - path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir 418 +def findUser():
498 - fd = open(path, 'r', 0)
499 - sys_data = fd.read()
500 - taps = re.findall('tap\d+', sys_data)
501 - fd.close()
502 - return taps
503 -
504 - @staticmethod
505 - def findUser():
506 "Try to return logged-in (usually non-root) user" 419 "Try to return logged-in (usually non-root) user"
507 try: 420 try:
508 # If we're running sudo 421 # If we're running sudo
...@@ -510,29 +423,32 @@ class LINCSwitch(OpticalSwitch): ...@@ -510,29 +423,32 @@ class LINCSwitch(OpticalSwitch):
510 except: 423 except:
511 try: 424 try:
512 # Logged-in user (if we have a tty) 425 # Logged-in user (if we have a tty)
513 - return quietRun('who am i').split()[ 0 ] 426 + return quietRun( 'who am i' ).split()[ 0 ]
514 except: 427 except:
515 # Give up and return effective user 428 # Give up and return effective user
516 - return quietRun('whoami') 429 + return quietRun( 'whoami' )
517 430
518 431
519 - @staticmethod 432 +def findTap( node, port, path=None ):
520 - def findTap(node, port, path=None):
521 '''utility function to parse through a sys.config 433 '''utility function to parse through a sys.config
522 file to find tap interfaces for a switch''' 434 file to find tap interfaces for a switch'''
523 - switch = False 435 + switch=False
524 portLine = '' 436 portLine = ''
525 intfLines = [] 437 intfLines = []
526 438
527 if path is None: 439 if path is None:
528 - path = '%s/rel/linc/releases/1.0/sys.config' % LINCSwitch.lincDir 440 + lincDir = findDir( 'linc-oe' )
441 + if not lincDir:
442 + error( '***ERROR: Could not find linc-oe in users home directory\n' )
443 + return None
444 + path = '%s/rel/linc/releases/1.0/sys.config' % lincDir
529 445
530 - with open(path) as f: 446 + with open( path ) as f:
531 for line in f: 447 for line in f:
532 if 'tap' in line: 448 if 'tap' in line:
533 - intfLines.append(line) 449 + intfLines.append( line )
534 - if node.dpid in line.translate(None, ':'): 450 + if node.dpid in line.translate( None, ':' ):
535 - switch = True 451 + switch=True
536 continue 452 continue
537 if switch: 453 if switch:
538 if 'switch' in line: 454 if 'switch' in line:
...@@ -542,129 +458,65 @@ class LINCSwitch(OpticalSwitch): ...@@ -542,129 +458,65 @@ class LINCSwitch(OpticalSwitch):
542 break 458 break
543 459
544 if portLine: 460 if portLine:
545 - m = re.search('port,\d+', portLine) 461 + m = re.search( 'port,\d+', portLine )
546 - port = m.group(0).split(',')[ 1 ] 462 + port = m.group( 0 ).split( ',' )[ 1 ]
547 else: 463 else:
548 - error('***ERROR: Could not find any ports in sys.config\n') 464 + error( '***ERROR: Could not find any ports in sys.config\n' )
549 return 465 return
550 466
551 for intfLine in intfLines: 467 for intfLine in intfLines:
552 if 'port,%s' % port in intfLine: 468 if 'port,%s' % port in intfLine:
553 - return re.findall('tap\d+', intfLine)[ 0 ] 469 + return re.findall( 'tap\d+', intfLine )[ 0 ]
554 -
555 - def json(self):
556 - "return json configuration dictionary for switch"
557 - return self.configDict
558 470
559 - def terminate(self):
560 - pass
561 471
562 -class LINCLink(Link): 472 +class MininetOE( Mininet ):
563 - """
564 - LINC link class
565 - """
566 - def __init__(self, node1, node2, port1=None, port2=None, allowed=True,
567 - intfName1=None, intfName2=None, linkType='OPTICAL',
568 - annotations={}, speed1=0, speed2=0, **params):
569 - "Creates a dummy link without a virtual ethernet pair."
570 - self.allowed = allowed
571 - self.annotations = annotations
572 - self.linkType = linkType
573 - self.port1 = port1
574 - self.port2 = port2
575 - params1 = { 'speed': speed1 }
576 - params2 = { 'speed': speed2 }
577 - # self.isCrossConnect = True if self.annotations.get('optical.type') == 'cross-connect' else False
578 - if isinstance(node1, LINCSwitch) and isinstance(node2, LINCSwitch):
579 - self.isCrossConnect = False
580 - else:
581 - self.isCrossConnect = True
582 - if isinstance(node1, LINCSwitch):
583 - cls1 = LINCIntf
584 - if self.isCrossConnect:
585 - node1.crossConnects.append(self)
586 - else:
587 - cls1 = Intf
588 - # bad hack to stop error message from appearing when we try to set up intf in a packet switch,
589 - # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up
590 - intfName1 = 'lo'
591 - if isinstance(node2, LINCSwitch):
592 - cls2 = LINCIntf
593 - if self.isCrossConnect:
594 - node2.crossConnects.append(self)
595 - else:
596 - cls2 = Intf
597 - intfName2 = 'lo'
598 - Link.__init__(self, node1, node2, port1=port1, port2=port2,
599 - intfName1=intfName1, intfName2=intfName2, cls1=cls1,
600 - cls2=cls2, params1=params1, params2=params2)
601 -
602 - @classmethod
603 - def makeIntfPair(_cls, intfName1, intfName2, *args, **kwargs):
604 - pass
605 -
606 - def json(self):
607 - "build and return the json configuration dictionary for this link"
608 - configData = {}
609 - configData[ 'src' ] = ('of:' + self.intf1.node.dpid +
610 - '/%s' % self.intf1.node.ports[ self.intf1 ])
611 - configData[ 'dst' ] = ('of:' + self.intf2.node.dpid +
612 - '/%s' % self.intf2.node.ports[ self.intf2 ])
613 - configData[ 'type' ] = self.linkType
614 - configData[ 'annotations' ] = self.annotations
615 - return configData
616 -
617 -class LINCIntf(OpticalIntf):
618 - """
619 - LINC interface class
620 - """
621 - def __init__(self, name=None, node=None, speed=0,
622 - port=None, link=None, **params):
623 - self.node = node
624 - self.speed = speed
625 - self.port = port
626 - self.link = link
627 - self.name = name
628 - node.addIntf(self, port=port)
629 - self.params = params
630 - self.ip = None
631 -
632 - def json(self):
633 - "build and return the JSON information for this interface( not used right now )"
634 - configDict = {}
635 - configDict[ 'port' ] = self.port
636 - configDict[ 'speed' ] = self.speed
637 - configDict[ 'type' ] = 'FIBER'
638 - return configDict
639 -
640 - def config(self, *args, **kwargs):
641 - "dont configure a dummy interface"
642 - pass
643 -
644 - def ifconfig(self, status):
645 - "configure the status"
646 - if status == "up":
647 - return self.node.w_port_up(self.port)
648 - elif status == "down":
649 - return self.node.w_port_down(self.port)
650 -
651 -
652 -class MininetOE(Mininet):
653 "Mininet with Linc-OE support (starts and stops linc-oe)" 473 "Mininet with Linc-OE support (starts and stops linc-oe)"
654 474
655 - def start(self): 475 + def start( self ):
656 - Mininet.start(self) 476 + Mininet.start( self )
657 - LINCSwitch.bootOE(self) 477 + startOE( self )
658 478
659 - def stop(self): 479 + def stop( self ):
660 - Mininet.stop(self) 480 + Mininet.stop( self )
661 - LINCSwitch.shutdownOE() 481 + stopOE()
662 482
663 - def addControllers(self, controllers): 483 + def addControllers( self, controllers ):
664 i = 0 484 i = 0
665 for ctrl in controllers: 485 for ctrl in controllers:
666 - self.addController(RemoteController('c%d' % i, ip=ctrl)) 486 + self.addController( RemoteController( 'c%d' % i, ip=ctrl ) )
667 - i += 1 487 +
488 +
489 +class OpticalTestTopo( Topo ):
490 +
491 + def build( self ):
492 + opticalAnn = { 'optical.waves': 80, 'optical.type': "WDM", 'durable': True }
493 + switchAnn = { 'bandwidth': 100000, 'optical.type': 'cross-connect', 'durable': True }
494 + h1 = self.addHost( 'h1' )
495 + h2 = self.addHost( 'h2' )
496 + s1 = self.addSwitch( 's1' )
497 + s2 = self.addSwitch( 's2' )
498 + O4 = self.addSwitch( 'O4', cls=OpticalSwitch )
499 + O5 = self.addSwitch( 'O5', cls=OpticalSwitch )
500 + O6 = self.addSwitch( 'O6', cls=OpticalSwitch )
501 + self.addLink( O4, O5, cls=OpticalLink, annotations=opticalAnn )
502 + self.addLink( O5, O6, cls=OpticalLink, annotations=opticalAnn )
503 + self.addLink( s1, O4, cls=OpticalLink, annotations=switchAnn )
504 + self.addLink( s2, O6, cls=OpticalLink, annotations=switchAnn )
505 + self.addLink( h1, s1 )
506 + self.addLink( h2, s2 )
668 507
669 if __name__ == '__main__': 508 if __name__ == '__main__':
670 - pass 509 + import sys
510 + if len( sys.argv ) >= 2:
511 + controllers = sys.argv[1:]
512 + else:
513 + print 'Usage: ./opticalUtils.py (<Controller IP>)+'
514 + print 'Using localhost...\n'
515 + controllers = [ '127.0.0.1' ]
516 +
517 + setLogLevel( 'info' )
518 + net = MininetOE( topo=OpticalTestTopo(), controller=None, autoSetMacs=True )
519 + net.addControllers( controllers )
520 + net.start()
521 + CLI( net )
522 + net.stop()
......