blob: af660d7e13b81afcd891ca67e9d309e675d3cba8 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jon Hall7eb38402015-01-08 17:19:54 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Oct-2012
4
Jon Hallbe6dfc42015-01-12 17:37:25 -08005author: Anil Kumar ( anilkumar.s@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
Jon Hall7eb38402015-01-08 17:19:54 -08008TestON is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
Jon Hall7eb38402015-01-08 17:19:54 -080013TestON is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
adminbae64d82013-08-01 10:50:15 -070017
Jon Hall7eb38402015-01-08 17:19:54 -080018You should have received a copy of the GNU General Public License
19along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
Jon Hallbe6dfc42015-01-12 17:37:25 -080021MininetCliDriver is the basic driver which will handle the Mininet functions
22
23Some functions rely on a modified version of Mininet. These functions
24should all be noted in the comments. To get this MN version run these commands
25from within your Mininet folder:
Jon Hall272a4db2015-01-12 17:43:48 -080026 git remote add jhall11 https://github.com/jhall11/mininet.git
Jon Hallbe6dfc42015-01-12 17:37:25 -080027 git fetch jhall11
Jon Hall272a4db2015-01-12 17:43:48 -080028 git checkout -b dynamic_topo remotes/jhall11/dynamic_topo
Jon Hallbe6dfc42015-01-12 17:37:25 -080029 git pull
30
Jon Hall272a4db2015-01-12 17:43:48 -080031
32 Note that you may need to run 'sudo make develop' if your mnexec.c file
Jon Hallbe6dfc42015-01-12 17:37:25 -080033changed when switching branches."""
adminbae64d82013-08-01 10:50:15 -070034import pexpect
adminbae64d82013-08-01 10:50:15 -070035import re
36import sys
kelvin-onlabfa6ada82015-06-11 13:06:24 -070037import types
kelvin-onlaba4074292015-07-09 15:19:49 -070038import os
Jon Hall1ccf82c2014-10-15 14:55:16 -040039from math import pow
adminbae64d82013-08-01 10:50:15 -070040from drivers.common.cli.emulatordriver import Emulator
adminbae64d82013-08-01 10:50:15 -070041
Jon Hall7eb38402015-01-08 17:19:54 -080042
kelvin-onlab50907142015-04-01 13:37:45 -070043class MininetCliDriver( Emulator ):
Jon Hall7eb38402015-01-08 17:19:54 -080044
45 """
46 MininetCliDriver is the basic driver which will handle
47 the Mininet functions"""
48 def __init__( self ):
49 super( Emulator, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070050 self.handle = self
Jon Hallefbd9792015-03-05 16:11:36 -080051 self.name = None
Jon Hall7eb38402015-01-08 17:19:54 -080052 self.wrapped = sys.modules[ __name__ ]
adminbae64d82013-08-01 10:50:15 -070053 self.flag = 0
54
Jon Hall7eb38402015-01-08 17:19:54 -080055 def connect( self, **connectargs ):
56 """
57 Here the main is the TestON instance after creating
58 all the log handles."""
kelvin-onlaba1484582015-02-02 15:46:20 -080059 try:
60 for key in connectargs:
61 vars( self )[ key ] = connectargs[ key ]
Jon Hallfbc828e2015-01-06 17:30:19 -080062
kelvin-onlaba1484582015-02-02 15:46:20 -080063 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070064
65 try:
66 if os.getenv( str( self.ip_address ) ) != None:
67 self.ip_address = os.getenv( str( self.ip_address ) )
68 else:
69 main.log.info( self.name +
70 ": Trying to connect to " +
71 self.ip_address )
72
73 except KeyError:
74 main.log.info( "Invalid host name," +
75 " connecting to local host instead" )
76 self.ip_address = 'localhost'
77 except Exception as inst:
78 main.log.error( "Uncaught exception: " + str( inst ) )
79
kelvin-onlaba1484582015-02-02 15:46:20 -080080 self.handle = super(
kelvin-onlab50907142015-04-01 13:37:45 -070081 MininetCliDriver,
kelvin-onlaba1484582015-02-02 15:46:20 -080082 self ).connect(
83 user_name=self.user_name,
84 ip_address=self.ip_address,
85 port=None,
86 pwd=self.pwd )
Jon Hallfbc828e2015-01-06 17:30:19 -080087
kelvin-onlaba1484582015-02-02 15:46:20 -080088 if self.handle:
Jon Hallefbd9792015-03-05 16:11:36 -080089 main.log.info( "Connection successful to the host " +
90 self.user_name +
91 "@" +
92 self.ip_address )
kelvin-onlaba1484582015-02-02 15:46:20 -080093 return main.TRUE
94 else:
95 main.log.error( "Connection failed to the host " +
Jon Hallefbd9792015-03-05 16:11:36 -080096 self.user_name +
97 "@" +
98 self.ip_address )
Jon Hallfebb1c72015-03-05 13:30:09 -080099 main.log.error( "Failed to connect to the Mininet CLI" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800100 return main.FALSE
101 except pexpect.EOF:
102 main.log.error( self.name + ": EOF exception found" )
103 main.log.error( self.name + ": " + self.handle.before )
104 main.cleanup()
105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 except Exception:
107 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800108 main.cleanup()
109 main.exit()
110
kelvin-onlab10e8d392015-06-03 13:53:45 -0700111 def startNet( self, topoFile='', args='', mnCmd='', timeout=120 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800112 """
kelvin-onlabf512e942015-06-08 19:42:59 -0700113 Description:
114 Starts Mininet accepts a topology(.py) file and/or an optional
115 argument, to start the mininet, as a parameter.
116 Can also send regular mininet command to load up desired topology.
117 Eg. Pass in a string 'sudo mn --topo=tree,3,3' to mnCmd
118 Options:
119 topoFile = file path for topology file (.py)
120 args = extra option added when starting the topology from the file
121 mnCmd = Mininet command use to start topology
122 Returns:
123 main.TRUE if the mininet starts successfully, main.FALSE
124 otherwise
kelvin-onlab00ac67b2015-02-04 09:52:02 -0800125 """
Jon Hall7eb38402015-01-08 17:19:54 -0800126 if self.handle:
Jon Hall689d8e42015-04-03 13:59:24 -0700127 # make sure old networks are cleaned up
128 main.log.info( self.name +
129 ": Clearing any residual state or processes" )
Jon Hall7eb38402015-01-08 17:19:54 -0800130 self.handle.sendline( "sudo mn -c" )
131 i = self.handle.expect( [ 'password\sfor\s',
132 'Cleanup\scomplete',
133 pexpect.EOF,
134 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800135 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800136 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700137 # Sudo asking for password
Jon Hall7eb38402015-01-08 17:19:54 -0800138 main.log.info( self.name + ": Sending sudo password" )
139 self.handle.sendline( self.pwd )
Jon Hallefbd9792015-03-05 16:11:36 -0800140 i = self.handle.expect( [ '%s:' % self.user,
Jon Hall7eb38402015-01-08 17:19:54 -0800141 '\$',
142 pexpect.EOF,
143 pexpect.TIMEOUT ],
kelvin-onlaba1484582015-02-02 15:46:20 -0800144 timeout )
Jon Hall7eb38402015-01-08 17:19:54 -0800145 if i == 1:
146 main.log.info( self.name + ": Clean" )
147 elif i == 2:
148 main.log.error( self.name + ": Connection terminated" )
149 elif i == 3: # timeout
Jon Hall689d8e42015-04-03 13:59:24 -0700150 main.log.error( self.name + ": Something while cleaning " +
151 "Mininet took too long... " )
152 # Craft the string to start mininet
153 cmdString = "sudo "
kelvin-onlab10e8d392015-06-03 13:53:45 -0700154 if not mnCmd:
155 if topoFile is None or topoFile == '': # If no file is given
156 main.log.info( self.name + ": building fresh Mininet" )
157 cmdString += "mn "
158 if args is None or args == '':
159 # If no args given, use args from .topo file
160 args = self.options[ 'arg1' ] +\
Jon Halld80cc142015-07-06 13:36:05 -0700161 " " + self.options[ 'arg2' ] +\
162 " --mac --controller " +\
163 self.options[ 'controller' ] + " " +\
164 self.options[ 'arg3' ]
kelvin-onlab10e8d392015-06-03 13:53:45 -0700165 else: # else only use given args
166 pass
167 # TODO: allow use of topo args and method args?
168 else: # Use given topology file
Jon Halld80cc142015-07-06 13:36:05 -0700169 main.log.info(
170 "Starting Mininet from topo file " +
171 topoFile )
kelvin-onlab10e8d392015-06-03 13:53:45 -0700172 cmdString += topoFile + " "
173 if args is None:
174 args = ''
175 # TODO: allow use of args from .topo file?
176 cmdString += args
177 else:
178 main.log.info( "Starting Mininet topology using '" + mnCmd +
179 "' command" )
180 cmdString += mnCmd
Jon Hall689d8e42015-04-03 13:59:24 -0700181 # Send the command and check if network started
182 self.handle.sendline( "" )
183 self.handle.expect( '\$' )
184 main.log.info( "Sending '" + cmdString + "' to " + self.name )
185 self.handle.sendline( cmdString )
186 while True:
Jon Hall7eb38402015-01-08 17:19:54 -0800187 i = self.handle.expect( [ 'mininet>',
Jon Hall689d8e42015-04-03 13:59:24 -0700188 'Exception',
189 '\*\*\*',
Jon Hallefbd9792015-03-05 16:11:36 -0800190 pexpect.EOF,
191 pexpect.TIMEOUT ],
Jon Hall689d8e42015-04-03 13:59:24 -0700192 timeout )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800193 if i == 0:
Jon Hall689d8e42015-04-03 13:59:24 -0700194 main.log.info( self.name + ": Mininet built" )
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800195 return main.TRUE
kelvin-onlabec228b82015-02-09 15:45:55 -0800196 elif i == 1:
Jon Hall689d8e42015-04-03 13:59:24 -0700197 response = str( self.handle.before +
198 self.handle.after )
199 self.handle.expect( '\$' )
200 response += str( self.handle.before +
Jon Halld80cc142015-07-06 13:36:05 -0700201 self.handle.after )
Jon Hall689d8e42015-04-03 13:59:24 -0700202 main.log.error(
203 self.name +
204 ": Launching Mininet failed: " + response )
205 return main.FALSE
206 elif i == 2:
207 self.handle.expect( [ "\n",
208 pexpect.EOF,
209 pexpect.TIMEOUT ],
210 timeout )
211 main.log.info( self.handle.before )
212 elif i == 3:
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800213 main.log.error( self.name + ": Connection timeout" )
214 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700215 elif i == 4: # timeout
kelvin-onlabef0cc1c2015-02-09 15:20:26 -0800216 main.log.error(
217 self.name +
218 ": Something took too long... " )
219 return main.FALSE
Jon Hall689d8e42015-04-03 13:59:24 -0700220 # Why did we hit this part?
221 main.log.error( "startNet did not return correctly" )
222 return main.FASLE
Jon Hall7eb38402015-01-08 17:19:54 -0800223 else: # if no handle
Jon Hall689d8e42015-04-03 13:59:24 -0700224 main.log.error( self.name + ": Connection failed to the host " +
225 self.user_name + "@" + self.ip_address )
Jon Hall7eb38402015-01-08 17:19:54 -0800226 main.log.error( self.name + ": Failed to connect to the Mininet" )
adminbae64d82013-08-01 10:50:15 -0700227 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800228
kelvin-onlabfccaafa2015-01-20 13:50:44 -0800229 def numSwitchesNlinks( self, topoType, depth, fanout ):
Jon Hall1ccf82c2014-10-15 14:55:16 -0400230 if topoType == 'tree':
Jon Hall7eb38402015-01-08 17:19:54 -0800231 # In tree topology, if fanout arg is not given, by default it is 2
232 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400233 fanout = 2
234 k = 0
Jon Hall38481722014-11-04 16:50:05 -0500235 count = 0
Jon Hall7eb38402015-01-08 17:19:54 -0800236 while( k <= depth - 1 ):
237 count = count + pow( fanout, k )
238 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 numSwitches = count
Jon Hall7eb38402015-01-08 17:19:54 -0800240 while( k <= depth - 2 ):
241 # depth-2 gives you only core links and not considering
242 # edge links as seen by ONOS. If all the links including
243 # edge links are required, do depth-1
244 count = count + pow( fanout, k )
245 k = k + 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 numLinks = count * fanout
Jon Hall7eb38402015-01-08 17:19:54 -0800247 # print "num_switches for %s(%d,%d) = %d and links=%d" %(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 # topoType,depth,fanout,numSwitches,numLinks )
Jon Hallfbc828e2015-01-06 17:30:19 -0800249
Jon Hall7eb38402015-01-08 17:19:54 -0800250 elif topoType == 'linear':
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 # In linear topology, if fanout or numHostsPerSw is not given,
Jon Hall7eb38402015-01-08 17:19:54 -0800252 # by default it is 1
253 if fanout is None:
Jon Hall1ccf82c2014-10-15 14:55:16 -0400254 fanout = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 numSwitches = depth
256 numHostsPerSw = fanout
257 totalNumHosts = numSwitches * numHostsPerSw
258 numLinks = totalNumHosts + ( numSwitches - 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800259 print "num_switches for %s(%d,%d) = %d and links=%d" %\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 ( topoType, depth, fanout, numSwitches, numLinks )
Jon Hallefbd9792015-03-05 16:11:36 -0800261 topoDict = { "num_switches": int( numSwitches ),
262 "num_corelinks": int( numLinks ) }
Jon Hall1ccf82c2014-10-15 14:55:16 -0400263 return topoDict
264
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 def calculateSwAndLinks( self ):
Jon Hall689d8e42015-04-03 13:59:24 -0700266 """
267 Calculate the number of switches and links in a topo."""
268 # TODO: combine this function and numSwitchesNlinks
269 argList = self.options[ 'arg1' ].split( "," )
270 topoArgList = argList[ 0 ].split( " " )
271 argList = map( int, argList[ 1: ] )
272 topoArgList = topoArgList[ 1: ] + argList
273
274 topoDict = self.numSwitchesNlinks( *topoArgList )
Jon Hall1ccf82c2014-10-15 14:55:16 -0400275 return topoDict
276
Jon Halld80cc142015-07-06 13:36:05 -0700277 def pingall( self, timeout=300, shortCircuit=False, acceptableFailed=0 ):
Jon Hall7eb38402015-01-08 17:19:54 -0800278 """
279 Verifies the reachability of the hosts using pingall command.
280 Optional parameter timeout allows you to specify how long to
281 wait for pingall to complete
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700282 Optional:
Jon Halld80cc142015-07-06 13:36:05 -0700283 timeout( seconds ) - How long to wait before breaking the pingall
kelvin-onlabfbcd82f2015-04-02 12:06:00 -0700284 shortCircuit - Break the pingall based on the number of failed hosts
kelvin-onlabc44f0192015-04-02 22:08:41 -0700285 ping
286 acceptableFailed - Set the number of acceptable failed pings for the
287 function to still return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800288 Returns:
289 main.TRUE if pingall completes with no pings dropped
Jon Hall390696c2015-05-05 17:13:41 -0700290 otherwise main.FALSE
291 """
292 import time
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700293 try:
Jon Hallfb760a02015-04-13 15:35:03 -0700294 timeout = int( timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700295 if self.handle:
296 main.log.info(
297 self.name +
298 ": Checking reachabilty to the hosts using pingall" )
299 response = ""
300 failedPings = 0
301 returnValue = main.TRUE
302 self.handle.sendline( "pingall" )
Jon Hall390696c2015-05-05 17:13:41 -0700303 startTime = time.time()
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700304 while True:
Jon Halld80cc142015-07-06 13:36:05 -0700305 i = self.handle.expect( [ "mininet>", "X",
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700306 pexpect.EOF,
307 pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -0700308 timeout )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700309 if i == 0:
Jon Halld80cc142015-07-06 13:36:05 -0700310 main.log.info( self.name + ": pingall finished" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700311 response += self.handle.before
312 break
313 elif i == 1:
314 response += self.handle.before + self.handle.after
315 failedPings = failedPings + 1
kelvin-onlabd26a3742015-04-06 15:31:16 -0700316 if failedPings > acceptableFailed:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700317 returnValue = main.FALSE
318 if shortCircuit:
319 main.log.error( self.name +
320 ": Aborting pingall - "
321 + str( failedPings ) +
322 " pings failed" )
323 break
Jon Hall390696c2015-05-05 17:13:41 -0700324 if ( time.time() - startTime ) > timeout:
325 returnValue = main.FALSE
326 main.log.error( self.name +
327 ": Aborting pingall - " +
328 "Function took too long " )
329 break
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700330 elif i == 2:
331 main.log.error( self.name +
332 ": EOF exception found" )
333 main.log.error( self.name + ": " +
334 self.handle.before )
335 main.cleanup()
336 main.exit()
337 elif i == 3:
338 response += self.handle.before
339 main.log.error( self.name +
340 ": TIMEOUT exception found" )
341 main.log.error( self.name +
342 ": " +
343 str( response ) )
344 # NOTE: Send ctrl-c to make sure pingall is done
345 self.handle.sendline( "\x03" )
346 self.handle.expect( "Interrupt" )
347 self.handle.expect( "mininet>" )
348 break
349 pattern = "Results\:"
350 main.log.info( "Pingall output: " + str( response ) )
351 if re.search( pattern, response ):
352 main.log.info( self.name + ": Pingall finished with "
353 + str( failedPings ) + " failed pings" )
354 return returnValue
355 else:
kelvin-onlabc44f0192015-04-02 22:08:41 -0700356 # NOTE: Send ctrl-c to make sure pingall is done
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700357 self.handle.sendline( "\x03" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700358 self.handle.expect( "Interrupt" )
kelvin-onlabc44f0192015-04-02 22:08:41 -0700359 self.handle.expect( "mininet>" )
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700360 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700361 else:
kelvin-onlabd9a8ed32015-04-03 13:55:28 -0700362 main.log.error( self.name + ": Connection failed to the host" )
363 main.cleanup()
364 main.exit()
365 except pexpect.TIMEOUT:
366 if response:
367 main.log.info( "Pingall output: " + str( response ) )
368 main.log.error( self.name + ": pexpect.TIMEOUT found" )
369 return main.FALSE
370 except pexpect.EOF:
371 main.log.error( self.name + ": EOF exception found" )
372 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -0500373 main.cleanup()
374 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700375
Jon Hall7eb38402015-01-08 17:19:54 -0800376 def fpingHost( self, **pingParams ):
377 """
378 Uses the fping package for faster pinging...
379 *requires fping to be installed on machine running mininet"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800380 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800381 command = args[ "SRC" ] + \
382 " fping -i 100 -t 20 -C 1 -q " + args[ "TARGET" ]
383 self.handle.sendline( command )
384 self.handle.expect(
385 [ args[ "TARGET" ], pexpect.EOF, pexpect.TIMEOUT ] )
386 self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
387 response = self.handle.before
388 if re.search( ":\s-", response ):
389 main.log.info( self.name + ": Ping fail" )
adminaeedddd2013-08-02 15:14:15 -0700390 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800391 elif re.search( ":\s\d{1,2}\.\d\d", response ):
392 main.log.info( self.name + ": Ping good!" )
adminaeedddd2013-08-02 15:14:15 -0700393 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800394 main.log.info( self.name + ": Install fping on mininet machine... " )
395 main.log.info( self.name + ": \n---\n" + response )
adminaeedddd2013-08-02 15:14:15 -0700396 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800397
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400398 def pingallHosts( self, hostList, pingType='ipv4' ):
399 """
kelvin-onlab2ff57022015-05-29 10:48:51 -0700400 Ping all specified hosts with a specific ping type
401
402 Acceptable pingTypes:
403 - 'ipv4'
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400404 - 'ipv6'
kelvin-onlab2ff57022015-05-29 10:48:51 -0700405
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400406 Acceptable hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700407 - [ 'h1','h2','h3','h4' ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700408
409 Returns main.TRUE if all hosts specified can reach
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400410 each other
kelvin-onlab2ff57022015-05-29 10:48:51 -0700411
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400412 Returns main.FALSE if one or more of hosts specified
413 cannot reach each other"""
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400414 if pingType == "ipv4":
kelvin-onlab2ff57022015-05-29 10:48:51 -0700415 cmd = " ping -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400416 elif pingType == "ipv6":
417 cmd = " ping6 -c 1 -i 1 -W 8 "
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400418 else:
419 main.log.warn( "Invalid pingType specified" )
420 return
421
422 try:
423 main.log.info( "Testing reachability between specified hosts" )
kelvin-onlab2ff57022015-05-29 10:48:51 -0700424
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400425 isReachable = main.TRUE
426
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400427 for host in hostList:
Jon Halld80cc142015-07-06 13:36:05 -0700428 listIndex = hostList.index( host )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400429 # List of hosts to ping other than itself
Jon Halld80cc142015-07-06 13:36:05 -0700430 pingList = hostList[ :listIndex ] + \
431 hostList[ ( listIndex + 1 ): ]
kelvin-onlab2ff57022015-05-29 10:48:51 -0700432
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400433 for temp in pingList:
434 # Current host pings all other hosts specified
Jon Halld80cc142015-07-06 13:36:05 -0700435 pingCmd = str( host ) + cmd + str( temp )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400436 self.handle.sendline( pingCmd )
437 i = self.handle.expect( [ pingCmd, pexpect.TIMEOUT ] )
438 j = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
439 response = self.handle.before
440 if re.search( ',\s0\%\spacket\sloss', response ):
Jon Halld80cc142015-07-06 13:36:05 -0700441 main.log.info( str( host ) + " -> " + str( temp ) )
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400442 else:
Jon Halld80cc142015-07-06 13:36:05 -0700443 main.log.info(
444 str( host ) + " -> X (" + str( temp ) + ") "
445 " Destination Unreachable" )
andrew@onlab.usdefe38c2015-05-14 19:18:18 -0400446 # One of the host to host pair is unreachable
447 isReachable = main.FALSE
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400448
kelvin-onlab2ff57022015-05-29 10:48:51 -0700449 return isReachable
andrew@onlab.us9fdee812015-05-14 17:23:26 -0400450
451 except pexpect.EOF:
452 main.log.error( self.name + ": EOF exception found" )
453 main.log.error( self.name + ": " + self.handle.before )
454 main.cleanup()
455 main.exit()
456
Jon Hall7eb38402015-01-08 17:19:54 -0800457 def pingHost( self, **pingParams ):
458 """
459 Ping from one mininet host to another
460 Currently the only supported Params: SRC and TARGET"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -0800461 args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
Jon Hall7eb38402015-01-08 17:19:54 -0800462 command = args[ "SRC" ] + " ping " + \
463 args[ "TARGET" ] + " -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700464 try:
Jon Hall61282e32015-03-19 11:34:11 -0700465 main.log.info( "Sending: " + command )
Jon Hall7eb38402015-01-08 17:19:54 -0800466 self.handle.sendline( command )
467 i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700468 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800469 main.log.error(
470 self.name +
471 ": timeout when waiting for response from mininet" )
472 main.log.error( "response: " + str( self.handle.before ) )
473 i = self.handle.expect( [ "mininet>", pexpect.TIMEOUT ] )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700474 if i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -0800475 main.log.error(
476 self.name +
477 ": timeout when waiting for response from mininet" )
478 main.log.error( "response: " + str( self.handle.before ) )
Jon Hall6e18c7b2014-04-23 16:26:33 -0700479 response = self.handle.before
Jon Hallfbc828e2015-01-06 17:30:19 -0800480 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800481 main.log.error( self.name + ": EOF exception found" )
482 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700483 main.cleanup()
484 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -0800485 main.log.info( self.name + ": Ping Response: " + response )
486 if re.search( ',\s0\%\spacket\sloss', response ):
487 main.log.info( self.name + ": no packets lost, host is reachable" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800488 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -0700489 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -0800490 else:
491 main.log.error(
492 self.name +
493 ": PACKET LOST, HOST IS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800494 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -0700495 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800496
Jon Hall7eb38402015-01-08 17:19:54 -0800497 def checkIP( self, host ):
498 """
499 Verifies the host's ip configured or not."""
500 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700501 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800502 response = self.execute(
503 cmd=host +
504 " ifconfig",
505 prompt="mininet>",
506 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800507 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800508 main.log.error( self.name + ": EOF exception found" )
509 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700510 main.cleanup()
511 main.exit()
adminbae64d82013-08-01 10:50:15 -0700512
Jon Hall7eb38402015-01-08 17:19:54 -0800513 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|" +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800514 "2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}" +\
515 "[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})." +\
516 "([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|" +\
517 "[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4]" +\
518 "[0-9]|25[0-5]|[0-9]{1,2})"
Jon Hall7eb38402015-01-08 17:19:54 -0800519 # pattern = "inet addr:10.0.0.6"
520 if re.search( pattern, response ):
521 main.log.info( self.name + ": Host Ip configured properly" )
adminbae64d82013-08-01 10:50:15 -0700522 return main.TRUE
523 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800524 main.log.error( self.name + ": Host IP not found" )
adminbae64d82013-08-01 10:50:15 -0700525 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800526 else:
527 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800528
Jon Hall7eb38402015-01-08 17:19:54 -0800529 def verifySSH( self, **connectargs ):
Jon Hallefbd9792015-03-05 16:11:36 -0800530 # FIXME: Who uses this and what is the purpose? seems very specific
Jon Hall6094a362014-04-11 14:46:56 -0700531 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800532 response = self.execute(
533 cmd="h1 /usr/sbin/sshd -D&",
534 prompt="mininet>",
535 timeout=10 )
536 response = self.execute(
537 cmd="h4 /usr/sbin/sshd -D&",
538 prompt="mininet>",
539 timeout=10 )
Jon Hall6094a362014-04-11 14:46:56 -0700540 for key in connectargs:
Jon Hall7eb38402015-01-08 17:19:54 -0800541 vars( self )[ key ] = connectargs[ key ]
542 response = self.execute(
543 cmd="xterm h1 h4 ",
544 prompt="mininet>",
545 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800546 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700549 main.cleanup()
550 main.exit()
adminbae64d82013-08-01 10:50:15 -0700551 import time
Jon Hall7eb38402015-01-08 17:19:54 -0800552 time.sleep( 20 )
adminbae64d82013-08-01 10:50:15 -0700553 if self.flag == 0:
554 self.flag = 1
555 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800556 else:
adminbae64d82013-08-01 10:50:15 -0700557 return main.TRUE
shahshreyae6c7cf42014-11-26 16:39:01 -0800558
kelvin-onlaba1484582015-02-02 15:46:20 -0800559 def moveHost( self, host, oldSw, newSw, ):
560 """
561 Moves a host from one switch to another on the fly
562 Note: The intf between host and oldSw when detached
563 using detach(), will still show up in the 'net'
564 cmd, because switch.detach() doesn't affect switch.intfs[]
Jon Halld80cc142015-07-06 13:36:05 -0700565 ( which is correct behavior since the interfaces
566 haven't moved ).
kelvin-onlaba1484582015-02-02 15:46:20 -0800567 """
568 if self.handle:
569 try:
570 # Bring link between oldSw-host down
Jon Halld80cc142015-07-06 13:36:05 -0700571 cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
Jon Hallefbd9792015-03-05 16:11:36 -0800572 "'," + "'down')"
kelvin-onlaba1484582015-02-02 15:46:20 -0800573 print "cmd1= ", cmd
Jon Hallefbd9792015-03-05 16:11:36 -0800574 response = self.execute( cmd=cmd,
575 prompt="mininet>",
576 timeout=10 )
Jon Hallafa8a472015-06-12 14:02:42 -0700577
kelvin-onlaba1484582015-02-02 15:46:20 -0800578 # Determine hostintf and Oldswitchintf
579 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800580 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800581 print "cmd2= ", cmd
582 self.handle.sendline( cmd )
583 self.handle.expect( "mininet>" )
584
shahshreya73537862015-02-11 15:15:24 -0800585 # Determine ip and mac address of the host-oldSw interface
kelvin-onlaba1484582015-02-02 15:46:20 -0800586 cmd = "px ipaddr = hintf.IP()"
587 print "cmd3= ", cmd
588 self.handle.sendline( cmd )
589 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800590
591 cmd = "px macaddr = hintf.MAC()"
592 print "cmd3= ", cmd
593 self.handle.sendline( cmd )
594 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700595
kelvin-onlaba1484582015-02-02 15:46:20 -0800596 # Detach interface between oldSw-host
597 cmd = "px " + oldSw + ".detach( sintf )"
598 print "cmd4= ", cmd
599 self.handle.sendline( cmd )
600 self.handle.expect( "mininet>" )
601
602 # Add link between host-newSw
603 cmd = "py net.addLink(" + host + "," + newSw + ")"
604 print "cmd5= ", cmd
605 self.handle.sendline( cmd )
606 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700607
kelvin-onlaba1484582015-02-02 15:46:20 -0800608 # Determine hostintf and Newswitchintf
609 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
Jon Hallefbd9792015-03-05 16:11:36 -0800610 ")[0]"
kelvin-onlaba1484582015-02-02 15:46:20 -0800611 print "cmd6= ", cmd
612 self.handle.sendline( cmd )
Jon Hallafa8a472015-06-12 14:02:42 -0700613 self.handle.expect( "mininet>" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800614
615 # Attach interface between newSw-host
616 cmd = "px " + newSw + ".attach( sintf )"
617 print "cmd3= ", cmd
618 self.handle.sendline( cmd )
619 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700620
kelvin-onlaba1484582015-02-02 15:46:20 -0800621 # Set ipaddress of the host-newSw interface
622 cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf)"
623 print "cmd7 = ", cmd
624 self.handle.sendline( cmd )
625 self.handle.expect( "mininet>" )
shahshreya73537862015-02-11 15:15:24 -0800626
627 # Set macaddress of the host-newSw interface
628 cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
629 print "cmd8 = ", cmd
630 self.handle.sendline( cmd )
631 self.handle.expect( "mininet>" )
Jon Hallafa8a472015-06-12 14:02:42 -0700632
kelvin-onlaba1484582015-02-02 15:46:20 -0800633 cmd = "net"
shahshreya73537862015-02-11 15:15:24 -0800634 print "cmd9 = ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800635 self.handle.sendline( cmd )
636 self.handle.expect( "mininet>" )
637 print "output = ", self.handle.before
638
639 # Determine ipaddress of the host-newSw interface
shahshreya73537862015-02-11 15:15:24 -0800640 cmd = host + " ifconfig"
641 print "cmd10= ", cmd
kelvin-onlaba1484582015-02-02 15:46:20 -0800642 self.handle.sendline( cmd )
643 self.handle.expect( "mininet>" )
644 print "ifconfig o/p = ", self.handle.before
Jon Hallafa8a472015-06-12 14:02:42 -0700645
kelvin-onlaba1484582015-02-02 15:46:20 -0800646 return main.TRUE
647 except pexpect.EOF:
648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
650 return main.FALSE
651
Jon Hall7eb38402015-01-08 17:19:54 -0800652 def changeIP( self, host, intf, newIP, newNetmask ):
653 """
654 Changes the ip address of a host on the fly
655 Ex: h2 ifconfig h2-eth0 10.0.1.2 netmask 255.255.255.0"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800656 if self.handle:
657 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800658 cmd = host + " ifconfig " + intf + " " + \
659 newIP + " " + 'netmask' + " " + newNetmask
660 self.handle.sendline( cmd )
661 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800662 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800663 main.log.info( "response = " + response )
664 main.log.info(
665 "Ip of host " +
666 host +
667 " changed to new IP " +
668 newIP )
shahshreyae6c7cf42014-11-26 16:39:01 -0800669 return main.TRUE
670 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800673 return main.FALSE
674
Jon Hall7eb38402015-01-08 17:19:54 -0800675 def changeDefaultGateway( self, host, newGW ):
676 """
677 Changes the default gateway of a host
678 Ex: h1 route add default gw 10.0.1.2"""
shahshreyae6c7cf42014-11-26 16:39:01 -0800679 if self.handle:
680 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800681 cmd = host + " route add default gw " + newGW
682 self.handle.sendline( cmd )
683 self.handle.expect( "mininet>" )
shahshreyae6c7cf42014-11-26 16:39:01 -0800684 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800685 main.log.info( "response = " + response )
686 main.log.info(
687 "Default gateway of host " +
688 host +
689 " changed to " +
690 newGW )
shahshreyae6c7cf42014-11-26 16:39:01 -0800691 return main.TRUE
692 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800693 main.log.error( self.name + ": EOF exception found" )
694 main.log.error( self.name + ": " + self.handle.before )
shahshreyae6c7cf42014-11-26 16:39:01 -0800695 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800696
Jon Hall7eb38402015-01-08 17:19:54 -0800697 def addStaticMACAddress( self, host, GW, macaddr ):
698 """
Jon Hallefbd9792015-03-05 16:11:36 -0800699 Changes the mac address of a gateway host"""
shahshreyad0c80432014-12-04 16:56:05 -0800700 if self.handle:
701 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800702 # h1 arp -s 10.0.1.254 00:00:00:00:11:11
703 cmd = host + " arp -s " + GW + " " + macaddr
704 self.handle.sendline( cmd )
705 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800706 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800707 main.log.info( "response = " + response )
708 main.log.info(
Jon Hallefbd9792015-03-05 16:11:36 -0800709 "Mac address of gateway " +
Jon Hall7eb38402015-01-08 17:19:54 -0800710 GW +
711 " changed to " +
712 macaddr )
shahshreyad0c80432014-12-04 16:56:05 -0800713 return main.TRUE
714 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800717 return main.FALSE
718
Jon Hall7eb38402015-01-08 17:19:54 -0800719 def verifyStaticGWandMAC( self, host ):
720 """
721 Verify if the static gateway and mac address assignment"""
shahshreyad0c80432014-12-04 16:56:05 -0800722 if self.handle:
723 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800724 # h1 arp -an
725 cmd = host + " arp -an "
726 self.handle.sendline( cmd )
727 self.handle.expect( "mininet>" )
shahshreyad0c80432014-12-04 16:56:05 -0800728 response = self.handle.before
Jon Hall7eb38402015-01-08 17:19:54 -0800729 main.log.info( host + " arp -an = " + response )
shahshreyad0c80432014-12-04 16:56:05 -0800730 return main.TRUE
731 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -0800734 return main.FALSE
735
Jon Hall7eb38402015-01-08 17:19:54 -0800736 def getMacAddress( self, host ):
737 """
738 Verifies the host's ip configured or not."""
739 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700740 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800741 response = self.execute(
742 cmd=host +
743 " ifconfig",
744 prompt="mininet>",
745 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800746 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800747 main.log.error( self.name + ": EOF exception found" )
748 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700749 main.cleanup()
750 main.exit()
adminbae64d82013-08-01 10:50:15 -0700751
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700752 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 macAddressSearch = re.search( pattern, response, re.I )
754 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800755 main.log.info(
756 self.name +
757 ": Mac-Address of Host " +
758 host +
759 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 macAddress )
761 return macAddress
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700762 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800763 main.log.error( self.name + ": Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700764
Jon Hall7eb38402015-01-08 17:19:54 -0800765 def getInterfaceMACAddress( self, host, interface ):
766 """
767 Return the IP address of the interface on the given host"""
768 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700769 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800770 response = self.execute( cmd=host + " ifconfig " + interface,
771 prompt="mininet>", timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800772 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
775 main.cleanup()
776 main.exit()
777
778 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 macAddressSearch = re.search( pattern, response, re.I )
780 if macAddressSearch is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800781 main.log.info( "No mac address found in %s" % response )
782 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 macAddress = macAddressSearch.group().split( " " )[ 1 ]
Jon Hall7eb38402015-01-08 17:19:54 -0800784 main.log.info(
785 "Mac-Address of " +
786 host +
787 ":" +
788 interface +
789 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 macAddress )
791 return macAddress
Jon Hall7eb38402015-01-08 17:19:54 -0800792 else:
793 main.log.error( "Connection failed to the host" )
794
795 def getIPAddress( self, host ):
796 """
797 Verifies the host's ip configured or not."""
798 if self.handle:
799 try:
800 response = self.execute(
801 cmd=host +
802 " ifconfig",
803 prompt="mininet>",
804 timeout=10 )
805 except pexpect.EOF:
806 main.log.error( self.name + ": EOF exception found" )
807 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700808 main.cleanup()
809 main.exit()
adminbae64d82013-08-01 10:50:15 -0700810
811 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 ipAddressSearch = re.search( pattern, response )
Jon Hall7eb38402015-01-08 17:19:54 -0800813 main.log.info(
814 self.name +
815 ": IP-Address of Host " +
816 host +
817 " is " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 ipAddressSearch.group( 1 ) )
819 return ipAddressSearch.group( 1 )
Jon Hall7eb38402015-01-08 17:19:54 -0800820 else:
821 main.log.error( self.name + ": Connection failed to the host" )
Jon Hallfbc828e2015-01-06 17:30:19 -0800822
Jon Hall7eb38402015-01-08 17:19:54 -0800823 def getSwitchDPID( self, switch ):
824 """
825 return the datapath ID of the switch"""
826 if self.handle:
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700827 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700828 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800829 response = self.execute(
830 cmd=cmd,
831 prompt="mininet>",
832 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800833 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700836 main.cleanup()
837 main.exit()
Jon Hall28bf54b2014-12-17 16:25:44 -0800838 pattern = r'^(?P<dpid>\w)+'
Jon Hall7eb38402015-01-08 17:19:54 -0800839 result = re.search( pattern, response, re.MULTILINE )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700840 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -0800841 main.log.info(
842 "Couldn't find DPID for switch %s, found: %s" %
843 ( switch, response ) )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700844 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -0800845 return str( result.group( 0 ) ).lower()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700846 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800847 main.log.error( "Connection failed to the host" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700848
Jon Hall7eb38402015-01-08 17:19:54 -0800849 def getDPID( self, switch ):
admin2580a0e2014-07-29 11:24:34 -0700850 if self.handle:
Jon Hall7eb38402015-01-08 17:19:54 -0800851 self.handle.sendline( "" )
852 self.expect( "mininet>" )
853 cmd = "py %s.dpid" % switch
admin2580a0e2014-07-29 11:24:34 -0700854 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800855 response = self.execute(
856 cmd=cmd,
857 prompt="mininet>",
858 timeout=10 )
859 self.handle.expect( "mininet>" )
admin2580a0e2014-07-29 11:24:34 -0700860 response = self.handle.before
861 return response
862 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800863 main.log.error( self.name + ": EOF exception found" )
864 main.log.error( self.name + ": " + self.handle.before )
admin2580a0e2014-07-29 11:24:34 -0700865 main.cleanup()
866 main.exit()
867
Jon Hall7eb38402015-01-08 17:19:54 -0800868 def getInterfaces( self, node ):
869 """
870 return information dict about interfaces connected to the node"""
871 if self.handle:
872 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s"' +\
kelvin-onlabedcff052015-01-16 12:53:55 -0800873 ' % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700874 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700875 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800876 response = self.execute(
877 cmd=cmd,
878 prompt="mininet>",
879 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800880 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800881 main.log.error( self.name + ": EOF exception found" )
882 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700883 main.cleanup()
884 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700885 return response
886 else:
Jon Hall7eb38402015-01-08 17:19:54 -0800887 main.log.error( "Connection failed to the node" )
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700888
Jon Hall7eb38402015-01-08 17:19:54 -0800889 def dump( self ):
890 main.log.info( self.name + ": Dump node info" )
Jon Hall6094a362014-04-11 14:46:56 -0700891 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800892 response = self.execute(
893 cmd='dump',
894 prompt='mininet>',
895 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800896 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700899 main.cleanup()
900 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700901 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800902
Jon Hall7eb38402015-01-08 17:19:54 -0800903 def intfs( self ):
904 main.log.info( self.name + ": List interfaces" )
Jon Hall6094a362014-04-11 14:46:56 -0700905 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800906 response = self.execute(
907 cmd='intfs',
908 prompt='mininet>',
909 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800910 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700913 main.cleanup()
914 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700915 return response
Jon Hallfbc828e2015-01-06 17:30:19 -0800916
Jon Hall7eb38402015-01-08 17:19:54 -0800917 def net( self ):
918 main.log.info( self.name + ": List network connections" )
Jon Hall6094a362014-04-11 14:46:56 -0700919 try:
Jon Hall7eb38402015-01-08 17:19:54 -0800920 response = self.execute( cmd='net', prompt='mininet>', timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -0800921 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -0800922 main.log.error( self.name + ": EOF exception found" )
923 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -0700924 main.cleanup()
925 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700926 return response
Jon Hall7eb38402015-01-08 17:19:54 -0800927
Jon Hallafa8a472015-06-12 14:02:42 -0700928 def links( self ):
929 main.log.info( self.name + ": List network links" )
930 try:
931 response = self.execute( cmd='links', prompt='mininet>',
932 timeout=10 )
933 except pexpect.EOF:
934 main.log.error( self.name + ": EOF exception found" )
935 main.log.error( self.name + ": " + self.handle.before )
936 main.cleanup()
937 main.exit()
938 return response
939
GlennRC61321f22015-07-16 13:36:54 -0700940 def iperftcpAll(self, hosts, timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700941 '''
942 Runs the iperftcp function with a given set of hosts and specified timeout.
GlennRC61321f22015-07-16 13:36:54 -0700943
kelvin-onlab7cce9382015-07-17 10:21:03 -0700944 @parm:
945 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
946 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
947 '''
948 for host1 in hosts:
949 for host2 in hosts:
950 if host1 != host2:
951 if self.iperftcp(host1, host2, timeout) == main.FALSE:
952 main.log.error(self.name + ": iperftcp test failed for " + host1 + " and " + host2)
GlennRC61321f22015-07-16 13:36:54 -0700953
954 def iperftcp(self, host1="h1", host2="h2", timeout=6):
kelvin-onlab7cce9382015-07-17 10:21:03 -0700955 '''
956 Creates an iperf TCP test between two hosts. Returns main.TRUE if test results
957 are valid.
GlennRC61321f22015-07-16 13:36:54 -0700958
kelvin-onlab7cce9382015-07-17 10:21:03 -0700959 @parm:
960 timeout: The defualt timeout is 6 sec to allow enough time for a successful test to complete,
961 and short enough to stop an unsuccessful test from quiting and cleaning up mininet.
962 '''
963 main.log.info( self.name + ": Simple iperf TCP test between two hosts" )
964 try:
965 # Setup the mininet command
966 cmd1 = 'iperf ' + host1 + " " + host2
967 self.handle.sendline( cmd1 )
968 outcome = self.handle.expect( "mininet>", timeout )
969 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -0700970
kelvin-onlab7cce9382015-07-17 10:21:03 -0700971 # checks if there are results in the mininet response
972 if "Results:" in response:
973 main.log.report(self.name + ": iperf test completed")
974 # parse the mn results
975 response = response.split("\r\n")
976 response = response[len(response)-2]
977 response = response.split(": ")
978 response = response[len(response)-1]
979 response = response.replace("[", "")
980 response = response.replace("]", "")
981 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -0700982
kelvin-onlab7cce9382015-07-17 10:21:03 -0700983 # this is the bandwith two and from the two hosts
984 bandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -0700985
kelvin-onlab7cce9382015-07-17 10:21:03 -0700986 # there should be two elements in the bandwidth list
987 # ['host1 to host2', 'host2 to host1"]
988 if len(bandwidth) == 2:
989 main.log.report(self.name + ": iperf test successful")
990 return main.TRUE
991 else:
992 main.log.error(self.name + ": invalid iperf results")
993 return main.FALSE
shahshreyae6c7cf42014-11-26 16:39:01 -0800994 else:
kelvin-onlab7cce9382015-07-17 10:21:03 -0700995 main.log.error( self.name + ": iperf test failed" )
Jon Hall7eb38402015-01-08 17:19:54 -0800996 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -0800997
GlennRC61321f22015-07-16 13:36:54 -0700998 except pexpect.TIMEOUT:
999 main.log.error( self.name + ": TIMEOUT exception found")
1000 main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
1001 return main.FALSE
1002
Jon Hallfbc828e2015-01-06 17:30:19 -08001003 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001004 main.log.error( self.name + ": EOF exception found" )
1005 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001006 main.cleanup()
kelvin-onlab7cce9382015-07-17 10:21:03 -07001007 main.exit()
GlennRC61321f22015-07-16 13:36:54 -07001008
1009 def iperfudpAll(self, hosts, bandwidth="10M"):
1010 '''
1011 Runs the iperfudp function with a given set of hosts and specified
1012 bandwidth
kelvin-onlab7cce9382015-07-17 10:21:03 -07001013
GlennRC61321f22015-07-16 13:36:54 -07001014 @param:
1015 bandwidth: the targeted bandwidth, in megabits ('M')
1016 '''
1017 for host1 in hosts:
1018 for host2 in hosts:
1019 if host1 != host2:
1020 if self.iperfudp(host1, host2, bandwidth) == main.FALSE:
1021 main.log.error(self.name + ": iperfudp test failed for " + host1 + " and " + host2)
1022
1023 def iperfudp( self, bandwidth="10M", host1="h1", host2="h2"):
1024
kelvin-onlab7cce9382015-07-17 10:21:03 -07001025 '''
1026 Creates an iperf UDP test with a specific bandwidth.
1027 Returns true if results are valid.
GlennRC61321f22015-07-16 13:36:54 -07001028
kelvin-onlab7cce9382015-07-17 10:21:03 -07001029 @param:
1030 bandwidth: the targeted bandwidth, in megabits ('M'), to run the test
1031 '''
1032 main.log.info(self.name + ": Simple iperf UDP test between two hosts")
1033 try:
1034 # setup the mininet command
1035 cmd = 'iperfudp ' + bandwidth + " " + host1 + " " + host2
1036 self.handle.sendline(cmd)
1037 self.handle.expect("mininet>")
1038 response = self.handle.before
GlennRC61321f22015-07-16 13:36:54 -07001039
kelvin-onlab7cce9382015-07-17 10:21:03 -07001040 # check if there are in results in the mininet response
1041 if "Results:" in response:
1042 main.log.report(self.name + ": iperfudp test completed")
1043 # parse the results
1044 response = response.split("\r\n")
1045 response = response[len(response)-2]
1046 response = response.split(": ")
1047 response = response[len(response)-1]
1048 response = response.replace("[", "")
1049 response = response.replace("]", "")
1050 response = response.replace("\'", "")
GlennRC61321f22015-07-16 13:36:54 -07001051
kelvin-onlab7cce9382015-07-17 10:21:03 -07001052 mnBandwidth = response.split(", ")
GlennRC61321f22015-07-16 13:36:54 -07001053
kelvin-onlab7cce9382015-07-17 10:21:03 -07001054 # check to see if there are at least three entries
1055 # ['bandwidth', 'host1 to host2', 'host2 to host1']
1056 if len(mnBandwidth) == 3:
1057 # if one entry is blank then something is wrong
1058 for item in mnBandwidth:
1059 if item == "":
1060 main.log.error(self.name + ": Could not parse iperf output")
1061 main.log.error(self.name + ": invalid iperfudp results")
1062 return main.FALSE
1063 # otherwise results are vaild
1064 main.log.report(self.name + ": iperfudp test successful")
1065 return main.TRUE
1066 else:
1067 main.log.error(self.name + ": invalid iperfudp results")
1068 return main.FALSE
GlennRC61321f22015-07-16 13:36:54 -07001069
kelvin-onlab7cce9382015-07-17 10:21:03 -07001070 except pexpect.EOF:
1071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
1073 main.cleanup()
1074 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001075
Jon Hall7eb38402015-01-08 17:19:54 -08001076 def nodes( self ):
1077 main.log.info( self.name + ": List all nodes." )
Jon Hall6094a362014-04-11 14:46:56 -07001078 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001079 response = self.execute(
1080 cmd='nodes',
1081 prompt='mininet>',
1082 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001083 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001084 main.log.error( self.name + ": EOF exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001086 main.cleanup()
1087 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -07001088 return response
Jon Hallfbc828e2015-01-06 17:30:19 -08001089
Jon Hall7eb38402015-01-08 17:19:54 -08001090 def pingpair( self ):
1091 main.log.info( self.name + ": Ping between first two hosts" )
Jon Hall6094a362014-04-11 14:46:56 -07001092 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001093 response = self.execute(
1094 cmd='pingpair',
1095 prompt='mininet>',
1096 timeout=20 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001097 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001098 main.log.error( self.name + ": EOF exception found" )
1099 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001100 main.cleanup()
1101 main.exit()
Jon Hallfbc828e2015-01-06 17:30:19 -08001102
Jon Hall7eb38402015-01-08 17:19:54 -08001103 if re.search( ',\s0\%\spacket\sloss', response ):
1104 main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 main.lastResult = main.TRUE
adminbae64d82013-08-01 10:50:15 -07001106 return main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001107 else:
1108 main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 main.lastResult = main.FALSE
adminbae64d82013-08-01 10:50:15 -07001110 return main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001111
Jon Hall7eb38402015-01-08 17:19:54 -08001112 def link( self, **linkargs ):
1113 """
1114 Bring link( s ) between two nodes up or down"""
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001115 args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001116 end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
1117 end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
1118 option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
1119 main.log.info(
1120 "Bring link between '" +
1121 end1 +
1122 "' and '" +
1123 end2 +
1124 "' '" +
1125 option +
1126 "'" )
1127 command = "link " + \
1128 str( end1 ) + " " + str( end2 ) + " " + str( option )
Jon Hall6094a362014-04-11 14:46:56 -07001129 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001130 self.handle.sendline( command )
1131 self.handle.expect( "mininet>" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001132 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001133 main.log.error( self.name + ": EOF exception found" )
1134 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001135 main.cleanup()
1136 main.exit()
adminbae64d82013-08-01 10:50:15 -07001137 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001138
Jon Hall7eb38402015-01-08 17:19:54 -08001139 def yank( self, **yankargs ):
1140 """
1141 yank a mininet switch interface to a host"""
1142 main.log.info( 'Yank the switch interface attached to a host' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001143 args = utilities.parse_args( [ "SW", "INTF" ], **yankargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001144 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1145 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1146 command = "py " + str( sw ) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001147 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001148 response = self.execute(
1149 cmd=command,
1150 prompt="mininet>",
1151 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001152 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001153 main.log.error( self.name + ": EOF exception found" )
1154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001155 main.cleanup()
1156 main.exit()
adminaeedddd2013-08-02 15:14:15 -07001157 return main.TRUE
1158
Jon Hall7eb38402015-01-08 17:19:54 -08001159 def plug( self, **plugargs ):
1160 """
1161 plug the yanked mininet switch interface to a switch"""
1162 main.log.info( 'Plug the switch interface attached to a switch' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001163 args = utilities.parse_args( [ "SW", "INTF" ], **plugargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001164 sw = args[ "SW" ] if args[ "SW" ] is not None else ""
1165 intf = args[ "INTF" ] if args[ "INTF" ] is not None else ""
1166 command = "py " + str( sw ) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -07001167 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001168 response = self.execute(
1169 cmd=command,
1170 prompt="mininet>",
1171 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001172 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001175 main.cleanup()
1176 main.exit()
adminbae64d82013-08-01 10:50:15 -07001177 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001178
Jon Hall7eb38402015-01-08 17:19:54 -08001179 def dpctl( self, **dpctlargs ):
1180 """
1181 Run dpctl command on all switches."""
1182 main.log.info( 'Run dpctl command on all switches' )
kelvin-onlab7d0c9672015-01-20 15:56:22 -08001183 args = utilities.parse_args( [ "CMD", "ARGS" ], **dpctlargs )
Jon Hall7eb38402015-01-08 17:19:54 -08001184 cmd = args[ "CMD" ] if args[ "CMD" ] is not None else ""
1185 cmdargs = args[ "ARGS" ] if args[ "ARGS" ] is not None else ""
1186 command = "dpctl " + cmd + " " + str( cmdargs )
1187 try:
1188 response = self.execute(
1189 cmd=command,
1190 prompt="mininet>",
1191 timeout=10 )
1192 except pexpect.EOF:
1193 main.log.error( self.name + ": EOF exception found" )
1194 main.log.error( self.name + ": " + self.handle.before )
1195 main.cleanup()
1196 main.exit()
1197 return main.TRUE
Jon Hallfbc828e2015-01-06 17:30:19 -08001198
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 def getVersion( self ):
Jon Halld80cc142015-07-06 13:36:05 -07001200 # FIXME: What uses this? This should be refactored to get
Jon Hallff6b4b22015-02-23 09:25:15 -08001201 # version from MN and not some other file
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 fileInput = path + '/lib/Mininet/INSTALL'
1203 version = super( Mininet, self ).getVersion()
adminbae64d82013-08-01 10:50:15 -07001204 pattern = 'Mininet\s\w\.\w\.\w\w*'
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 for line in open( fileInput, 'r' ).readlines():
Jon Hall7eb38402015-01-08 17:19:54 -08001206 result = re.match( pattern, line )
adminbae64d82013-08-01 10:50:15 -07001207 if result:
Jon Hall7eb38402015-01-08 17:19:54 -08001208 version = result.group( 0 )
Jon Hallec3c21e2014-11-10 22:22:37 -05001209 return version
adminbae64d82013-08-01 10:50:15 -07001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def getSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001212 """
Jon Hallec3c21e2014-11-10 22:22:37 -05001213 Parameters:
1214 sw: The name of an OVS switch. Example "s1"
1215 Return:
Jon Hall7eb38402015-01-08 17:19:54 -08001216 The output of the command from the mininet cli
1217 or main.FALSE on timeout"""
1218 command = "sh ovs-vsctl get-controller " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001219 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001220 response = self.execute(
1221 cmd=command,
1222 prompt="mininet>",
1223 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001224 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -05001225 return response
admin2a9548d2014-06-17 14:08:07 -07001226 else:
1227 return main.FALSE
1228 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001229 main.log.error( self.name + ": EOF exception found" )
1230 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001231 main.cleanup()
1232 main.exit()
adminbae64d82013-08-01 10:50:15 -07001233
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001234 def assignSwController( self, sw, ip, port="6633", ptcp="" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001235 """
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001236 Description:
1237 Assign switches to the controllers ( for ovs use only )
1238 Required:
1239 sw - Name of the switch. This can be a list or a string.
1240 ip - Ip addresses of controllers. This can be a list or a string.
1241 Optional:
1242 port - ONOS use port 6633, if no list of ports is passed, then
1243 the all the controller will use 6633 as their port number
1244 ptcp - ptcp number, This can be a string or a list that has
1245 the same length as switch. This is optional and not required
1246 when using ovs switches.
1247 NOTE: If switches and ptcp are given in a list type they should have the
1248 same length and should be in the same order, Eg. sw=[ 's1' ... n ]
1249 ptcp=[ '6637' ... n ], s1 has ptcp number 6637 and so on.
Jon Hallf89c8552014-04-02 13:14:06 -07001250
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001251 Return:
1252 Returns main.TRUE if mininet correctly assigned switches to
1253 controllers, otherwise it will return main.FALSE or an appropriate
1254 exception(s)
1255 """
1256 assignResult = main.TRUE
1257 # Initial ovs command
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001258 commandList = []
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001259 command = "sh ovs-vsctl set-controller "
1260 onosIp = ""
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001261 try:
1262 if isinstance( ip, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001263 onosIp = "tcp:" + str( ip ) + ":"
kelvin-onlab5c2df432015-06-11 17:29:56 -07001264 if isinstance( port, types.StringType ) or \
1265 isinstance( port, types.IntType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001266 onosIp += str( port )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001267 elif isinstance( port, types.ListType ):
1268 main.log.error( self.name + ": Only one controller " +
1269 "assigned and a list of ports has" +
1270 " been passed" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001271 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001272 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001273 main.log.error( self.name + ": Invalid controller port " +
1274 "number. Please specify correct " +
1275 "controller port" )
1276 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001277
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001278 elif isinstance( ip, types.ListType ):
kelvin-onlab5c2df432015-06-11 17:29:56 -07001279 if isinstance( port, types.StringType ) or \
1280 isinstance( port, types.IntType ):
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001281 for ipAddress in ip:
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001282 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1283 str( port ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001284 elif isinstance( port, types.ListType ):
1285 if ( len( ip ) != len( port ) ):
1286 main.log.error( self.name + ": Port list = " +
1287 str( len( port ) ) +
1288 "should be the same as controller" +
1289 " ip list = " + str( len( ip ) ) )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001290 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001291 else:
1292 onosIp = ""
1293 for ipAddress, portNum in zip( ip, port ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001294 onosIp += "tcp:" + str( ipAddress ) + ":" + \
1295 str( portNum ) + " "
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001296 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001297 main.log.error( self.name + ": Invalid controller port " +
1298 "number. Please specify correct " +
1299 "controller port" )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001300 return main.FALSE
kelvin-onlabe5edb9e2015-06-12 09:38:47 -07001301 else:
1302 main.log.error( self.name + ": Invalid ip address" )
1303 return main.FALSE
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001304
1305 if isinstance( sw, types.StringType ):
1306 command += sw + " "
1307 if ptcp:
1308 if isinstance( ptcp, types.StringType ):
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001309 command += "ptcp:" + str( ptcp ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001310 elif isinstance( ptcp, types.ListType ):
1311 main.log.error( self.name + ": Only one switch is " +
1312 "being set and multiple PTCP is " +
1313 "being passed " )
1314 else:
1315 main.log.error( self.name + ": Invalid PTCP" )
1316 ptcp = ""
1317 command += onosIp
1318 commandList.append( command )
1319
1320 elif isinstance( sw, types.ListType ):
1321 if ptcp:
1322 if isinstance( ptcp, types.ListType ):
1323 if len( ptcp ) != len( sw ):
1324 main.log.error( self.name + ": PTCP length = " +
1325 str( len( ptcp ) ) +
1326 " is not the same as switch" +
1327 " length = " +
1328 str( len( sw ) ) )
1329 return main.FALSE
1330 else:
1331 for switch, ptcpNum in zip( sw, ptcp ):
1332 tempCmd = "sh ovs-vsctl set-controller "
kelvin-onlabf713d7c2015-06-11 14:29:05 -07001333 tempCmd += switch + " ptcp:" + \
Jon Halld80cc142015-07-06 13:36:05 -07001334 str( ptcpNum ) + " "
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001335 tempCmd += onosIp
1336 commandList.append( tempCmd )
1337 else:
1338 main.log.error( self.name + ": Invalid PTCP" )
1339 return main.FALSE
1340 else:
1341 for switch in sw:
1342 tempCmd = "sh ovs-vsctl set-controller "
1343 tempCmd += switch + " " + onosIp
1344 commandList.append( tempCmd )
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001345 else:
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001346 main.log.error( self.name + ": Invalid switch type " )
1347 return main.FALSE
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001348
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001349 for cmd in commandList:
1350 try:
kelvin-onlabfa6ada82015-06-11 13:06:24 -07001351 self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
kelvin-onlab4f9f7e02015-06-11 14:07:20 -07001352 except pexpect.TIMEOUT:
1353 main.log.error( self.name + ": pexpect.TIMEOUT found" )
1354 return main.FALSE
1355 except pexpect.EOF:
1356 main.log.error( self.name + ": EOF exception found" )
1357 main.log.error( self.name + ": " + self.handle.before )
1358 main.cleanup()
1359 main.exit()
1360 return main.TRUE
1361 except Exception:
1362 main.log.exception( self.name + ": Uncaught exception!" )
1363 main.cleanup()
1364 main.exit()
adminbae64d82013-08-01 10:50:15 -07001365
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 def deleteSwController( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001367 """
1368 Removes the controller target from sw"""
1369 command = "sh ovs-vsctl del-controller " + str( sw )
Jon Hall0819fd92014-05-23 12:08:13 -07001370 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001371 response = self.execute(
1372 cmd=command,
1373 prompt="mininet>",
1374 timeout=10 )
Jon Hallfbc828e2015-01-06 17:30:19 -08001375 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001376 main.log.error( self.name + ": EOF exception found" )
1377 main.log.error( self.name + ": " + self.handle.before )
Jon Hall0819fd92014-05-23 12:08:13 -07001378 main.cleanup()
1379 main.exit()
1380 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001381 main.log.info( response )
Jon Hall0819fd92014-05-23 12:08:13 -07001382
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 def addSwitch( self, sw, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001384 """
Jon Hallb1290e82014-11-18 16:17:48 -05001385 adds a switch to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001386 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001387 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001388 NOTE: cannot currently specify what type of switch
1389 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001390 sw = name of the new switch as a string
1391 optional keywords:
Jon Hallb1290e82014-11-18 16:17:48 -05001392 dpid = "dpid"
Jon Hallefbd9792015-03-05 16:11:36 -08001393 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001394 """
1395 dpid = kwargs.get( 'dpid', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001396 command = "addswitch " + str( sw ) + " " + str( dpid )
Jon Hallb1290e82014-11-18 16:17:48 -05001397 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001398 response = self.execute(
1399 cmd=command,
1400 prompt="mininet>",
1401 timeout=10 )
1402 if re.search( "already exists!", response ):
1403 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001404 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001405 elif re.search( "Error", response ):
1406 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001407 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001408 elif re.search( "usage:", response ):
1409 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001410 return main.FALSE
1411 else:
1412 return main.TRUE
1413 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001414 main.log.error( self.name + ": EOF exception found" )
Jon Halld80cc142015-07-06 13:36:05 -07001415 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001416 main.cleanup()
1417 main.exit()
1418
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 def delSwitch( self, sw ):
Jon Hall7eb38402015-01-08 17:19:54 -08001420 """
Jon Hallbe6dfc42015-01-12 17:37:25 -08001421 delete a switch from the mininet topology
1422 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001423 dynamic_topo branch
Jon Hallbe6dfc42015-01-12 17:37:25 -08001424 required params:
Jon Hallefbd9792015-03-05 16:11:36 -08001425 sw = name of the switch as a string
1426 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001427 command = "delswitch " + str( sw )
Jon Hallb1290e82014-11-18 16:17:48 -05001428 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001429 response = self.execute(
1430 cmd=command,
1431 prompt="mininet>",
1432 timeout=10 )
1433 if re.search( "no switch named", response ):
1434 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001435 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001436 elif re.search( "Error", response ):
1437 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001438 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001439 elif re.search( "usage:", response ):
1440 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001441 return main.FALSE
1442 else:
1443 return main.TRUE
1444 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001445 main.log.error( self.name + ": EOF exception found" )
1446 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001447 main.cleanup()
1448 main.exit()
1449
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 def addLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001451 """
1452 add a link to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001453 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001454 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001455 NOTE: cannot currently specify what type of link
1456 required params:
1457 node1 = the string node name of the first endpoint of the link
1458 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001459 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001460 command = "addlink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001461 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001462 response = self.execute(
1463 cmd=command,
1464 prompt="mininet>",
1465 timeout=10 )
1466 if re.search( "doesnt exist!", response ):
1467 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001468 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001469 elif re.search( "Error", response ):
1470 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001471 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001472 elif re.search( "usage:", response ):
1473 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001474 return main.FALSE
1475 else:
1476 return main.TRUE
1477 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001478 main.log.error( self.name + ": EOF exception found" )
1479 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001480 main.cleanup()
1481 main.exit()
1482
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 def delLink( self, node1, node2 ):
Jon Hall7eb38402015-01-08 17:19:54 -08001484 """
1485 delete a link from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001486 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001487 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001488 required params:
1489 node1 = the string node name of the first endpoint of the link
1490 node2 = the string node name of the second endpoint of the link
Jon Hallefbd9792015-03-05 16:11:36 -08001491 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001492 command = "dellink " + str( node1 ) + " " + str( node2 )
Jon Hallb1290e82014-11-18 16:17:48 -05001493 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001494 response = self.execute(
1495 cmd=command,
1496 prompt="mininet>",
1497 timeout=10 )
1498 if re.search( "no node named", response ):
1499 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001500 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001501 elif re.search( "Error", response ):
1502 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001503 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001504 elif re.search( "usage:", response ):
1505 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001506 return main.FALSE
1507 else:
1508 return main.TRUE
1509 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001510 main.log.error( self.name + ": EOF exception found" )
1511 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001512 main.cleanup()
1513 main.exit()
1514
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 def addHost( self, hostname, **kwargs ):
Jon Hall7eb38402015-01-08 17:19:54 -08001516 """
Jon Hallb1290e82014-11-18 16:17:48 -05001517 Add a host to the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001518 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001519 dynamic_topo branch
Jon Hallb1290e82014-11-18 16:17:48 -05001520 NOTE: cannot currently specify what type of host
1521 required params:
1522 hostname = the string hostname
1523 optional key-value params
1524 switch = "switch name"
Jon Hallefbd9792015-03-05 16:11:36 -08001525 returns: main.FALSE on an error, else main.TRUE
Jon Hall7eb38402015-01-08 17:19:54 -08001526 """
1527 switch = kwargs.get( 'switch', '' )
Jon Hallffb386d2014-11-21 13:43:38 -08001528 command = "addhost " + str( hostname ) + " " + str( switch )
Jon Hallb1290e82014-11-18 16:17:48 -05001529 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001530 response = self.execute(
1531 cmd=command,
1532 prompt="mininet>",
1533 timeout=10 )
1534 if re.search( "already exists!", response ):
1535 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001536 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001537 elif re.search( "doesnt exists!", response ):
1538 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001539 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001540 elif re.search( "Error", response ):
1541 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001542 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001543 elif re.search( "usage:", response ):
1544 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001545 return main.FALSE
1546 else:
1547 return main.TRUE
1548 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001549 main.log.error( self.name + ": EOF exception found" )
1550 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001551 main.cleanup()
1552 main.exit()
1553
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 def delHost( self, hostname ):
Jon Hall7eb38402015-01-08 17:19:54 -08001555 """
1556 delete a host from the mininet topology
Jon Hallbe6dfc42015-01-12 17:37:25 -08001557 NOTE: This uses a custom mn function. MN repo should be on
Jon Hall272a4db2015-01-12 17:43:48 -08001558 dynamic_topo branch
Jon Hall7eb38402015-01-08 17:19:54 -08001559 NOTE: this uses a custom mn function
1560 required params:
1561 hostname = the string hostname
Jon Hallefbd9792015-03-05 16:11:36 -08001562 returns: main.FALSE on an error, else main.TRUE"""
Jon Hallffb386d2014-11-21 13:43:38 -08001563 command = "delhost " + str( hostname )
Jon Hallb1290e82014-11-18 16:17:48 -05001564 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001565 response = self.execute(
1566 cmd=command,
1567 prompt="mininet>",
1568 timeout=10 )
1569 if re.search( "no host named", response ):
1570 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001571 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001572 elif re.search( "Error", response ):
1573 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001574 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001575 elif re.search( "usage:", response ):
1576 main.log.warn( response )
Jon Hallb1290e82014-11-18 16:17:48 -05001577 return main.FALSE
1578 else:
1579 return main.TRUE
1580 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001581 main.log.error( self.name + ": EOF exception found" )
1582 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05001583 main.cleanup()
1584 main.exit()
Jon Hall0819fd92014-05-23 12:08:13 -07001585
Jon Hall7eb38402015-01-08 17:19:54 -08001586 def disconnect( self ):
kelvin-onlaba1484582015-02-02 15:46:20 -08001587 """
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001588 Called at the end of the test to stop the mininet and
1589 disconnect the handle.
kelvin-onlaba1484582015-02-02 15:46:20 -08001590 """
Jon Halld80cc142015-07-06 13:36:05 -07001591 self.handle.sendline( '' )
Jon Halld61331b2015-02-17 16:35:47 -08001592 i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
Jon Halld80cc142015-07-06 13:36:05 -07001593 timeout=2 )
Jon Hall390696c2015-05-05 17:13:41 -07001594 response = main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001595 if i == 0:
Jon Hall390696c2015-05-05 17:13:41 -07001596 response = self.stopNet()
Jon Halld61331b2015-02-17 16:35:47 -08001597 elif i == 1:
1598 return main.TRUE
kelvin-onlaba1484582015-02-02 15:46:20 -08001599 # print "Disconnecting Mininet"
1600 if self.handle:
1601 self.handle.sendline( "exit" )
1602 self.handle.expect( "exit" )
1603 self.handle.expect( "(.*)" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001604 else:
1605 main.log.error( "Connection failed to the host" )
kelvin-onlaba1484582015-02-02 15:46:20 -08001606 return response
1607
Jon Halld80cc142015-07-06 13:36:05 -07001608 def stopNet( self, fileName="", timeout=5 ):
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001609 """
Jon Hall21270ac2015-02-16 17:59:55 -08001610 Stops mininet.
Jon Hallefbd9792015-03-05 16:11:36 -08001611 Returns main.TRUE if the mininet successfully stops and
Jon Hall21270ac2015-02-16 17:59:55 -08001612 main.FALSE if the pexpect handle does not exist.
1613
Jon Halld61331b2015-02-17 16:35:47 -08001614 Will cleanup and exit the test if mininet fails to stop
kelvin-onlab00ac67b2015-02-04 09:52:02 -08001615 """
Jon Halld61331b2015-02-17 16:35:47 -08001616 main.log.info( self.name + ": Stopping mininet..." )
adminbae64d82013-08-01 10:50:15 -07001617 response = ''
1618 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -07001619 try:
Jon Halld80cc142015-07-06 13:36:05 -07001620 self.handle.sendline( "" )
kelvin-onlab56a3f462015-02-06 14:04:43 -08001621 i = self.handle.expect( [ 'mininet>',
1622 '\$',
1623 pexpect.EOF,
1624 pexpect.TIMEOUT ],
1625 timeout )
1626 if i == 0:
1627 main.log.info( "Exiting mininet..." )
Jon Hall7eb38402015-01-08 17:19:54 -08001628 response = self.execute(
1629 cmd="exit",
1630 prompt="(.*)",
1631 timeout=120 )
Jon Halld80cc142015-07-06 13:36:05 -07001632 main.log.info( self.name + ": Stopped" )
Jon Hall7eb38402015-01-08 17:19:54 -08001633 self.handle.sendline( "sudo mn -c" )
shahshreya328c2a72014-11-17 10:19:50 -08001634 response = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001635
kelvin-onlab56a3f462015-02-06 14:04:43 -08001636 if i == 1:
1637 main.log.info( " Mininet trying to exit while not " +
1638 "in the mininet prompt" )
1639 elif i == 2:
1640 main.log.error( "Something went wrong exiting mininet" )
1641 elif i == 3: # timeout
1642 main.log.error( "Something went wrong exiting mininet " +
1643 "TIMEOUT" )
Jon Hallafa8a472015-06-12 14:02:42 -07001644
Hari Krishnab35c6d02015-03-18 11:13:51 -07001645 if fileName:
Jon Halld80cc142015-07-06 13:36:05 -07001646 self.handle.sendline( "" )
1647 self.handle.expect( '\$' )
1648 self.handle.sendline(
1649 "sudo kill -9 \`ps -ef | grep \"" +
1650 fileName +
1651 "\" | grep -v grep | awk '{print $2}'\`" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001652 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001653 main.log.error( self.name + ": EOF exception found" )
1654 main.log.error( self.name + ": " + self.handle.before )
Jon Hall6094a362014-04-11 14:46:56 -07001655 main.cleanup()
1656 main.exit()
Jon Hall7eb38402015-01-08 17:19:54 -08001657 else:
1658 main.log.error( self.name + ": Connection failed to the host" )
adminbae64d82013-08-01 10:50:15 -07001659 response = main.FALSE
Jon Hallfbc828e2015-01-06 17:30:19 -08001660 return response
1661
kelvin-onlabf0594d72015-05-19 17:25:12 -07001662 def arping( self, host="", ip="10.128.20.211", ethDevice="" ):
kelvin-onlab65782a82015-05-07 14:12:13 -07001663 """
1664 Description:
1665 Sends arp message from mininet host for hosts discovery
1666 Required:
1667 host - hosts name
1668 Optional:
1669 ip - ip address that does not exist in the network so there would
1670 be no reply.
1671 """
kelvin-onlabf0594d72015-05-19 17:25:12 -07001672 if ethDevice:
1673 ethDevice = '-I ' + ethDevice + ' '
Jon Halld80cc142015-07-06 13:36:05 -07001674 cmd = " py " + host + ".cmd(\"arping -c 1 " + ethDevice + ip + "\")"
admin07529932013-11-22 14:58:28 -08001675 try:
kelvin-onlab65782a82015-05-07 14:12:13 -07001676 main.log.warn( "Sending: " + cmd )
1677 self.handle.sendline( cmd )
1678 response = self.handle.before
1679 self.handle.sendline( "" )
1680 self.handle.expect( "mininet>" )
admin07529932013-11-22 14:58:28 -08001681 return main.TRUE
kelvin-onlab65782a82015-05-07 14:12:13 -07001682
1683 except pexpect.EOF:
1684 main.log.error( self.name + ": EOF exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
1686 main.cleanup()
1687 main.exit()
admin07529932013-11-22 14:58:28 -08001688
Jon Hall7eb38402015-01-08 17:19:54 -08001689 def decToHex( self, num ):
1690 return hex( num ).split( 'x' )[ 1 ]
Jon Hallfbc828e2015-01-06 17:30:19 -08001691
Jon Hall7eb38402015-01-08 17:19:54 -08001692 def getSwitchFlowCount( self, switch ):
1693 """
1694 return the Flow Count of the switch"""
admin2a9548d2014-06-17 14:08:07 -07001695 if self.handle:
1696 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
1697 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001698 response = self.execute(
1699 cmd=cmd,
1700 prompt="mininet>",
1701 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001702 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001703 main.log.error( self.name + ": EOF exception found" )
1704 main.log.error( self.name + " " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001705 main.cleanup()
1706 main.exit()
1707 pattern = "flow_count=(\d+)"
Jon Hall7eb38402015-01-08 17:19:54 -08001708 result = re.search( pattern, response, re.MULTILINE )
admin2a9548d2014-06-17 14:08:07 -07001709 if result is None:
Jon Hall7eb38402015-01-08 17:19:54 -08001710 main.log.info(
1711 "Couldn't find flows on switch %s, found: %s" %
1712 ( switch, response ) )
admin2a9548d2014-06-17 14:08:07 -07001713 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001714 return result.group( 1 )
admin2a9548d2014-06-17 14:08:07 -07001715 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001716 main.log.error( "Connection failed to the Mininet host" )
Jon Hallfbc828e2015-01-06 17:30:19 -08001717
kelvin-onlabd3b64892015-01-20 13:26:24 -08001718 def checkFlows( self, sw, dumpFormat=None ):
1719 if dumpFormat:
Jon Hall7eb38402015-01-08 17:19:54 -08001720 command = "sh ovs-ofctl -F " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 dumpFormat + " dump-flows " + str( sw )
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -07001722 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001723 command = "sh ovs-ofctl dump-flows " + str( sw )
admin2a9548d2014-06-17 14:08:07 -07001724 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001725 response = self.execute(
1726 cmd=command,
1727 prompt="mininet>",
1728 timeout=10 )
admin2a9548d2014-06-17 14:08:07 -07001729 return response
1730 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001731 main.log.error( self.name + ": EOF exception found" )
1732 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001733 main.cleanup()
1734 main.exit()
admin2a9548d2014-06-17 14:08:07 -07001735
Jon Hall9043c902015-07-30 14:23:44 -07001736 def getFlowTable( self, protoVersion, sw ):
1737 """
1738 Returns certain fields of an OVS flow table. Will force output to
1739 either OF 1.0 or 1.3 format for consistency.
1740
1741 TODO add option to look at cookies. ignoring them for now
1742
1743 NOTE: Use format to force consistent flow table output across
1744 versions
1745 """
1746 try:
1747 self.handle.sendline( "" )
1748 self.handle.expect( "mininet>" )
1749 command = "sh ovs-ofctl dump-flows " + sw
1750 if protoVersion == 1.0:
1751 command += " -F OpenFlow10-table_id | awk '{OFS=\",\" ;" +\
1752 " print $1 $3 $6 $7 $8}' | "
1753 elif protoVersion == 1.3:
1754 command += " -O OpenFlow13 | awk '{OFS=\",\" ;" +\
1755 " print $1 $3 $6 $7}' | "
1756 else:
1757 main.log.error(
1758 "Unknown protoVersion in getFlowTable(). given: (" +
1759 str( type( protoVersion ) ) +
1760 ") '" + str( protoVersion ) + "'" )
1761 return None
1762 command += "cut -d ',' -f 2- | sort -n -k1 -r"
1763 self.handle.sendline( command )
1764 self.handle.expect( "sort" )
1765 self.handle.expect( "OFPST_FLOW" )
1766 response = self.handle.before
1767 return response
1768 except pexpect.EOF:
1769 main.log.error( self.name + ": EOF exception found" )
1770 main.log.error( self.name + ": " + self.handle.before )
1771 main.cleanup()
1772 main.exit()
1773 except pexpect.TIMEOUT:
1774 main.log.exception( self.name + ": Timeout exception: " )
1775 return None
1776
1777 def flowComp( self, flow1, flow2 ):
1778 if flow1 == flow2:
1779 return main.TRUE
1780 else:
1781 main.log.info( "Flow tables do not match, printing tables:" )
1782 main.log.info( "Flow Table 1:" )
1783 main.log.info( flow1 )
1784 main.log.info( "Flow Table 2:" )
1785 main.log.info( flow2 )
1786 return main.FALSE
1787
kelvin-onlabd3b64892015-01-20 13:26:24 -08001788 def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
Jon Hall7eb38402015-01-08 17:19:54 -08001789 """
Jon Hallefbd9792015-03-05 16:11:36 -08001790 Runs tpdump on an interface and saves the file
Jon Hall7eb38402015-01-08 17:19:54 -08001791 intf can be specified, or the default eth0 is used"""
admin2a9548d2014-06-17 14:08:07 -07001792 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001793 self.handle.sendline( "" )
1794 self.handle.expect( "mininet>" )
1795 self.handle.sendline(
1796 "sh sudo tcpdump -n -i " +
1797 intf +
1798 " " +
1799 port +
1800 " -w " +
1801 filename.strip() +
1802 " &" )
1803 self.handle.sendline( "" )
1804 i = self.handle.expect( [ 'No\ssuch\device',
1805 'listening\son',
1806 pexpect.TIMEOUT,
1807 "mininet>" ],
1808 timeout=10 )
1809 main.log.warn( self.handle.before + self.handle.after )
1810 self.handle.sendline( "" )
1811 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001812 if i == 0:
Jon Hall7eb38402015-01-08 17:19:54 -08001813 main.log.error(
1814 self.name +
1815 ": tcpdump - No such device exists. " +
1816 "tcpdump attempted on: " +
1817 intf )
admin2a9548d2014-06-17 14:08:07 -07001818 return main.FALSE
1819 elif i == 1:
Jon Hall7eb38402015-01-08 17:19:54 -08001820 main.log.info( self.name + ": tcpdump started on " + intf )
admin2a9548d2014-06-17 14:08:07 -07001821 return main.TRUE
1822 elif i == 2:
Jon Hall7eb38402015-01-08 17:19:54 -08001823 main.log.error(
1824 self.name +
1825 ": tcpdump command timed out! Check interface name," +
1826 " given interface was: " +
1827 intf )
admin2a9548d2014-06-17 14:08:07 -07001828 return main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08001829 elif i == 3:
1830 main.log.info( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001831 return main.TRUE
1832 else:
Jon Hall7eb38402015-01-08 17:19:54 -08001833 main.log.error( self.name + ": tcpdump - unexpected response" )
admin2a9548d2014-06-17 14:08:07 -07001834 return main.FALSE
1835 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001836 main.log.error( self.name + ": EOF exception found" )
1837 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001838 main.cleanup()
1839 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001840 except Exception:
1841 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001842 main.cleanup()
1843 main.exit()
1844
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 def stopTcpdump( self ):
Jon Hallefbd9792015-03-05 16:11:36 -08001846 """
1847 pkills tcpdump"""
admin2a9548d2014-06-17 14:08:07 -07001848 try:
Jon Hall7eb38402015-01-08 17:19:54 -08001849 self.handle.sendline( "sh sudo pkill tcpdump" )
1850 self.handle.expect( "mininet>" )
1851 self.handle.sendline( "" )
1852 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07001853 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08001854 main.log.error( self.name + ": EOF exception found" )
1855 main.log.error( self.name + ": " + self.handle.before )
admin2a9548d2014-06-17 14:08:07 -07001856 main.cleanup()
1857 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001858 except Exception:
1859 main.log.exception( self.name + ": Uncaught exception!" )
admin2a9548d2014-06-17 14:08:07 -07001860 main.cleanup()
1861 main.exit()
1862
Jon Halld80cc142015-07-06 13:36:05 -07001863 def getPorts( self, nodeName, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001864 """
1865 Read ports from a Mininet switch.
1866
1867 Returns a json structure containing information about the
1868 ports of the given switch.
1869 """
1870 response = self.getInterfaces( nodeName )
1871 # TODO: Sanity check on response. log if no such switch exists
1872 ports = []
1873 for line in response.split( "\n" ):
1874 if not line.startswith( "name=" ):
1875 continue
1876 portVars = {}
1877 for var in line.split( "," ):
1878 key, value = var.split( "=" )
1879 portVars[ key ] = value
1880 isUp = portVars.pop( 'enabled', "True" )
1881 isUp = "True" in isUp
1882 if verbose:
1883 main.log.info( "Reading switch port %s(%s)" %
1884 ( portVars[ 'name' ], portVars[ 'mac' ] ) )
1885 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001886 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001887 mac = None
1888 ips = []
1889 ip = portVars[ 'ip' ]
1890 if ip == 'None':
1891 ip = None
1892 ips.append( ip )
1893 name = portVars[ 'name' ]
1894 if name == 'None':
1895 name = None
1896 portRe = r'[^\-]\d\-eth(?P<port>\d+)'
1897 if name == 'lo':
1898 portNo = 0xfffe # TODO: 1.0 value - Should we just return lo?
1899 else:
1900 portNo = re.search( portRe, name ).group( 'port' )
1901 ports.append( { 'of_port': portNo,
1902 'mac': str( mac ).replace( '\'', '' ),
1903 'name': name,
1904 'ips': ips,
1905 'enabled': isUp } )
1906 return ports
1907
Jon Halld80cc142015-07-06 13:36:05 -07001908 def getSwitches( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001909 """
1910 Read switches from Mininet.
1911
1912 Returns a dictionary whose keys are the switch names and the value is
1913 a dictionary containing information about the switch.
1914 """
Jon Halla22481b2015-07-28 17:46:01 -07001915 # NOTE: To support new Mininet switch classes, just append the new
1916 # class to the switchClasses variable
Jon Hallafa8a472015-06-12 14:02:42 -07001917
Jon Halla22481b2015-07-28 17:46:01 -07001918 # Regex patterns to parse 'dump' output
1919 # Example Switches:
Jon Hallafa8a472015-06-12 14:02:42 -07001920 # <OVSSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=5238>
Jon Halld80cc142015-07-06 13:36:05 -07001921 # <OVSSwitch{ 'protocols': 'OpenFlow10' } s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=25974>
Jon Halla22481b2015-07-28 17:46:01 -07001922 # <OVSSwitchNS s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None,s1-eth3:None pid=22550>
1923 # <OVSBridge s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=26830>
1924 # <UserSwitch s1: lo:127.0.0.1,s1-eth1:None,s1-eth2:None pid=14737>
1925 switchClasses = r"(OVSSwitch)|(OVSBridge)|(OVSSwitchNS)|(IVSSwitch)|(LinuxBridge)|(UserSwitch)"
1926 swRE = r"<(?P<class>" + switchClasses + r")" +\
1927 r"(?P<options>\{.*\})?\s" +\
1928 r"(?P<name>[^:]+)\:\s" +\
1929 r"(?P<ports>([^,]+,)*[^,\s]+)" +\
1930 r"\spid=(?P<pid>(\d)+)"
Jon Hallafa8a472015-06-12 14:02:42 -07001931 # Update mn port info
1932 self.update()
Jon Halld80cc142015-07-06 13:36:05 -07001933 output = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001934 dump = self.dump().split( "\n" )
1935 for line in dump:
Jon Halla22481b2015-07-28 17:46:01 -07001936 result = re.search( swRE, line, re.I )
1937 if result:
Jon Hallafa8a472015-06-12 14:02:42 -07001938 name = result.group( 'name' )
1939 dpid = str( self.getSwitchDPID( name ) ).zfill( 16 )
Jon Halla22481b2015-07-28 17:46:01 -07001940 pid = result.group( 'pid' )
1941 swClass = result.group( 'class' )
1942 options = result.group( 'options' )
Jon Hallafa8a472015-06-12 14:02:42 -07001943 if verbose:
1944 main.log.info( "Reading switch %s(%s)" % ( name, dpid ) )
1945 ports = self.getPorts( name )
Jon Halla22481b2015-07-28 17:46:01 -07001946 output[ name ] = { "dpid": dpid,
1947 "ports": ports,
1948 "swClass": swClass,
1949 "pid": pid,
1950 "options": options }
Jon Hallafa8a472015-06-12 14:02:42 -07001951 return output
1952
Jon Halld80cc142015-07-06 13:36:05 -07001953 def getHosts( self, verbose=False ):
Jon Hallafa8a472015-06-12 14:02:42 -07001954 """
1955 Read hosts from Mininet.
1956
1957 Returns a dictionary whose keys are the host names and the value is
1958 a dictionary containing information about the host.
1959 """
1960 # Regex patterns to parse dump output
1961 # Example host: <Host h1: h1-eth0:10.0.0.1 pid=5227>
kelvin-onlab299ab062015-07-15 10:58:27 -07001962 # <Host h1: pid=12725>
1963 # <VLANHost h12: h12-eth0.100.100.100:100.1.0.3 pid=30186>
1964 # <dualStackHost h19: h19-eth0:10.1.0.9 pid=30200>
1965 # <IPv6Host h18: h18-eth0:10.0.0.18 pid=30198>
Jon Hallafa8a472015-06-12 14:02:42 -07001966 # NOTE: Does not correctly match hosts with multi-links
1967 # <Host h2: h2-eth0:10.0.0.2,h2-eth1:10.0.1.2 pid=14386>
1968 # FIXME: Fix that
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001969 hostRE = r"Host\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
Jon Halld80cc142015-07-06 13:36:05 -07001970 "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
Jon Hallafa8a472015-06-12 14:02:42 -07001971 # update mn port info
1972 self.update()
1973 # Get mininet dump
1974 dump = self.dump().split( "\n" )
Jon Hall5b0120a2015-06-12 17:35:53 -07001975 hosts = {}
Jon Hallafa8a472015-06-12 14:02:42 -07001976 for line in dump:
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001977 if "Host" in line :
Jon Hallafa8a472015-06-12 14:02:42 -07001978 result = re.search( hostRE, line )
1979 name = result.group( 'name' )
1980 interfaces = []
1981 response = self.getInterfaces( name )
1982 # Populate interface info
1983 for line in response.split( "\n" ):
1984 if line.startswith( "name=" ):
1985 portVars = {}
1986 for var in line.split( "," ):
1987 key, value = var.split( "=" )
1988 portVars[ key ] = value
1989 isUp = portVars.pop( 'enabled', "True" )
1990 isUp = "True" in isUp
1991 if verbose:
1992 main.log.info( "Reading host port %s(%s)" %
1993 ( portVars[ 'name' ],
1994 portVars[ 'mac' ] ) )
1995 mac = portVars[ 'mac' ]
Jon Halld80cc142015-07-06 13:36:05 -07001996 if mac == 'None':
Jon Hallafa8a472015-06-12 14:02:42 -07001997 mac = None
1998 ips = []
1999 ip = portVars[ 'ip' ]
2000 if ip == 'None':
2001 ip = None
2002 ips.append( ip )
2003 intfName = portVars[ 'name' ]
2004 if name == 'None':
2005 name = None
2006 interfaces.append( {
2007 "name": intfName,
2008 "ips": ips,
2009 "mac": str( mac ),
2010 "isUp": isUp } )
Jon Hall5b0120a2015-06-12 17:35:53 -07002011 hosts[ name ] = { "interfaces": interfaces }
Jon Hallafa8a472015-06-12 14:02:42 -07002012 return hosts
2013
2014 def getLinks( self ):
2015 """
2016 Gathers information about current Mininet links. These links may not
2017 be up if one of the ports is down.
2018
2019 Returns a list of dictionaries with link endpoints.
2020
2021 The dictionary structure is:
Jon Halld80cc142015-07-06 13:36:05 -07002022 { 'node1': str( node1 name )
2023 'node2': str( node2 name )
2024 'port1': str( port1 of_port )
2025 'port2': str( port2 of_port ) }
Jon Hallafa8a472015-06-12 14:02:42 -07002026 Note: The port number returned is the eth#, not necessarily the of_port
2027 number. In Mininet, for OVS switch, these should be the same. For
2028 hosts, this is just the eth#.
2029 """
2030 self.update()
2031 response = self.links().split( '\n' )
2032
2033 # Examples:
2034 # s1-eth3<->s2-eth1 (OK OK)
2035 # s13-eth3<->h27-eth0 (OK OK)
2036 linkRE = "(?P<node1>[\w]+)\-eth(?P<port1>[\d]+)\<\-\>" +\
2037 "(?P<node2>[\w]+)\-eth(?P<port2>[\d]+)"
2038 links = []
2039 for line in response:
2040 match = re.search( linkRE, line )
2041 if match:
2042 node1 = match.group( 'node1' )
2043 node2 = match.group( 'node2' )
2044 port1 = match.group( 'port1' )
2045 port2 = match.group( 'port2' )
2046 links.append( { 'node1': node1,
2047 'node2': node2,
2048 'port1': port1,
2049 'port2': port2 } )
2050 return links
2051
2052 def compareSwitches( self, switches, switchesJson, portsJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002053 """
2054 Compare mn and onos switches
Jon Hallafa8a472015-06-12 14:02:42 -07002055 switchesJson: parsed json object from the onos devices api
Jon Hall3d87d502014-10-17 18:37:42 -04002056
Jon Hallafa8a472015-06-12 14:02:42 -07002057 Dependencies:
2058 1. numpy - "sudo pip install numpy"
2059 """
2060 from numpy import uint64
Jon Hall3d87d502014-10-17 18:37:42 -04002061 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall7eb38402015-01-08 17:19:54 -08002062 mnDPIDs = []
Jon Hallafa8a472015-06-12 14:02:42 -07002063 for swName, switch in switches.iteritems():
Jon Hall7eb38402015-01-08 17:19:54 -08002064 mnDPIDs.append( switch[ 'dpid' ].lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002065 mnDPIDs.sort()
kelvin-onlabd3b64892015-01-20 13:26:24 -08002066 if switchesJson == "": # if rest call fails
Jon Hall7eb38402015-01-08 17:19:54 -08002067 main.log.error(
2068 self.name +
Jon Hallfeff3082015-05-19 10:23:26 -07002069 ".compareSwitches(): Empty JSON object given from ONOS" )
Jon Hall3d87d502014-10-17 18:37:42 -04002070 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 onos = switchesJson
Jon Hall7eb38402015-01-08 17:19:54 -08002072 onosDPIDs = []
Jon Hall3d87d502014-10-17 18:37:42 -04002073 for switch in onos:
Jon Hall7eb38402015-01-08 17:19:54 -08002074 if switch[ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002075 onosDPIDs.append(
2076 switch[ 'id' ].replace(
2077 ":",
2078 '' ).replace(
2079 "of",
2080 '' ).lower() )
Jon Hall3d87d502014-10-17 18:37:42 -04002081 onosDPIDs.sort()
Jon Hall3d87d502014-10-17 18:37:42 -04002082
Jon Hall7eb38402015-01-08 17:19:54 -08002083 if mnDPIDs != onosDPIDs:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 switchResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002085 main.log.error( "Switches in MN but not in ONOS:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002086 list1 = [ switch for switch in mnDPIDs if switch not in onosDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002087 main.log.error( str( list1 ) )
2088 main.log.error( "Switches in ONOS but not in MN:" )
Jon Hall7eb38402015-01-08 17:19:54 -08002089 list2 = [ switch for switch in onosDPIDs if switch not in mnDPIDs ]
Jon Hallafa8a472015-06-12 14:02:42 -07002090 main.log.error( str( list2 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002091 else: # list of dpid's match in onos and mn
kelvin-onlabd3b64892015-01-20 13:26:24 -08002092 switchResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07002093 finalResults = switchResults
Jon Hall3d87d502014-10-17 18:37:42 -04002094
Jon Hall7eb38402015-01-08 17:19:54 -08002095 # FIXME: this does not look for extra ports in ONOS, only checks that
2096 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 portsResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002098
Jon Hall7eb38402015-01-08 17:19:54 -08002099 # PORTS
Jon Hallafa8a472015-06-12 14:02:42 -07002100 for name, mnSwitch in switches.iteritems():
kelvin-onlabd3b64892015-01-20 13:26:24 -08002101 mnPorts = []
2102 onosPorts = []
2103 switchResult = main.TRUE
2104 for port in mnSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002105 if port[ 'enabled' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002106 mnPorts.append( int( port[ 'of_port' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002107 for onosSwitch in portsJson:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 if onosSwitch[ 'device' ][ 'available' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002109 if onosSwitch[ 'device' ][ 'id' ].replace(
2110 ':',
2111 '' ).replace(
2112 "of",
2113 '' ) == mnSwitch[ 'dpid' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002114 for port in onosSwitch[ 'ports' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002115 if port[ 'isEnabled' ]:
2116 if port[ 'port' ] == 'local':
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 # onosPorts.append( 'local' )
2118 onosPorts.append( long( uint64( -2 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002119 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002120 onosPorts.append( int( port[ 'port' ] ) )
Jon Hallb1290e82014-11-18 16:17:48 -05002121 break
kelvin-onlabd3b64892015-01-20 13:26:24 -08002122 mnPorts.sort( key=float )
2123 onosPorts.sort( key=float )
Jon Hallafa8a472015-06-12 14:02:42 -07002124
kelvin-onlabd3b64892015-01-20 13:26:24 -08002125 mnPortsLog = mnPorts
2126 onosPortsLog = onosPorts
2127 mnPorts = [ x for x in mnPorts ]
2128 onosPorts = [ x for x in onosPorts ]
Jon Hall38481722014-11-04 16:50:05 -05002129
Jon Hall7eb38402015-01-08 17:19:54 -08002130 # TODO: handle other reserved port numbers besides LOCAL
2131 # NOTE: Reserved ports
2132 # Local port: -2 in Openflow, ONOS shows 'local', we store as
2133 # long( uint64( -2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 for mnPort in mnPortsLog:
2135 if mnPort in onosPorts:
Jon Hall7eb38402015-01-08 17:19:54 -08002136 # don't set results to true here as this is just one of
2137 # many checks and it might override a failure
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 mnPorts.remove( mnPort )
2139 onosPorts.remove( mnPort )
Jon Hallafa8a472015-06-12 14:02:42 -07002140
Jon Hall7eb38402015-01-08 17:19:54 -08002141 # NOTE: OVS reports this as down since there is no link
Jon Hallb1290e82014-11-18 16:17:48 -05002142 # So ignoring these for now
Jon Hall7eb38402015-01-08 17:19:54 -08002143 # TODO: Come up with a better way of handling these
kelvin-onlabd3b64892015-01-20 13:26:24 -08002144 if 65534 in mnPorts:
2145 mnPorts.remove( 65534 )
2146 if long( uint64( -2 ) ) in onosPorts:
2147 onosPorts.remove( long( uint64( -2 ) ) )
2148 if len( mnPorts ): # the ports of this switch don't match
2149 switchResult = main.FALSE
2150 main.log.warn( "Ports in MN but not ONOS: " + str( mnPorts ) )
2151 if len( onosPorts ): # the ports of this switch don't match
2152 switchResult = main.FALSE
Jon Hall7eb38402015-01-08 17:19:54 -08002153 main.log.warn(
2154 "Ports in ONOS but not MN: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 str( onosPorts ) )
2156 if switchResult == main.FALSE:
Jon Hallafa8a472015-06-12 14:02:42 -07002157 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002158 "The list of ports for switch %s(%s) does not match:" %
Jon Hallafa8a472015-06-12 14:02:42 -07002159 ( name, mnSwitch[ 'dpid' ] ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 main.log.warn( "mn_ports[] = " + str( mnPortsLog ) )
2161 main.log.warn( "onos_ports[] = " + str( onosPortsLog ) )
2162 portsResults = portsResults and switchResult
Jon Hallafa8a472015-06-12 14:02:42 -07002163 finalResults = finalResults and portsResults
2164 return finalResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002165
Jon Hallafa8a472015-06-12 14:02:42 -07002166 def compareLinks( self, switches, links, linksJson ):
Jon Hall7eb38402015-01-08 17:19:54 -08002167 """
2168 Compare mn and onos links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002169 linksJson: parsed json object from the onos links api
Jon Hall72cf1dc2014-10-20 21:04:50 -04002170
Jon Hallafa8a472015-06-12 14:02:42 -07002171 """
Jon Hall7eb38402015-01-08 17:19:54 -08002172 # FIXME: this does not look for extra links in ONOS, only checks that
Jon Hallefbd9792015-03-05 16:11:36 -08002173 # ONOS has what is in MN
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 onos = linksJson
Jon Hall72cf1dc2014-10-20 21:04:50 -04002175
Jon Halld80cc142015-07-06 13:36:05 -07002176 mnLinks = []
Jon Hallafa8a472015-06-12 14:02:42 -07002177 for l in links:
2178 try:
2179 node1 = switches[ l[ 'node1' ] ]
2180 node2 = switches[ l[ 'node2' ] ]
2181 enabled = True
2182 for port in node1[ 'ports' ]:
2183 if port[ 'of_port' ] == l[ 'port1' ]:
2184 enabled = enabled and port[ 'enabled' ]
2185 for port in node2[ 'ports' ]:
Jon Halld80cc142015-07-06 13:36:05 -07002186 if port[ 'of_port' ] == l[ 'port2' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002187 enabled = enabled and port[ 'enabled' ]
2188 if enabled:
2189 mnLinks.append( l )
2190 except KeyError:
2191 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002192 if 2 * len( mnLinks ) == len( onos ):
2193 linkResults = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002194 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 linkResults = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002196 main.log.error(
Jon Hall328ddca2015-01-28 15:57:15 -08002197 "Mininet has " + str( len( mnLinks ) ) +
2198 " bidirectional links and ONOS has " +
2199 str( len( onos ) ) + " unidirectional links" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002200
Jon Hall7eb38402015-01-08 17:19:54 -08002201 # iterate through MN links and check if an ONOS link exists in
2202 # both directions
kelvin-onlabd3b64892015-01-20 13:26:24 -08002203 for link in mnLinks:
Jon Hall7eb38402015-01-08 17:19:54 -08002204 # TODO: Find a more efficient search method
Jon Hall72cf1dc2014-10-20 21:04:50 -04002205 node1 = None
2206 port1 = None
2207 node2 = None
2208 port2 = None
kelvin-onlabd3b64892015-01-20 13:26:24 -08002209 firstDir = main.FALSE
2210 secondDir = main.FALSE
Jon Hallafa8a472015-06-12 14:02:42 -07002211 for swName, switch in switches.iteritems():
2212 if swName == link[ 'node1' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002213 node1 = switch[ 'dpid' ]
2214 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002215 if str( port[ 'of_port' ] ) == str( link[ 'port1' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002216 port1 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002217 if node1 is not None and node2 is not None:
2218 break
Jon Hallafa8a472015-06-12 14:02:42 -07002219 if swName == link[ 'node2' ]:
Jon Hall7eb38402015-01-08 17:19:54 -08002220 node2 = switch[ 'dpid' ]
2221 for port in switch[ 'ports' ]:
Jon Hallafa8a472015-06-12 14:02:42 -07002222 if str( port[ 'of_port' ] ) == str( link[ 'port2' ] ):
Jon Hall7eb38402015-01-08 17:19:54 -08002223 port2 = port[ 'of_port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002224 if node1 is not None and node2 is not None:
2225 break
2226
kelvin-onlabd3b64892015-01-20 13:26:24 -08002227 for onosLink in onos:
2228 onosNode1 = onosLink[ 'src' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002229 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002230 onosNode2 = onosLink[ 'dst' ][ 'device' ].replace(
Jon Hallafa8a472015-06-12 14:02:42 -07002231 ":", '' ).replace( "of", '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002232 onosPort1 = onosLink[ 'src' ][ 'port' ]
2233 onosPort2 = onosLink[ 'dst' ][ 'port' ]
Jon Hall72cf1dc2014-10-20 21:04:50 -04002234
Jon Hall72cf1dc2014-10-20 21:04:50 -04002235 # check onos link from node1 to node2
kelvin-onlabd3b64892015-01-20 13:26:24 -08002236 if str( onosNode1 ) == str( node1 ) and str(
2237 onosNode2 ) == str( node2 ):
2238 if int( onosPort1 ) == int( port1 ) and int(
2239 onosPort2 ) == int( port2 ):
2240 firstDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002241 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002242 main.log.warn(
2243 'The port numbers do not match for ' +
2244 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002245 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002246 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002247 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002248 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002249 ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002250
2251 # check onos link from node2 to node1
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 elif ( str( onosNode1 ) == str( node2 ) and
2253 str( onosNode2 ) == str( node1 ) ):
2254 if ( int( onosPort1 ) == int( port2 )
2255 and int( onosPort2 ) == int( port1 ) ):
2256 secondDir = main.TRUE
Jon Hall72cf1dc2014-10-20 21:04:50 -04002257 else:
Jon Hall7eb38402015-01-08 17:19:54 -08002258 main.log.warn(
2259 'The port numbers do not match for ' +
2260 str( link ) +
Jon Hallefbd9792015-03-05 16:11:36 -08002261 ' between ONOS and MN. When checking ONOS for ' +
Jon Hall7eb38402015-01-08 17:19:54 -08002262 'link %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002263 ( node1, port1, node2, port2 ) +
Jon Hall7eb38402015-01-08 17:19:54 -08002264 ' ONOS has the values %s/%s -> %s/%s' %
Jon Hallafa8a472015-06-12 14:02:42 -07002265 ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
Jon Hall7eb38402015-01-08 17:19:54 -08002266 else: # this is not the link you're looking for
Jon Hall72cf1dc2014-10-20 21:04:50 -04002267 pass
kelvin-onlabd3b64892015-01-20 13:26:24 -08002268 if not firstDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002269 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002270 'ONOS does not have the link %s/%s -> %s/%s' %
2271 ( node1, port1, node2, port2 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 if not secondDir:
Jon Hallafa8a472015-06-12 14:02:42 -07002273 main.log.error(
Jon Hall7eb38402015-01-08 17:19:54 -08002274 'ONOS does not have the link %s/%s -> %s/%s' %
2275 ( node2, port2, node1, port1 ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 linkResults = linkResults and firstDir and secondDir
2277 return linkResults
Jon Hall72cf1dc2014-10-20 21:04:50 -04002278
Jon Hallafa8a472015-06-12 14:02:42 -07002279 def compareHosts( self, hosts, hostsJson ):
Jon Hallff6b4b22015-02-23 09:25:15 -08002280 """
Jon Hallafa8a472015-06-12 14:02:42 -07002281 Compare mn and onos Hosts.
2282 Since Mininet hosts are quiet, ONOS will only know of them when they
2283 speak. For this reason, we will only check that the hosts in ONOS
2284 stores are in Mininet, and not vice versa.
Jon Hallff6b4b22015-02-23 09:25:15 -08002285
Jon Hallafa8a472015-06-12 14:02:42 -07002286 Arguments:
2287 hostsJson: parsed json object from the onos hosts api
2288 Returns:
2289 """
Jon Hallff6b4b22015-02-23 09:25:15 -08002290 import json
2291 hostResults = main.TRUE
Jon Hallff6b4b22015-02-23 09:25:15 -08002292 for onosHost in hostsJson:
2293 onosMAC = onosHost[ 'mac' ].lower()
2294 match = False
Jon Halld80cc142015-07-06 13:36:05 -07002295 for mnHost, info in hosts.iteritems():
2296 for mnIntf in info[ 'interfaces' ]:
2297 if onosMAC == mnIntf[ 'mac' ].lower():
Jon Hallff6b4b22015-02-23 09:25:15 -08002298 match = True
2299 for ip in mnIntf[ 'ips' ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002300 if ip in onosHost[ 'ipAddresses' ]:
Jon Hallff6b4b22015-02-23 09:25:15 -08002301 pass # all is well
2302 else:
2303 # misssing ip
Jon Halld80cc142015-07-06 13:36:05 -07002304 main.log.error( "ONOS host " +
2305 onosHost[ 'id' ] +
2306 " has a different IP(" +
Jon Hallafa8a472015-06-12 14:02:42 -07002307 str( onosHost[ 'ipAddresses' ] ) +
2308 ") than the Mininet host(" +
Jon Halld80cc142015-07-06 13:36:05 -07002309 str( ip ) +
2310 ")." )
Jon Hallff6b4b22015-02-23 09:25:15 -08002311 output = json.dumps(
Jon Halld80cc142015-07-06 13:36:05 -07002312 onosHost,
2313 sort_keys=True,
2314 indent=4,
2315 separators=( ',', ': ' ) )
Jon Hallff6b4b22015-02-23 09:25:15 -08002316 main.log.info( output )
2317 hostResults = main.FALSE
2318 if not match:
2319 hostResults = main.FALSE
2320 main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
2321 "corresponding Mininet host." )
2322 output = json.dumps( onosHost,
2323 sort_keys=True,
2324 indent=4,
2325 separators=( ',', ': ' ) )
2326 main.log.info( output )
Jon Hallff6b4b22015-02-23 09:25:15 -08002327 return hostResults
2328
Jon Hallafa8a472015-06-12 14:02:42 -07002329 def getHostsOld( self ):
Jon Hall7eb38402015-01-08 17:19:54 -08002330 """
2331 Returns a list of all hosts
2332 Don't ask questions just use it"""
2333 self.handle.sendline( "" )
2334 self.handle.expect( "mininet>" )
Jon Hall72cf1dc2014-10-20 21:04:50 -04002335
Jon Hall7eb38402015-01-08 17:19:54 -08002336 self.handle.sendline( "py [ host.name for host in net.hosts ]" )
2337 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002338
kelvin-onlabd3b64892015-01-20 13:26:24 -08002339 handlePy = self.handle.before
2340 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2341 handlePy = handlePy.rstrip()
admin2a9548d2014-06-17 14:08:07 -07002342
Jon Hall7eb38402015-01-08 17:19:54 -08002343 self.handle.sendline( "" )
2344 self.handle.expect( "mininet>" )
admin2a9548d2014-06-17 14:08:07 -07002345
kelvin-onlabd3b64892015-01-20 13:26:24 -08002346 hostStr = handlePy.replace( "]", "" )
2347 hostStr = hostStr.replace( "'", "" )
2348 hostStr = hostStr.replace( "[", "" )
kelvin-onlab2ccad6e2015-05-18 10:36:54 -07002349 hostStr = hostStr.replace( " ", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002350 hostList = hostStr.split( "," )
andrewonlab3f0a4af2014-10-17 12:25:14 -04002351
kelvin-onlabd3b64892015-01-20 13:26:24 -08002352 return hostList
adminbae64d82013-08-01 10:50:15 -07002353
kelvin-onlabfa6ada82015-06-11 13:06:24 -07002354 def getSwitch( self ):
2355 """
2356 Returns a list of all switches
2357 Again, don't ask question just use it...
2358 """
2359 # get host list...
2360 hostList = self.getHosts()
2361 # Make host set
2362 hostSet = set( hostList )
2363
2364 # Getting all the nodes in mininet
2365 self.handle.sendline( "" )
2366 self.handle.expect( "mininet>" )
2367
2368 self.handle.sendline( "py [ node.name for node in net.values() ]" )
2369 self.handle.expect( "mininet>" )
2370
2371 handlePy = self.handle.before
2372 handlePy = handlePy.split( "]\r\n", 1 )[ 1 ]
2373 handlePy = handlePy.rstrip()
2374
2375 self.handle.sendline( "" )
2376 self.handle.expect( "mininet>" )
2377
2378 nodesStr = handlePy.replace( "]", "" )
2379 nodesStr = nodesStr.replace( "'", "" )
2380 nodesStr = nodesStr.replace( "[", "" )
2381 nodesStr = nodesStr.replace( " ", "" )
2382 nodesList = nodesStr.split( "," )
2383
2384 nodesSet = set( nodesList )
2385 # discarding default controller(s) node
2386 nodesSet.discard( 'c0' )
2387 nodesSet.discard( 'c1' )
2388 nodesSet.discard( 'c2' )
2389
2390 switchSet = nodesSet - hostSet
2391 switchList = list( switchSet )
2392
2393 return switchList
2394
Jon Hall7eb38402015-01-08 17:19:54 -08002395 def update( self ):
2396 """
2397 updates the port address and status information for
2398 each port in mn"""
2399 # TODO: Add error checking. currently the mininet command has no output
Jon Hallefbd9792015-03-05 16:11:36 -08002400 main.log.info( "Updating MN port information" )
Jon Hallb1290e82014-11-18 16:17:48 -05002401 try:
Jon Hall7eb38402015-01-08 17:19:54 -08002402 self.handle.sendline( "" )
2403 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002404
Jon Hall7eb38402015-01-08 17:19:54 -08002405 self.handle.sendline( "update" )
2406 self.handle.expect( "update" )
2407 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002408
Jon Hall7eb38402015-01-08 17:19:54 -08002409 self.handle.sendline( "" )
2410 self.handle.expect( "mininet>" )
Jon Hall38481722014-11-04 16:50:05 -05002411
Jon Hallb1290e82014-11-18 16:17:48 -05002412 return main.TRUE
2413 except pexpect.EOF:
Jon Hall7eb38402015-01-08 17:19:54 -08002414 main.log.error( self.name + ": EOF exception found" )
2415 main.log.error( self.name + ": " + self.handle.before )
Jon Hallb1290e82014-11-18 16:17:48 -05002416 main.cleanup()
2417 main.exit()
2418
Jon Halld80cc142015-07-06 13:36:05 -07002419 def assignVLAN( self, host, intf, vlan ):
kaouthera3f13ca22015-05-05 15:01:41 -07002420 """
2421 Add vlan tag to a host.
2422 Dependencies:
2423 This class depends on the "vlan" package
2424 $ sudo apt-get install vlan
2425 Configuration:
2426 Load the 8021q module into the kernel
2427 $sudo modprobe 8021q
2428
2429 To make this setup permanent:
2430 $ sudo su -c 'echo "8021q" >> /etc/modules'
2431 """
2432 if self.handle:
2433 try:
Jon Halld80cc142015-07-06 13:36:05 -07002434 # get the ip address of the host
2435 main.log.info( "Get the ip address of the host" )
2436 ipaddr = self.getIPAddress( host )
2437 print repr( ipaddr )
kaouthera3f13ca22015-05-05 15:01:41 -07002438
Jon Halld80cc142015-07-06 13:36:05 -07002439 # remove IP from interface intf
2440 # Ex: h1 ifconfig h1-eth0 inet 0
2441 main.log.info( "Remove IP from interface " )
2442 cmd2 = host + " ifconfig " + intf + " " + " inet 0 "
2443 self.handle.sendline( cmd2 )
2444 self.handle.expect( "mininet>" )
2445 response = self.handle.before
2446 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002447
Jon Halld80cc142015-07-06 13:36:05 -07002448 # create VLAN interface
2449 # Ex: h1 vconfig add h1-eth0 100
2450 main.log.info( "Create Vlan" )
2451 cmd3 = host + " vconfig add " + intf + " " + vlan
2452 self.handle.sendline( cmd3 )
2453 self.handle.expect( "mininet>" )
2454 response = self.handle.before
2455 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002456
Jon Halld80cc142015-07-06 13:36:05 -07002457 # assign the host's IP to the VLAN interface
2458 # Ex: h1 ifconfig h1-eth0.100 inet 10.0.0.1
2459 main.log.info( "Assign the host IP to the vlan interface" )
2460 vintf = intf + "." + vlan
2461 cmd4 = host + " ifconfig " + vintf + " " + " inet " + ipaddr
2462 self.handle.sendline( cmd4 )
2463 self.handle.expect( "mininet>" )
2464 response = self.handle.before
2465 main.log.info( "====> %s ", response )
kaouthera3f13ca22015-05-05 15:01:41 -07002466
2467 return main.TRUE
2468 except pexpect.EOF:
2469 main.log.error( self.name + ": EOF exception found" )
2470 main.log.error( self.name + ": " + self.handle.before )
2471 return main.FALSE
2472
adminbae64d82013-08-01 10:50:15 -07002473if __name__ != "__main__":
2474 import sys
kelvin-onlab50907142015-04-01 13:37:45 -07002475 sys.modules[ __name__ ] = MininetCliDriver()